www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/@xregfittree/build.m
function varargout = build( Tree, varargin ) %BUILD Build a regression tree for RBF fitting % % TREE = BUILD(TREE,<OPTIONS>) build a regression tree model for the data in % TREE. % % Options: % -------- % MinPerPanel, integer, default 2. % Minimum number of data points in a panel that is allowed to be split. % MaxNPanels, integer, default Inf. % Maximum number of panels allowed in the tree. % PanelSize, {'Cover'}|'Shrink', % How the sizes of the child panels are determined from the parent. 'Cover' % means that the total size of the two children should be equal to that of % the parent. 'Shrink' means that the sizes of the child panels should be % dictated by the data they contain. While this option would have no effect % if the tree was being built as a regression tree model, it will effect of % the RBF widths when it is being used to guide the construction of an RBF % model. % % The overall syntax to build a model is % tree = xregfittree( xdata, ydata ); % tree = build( tree ); % % See also XREGFITTREE. % Copyright 2000-2007 The MathWorks, Inc. and Ford Global Technologies, Inc. % Default values for user options MinPerPanel = 2; MaxNPanels = Inf; PanelSize = 'Cover'; % Get user options if ~mod( nargin, 2 ) % i.e., if nargin is even error(message('mbc:xregfittree:InvalidArgument')); end for i = 1:2:(nargin-1) if strcmpi( varargin{i}, 'MinPerPanel' ) MinPerPanel = varargin{i+1}; elseif strcmpi( varargin{i}, 'MaxNPanels' ) MaxNPanels = varargin{i+1}; elseif strcmpi( varargin{i}, 'PanelSize' ) PanelSize = varargin{i+1}; else error(message('mbc:xregfittree:InvalidArgument1', varargin{ i })); end end nDim = size( Tree.XData, 2 ); TwoMinPerPanel = 2 * MinPerPanel; panel = 1; Tree.UserData{1} = 0; while ~isempty( panel ) && length( Tree.Parent ) < MaxNPanels % % Find best place to split node % ----------------------------- first = Tree.First(panel); last = Tree.Last(panel); bestCost = Inf; for iDim = 1:nDim, xData = Tree.XData(first:last,:); yData = Tree.YData(first:last); nData = size( xData, 1 ); % sort data by coordinate in this dimension [junk, ind] = sort( xData(:,iDim) ); xData = xData(ind,:); yData = yData(ind); % initialize totals of left and right subsets leftTotal = sum( yData(1:MinPerPanel-1) ); rightTotal = sum( yData(MinPerPanel:end) ); % try all possible splits for iData = MinPerPanel:(nData-MinPerPanel) % try split between iData and iData+1 % the iData point gets moved from the right subset to the left subset nLeft = iData; nRight = nData - iData; leftTotal = leftTotal + yData(iData); rightTotal = rightTotal - yData(iData); leftMean = leftTotal /nLeft; rightMean = rightTotal /nRight; iDelta = xData(iData+1,iDim) - xData(iData,iDim); if iDelta > 0 diff = [ yData(1:nLeft) - leftMean; yData(nLeft+1:end) - rightMean ]; cost = sum( diff .^2 ); if cost < bestCost bestCost = cost; splitDim = iDim; leftPoints = ind(1:iData); rightPoints = ind(iData+1:end); end end end end if isinf(bestCost) % In this situation we didn't manage to calculate a cost for any % splits, which means the panel wasn't really splittable. This can % happen if the panel contains only one unique xdata value. Tree.Splitable(panel) = false; else % % Split node % ---------- Tree = split( Tree, panel, splitDim, {leftPoints, rightPoints}, PanelSize ); % % Work out costs for new panels % ----------------------------- [child1, child2] = getchildren( Tree, panel ); setuserdata( Tree, child1, pr_VarianceCost( Tree, child1 ) ); setuserdata( Tree, child2, pr_VarianceCost( Tree, child2 ) ); setuserdata( Tree, panel, 0.0 ); setsplitable( Tree, [child1; child2], ... getndata( Tree, [child1; child2] ) >= TwoMinPerPanel ); end % % Find next panel to split % ------------------------ tmp = find( Tree.Splitable ); [null, ind] = max( [ Tree.UserData{tmp} ] ); panel = tmp(ind); end % remove the user data Tree.UserData = cell( size( Tree.Parent ) ); % all done, assign outputs and return if nargout == 1 varargout{1} = Tree; elseif isvarname( inputname(1) ) assignin( 'caller', inputname(1), Tree ); end