www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/@xregdynlolimot/poles.m
function varargout = poles( m, action, varargin ) %XREGARX/POLES Plot the poles of a dynamic lolimot model % FIGH = POLES(M,'Figure',NAME,TSAMPLE) displays a window for viewing the % poles of the linear submodels (betamodels) of the dynamic lolimot model M. % NAME is an optional string containing the model name to be displayed in % the title bar of the window. TSAMPLE is the time in seconds for each sample % and is also optional. It is used to calculate the time constant for the % poles. % % POLES(M,'Enable') returns true of false to indicate whether this pole % viewer is available for the given dynamic lolimot model M. % % [LYT,UD] = POLES(M,'Layout',FIGH) % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. if nargin < 1, error(message('mbc:xregdynlolimot:InvalidArgument5')); end if nargin < 2, action = 'Figure'; end switch lower( action ), case 'enable', varargout{1} = i_IsLinearLolimot( m ); case 'figure', varargout{1} = i_CreateDialog( m, varargin{:} ); case 'layout', [varargout{1}, varargout{2}] = i_CreateLayout( m, varargin{:} ); otherwise error(message('mbc:xregdynlolimot:InvalidArgument6', action)); end return %------------------------------------------------------------------------------| function en = i_IsLinearLolimot( m ) % en is a 0/1 flag which to enable/disable the menu item on the main MBC Browser % Must have a feedback term if m.delmat(1,end) == 0, en = 0; return end % To be able to enable ploting of the poles all the beta models must be linear bm = get( m, 'BetaModels' ); ncent = size( get( m, 'centers' ), 1 ); bmc = cell( 1, ncent ); for i=1:ncent, bmc{i} = name( bm{i} ); end bmc = unique( bmc ); en = ( length( bmc ) == 1 ) & ... ( strcmpi( bmc, 'linear' ) | strcmpi( bmc, 'xreglinear' ) ); return %------------------------------------------------------------------------------| function figh = i_CreateDialog( m, modelname, tsample ) i_deleteold if nargin < 2, modelname = ''; end if nargin < 3, tsample = 1; end figh = xregfigure('Tag', i_hash_fig_tag,... 'Name', sprintf( 'LOLIMOT Poles: %s', modelname ),... 'Visible', 'Off' ); xregcenterfigure( figh, [600, 450] ); figh.MinimumSize = [600, 450]; [lyt, ud] = i_CreateLayout( m, figh ); ud.model = m; ud.tsample = tsample; btnClose = uicontrol( 'Parent', figh,... 'Style', 'PushButton',... 'String', 'Close',... 'Interruptible', 'off',... 'Callback', 'set( gcbf, ''visible'', ''off'' );' ); DividerLine = xregGui.dividerline( figh ); lyt = xreggridbaglayout( figh, ... 'Dimension',[3, 3],... 'RowSizes',[-1, 2, 25 ],... 'ColSizes',[-1, 65, 65],... 'GapY',5,... 'GapX',7,... 'Border',[5, 5, 5, 5],... 'MergeBlock', { [1, 1], [1, 3] }, ... 'MergeBlock', { [2, 2], [1, 3] }, ... 'Elements', { ... lyt, [], []; ... DividerLine, [], []; ... [], [], btnClose } ); % tell the figure about all the data associated with it set( figh, 'UserData', ud ); % Initialization i_clickModel( [], [], figh ); % % All ready, turn it on figh.LayoutManager = lyt; set( lyt, 'packstatus', 'on' ); set( figh, 'Visible', 'on' ); % we wait for the user to close the window %%delete( figh ); return %------------------------------------------------------------------------------| function [lyt, ud] = i_CreateLayout( m, figh ) % +---------------------------------------------------+ % | Local Model <[ ]> [Plot][Table] | % | +--------------------+ +----+------+-----------+ | % | | Center Width | | | | % | | x1 [ ] [ ] | | | | % | | x2 [ ] [ ] | | | | % | | y1 [ ] [ ] | | | | % | | | | | | % | +--------------------+ +-----------------------+ | % +---------------------------------------------------+ BackgroundColor = get( figh, 'Color' ); ncent = get( m, 'NumberOfCenters' ); symbols = get( m, 'Symbols' ); nf = length( symbols ); ud.clickModel = mbcgui.widget.Spinner( 'Parent', figh, ... 'Min', 1, ... 'Max', ncent, ... 'ClickIncrement', 1, ... 'Visible', 'on', ... 'Callback', { @i_clickModel, figh } ); lctrlModel = xregGui.labelcontrol( ... 'parent',figh,... 'Control', ud.clickModel,... 'String','Local Model',... 'Enable','on', ... 'ControlSize', 100, ... 'ControlSizeMode', 'absolute'); % center and width display table ud.tableCenterWidth = xregtable( figh,... 'frame.visible', 'off',... 'frame.hborder', [0, 0],... 'frame.vborder', [0, 0],... 'defaultcellformat', '%.4f',... 'defaultcelltype', 'uiedit',... 'cols.size', 55,... 'cols.spacing', 2,... 'rows.spacing', 2,... 'cells.defaultinterruptible', 'off',... 'cells.defaultbackgroundcolor', [1, 1, 1],... 'zeroindex', [2, 2],... ... % Title row 'cells.rowselection', [1, 1],... 'cells.colselection', [1, 3],... 'cells.type', 'uitext',... 'cells.string', {'', 'Center', 'Width'},... 'cells.horizontalalignment', 'center',... 'cells.fontweight', 'normal',... 'cells.backgroundcolor', BackgroundColor,... 'rows.fixed', 1,... ... % Symbol name column 'cells.rowselection', [2, nf+1],... 'cells.colselection', [1, 1],... 'cells.type', 'uitext',... 'cells.string', symbols,... 'cells.horizontalalignment', 'left',... 'cells.backgroundcolor', BackgroundColor,... 'cols.fixed', 1, ... ... % Center and width columns 'cells.rowselection', [2, nf+1],... 'cells.colselection', [2, 3],... 'cells.type', 'uiedit',... 'cells.enable', 'inactive',... 'cells.horizontalalignment', 'right' ); ud.tableCenterWidth.redrawmode = 'normal'; tablyt = uitabgroup('Parent',figh,... 'Units','pixels'); axesTab = mbcgui.container.uitab('Parent',tablyt,... 'Title','Plot'); % This layout provides a bit of a border around the axes to allow room for the % TickLabels. lytAxes = mbcgui.widget.AxesContainer('AxesHandle', axesTab, ... 'PositionSetting','outer',... 'Border', [30 30 5 5]); ud.axesPols = lytAxes.AxesHandle; set(ud.axesPoles , ... 'Box', 'on',... 'XGrid', 'on',... 'YGrid', 'on', ... 'XLimMode', 'Manual', ... 'YLimMode', 'Manual', ... 'XLim', [-1.5, 1.5], ... 'YLim', [-1.5, 1.5], ... 'XTick', 0, ... 'YTick', 0, ... 'PlotBoxAspectRatioMode', 'Manual', ... 'PlotBoxAspectRatio', [1, 1, 1] ); axesTab.LayoutComponent = lytAxes; t = linspace( -pi, pi, 200 ); line( ... 'Parent', ud.axesPoles, ... 'XData', cos( t ), ... 'YData', sin( t ), ... 'Color', 'k', ... 'LineStyle', ':', ... 'LineWidth', 0.5, ... 'Marker', 'none' ); ud.linePoles = line( ... 'Parent', ud.axesPoles, ... 'XData', [], ... 'YData', [], ... 'LineStyle', 'none', ... 'LineWidth', 3.0, ... % really the width of the marker edge 'Marker', 'x', ... 'MarkerEdgeColor', 'r', ... 'MarkerFaceColor', 'r', ... 'MarkerSize', 12, ... 'ButtonDownFcn', { @i_linePoles, figh } ); tableTab = mbcgui.container.uitab('Parent',tablyt,... 'Title','Table'); % table for pole display ud.tablePoles = xregtable(tableTab,... 'visible', 'on',... 'frame.visible', 'off',... 'frame.hborder', [0, 0],... 'frame.vborder', [0, 0],... 'defaultcellformat', '%.4f',... 'defaultcelltype', 'uiedit',... 'cols.size', 65,... 'cols.spacing', 2,... 'rows.spacing', 2,... 'cells.defaultinterruptible', 'off',... 'cells.defaultbackgroundcolor', [1, 1, 1],... 'zeroindex', [2, 1],... ... % Title row 'cells.rowselection', [1, 1],... 'cells.colselection', [1, 5],... 'cells.type', 'uitext',... 'cells.string', {'Real', 'Imag.', 'Magnitude', 'Angle', 'Time Const.'},... 'cells.horizontalalignment', 'center',... 'cells.fontweight', 'normal',... 'cells.backgroundcolor', BackgroundColor,... 'rows.fixed', 1 ); ud.tablePoles.redrawmode = 'normal'; lytTablePoles = xregborderlayout( tableTab, ... 'Border', [5, 5, 5, 5], ... % [W, S, E, N] 'Center', ud.tablePoles ); tableTab.LayoutComponent = lytTablePoles; % overall window layout lyt = xreggridbaglayout(figh, ... 'Dimension',[2, 2],... 'RowSizes',[20, -1 ],... 'ColSizes',[200, -1],... 'GapY',5,... 'GapX',7,... 'Border',[5, 5, 5, 5],... 'MergeBlock', { [1, 2], [2, 2] }, ... 'Elements', { ... lctrlModel, tablyt; ... ud.tableCenterWidth, [] } ); return %------------------------------------------------------------------------------| function i_clickModel( src, ~, figh ) ud = get( figh, 'UserData' ); m = ud.model; if isempty( src ), src = ud.clickModel; end % What is the local model to display? ind = get( src, 'Value' ); % Display centers, widths associated with that local model table = ud.tableCenterWidth; nf = nfactors( m ); centers = get( m, 'Centers' ); width = get( m, 'Width' ); table(1:nf,1) = transpose( centers(ind,:) ); table(1:nf,2) = transpose( width(ind,:) ); %#ok<NASGU> % Display poles for that model i_DisplayPoles( ud ) return %------------------------------------------------------------------------------| function i_linePoles( src, ~, figh ) % src is the line object ud = get( figh, 'UserData' ); axh = ud.axesPoles; % find where the user clicked cp = get( axh, 'CurrentPoint' ); cp = cp(1,[1,2]); % only need x- any y-coordinates % % Find closet data points to where user clicked % % get coorindates of data points XData = get( src, 'XData' ); YData = get( src, 'YData' ); % find all data points within 1/40 of the plot size of currentPoint accuracy = 40; XTol = diff( get( axh, 'XLim' ) ) /accuracy; YTol = diff( get( axh, 'YLim' ) ) /accuracy; ind = find( abs( XData - cp(1) ) < XTol & abs( YData - cp(2) ) < YTol ); % sometimes the patch appears with no data if isempty(ind) disp( 'No points nearby' ) % at worst, show the two points that were very near to cp [~, xind] = min( abs( XData - cp(1) ) ); [~, yind] = min( abs( YData - cp(2) ) ); ind = [xind, yind]; end ind = unique( ind ); % % Setup string % p = XData(ind) + 1i * YData(ind); if length( p ) == 1, if isreal( p ), str1 = sprintf( 'Pole = %.4g', real( p ) ); else str1 = sprintf( 'Pole = %.4g %+.4gi', real( p ), imag( p ) ); end str = char( ... str1, ... sprintf( 'Magnitude = %.4g', abs( p ) ), ... sprintf( 'Angle = %d deg', round( 180 * angle( p )/ pi ) ), ... sprintf( 'Time const = %.4g s', ud.tsample ./ abs( p ) ), ... '' ); else str = char( ... 'Real part ', ... 'Imag part ', ... 'Magnitude ', ... 'Angle ', ... 'Time const' ); for ii = 1:length( p ), str = cat( 2, str, blanks( 5 )', char( ... num2str( real( p(ii) ), 4 ), ... num2str( imag( p(ii) ), 4 ), ... num2str( abs( p(ii) ), 4 ), ... num2str( round( 180 * angle( p(ii) )/ pi ), 4 ), ... num2str( ud.tsample ./ abs( p(ii) ), 4 ), ... '' ) ); end end % % Display the patch % i_TextPatch( axh, str, cp ); return %------------------------------------------------------------------------------| function i_DisplayPoles( ud ) m = ud.model; bm = get( m, 'BetaModels' ); delmat = get( m, 'delmat' ); order = delmat(1,end); delay = delmat(2,end); ind = get( ud.clickModel, 'Value' ); beta = double( bm{ind} ); beta = beta(end-order+1:end); % y(k) - b(1) y(k-1) - ... - b(q) y(k-q) = f( x1(k), ..., xn(k-p) ) % ==> want the zeros of z^q - b(1) x^(q-1) - ... - b(q) p = roots( [1, zeros( 1, delay-1 ), -beta(:)'] ); set( ud.linePoles, 'XData', real( p ) ); set( ud.linePoles, 'YData', imag( p ) ); ind = 1:length(p); ud.tablePoles(ind,1) = real( p ); ud.tablePoles(ind,2) = imag( p ); ud.tablePoles(ind,3) = abs( p ); ud.tablePoles(ind,4) = 180 * angle( p )/ pi; % convert to degrees ud.tablePoles(ind,5) = ud.tsample ./ abs( p ); % time const return %---------------------------------|--------------------------------------------| function i_TextPatch( ax, infoStr, CP ) % taken from mbcmodels/validate_rstool xmode = get(ax,'XLimMode'); ymode = get(ax,'YLimMode'); set(ax,'XLimMode','manual','YLimMode','manual','Layer','bottom') % save old ax units oldUnits=get(ax,'Units'); commonUnit = 'point'; %create the text to find out its extent and hence if it fits in the figure ph=patch('FaceColor',[1 1 0.8],... 'Parent',ax,... 'Visible','off',... 'EdgeColor','k',... 'Tag','dataPatch',... 'FaceAlpha',1,... 'Clipping','off'); th=text(CP(1),CP(2),3.0,infoStr,... 'Units','data',... 'Visible','off',... 'Parent',ax,... 'FontName','Lucida Console',... 'Clipping','off',... 'HorizontalAlignment','left',... 'VerticalAlignment','bottom',... 'Interpreter','none'); % everything in same units (commonUnit) to see if it all fits on set([ax,th],'Units',commonUnit); Apos=get(ax,'Position'); % =ax pos in commonUnit axW = Apos(3); axH = Apos(4); % sort out text size (a bit!) maxFontSize = 8; %in 'point' fsize= min(axH/size(infoStr,1),maxFontSize); fsize= min(fsize,1.7*axW/size(infoStr,2)); % set text fontsize in 'point' set(th,'FontSize',fsize); % now find how much space the text takes up ext = get(th,'Extent'); if (ext(1)+ext(3))>axW %% goes off axes right if (ext(1)-ext(3))<0 %% will go off left if we right-align text Tpos = get(th,'Position'); set(th,'Position',[0, Tpos(2)]); else set(th,'HorizontalAlignment','right'); end end if (ext(2)+ext(4))>axH %% goes off axes top if (ext(2)-ext(4))<0 %% goes off bottom Tpos = get(th,'Position'); set(th,'Position',[Tpos(1),0]); else set(th,'VerticalAlignment','top'); end end % revert to original units set(ax,'Units',oldUnits); set(th,'Units','data'); ex=get(th,'Extent'); set(ph,... 'XData', [ex(1), ex(1), ex(1)+ex(3), ex(1)+ex(3)],... 'YData', [ex(2), ex(2)+ex(4), ex(2)+ex(4), ex(2)],... 'ZData', repmat( 2.0, [1,4] ) ); oldUpFcn = get(gcbf ,'WindowButtonUpFcn'); set(gcbf, 'WindowButtonUpFcn', ... { @i_killtextpatch, ph, th, xmode, ymode, oldUpFcn } ); set([th,ph],'Visible','on'); return %---------------------------------|--------------------------------------------| function i_killtextpatch(~, ~, ph, th, xmode, ymode, oldUpFcn) % Remove text and patch % taken from mbcmodels/validate_rstool set(get(ph,'Parent'),'XLimMode',xmode,'YLimMode',ymode) set(gcbf ,'WindowButtonUpFcn',oldUpFcn); delete(ph); delete(th); return %------------------------------------------------------------------------------| function i_deleteold h = findobj( allchild(0), 'flat', 'Tag', i_hash_fig_tag ); if ~isempty( h ) delete( h ); end return %------------------------------------------------------------------------------| function s = i_hash_fig_tag s = 'XregdynlolimotPoles'; return