www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/mv_stepwise.m
function varargout=mv_stepwise(Action,varargin) % MV_STEPWISE Interactive tool for stepwise regression. % % Stepwise GUI tool for use with MBrowser % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. switch lower(Action) case 'create' % Create Stepwise Figure varargout{1}=i_Create(varargin{:}); case 'update' i_Update(varargin{:}); case 'click' % Toggle term in and out of model % Click on Table Entry or Errorbar i_Step(varargin{:}); case 'auto' % Minimise PRESS % Click on 'Auto' Button i_MinPress(varargin{:}); case 'crit' % Change Significance Level for Confidence Interval % Change Entry in CI editbox i_ChangeCrit case 'radio' i_Radio(varargin{:}); case 'vslider' i_VSlider case 'includeall' % Include all terms in model % Click on 'Include All' Button i_IncludeAll(varargin{:}); case 'removeall' % Remove all terms from model % Click on 'Remove All' Button i_RemoveAll(varargin{:}); case 'remove' % Remove Statistically Insignificant Terms from model % Click on 'Remove' Button i_RemoveInsig(varargin{:}); case 'addsig' % Add Statistically significant Terms to model % Click on 'Add' Button i_AddSig(varargin{:}); case 'history' % Retrieve Model from History % Click on History Points i_History(varargin{:}) case 'close' % Close Figure and Update Model Results i_Close end %------------------------------------------------------------------------ % SUBFUNCTION i_Create %------------------------------------------------------------------------ function table_fig= i_Create(p_mdev,alpha,UpdateFcn) if nargin<3 UpdateFcn = ''; end hFig= findobj(get(0,'Children'),'flat','Tag','stepwisefig'); if ~isempty(hFig) hFig=hFig(1); table_fig=hFig; ud= get(hFig,'UserData'); % Model for Stepwise Model= p_mdev.model; if ~( strcmp(class(Model),class(ud.Model)) && size(Model,1) == size(ud.Model,1) ) % create a new stepwise figure delete(hFig); table_fig= i_Create(p_mdev,alpha,UpdateFcn); return end refreshFigure(p_mdev,Model,ud,hFig); figure(hFig); return end %========================================================= % only come in here first time to create the UI %========================================================= % since this takes a while - give people a waitbar to look at wb = xregGui.waitdlg('title', 'Creating Stepwise Figure', 'parent', mvf); % Model for Stepwise Model= p_mdev.model; Yname= p_mdev.name; % Number of parameters in full model p=size(Model,1); % Data is stored in Model Object while in GR. % Need to determine total number of observations Constant = IncludeConst(Model); % (3,2) element is the df for SST Xdata= p_mdev.getdata('X'); Nobs= size(Xdata,1); alpha=0.05; % Calculate Critical y values for all possible cases sigprob = 1 - alpha/2; df = 1:max(Nobs,size(Model,1)); crit = i_Calctinv(sigprob,df); [Model,~,NewPRESS,B]= stepwise(Model); % Coefficient Table. % This needs to be Axes/Text based because TeX labels are required % determine height of table units = get(0,'Units'); set(0,'Units','pixels'); screen= get(0,'ScreenSize'); set(0,'Units',units); Aht= screen(end,4)-200; fht=max(Aht+100,680); rows = p; TableSize = [ 65*6 , Aht+25 ]; % Create the figure for the Stepwise GUI table_fig = xregfigure('Visible','off',... 'HandleVisibility','callback',... 'Tag','stepwisefig',... 'Resize','off',... 'Name',['Stepwise Regression for ',Yname],... 'CloseRequestFcn',[mfilename,'(''Close'')']); % Table for Coefficients and Statistics Headings = {'Term','Status','B','std B','t','Next PRESS'}; % Table Spacing % Extra properties % update waitbar wb.Waitbar.value = 0.1; lbls = labels(Model); % use biggest label to determine size of text items [~,pmax]= max(cellfun('prodofsize',lbls)); htmp= uicontrol('Parent',table_fig,... 'Style','popup',... 'String',lbls{pmax},... 'Position',[0 0 63 18],... 'Visible','off'); hextent= get(htmp,'Extent'); delete(htmp); rowHt= hextent(4)+6; hAx = axes('Parent',table_fig); htmp = text('Parent',hAx,'String',lbls{pmax},'Units','pixels'); hextent= get(htmp,'Extent'); delete(hAx); % reduce size of GUI when there are fewer terms than screen size fht = max(min((rows+1)*(rowHt)+100,fht),630); % add offset for terms TermsOffset = min(max(hextent(3)-30,0)); apos= [TableSize(1)+TermsOffset+250 100 360 170]; figpos = [1 screen(4)-fht-50 apos(1)+apos(3)+30 fht]; if figpos(3)>screen(3) % reduce offset if it makes the figure bigger than the screen TermsOffset = min(TermsOffset - (figpos(3)-screen(3)),0); apos= [TableSize(1)+TermsOffset+250 100 360 170]; figpos = [1 screen(4)-fht-50 apos(1)+apos(3)+10 fht]; end tbl=xregtable(table_fig,... 'cols.size',65,... 'rows.size',rowHt,... 'frame.hborder',[2+TermsOffset 0],... 'frame.vborder',[2 20],... 'frame.box','on',... 'rows.spacing',0,... 'cols.spacing',0,... 'cells.defaultbackgroundcolor',[1 1 1],... 'defaultcelltype','uiemuedit0',... 'defaultcellformat','%p4.9',... 'rows.number',rows+1,... 'cols.number',6,... 'rows.fixed',1,... 'cols.fixed',1,... 'zeroindex',[2 2],... 'frame.visible','off',... 'vslider.callback',[mfilename,'(''vslider'')']); % update waitbar wb.Waitbar.value = 0.6; tbl.redrawmode= 'basic'; if TermsOffset<30 halign = 'center'; else halign = 'right'; end set(tbl,... 'cells.rowselection',[1 1],... 'cells.colselection',[1 6],... 'cells.type','text',... 'cells.string',Headings,... 'cells.rowselection',[1 1],... 'cells.colselection',[1 1],... 'cells.HorizontalAlignment',halign,... 'cells.rowselection',[2 rows+1],... 'cells.colselection',[1 1],... 'cells.type','text',... 'cells.string',lbls,... 'cells.HorizontalAlignment',halign,... 'cells.rowselection',[2 rows+1],... 'cells.colselection',[2 2],... 'cells.type','uipopupmenu',... 'cells.string',repmat({{'Always','Never','Step'}},rows,1),... 'cells.BackGroundColor','w',... 'cells.HorizontalAlignment','left',... 'cells.rowselection',[2 rows+1],... 'cells.colselection',[2 6],... 'cells.HorizontalAlignment','right') % update waitbar wb.Waitbar.value = 0.67; ud.TermsOrder= termorder(Model)'; Status= getstatus(Model); tbl(:,1)= Status(ud.TermsOrder); tbl(0,end).FontWeight= 'bold'; pnl = get(tbl,'panel'); set(pnl,'BorderType', 'none') [step_axes,bhandles,phandle] = createCIAxes(pnl,p,Model); % Anova Table and other Stats Stats= gui_diagstats(Model, 'create',table_fig); if isa(get(Stats.layout,'LayoutComponent'), 'xregcontainer') set(get(Stats.layout,'LayoutComponent'), 'packstatus', 'on'); end set(Stats.layout,'Visible','on'); % update waitbar wb.Waitbar.value = 0.88; [ud,CIlyt] = createCIControls(alpha,table_fig,ud); ud.UpdateHistory = @i_UpdateHistory; % History display HistPanel = createHistoryAxes(table_fig,Nobs,p); HistAxes = HistPanel.AxesHandle; [hLabels,hList] = createHistoryList(p_mdev,table_fig); [CallBack,BottomLyt] = createButtons(table_fig); RHScomponents = {HistPanel,... [],... hLabels,... hList,... Stats.layout,... CIlyt,[]}; MainLyt = xreggridbaglayout(table_fig,... 'dimension',[9 3],... 'ColSizes',[-1 30 330],... 'gapy',1,... 'Border',[10 10 10 10],... 'RowSizes',[200,30,15,150,170,20,-1,20,25],... 'elements',[{tbl},cell(1,7),{BottomLyt},... cell(1,9),... [RHScomponents,cell(1,2)]],... 'MergeBlock',{[1 7],[1 1]},... 'MergeBlock',{[9 9],[1 3]}); % Set up Figure Position here set(table_fig, ... 'Position',figpos); set(table_fig,'ContentHandle',MainLyt); % Position errorbar plot VisRows= min(tbl.rows.onscreen-1,p); tpos = get(tbl,'Position'); ah= tpos(4)-(VisRows+1)*(rowHt); set(step_axes,'Position',[TableSize(1)+30+TermsOffset ah 180 (VisRows)*(rowHt)],... 'YLim',[0.5 VisRows+0.5]); createMenus(table_fig,CallBack); % update waitbar wb.Waitbar.value = 0.91; % Figure UserData Structure ud.crit = crit; ud.Nobs = Nobs; ud.Model = Model; ud.OrigModel = Model; ud.Constant = Constant; ud.p_mdev = p_mdev; ud.UpdateFcn = UpdateFcn; ud.DoingUpdate = false; ud.ParentFig = get(MBrowser,'Figure'); ud.Stats = Stats; ud.TermsOrder= termorder(Model)'; ud.Hand.Figure = table_fig; ud.Hand.Labels = zeros(p,1); ud.Hand.Table = tbl; ud.Hand.CIAxes= step_axes; ud.Hand.Point= phandle; ud.Hand.Bar = bhandles; ud.Hand.HistAxes= HistAxes; ud.Hand.hList= hList; % Make Table Text Handles Status = getstatus(Model); % Variable Names tbl(:,end).Enable= 'inactive'; for i=1:3 s= find(Status(ud.TermsOrder)==i); i_DisplayStatus(ud,i,s) tbl(s,[0 end]).ButtonDownFcn = [mfilename,'(''click'')']; tbl(s,1).CallBack= [mfilename,'(''radio'')']; end % Display Initial Results set(table_fig,'UserData',ud); set(table_fig,'Visible','on'); tbl.visible='on'; i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,Model,table_fig,HistAxes); % update waitbar wb.Waitbar.value = 1.0; % kill the waitbar delete(wb); return %------------------------------------------- % SUBFUNCTION i_Update %------------------------------------------- function i_Update(hFig) ud= get(hFig,'UserData'); if ud.DoingUpdate % event was initiated from stepwise UI ud.DoingUpdate = false; else m= ud.p_mdev.model; % Recalcuate old model [ud.Model,~,NewPRESS,B]= stepwise(m); % Update Displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); end set(hFig,'UserData',ud); %------------------------------------------- % SUBFUNCTION i_CIntervals %------------------------------------------- function [Bint,crit]= i_CIntervals(B,ud) CritVals = ud.crit; beta= B(:,1); crit= zeros(size(beta)); df= B(:,3); intdf= df==fix(df) & df>=1; crit(intdf)= CritVals(df(intdf)); if ~all(intdf) && ~any(df(~intdf)<10) % use linear interpolation for non-integer fdf= floor(df(~intdf)); cdf= ceil(df(~intdf)); crit(~intdf)= CritVals(fdf)+ (df(~intdf)-fdf)./(cdf-fdf).*(CritVals(cdf)-CritVals(fdf)); elseif ~all(intdf) && any(df(~intdf)<10) % except if df <10, when you should recalculate tinv alpha= get(ud.CritVal,'UserData')/100; sigprob= 1-alpha/2; crit(~intdf)= i_Calctinv(sigprob,df(~intdf)); end % calculate confidence intervals and tcrit values Bint= [B(:,1)-crit.*B(:,2) B(:,1)+crit.*B(:,2)]; %------------------------------------------------------------------------ % SUBFUNCTION i_DisplayResults %------------------------------------------------------------------------ function i_DisplayResults(ud,PRESS,B) % Local function for writing out all the entries in the Parameter Data Table. Bint= i_CIntervals(B,ud); beta= B(:,1); % round this for the moment df1=ceil(max(B(:,3))); df2=floor(min(B(:,3))); sig= get(ud.CritVal,'UserData'); if df1>0 t1= ud.crit(df1); set(ud.CritVal1,'String',sprintf('t(%.2g,%1d) = %.3f',sig/200,df1,t1)) else set(ud.CritVal1,'String','') end if df2>0 t2= ud.crit(df2); set(ud.CritVal2,'String',sprintf('t(%.2g,%1d) = %.3f',sig/200,df2,t2)) else set(ud.CritVal2,'String','') end NextPress= B(:,end); p= size(ud.Model,1); inmodel= Terms(ud.Model); for i= 1:p params = ud.TermsOrder(i); % update table entries % Update errorbars set(ud.Hand.Point(i),'XData',beta(params)); set(ud.Hand.Bar(i),'XData',Bint(params,:)); if inmodel(params) % Terms in model set(ud.Hand.Point(i),'Color','k'); set(ud.Hand.Bar(i),'Color','k'); else % Terms out of model set(ud.Hand.Point(i),'Color','r'); set(ud.Hand.Bar(i),'Color','r'); end end inmodel= inmodel(ud.TermsOrder); t= zeros(size(beta)); if ~all(B(:,2)==0) t(B(:,2)~=0)=beta(B(:,2)~=0)./B((B(:,2)~=0),2); else t= zeros(size(beta)); end Nums= [beta B(:,2) t NextPress]; % Find Minimum Press for next step [MinPress,MinInd]=nanmin(NextPress(ud.TermsOrder)); ud.Hand.Table(:,end).backgroundcolor='w'; if MinPress < PRESS ud.Hand.Table(0,end).color='y'; ud.Hand.Table(MinInd,end).backgroundcolor='y'; % Highlight minimum press yellow else ud.Hand.Table(0,end).color='k'; end Nums(getstatus(ud.Model)==2,2:4)=NaN; ud.Hand.Table(:,2:end)= Nums(ud.TermsOrder,:); ud.Hand.Table(inmodel,0:end).ForeGroundColor = 'k'; ud.Hand.Table(~inmodel,0:end).ForeGroundColor = 'r'; % X Axes Limits for ErrorBar Plot % Don't include constant coeff in this calculation set(get(ud.Hand.Bar(1),'Parent'),... 'XLimMode','auto'); % Colour Insignicant intervals and errorbars purple insig = Bint(:,1)<0 & Bint(:,2)>0; insig = insig(ud.TermsOrder); ud.Hand.Table(insig,end-1).foregroundcolor= 'b'; ud.Hand.Table(~insig,end-1).foregroundcolor= 'k'; set(ud.Hand.Bar(insig),'Color','b') % set(ud.Hand.Bar(~insig),'color','k') ud.Hand.Table.redraw; gui_diagstats(ud.Model,'display',ud.Stats); %------------------------------------------------------------------------ % SUBFUNCTION i_Radio %------------------------------------------------------------------------ function i_Radio(~) ud= get(gcbf,'UserData'); tbl= ud.Hand.Table; rud= get(gcbo,'UserData'); if strcmp(tbl.vslider.visible,'on') StepTerm=rud.row+tbl.vslider.value-1; else StepTerm=rud.row; end TermStatus= get(gcbo,'Value'); OldStatus= getstatus(ud.Model); if TermStatus~=OldStatus(ud.TermsOrder(StepTerm)) i_DisplayStatus(ud,TermStatus,StepTerm) StepTerm= ud.TermsOrder(StepTerm); ud.Model=setstatus(ud.Model,StepTerm,TermStatus); % Do step [ud.Model,OK,NewPRESS,B]= stepwise(ud.Model,~Terms(ud.Model)); if ~OK; % Step couldn't be taken errordlg('There is insufficient data to add this term to the model',... 'Stepwise','modal'); return end % Update display i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,gcbf,ud.Hand.HistAxes); set(gcbf,'UserData',ud); % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(gcbf); end % i_DisplayStatus function i_DisplayStatus(ud,TermStatus,StepTerm) switch TermStatus case 1 % Term always incuded in Model % Display Confidence Intervals set(ud.Hand.Bar(StepTerm),'Visible','on') set(ud.Hand.Point(StepTerm),'Visible','on') if (ismember(1,StepTerm) && isconstant(ud.Model)) % StepTerm= setdiff(StepTerm,1); set(ud.Hand.Bar(1),'Visible','off') set(ud.Hand.Point(1),'Visible','off') end ud.Hand.Table(StepTerm,3:end-1).Visible= 'on'; % Hide Next PRESS text % Disable ButtonDownFcn ud.Hand.Table(StepTerm,[0 end]).HitTest= 'off'; case 2 % Term never incuded in Model % Hide Confidence Intervals and Next PRESS set(ud.Hand.Bar(StepTerm),'Visible','off') set(ud.Hand.Point(StepTerm),'Visible','off') % Disable ButtonDownFcn ud.Hand.Table(StepTerm,[0 end]).HitTest= 'off'; case 3 % Term can be stepped in and out % Show Confidence Intervals and Next PRESS set(ud.Hand.Bar(StepTerm),'Visible','on') set(ud.Hand.Point(StepTerm),'Visible','on') if (ismember(1,StepTerm) && isconstant(ud.Model)) % StepTerm= setdiff(StepTerm,1); set(ud.Hand.Bar(1),'Visible','off') set(ud.Hand.Point(1),'Visible','off') end % Enable ButtonDownFcn ud.Hand.Table(StepTerm,[0 end]).HitTest= 'on'; end %------------------------------------------------------------------------ % SUBFUNCTION i_VSilder %------------------------------------------------------------------------ function i_VSlider ud= get(gcbf,'UserData'); OldYlim= get(ud.Hand.CIAxes,'YLim'); Top=get(ud.Hand.Table,'vslider.value'); set(ud.Hand.CIAxes,'YLim',Top-0.5+[0 diff(OldYlim)]) %------------------------------------------------------------------------ % SUBFUNCTION i_Step %------------------------------------------------------------------------ function i_Step(~) % Toggle single term (based on click in table or errorbar) hFig=gcbf; ud = get(hFig,'UserData'); tbl= ud.Hand.Table; rud= get(gcbo,'UserData'); if ~isempty(rud) % click on table if strcmp(rud.type,'fixed') StepTerm= rud.row-tbl.rows.fixed; else % convert to index StepTerm=scrollindex(tbl,rud.row,rud.col); end else % click on CI plot StepTerm= get(gcbo,'YData'); StepTerm= StepTerm(1); end % Do step StepTerm= ud.TermsOrder(StepTerm); [ud.Model,OK,NewPRESS,B]= stepwise(ud.Model,StepTerm); if ~OK; % Step couldn't be taken errordlg('There is insufficient data to add this term to the model',... 'Stepwise','modal'); return end set(hFig,'Pointer','watch'); % Update display i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(hFig); set(hFig,'Pointer','arrow'); %------------------------------------------------------------------------ % SUBFUNCTION i_MinPress %------------------------------------------------------------------------ function i_MinPress(hFig) % Take all steps to mininise PRESS if ~nargin hFig=gcbf; end set(hFig,'Pointer','watch'); ud = get(hFig,'UserData'); om= minpress(ud.Model); set(om,'isInitialised',true); set(om,'guidisp',true) [ud.Model,~,OK,NewPRESS,B]= run(om,ud.Model,ud); % Update Coeff Table and ErrorBar Plots i_DisplayResults(ud,NewPRESS,B) % update modeldev's model ud.p_mdev.setmodel(ud.Model,OK); % update browser view and other windows; doUpdate(ud) figure(hFig); set(hFig,'Pointer','arrow'); %------------------------------------------------------------------------ % SUBFUNCTION i_ChangeCrit %------------------------------------------------------------------------ function i_ChangeCrit % Change significance level for CI's % Check entry is a valid % if xregCheckIsNum('range',[0.1,10]); ud = get(gcbf,'UserData'); % Calculate new critical values alpha = get(gcbo,'UserData')/100; sigprob = 1 - alpha/2; % Set up critical values so df(SSR)+1 gives index to crit values df = 1:ud.Nobs; %:-1:ud.Nobs-size(ud.Model,1); ud.crit = i_Calctinv(sigprob,df); % recalculate all stats [~,OK,NewPRESS,B]= stepwise(ud.Model); % update displays i_DisplayResults(ud,NewPRESS,B) % Don't update history because model hasn't changed % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(gcbf); end %------------------------------------------------------------------------ % SUBFUNCTION i_RemoveInsig %------------------------------------------------------------------------ function i_RemoveInsig(hFig) if ~nargin hFig=gcbf; end ud = get(hFig,'UserData'); om= backwardselect(ud.Model); set(om,'isInitialised',true); set(om,'guidisp',true) % turn off include all option set(om,'includeall',false) % run optimMgr [ud.Model,~,OK,NewPRESS,B]= run(om,ud.Model,ud); % Update Coeff Table and ErrorBar Plots i_DisplayResults(ud,NewPRESS,B) set(gcbf,'UserData',ud); % Update displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); % update modeldev's model ud.p_mdev.setmodel(ud.Model,OK); % update browser view and other windows; doUpdate(ud) figure(hFig); %------------------------------------------------------------------------ % SUBFUNCTION i_AddSig %------------------------------------------------------------------------ function i_AddSig(hFig) if ~nargin hFig=gcbf; end ud = get(hFig,'UserData'); om= forwardselect(ud.Model); set(om,'isInitialised',true); set(om,'guidisplay',true) % turn off include all option set(om,'removeall',false) % run optimMgr [ud.Model,~,OK,NewPRESS,B]= run(om,ud.Model,ud); % Update displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); % update browser view and other windows; % update modeldev's model ud.p_mdev.setmodel(ud.Model,OK); % update browser view and other windows; doUpdate(ud) figure(hFig); %------------------------------------------------------------------------ % SUBFUNCTION i_IncludeAll %------------------------------------------------------------------------ function i_IncludeAll(hFig) % Include all terms in model if ~nargin hFig=gcbf; end ud = get(hFig,'UserData'); % No Terms left out of model OutModel = false(size(ud.Model)); % calculate new model [ud.Model,OK,NewPRESS,B]= stepwise(ud.Model,OutModel); if ~OK; % check that it is possible to include all terms in model errordlg('There is insufficient data to include all terms in this model',... 'Stepwise','modal'); return end % update displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(hFig); %------------------------------------------------------------------------ % SUBFUNCTION i_RemoveAll %------------------------------------------------------------------------ function i_RemoveAll(hFig) % Remove all terms for model (e.g. for Forward Selection) if ~nargin hFig=gcbf; end ud = get(hFig,'UserData'); % All Terms left out of model OutModel = true(size(ud.Model)); % calculate new model [ud.Model,OK,NewPRESS,B]= stepwise(ud.Model,OutModel); % update displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,hFig,ud.Hand.HistAxes); set(gcbf,'UserData',ud); % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(hFig); %------------------------------------------------------------------------ % SUBFUNCTION i_History %------------------------------------------------------------------------ function i_History(h,~,flag) % Return to previous model (from History plot click) fig = ancestor(h,'figure'); if isgraphics(h,'uicontrol'); if ~strcmp(get(fig,'SelectionType'),'open') return end flag= get(h,'Value'); end ud= get(fig,'UserData'); % histud stored in HistAxes UserData histud= get(ud.Hand.HistAxes,'UserData'); in = histud.instore; Terms = in(:,flag); % Recalcuate old model [ud.Model,OK,NewPRESS,B]= stepwise(ud.Model,Terms); % Update Displays i_DisplayResults(ud,NewPRESS,B) i_UpdateHistory(NewPRESS,ud.Model,fig,ud.Hand.HistAxes); set(fig,'UserData',ud); % update browser view and other windows; ud.p_mdev.setmodel(ud.Model,OK); doUpdate(ud) figure(fig); %------------------------------------------------------------------------ % SUBFUNCTION i_UpdateHistory %------------------------------------------------------------------------ function i_UpdateHistory(NewPRESS,Model,hFig,HistAxes) % Local function for adding new press error bar to History Plot. set(hFig,'CurrentAxes',HistAxes) histud = get(HistAxes,'UserData'); tmp = ~Terms(Model); if ~isfield(histud,'pressdothndl') % No History histud.pressdothndl(1)=-1; histud.instore = tmp(:); num_mod = 1; else % Add New Model to history store in = histud.instore; in = [in tmp(:)]; histud.instore = in; num_mod = length(histud.pressdothndl)+1; end % plot CI bar set(HistAxes,'XLim',[max(0.5,num_mod-19.5),num_mod+0.5],'XTick',(1:num_mod) ); % plot PRESS point histud.pressdothndl(num_mod) = plot(num_mod,NewPRESS,'.k','Parent',HistAxes); % Set ButtonDwn callbacks set(histud.pressdothndl(num_mod),'MarkerSize',20,... 'ButtonDownFcn',{@i_History,num_mod}); % Save history UserData set(HistAxes,'UserData',histud); % show summary statistics [nObs,NumParams,Box-Cox,PRESS RMSE,RMSE] s=FitSummary(Model); ud= get(hFig,'UserData'); str= [get(ud.Hand.hList,'String') sprintf('%5d %6d %8.2g %10.4g %10.4g',s(1:5))]; set(ud.Hand.hList,'String',str,... 'Value',size(str,1),... 'ListboxTop',max(1,size(str,1)-8)); %------------------------------------------------------------------------ % SUBFUNCTION i_Close %------------------------------------------------------------------------ function i_Close hFig= findobj(get(0,'Children'),'flat','Tag','stepwisefig','Visible','on'); if ~isempty(hFig); figure(hFig(1)); ud= get(hFig(1),'UserData'); confirm=questdlg('Do you want to update Regression Results?',... 'Confirm Stepwise Exit',... 'Yes',... 'No',... 'Cancel',... 'Yes'); if isempty(confirm) confirm = 'Cancel'; end if ~strcmp(confirm,'Cancel') if strcmp(confirm,'No') && size(get(ud.Hand.hList,'String'),1)>1 % save old model - don't do this if there is only one entry in % history ud.p_mdev.setmodel(ud.OrigModel,1); doUpdate(ud) end % close DOE evaluation figure hDOE= findobj(get(0,'Children'),'flat','Tag','DOEtool','Visible','on'); close(hDOE); set(hFig(1),'Visible','off'); % Bring main Model Browser figure to foreground if isgraphics(ud.ParentFig,'figure') figure(ud.ParentFig) end end end %------------------------------------------------------------------------ % SUBFUNCTION i_Calctinv %------------------------------------------------------------------------ function crit= i_Calctinv(sigprob,df) df= df(:); crit= zeros(size(df)); if max(df)>100 crit(df<100)= tinv(sigprob,df(df<100)); crit(df>=100)= norminv(sigprob); else crit= tinv(sigprob,df); end function refreshFigure(p_mdev,Model,ud,hFig) Yname= p_mdev.name; Constant = IncludeConst(Model); [Model,~,NewPRESS,B]= stepwise(Model); % (3,2) element is the df for SST Xdata= p_mdev.getdata('X'); Nobs= size(Xdata,1); df = 1:max(Nobs,size(Model,1)); alpha= get(ud.CritVal,'UserData')/100; sigprob= 1-alpha/2; ud.crit= i_Calctinv(sigprob,df); ud.Model = Model; ud.OrigModel = Model; ud.Constant = Constant; ud.p_mdev = p_mdev; ud.DoingUpdate = false; Status= getstatus(Model); %#ok<*FOBS> ud.Hand.Table(:,0).string= labels(Model); ud.Hand.Table(:,1)=Status(ud.TermsOrder); for i=1:3 s= find(Status(ud.TermsOrder)==i); i_DisplayStatus(ud,i,s) end % Display Initial Results i_DisplayResults(ud,NewPRESS,B) delete(get(ud.Hand.HistAxes,'Children')); set(ud.Hand.hList,'String',''); histud= get(ud.Hand.HistAxes,'UserData'); histud= rmfield(histud,'pressdothndl'); set(ud.Hand.HistAxes,'UserData',histud,'XLim',[0 10],'YLimMode','auto'); i_UpdateHistory(NewPRESS,Model,hFig,ud.Hand.HistAxes); set(hFig,'UserData',ud,... 'Name',['Stepwise Regression for ',Yname]); function [step_axes,bhandles,phandle] = createCIAxes(pnl,p,Model) step_axes= axes('Parent',pnl,'NextPlot','add',... 'Tag','stepaxes','Box','on',... 'YDir','reverse',... 'YTickLabel','','YTick',[],... 'Units','pixels',... 'FontSize',8); title(step_axes,'Coefficients with Errorbars',... 'FontSize',9) % Make Lines and handles % Vertical line at zero plot([0 0],[0.5,p+0.5],'k-', 'Parent', step_axes); bhandles = gobjects(p,1); phandle = bhandles; for k = 1:p % Interval Estimate bhandles(k,1)=line('Parent',step_axes,... 'XData',[0 0]','YData',[k k],... 'ButtonDownFcn',[mfilename,'(''click'',',int2str(k),')'],'LineWidth',2); % Point Estimate phandle(k,1)= line('Parent',step_axes,... 'XData',0,'YData',k,... 'Marker','.','MarkerSize',20,... 'ButtonDownFcn',[mfilename,'(''click'',',int2str(k),')']); end if isconstant(Model) % Don't display errorbar for constant term as it is usually too large. set(phandle(1),'Visible','off'); set(bhandles(1),'Visible','off'); end function [CallBack,BottomLyt] = createButtons(table_fig) % Stepwise Buttons (at bottom of Figure) ToolTipString = { 'Minimize PRESS',... 'Include all terms in model',... 'Remove all terms from model',... 'Forward addition of significant terms to model',... 'Backwards removal of insignificant terms from model'}; String= {'Min. PRESS',... 'Include All',... 'Remove All',... 'Forward',... 'Backwards'}; CallBack= {[mfilename,'(''Auto'')'],... [mfilename,'(''IncludeAll'')'],... [mfilename,'(''RemoveAll'')'],... [mfilename,'(''AddSig'')'],... [mfilename,'(''Remove'')']}; hButtons = cell(size(String)); for i=1:length(String) hButtons{i} = uicontrol('Parent',table_fig,... 'Style','Pushbutton','Units','Pixels',... 'String',String{i},... 'BusyAction','cancel',... 'TooltipString',ToolTipString{i},... 'Callback',CallBack{i}); end BottomLyt = xreggridlayout(table_fig,... 'dimension',[1 length(String)+1],... 'colsizes',[repmat(100,1,length(String)) -1],... 'gapx',20,... 'elements',hButtons); function createMenus(table_fig,CallBack) MainMenu= {'&Figure','&Regression'}; mmh= xregmenutool('create',table_fig,'Label',MainMenu); % Figure Menu hf=xregmenutool('create',mmh(1),'Label',{'&Close'},'Callback',{[mfilename,'(''Close'')']}); set(hf,'Accelerator','W'); Label= {'Minimize &PRESS',... '&Include All',... '&Remove All',... '&Forward',... '&Backwards'}; xregmenutool('create',mmh(2),'Label',Label,'CallBack',CallBack); xregwinlist(table_fig); % initialize Window Menu %HELP MENU mv_helpmenu(table_fig,{'&Stepwise Help','xreg_stepwise'}); function [hLabels,hList] = createHistoryList(p_mdev,table_fig) str=p_mdev.colhead; % truncate these strings so cols line up okay maxLength = [3 5 7 10 10]; numHeaders = min(length(str),5); for i = 1:numHeaders thisLength = min(length(str{i}),maxLength(i)); str{i} = str{i}(1:thisLength); end hLabels = uicontrol('Parent',table_fig,... 'Units','pixels',... 'Style','text',... 'String',sprintf('%5s %6s %8s %10s %10s',str{:}),... 'FontSize',9,... 'FontName','Courier New',... 'HorizontalAlignment','left',... 'BackgroundColor',get(table_fig,'Color')); hList=uicontrol('Parent',table_fig,... 'Units','pixels',... 'Style','listbox',... 'String','',... 'FontSize',9,... 'FontName','Courier New',... 'BackgroundColor','w',... 'Callback',@i_History); function HistPanel = createHistoryAxes(table_fig,Nobs,p) HistPanel = mbcgui.widget.AxesPanel('Parent',table_fig,... 'Border',[50 20 0 20]); HistAxes = HistPanel.AxesHandle; set(HistAxes,... 'Units','pixels',... 'Tag','HistoryAxes',... 'Box','on',... 'NextPlot','add',... 'FontSize',8); % Critical Values for PRESS CI's trm = Nobs:-1:Nobs-p-1; trml = length(trm); low = 0.025; hi = 0.975; histud.chi2crit = chi2inv([low(ones(trml,1),1) hi(ones(trml,1),1)],[trm' trm']); set(HistAxes,'UserData',histud); set(get(HistAxes,'XLabel'),'String','Model Number','FontSize',9); set(get(HistAxes,'Title'),'String','Stepwise PRESS History','FontSize',9); function [ud,CIlyt] = createCIControls(alpha,table_fig,ud) % Confidence Interval label and edit box hAlpha = uicontrol('Parent',table_fig,... 'Style','text','Units','Pixels',... 'FontName','Symbol',... 'String','a (%)', ... 'HorizontalAlignment','left'); ud.CritVal= uicontrol('Parent',table_fig,... 'Style','edit','Units','Pixels',... 'String',alpha*100,'UserData',alpha*100, ... 'Callback',[mfilename,'(''crit'')'],... 'BackgroundColor','w',... 'Tag', 'crit'); ud.CritVal1= uicontrol('Parent',table_fig,... 'Style','text','Units','Pixels',... 'String','a (%)', ... 'BackgroundColor','w',... 'ForegroundColor','k'); ud.CritVal2= uicontrol('Parent',table_fig,... 'Style','text','Units','Pixels',... 'String','a (%)', ... 'BackgroundColor','w',... 'ForegroundColor','r'); CIlyt = xreggridlayout(table_fig,.... 'dimension',[1 4],... 'colsizes',[39 69 -1 -1],... 'CorrectAlg','on',... 'elements',{hAlpha,ud.CritVal,ud.CritVal1,ud.CritVal2}); function doUpdate(ud) if ~ud.DoingUpdate && ~isempty(ud.UpdateFcn) ud.DoingUpdate = true; set(ud.Hand.Figure,'UserData',ud); ud.UpdateFcn(); end