www.gusucode.com > mbcexpr 工具箱 matlab 源码程序 > mbcexpr/@cglookup/guiInvertTable.m
function [Tfill,OK] = guiInvertTable(Tinv,CGP) %guiInvertTable table inversion dialog % OK = guiInvertTable(LT,CGP) % Copyright 2013-2013 The MathWorks, Inc. and Ford Global Technologies, Inc. Tlist = filterbytype(info(CGP), cgtypes.cgtabletype); OK = false; Tfill = []; [pTableList,TableListString] = InversionFilter(Tinv,Tlist); % check that there are tables to invert if ~isempty(pTableList) % need 'HelpCode' d = mbcgui.container.Dialog('Name', 'Table Inversion',... 'Size', [400, 500],... 'HelpCode','cgInvertTable',... 'Buttons', 'OK_CANCEL_HELP'); pUD = xregGui.RunTimePointer; d.Content = createLayout(d.Figure,pUD); ud = pUD.info; set(ud.tableCombo,'String',TableListString,'Value',1); ud.pTableList = pTableList; ud.Tinv = Tinv; ud.Dialog = d; pUD.info = ud; % update the GUI update(pUD) % Does the waitfor closeMode = d.showDialog(); % The tag is set to either 'OK' or 'CANCEL' switch closeMode case 'OK' OK = true; % get filled table from user data ud = pUD.info; % update on heap xregpointer(ud.TFill); Tfill = ud.TFill; case 'CANCEL' end delete(d) else h = errordlg(sprintf('There are no tables to fill with an inversion of %s.', ... iTableLabel(Tinv)), 'Inversion Error', 'modal'); waitfor(h); end function lyt = createLayout(Parent,pUD) %createLayout create dialog layout % lyt = createLayout(Parent,pUD) % pUD is an xregGui.RunTimePointer to contain user data % popup for tables ud.tableCombo = uicontrol('Parent',Parent,... 'Style','popupmenu',... 'Callback',{@iCallBack,pUD},... 'BackgroundColor','w',... 'Tag','TableSelectCombo'); tableLabel = xregGui.labelcontrol('parent',Parent,... 'LabelAlignment','left','gap',5,... 'control', ud.tableCombo ,... 'ControlSize',180,... 'string','Table to fill:'); ud.inversionInfo = uicontrol('Parent',Parent,... 'Style','text',... 'HorizontalAlignment','left'); %Multiple values ud.multiCombo = uicontrol('Parent',Parent,... 'Style','popupmenu',... 'String',{'Minimum','Maximum','Intermediate','Least squares'},... 'Value',4,... 'Callback',{@iCallBack,pUD},... 'BackgroundColor','w',... 'Tag','ResolveMethodCombo'); multilabel = xregGui.labelcontrol('parent',Parent,... 'LabelAlignment','left','gap',5,... 'control', ud.multiCombo ,... 'ControlSize',180,... 'string','Resolve nonunique inverses with:'); % Axes and plot type combo box complayout = mbcgui.container.layoutpanel(... 'Parent', Parent, ... 'Title','Inversion Error',... 'BorderType', 'beveledin'); ud.ComparisonPane = cgtools.comparisonpane('Parent', complayout); % display inversion error by default ud.ComparisonPane.PlotType = 2; plottypecombo = ud.ComparisonPane.createComboController(... 'Parent', complayout,... 'Tag', 'ErrorPlotTypeCombo'); cblabel = xregGui.labelcontrol('parent',complayout,... 'LabelAlignment','left','gap',5,... 'control', plottypecombo ,... 'ControlSize',180,... 'string','Plot type:'); DisplayLyt = xreggridbaglayout(complayout,... 'dimension',[2,1],... 'rowsizes',[20,-1],... 'gap',2, ... 'elements',{cblabel, ud.ComparisonPane }); set(complayout, 'LayoutComponent', {DisplayLyt}); lyt = xreggridbaglayout(Parent,... 'dimension',[4,1],... 'rowsizes',[20,20,40,-1],... 'gap',5, ... 'elements',{tableLabel, multilabel,ud.inversionInfo,complayout}); pUD.info = ud; function iCallBack(~,~,pUD) % call back function pass user data to update update(pUD) function update(pUD) %update update table inversion ud = pUD.info; % get tabNumber = get(ud.tableCombo,'Value'); Tfill = info(ud.pTableList( tabNumber )); flag = get(ud.multiCombo,'Value'); % always start from base table values % ud.Tfill.info = ud.BaseTable; [signal,p1,p2]=commonInputs(Tfill,ud.Tinv); if ~isscalar(signal) % perform table inversion for 2D lookup [Tfill,err] = tableinversion(Tfill,ud.Tinv,signal(2), signal(1), 1,flag); else % perform table inversion for 1D lookup [Tfill,err] = tableinversion(Tfill, ud.Tinv,flag); end set(ud.inversionInfo,'String',sprintf('Invert %s: %s to %s',iTableLabel(ud.Tinv),p1.getname, p2.getname)) if ~isempty(err) % disable errordlg(err,'Table Inversion Error','modal'); disableButtons(ud.Dialog,'OK'); else enableButtons(ud.Dialog,'OK'); plotInversion(ud,Tfill,ud.Tinv,signal,p2) ud.TFill = Tfill; pUD.info = ud; end function [signal,p1,p2]=commonInputs(T1,T2) p1 = get(T1,'axesptrs'); p2 = get(T2,'axesptrs'); if length(p1)==2 % determine the common signal for 2D tables OK1 = ismember(p1,p2); OK2 = ismember(p2,p1); % need to invert as axes ptrs are stored as X,Y whereas tables are stored as rows(Y)/cols(X). p1 = p1(~OK1); p2 = p2(~OK2); signal = [find(~OK1) find(~OK2)]; else signal = 0; end function plotInversion(ud,Tfill,Tinv,signal,p2) %plotInversion update the comparison plot for inversion % plotInversion(ud,Tfill,Tinv,signal,p2) % Tfill(Tinv(Xinput,Y),Y) -> XOutput % Tfill(X,Tinv(X,Yinput)) -> YOutput % A perfect inversion should have Xinput = Xoutput. TfillVal = get(Tfill,'values'); TinvVal = get(Tinv,'values'); cgm = cgmathsobject; if isscalar(signal) % 1D Table comparison fLinear1 = gethandle(cgm, 'linear1'); % our x axis is the input to the inverted table xptr = get(Tinv,'axesptrs'); xname = xptr.getname; TfillBP = get(Tfill,'allbreakpoints'); TinvBP = get(Tinv,'allbreakpoints'); % For the input, use 51 points, evenly covering the range of the inverted table input plotX = linspace(TinvBP(1),TinvBP(end),51); % Our first output is the same as the input. Input = plotX; % Get the output of the inverted table over this range. TinvValEx = fLinear1(TinvBP,TinvVal,plotX); % Now get the output from the new table from these inputs. This is our % second output. Output = fLinear1(TfillBP,TfillVal,TinvValEx); yname = []; plotY = []; else % 2D table comparison fExtInterp2 = gethandle(cgm,'extinterp2'); fLinear2 = gethandle(cgm, 'linear2'); xptr = get(Tinv,'axesptrs'); xname = xptr(1).getname; yname = xptr(2).getname; TfillBPx = i_getbreakpoints(Tfill,'x'); TfillBPy = i_getbreakpoints(Tfill,'y'); TinvBPx = i_getbreakpoints(Tinv,'x'); TinvBPy = i_getbreakpoints(Tinv,'y'); TinvVal = get(Tinv,'values'); TinvVal = TinvVal'; % transpose so that it is length(x) * length(y) % For our input, we'll use 51 points in each direction, % evenly covering the ranges of the inverted table inputs plotX = linspace(TinvBPx(1),TinvBPx(end),51); plotY = linspace(TinvBPy(1),TinvBPy(end),51); % Get the output of the inverted table over this range TinvValEx = fLinear2(TinvBPx,TinvBPy,TinvVal,plotX,plotY); [X,Y] = ndgrid(plotX,plotY); % Now calculate the output of the new table over this range, taking care to % match up the correct signals. if isequal(signal,[2,2]) % Y = Tfill( X , Tinv ) Input = Y; Output = fExtInterp2(TfillBPx,TfillBPy,TfillVal,X,TinvValEx); elseif isequal(signal,[2,1]) % X = Tfill( Y , Tinv ) Input = X; Output = fExtInterp2(TfillBPx,TfillBPy,TfillVal,Y,TinvValEx); elseif isequal(signal,[1,2]) % Y = Tfill( Tinv , X ) Input = Y; Output = fExtInterp2(TfillBPx,TfillBPy,TfillVal,TinvValEx,X); elseif isequal(signal,[1,1]) % X = Tfill( Tinv , Y ) Input = X; Output = fExtInterp2(TfillBPx,TfillBPy,TfillVal,TinvValEx,Y); end end % Note transposes to get orientations correct ud.ComparisonPane.setdata(Input',Output', plotX, xname, plotY, yname); ud.ComparisonPane.setDataNames([p2.getname,' Input'],[p2.getname,' Output']); %---------------------------------- function bp = i_getbreakpoints(LT,expr) normptr = get(LT,expr); vals = normptr.get('values'); bp = normptr.invert(0:vals(end)); function str = iTableLabel(LT) pInputs = get(LT,'axesptrs'); str = sprintf('%s(%s)',getname(LT), strjoin( fliplr(pveceval(pInputs,@getname)),',' ));