www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cgcalsetup/TableData.m
classdef TableData < cgcalsetup.ModelData %TableData data object for creating tables and tradeoffs from a model % % C = cgcalsetup.TableData(pNode,MakeTables); % Copyright 2009-2013 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (SetObservable,AbortSet) %TableInputs index to inputs for use as table inputs TableInputs %BreakPoints - breakpoints for table BreakPoints %pNorm - pointers to table normalizers pNorm = mbcpointer(1,2); %CreateTables - logical array indicating which tables to make CreateTables %MakeTables CreateTradeoff = false; %pItems - list of all possible items to create pItems %TableName - names of tables TableName %pTables array of pointers to tables pTables = xregpointer; %pFill - filling items for tables pFill %TableRange ranges for new tables TableRange end properties (SetObservable) %UseOpPoints use model operating points for normalizer values UseOpPoints end properties (Dependent) %TabInputList list of inputs available as table inputs. % TabInputList is restricted to SwitchFactors if IsSwitchExpr is % true. TabInputList %pTableInputs list of inputs to table pTableInputs end methods function C = TableData(varargin) %TableData - constructor C@cgcalsetup.ModelData(varargin{:}); C.Title = 'Tables and Tradeoff'; C.Description = 'Select a model to base the new tables on.'; C.ErrorMessage = 'You must have models with at least two inputs in the CAGE project before you can create tables from a model.'; end function set.TableInputs(C,NewValue) %select which inputs to use as table inputs if length(NewValue)==2 && length(C.TableInputs)==2 Changed = C.TableInputs~=NewValue; if sum(Changed)==1 OldValues = C.TableInputs; if any(OldValues(~Changed) == NewValue(Changed)) % copy value changing to the other table input NewValue(~Changed) = OldValues(Changed); Changed(~Changed) = true; end end C.TableInputs = NewValue; for i= find(Changed) setDefaultBreakPoints(C,i) end else C.TableInputs = NewValue; end end function pTabInputs = get.TabInputList(C) if C.UseOpPoints pTabInputs = C.pSwitchInputs; else pTabInputs = [C.pInputs address(C.Model)]; end end function set.UseOpPoints(C,NewValue) C.UseOpPoints = NewValue; setDefaultInputs(C); setDefaultBreakPoints(C,1) setDefaultBreakPoints(C,2) end function pTabInputs = get.pTableInputs(C) if C.UseOpPoints pTabInputs = C.pSwitchInputs(C.TableInputs); else pTabInputs = C.TabInputList(C.TableInputs); end end function createItems(C) %createItems - create table items for model createItems@cgcalsetup.ModelData(C); if any(C.CreateTables) createTables(C); end end function defineItems(C) %defineItems - set up defaults based on selection of normalizer %inputs pOther = findAllAdditionalModels(C); pAll = [C.pInputs,address(C.Model),pOther]; [~,ia] = setdiff(pAll,C.pTableInputs); C.pItems = pAll(sort(ia)); Names = pveceval(C.pItems,@getname); Ranges = cell(length(C.pItems),1); for i=1:length(Names) Names{i} = sprintf('%s_Table',Names{i}); if C.pItems(i).isinport Ranges{i} = C.pItems(i).getrange; else Ranges{i} = [-Inf Inf]; end end C.TableName = Names; C.TableRange = Ranges; C.CreateTables = true(size(C.pItems)); % don't make tables for extra models C.CreateTables(end-length(pOther)+1:end) = false; end function setDefaultBreakPoints(C,index,Size) %setDefaultBreakPoints set up default breakpoints for tables % % setDefaultBreakPoints(C,index,Size) if nargin<3 if length(C.BreakPoints)>=index Size = length(C.BreakPoints{index}); else Size = 10; end end if index>length(C.pTableInputs) setDefaultInputs(C) end pTableInput = C.pTableInputs(index); if C.UseOpPoints % switch models [OK,loc]=ismember(pTableInput,C.pSwitchInputs); if OK(1) SwitchModel = getSwitchModel(C.Model); OpPoints = getSwitchPoints(SwitchModel); tol = getAbsoluteTolerance(get(SwitchModel,'model')); C.BreakPoints{index} = curvefitlib.internal.uniqueWithinTol(OpPoints(:,loc(1)),tol(loc(1))); end else if pTableInput.isinport % auto space models based on variable range r = pTableInput.getrange; C.BreakPoints{index} = linspace(r(1),r(2),Size); else % Model Output -> use [0,1] as default range C.BreakPoints{index} = linspace(0,1,Size); end end end function changeBreakpointSize(C,index,Size) bp = C.BreakPoints{index}; if length(bp)~=Size % use min and max from current values C.BreakPoints{index} = linspace(bp(1),bp(end),Size); else % no change in breakpoints end end function f = getModelNextPage(W) %#ok<MANU> %getModelNextPage - page to follow the model page in wizard % % f = getModelNextPage(W) % The normalizer page follows the model page f = @cgcalsetup.NormalizerPage.createPage; end end methods (Access=protected) function initializeSwitchTables(C) %initializeSwitchTables initialize tables for switch models mdl = getSwitchModel(C.Model); [OK,loc]= ismember(C.pInputs,getinputs(mdl)); InputVals = cell(1,length(C.pInputs)); if ~all(OK) % use nominal values where input is not an input to the switch model InputVals(~OK) = pveceval(C.pInputs(~OK),@getnomvalue); end % use initial values for all other inputs m = get(mdl,'model'); data = InitialValues(m); InputVals(OK) = num2cell( data(:,loc(OK)), 1); [OK,loc]=ismember(C.pInputs,C.pFill); Y = cell(1,length(C.pFill)); Y(loc(OK))= InputVals(OK); for j= sum(OK)+1:length(C.pFill) % evaluate expressions Y{j} = cgsimfill.ExpressionChain.fastEvaluate(C.pFill(j).info,InputVals); end TableVals = pveceval(C.pTables,@(T) get(T,'values')); Mask = false(size(TableVals{1})); TableBreakPoints = pveceval(C.pNorm,@(T) get(T,'breakpoints')); [~,loc] = ismember(C.pTableInputs,C.pInputs); for i=1:size(data,1) % find grid point IndX = find(InputVals{loc(2)}(i) == TableBreakPoints{2}); IndY = find(InputVals{loc(1)}(i) == TableBreakPoints{1}); if ~isempty(IndX) && ~isempty(IndY) % extrapolation mask Mask(IndY,IndX) = true; for j=1:length(C.pTables) % update table value TableVals{j}(IndY,IndX) = Y{j}(i); end end end for j=1:length(C.pTables) % make note for history if C.pFill(j).isinport Note = sprintf('Initial values for ''%s'' using point-by-point model ''%s''',C.pInputs(j).getname,getname(mdl)); else Note = sprintf('Initial values using point-by-point model ''%s''',getname(mdl)); end % set values LT = set(C.pTables(j).info,'values',{TableVals{j},Note}); % set mask and extrapolate [Rows,Cols]= find(Mask); LT= addToExtrapolationMask(LT,Rows,Cols); LT= extrapolate(LT); C.pTables(j).info = LT; end end function setModelNode(C) %setModelNode initializes TableData for a model setModelNode@cgcalsetup.ModelData(C); C.UseOpPoints = isSwitchModel(C) && length(C.pSwitchInputs)>=2; C.CreateTradeoff= true; defineItems(C) end function setDefaultInputs(C) if C.UseOpPoints [~,loc] = ismember(C.pSwitchInputs,C.TabInputList); loc = loc(1:2); else % use last two loc = length(C.pInputs)-1:length(C.pInputs); end C.TableInputs = loc; end function pList = getModelList(C) %getModelList models have to have at least 2 inputs pList = getModelList@cgcalsetup.ModelData(C); if ~isempty(pList) pInp=pveceval(pList,@getinports); pList = pList(cellfun(@length,pInp)>=2); end end function [pItems,pExpr] = getCreatedItems(C) %getCreatedItems list of created items and associated expressions % % [pItems,pExpr] = getCreatedItems(C) [pItems,pExpr] = getCreatedItems@cgcalsetup.ModelData(C); if ~any(isnull(C.pTables)) pExpr = [pExpr, C.pFill]; end if C.CreateTradeoff pExpr = [pExpr, address(C.Model)]; end end function createTables(C) %createTables create tables for model pTableInputs = C.pTableInputs; OriginalNorms = C.pNorm; setupNormalizers(C,pTableInputs); % Make the tables for the variables createAllTables(C); if any(isnull(OriginalNorms)) % record that normalizers were created pAddItems = [C.pNorm(isnull(OriginalNorms)), C.pTables]; else pAddItems = C.pTables; end hAddItems = infoarray(pAddItems); ndP = null(xregpointer, 1, length(pAddItems)); for n = 1:length(ndP) % make nodes ndP(n)=cgnode(hAddItems{n},[],pAddItems(n),1); end CGP = C.Project; % Add the items to the project CGP.addnodestoproject(ndP); addCreatedItems(C,pAddItems); if C.UseOpPoints %initialize tables for point-by-point models initializeSwitchTables(C) end if C.CreateTradeoff createTradeoff(C,C.pTables,C.pFill) end if isMultiModal(C.Model) % set precision of Mode table to polynomial to restrict % table values to integers [~,pInp]=getSwitchModel(C.Model); [OK,loc]=ismember(pInp(end),C.pFill); if OK C.pTables(loc).info= set(C.pTables(loc).info,'precision',cgprecpolyfix); end end if any(isnull(OriginalNorms)) % add table inputs to fill list to match normalizers C.pFill = [pTableInputs(isnull(OriginalNorms)) C.pFill]; end end function createTradeoff(C,pTables,pFill) %createTradeoff % % createTradeoff(C,pTables,pFill) TO = cgtradeoffnode(sprintf('%s_Tradeoff',getname(C.Model))); CGP = C.Project; CGP.addnodestoproject(address(TO)); TO = info(TO); for i=1:length(pTables) % add table to tradeoff TO = addTable(TO, pTables(i), false) ; if C.UseOpPoints % use model to define valid operating points TO = setFillExpression(TO, pTables(i), pFill(i),address(C.Model)); else % set fill expression for table TO = setFillExpression(TO, pTables(i), pFill(i)); end end % need to make sure that the project connections are updated to include % links tables and models CGP.UpdateConnections(address(TO)); if C.UseOpPoints % initialize tradeoff in table mask TO = initTableInputsForValidCells(TO, C.pTables(end)); end mask = C.pTables(end).getExtrapolationMask; if ~isempty(mask) && any(mask(:)) TO = updateFromTables(TO,mask); end addCreatedItems(C, address(TO)); end end end function setupNormalizers(C,pTableInputs) %setupNormalizers setup or create normalizers for tables if isempty(C.pNorm) C.pNorm = mbcpointer(1,2); end for i=1:length(C.pNorm) if isnull(C.pNorm(i)) % create the normalizers for the tables C.pNorm(i) = iCreateNorm(C,pTableInputs(i),C.BreakPoints{i}); else %use existing normalizers C.pNorm(i) = C.pNorm(i); end end end function pNorm = iCreateNorm(C,pTableInput,Breakpoints) %iCreateNorm main creation routine for normalizer % % pNorm = iCreateNorm(pTableInput,Breakpoints) % Make the normalisers for the tables inputname = pTableInput.getname; if ~pTableInput.isinport % create variable called <modelname>_input [~,pTableInput] = add(info(C.Project.getdd), [inputname,'_input']); % set variable range to breakpoint range pTableInput.info = setrange(pTableInput.info,[min(Breakpoints) max(Breakpoints)]); end bp = Breakpoints; val = 0:length(bp)-1; pNorm = cgnormaliser([inputname '_norm'], [bp(:) val(:)], pTableInput); pNorm.info = pNorm.set('bplocks' , ones(size(bp(:)))); end function createAllTables(C) %createAllTables create all tables C.pTables = mbcpointer(1, sum(C.CreateTables)); C.pFill = mbcpointer(1, sum(C.CreateTables)); TableSize= cellfun(@length,C.BreakPoints); tbl_n = 0; for n = 1:length(C.pItems) if C.CreateTables(n) pExpr = C.pItems(n); tblname = C.TableName{n}; tbl_n = tbl_n + 1; if C.pItems(n).isinport % create tables for inputs C.pTables(tbl_n) = iCreateLookupTwo(pExpr ,tblname,C.pNorm, C.pItems(n).getnomvalue,TableSize,C.TableRange{n}); else %create table for model passign(C.pInputs, parrayeval(C.pInputs,@setvalue,{pveceval(C.pInputs,@getnomvalue)})) Y = evaluate(pExpr.info); if isnan(Y) Y = 0; end C.pTables(tbl_n) = iCreateLookupTwo(pExpr ,tblname,C.pNorm,Y,TableSize,C.TableRange{n}); end C.pFill(tbl_n) = pExpr; end end end function pTable = iCreateLookupTwo(pItem,TableName,pNorm,v,TableSize,Range) %iCreateLookupTwo main creatopm routine for tables % % pTable = iCreateLookupTwo(pItem,TableName,pNorm,v,TableSize,Range) tablevals = v*ones(TableSize); pTable = cglookuptwo(TableName, tablevals, pNorm(2), pNorm(1)); LT = pTable.info; LT = set(LT,'range',Range); M = get(LT,'memory'); M(1).Information = sprintf('Table for ''%s''',pItem.getname); LT = set(LT,'memory',M(1)); pTable.info = LT; end