www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optimoutput/ObjGraphViewData.m
classdef ObjGraphViewData < mbcgui.widget.ScrollTableData %cageview.optimoutput.ObjGraphViewData class % cageview.optimoutput.ObjGraphViewData extends mbcgui.widget.ScrollTableData. % % cageview.optimoutput.ObjGraphViewData properties: % MessageService - Property is of type 'handle' % DisplayConstraints - Property is of type 'bool' % hTable - Property is of type 'handle' % CacheIsFilled - Property is of type 'bool' % CellIsCalculated - Property is of type 'MATLAB array' % ConIsCalculated - Property is of type 'MATLAB array' % LimitsX - Property is of type 'MATLAB array' % LimitsY - Property is of type 'MATLAB array' % LabelsX - Property is of type 'MATLAB array' % LabelsY - Property is of type 'MATLAB array' % LocationX - Property is of type 'MATLAB array' % LocationY - Property is of type 'MATLAB array' % SweepX - Property is of type 'MATLAB array' % SweepY - Property is of type 'MATLAB array' % NumConstraints - Property is of type 'int' % SweepConEdges - Property is of type 'MATLAB array' % CellHasSweep - Property is of type 'MATLAB array' % % cageview.optimoutput.ObjGraphViewData methods: % fillDataCache - Evalaute data for all cells. % getCellData - Get a structure of data for display in a table cell. % getColumnCount - Return the number of columns in the data model. % getRowCount - Return the number of rows in the data model. % getStandardColumnHeaderData - Get the standard column header data structure. % getStandardRowHeaderData - Get the standard row header data structure. % reset - Clear cache and recalculate the one-time data. % updateYLimits - Update y limits of graphs. % Copyright 2005-2015 The MathWorks, Inc. properties (AbortSet, SetObservable) %MESSAGESERVICE Property is of type 'handle' MessageService = []; %DISPLAYCONSTRAINTS Property is of type 'bool' DisplayConstraints = true; %HTABLE Property is of type 'handle' hTable = []; %CACHEISFILLED Property is of type 'bool' CacheIsFilled %CELLISCALCULATED Property is of type 'MATLAB array' CellIsCalculated = []; %CONISCALCULATED Property is of type 'MATLAB array' ConIsCalculated = []; %LIMITSX Property is of type 'MATLAB array' LimitsX = []; %LIMITSY Property is of type 'MATLAB array' LimitsY = []; %LABELSX Property is of type 'MATLAB array' LabelsX = []; %LABELSY Property is of type 'MATLAB array' LabelsY = []; %LOCATIONX Property is of type 'MATLAB array' LocationX = []; %LOCATIONY Property is of type 'MATLAB array' LocationY = []; %SWEEPX Property is of type 'MATLAB array' SweepX = []; %SWEEPY Property is of type 'MATLAB array' SweepY = []; %NUMCONSTRAINTS Property is of type 'int' NumConstraints %SWEEPCONEDGES Property is of type 'MATLAB array' SweepConEdges = []; %CELLHASSWEEP Property is of type 'MATLAB array' CellHasSweep = []; end events YLimUpdated end % events methods % public methods %---------------------------------------- function fillDataCache(obj) %FILLDATACACHE Evalaute data for all cells. % FILLDATACACHE(OBJ) fills up the data cache for all cells that have not % yet been evaluated. if ~obj.CacheIsFilled DataExists = all(obj.CellIsCalculated, 1); SweepIdx = find(~DataExists); obj.pUpdateEvalCache(SweepIdx); %#ok<FNDSB> SweepIdx = find(~obj.ConIsCalculated); obj.pUpdateConCache(SweepIdx); %#ok<FNDSB> obj.CacheIsFilled = true; end end % fillDataCache %---------------------------------------- function data = getCellData(obj, R, C) %GETCELLDATA Get a structure of data for display in a table cell. % DATA = GETCELLDATA(OBJ, R, C) returns a data structure that contains % all of the information needed to display in the specified table cell. if ~obj.CellIsCalculated(R, C) % Update the cache obj.pUpdateEvalCache(obj.pGetEvalChunk(R, C)); obj.updateYLimits; end if R==obj.getRowCount Xlab = obj.LabelsX{C}; else Xlab = ''; end if C==1 Ylab = obj.LabelsY{R}; else Ylab = ''; end % Form the main data structure data = struct('showdata', obj.CellHasSweep(R, C), ... 'xlim', obj.LimitsX{C}, ... 'ylim', obj.LimitsY{R}, ... 'xdata', obj.SweepX{C}, ... 'ydata', obj.SweepY{R, C}, ... 'value', obj.LocationX(C), ... 'xlabel', Xlab, ... 'ylabel', Ylab); % Add constraints data if obj.DisplayConstraints if ~obj.ConIsCalculated(C) % Update the constraint cache obj.pUpdateConCache(obj.pGetConChunk(R, C)); end data.constraintedges = obj.SweepConEdges{C}; else data.constraintedges = NaN; end end % getCellData %---------------------------------------- function nC = getColumnCount(obj) %GETCOLUMNCOUNT Return the number of columns in the data model. % NC = GETCOLUMNCOUNT(OBJ) returns the number of columns in the data model. nC = length(obj.LabelsX); end % getColumnCount %---------------------------------------- function nR = getRowCount(obj) %GETROWCOUNT Return the number of rows in the data model. % NR = GETROWCOUNT(OBJ) returns the number of rows in the data model. nR = length(obj.LabelsY); end % getRowCount %---------------------------------------- function data = getStandardColumnHeaderData(obj, Cidx) %GETSTANDARDCOLUMNHEADERDATA Get the standard column header data structure. % DATA = GETSTANDARDCOLUMNHEADERDATA(OBJ, CIDX) returns a standard data % structure for the specified column header. The structure must have % fields Limits, Value and Label. % % The standard header data is designed for use with header GUI % objects such as the sharedAxisHeader. data = struct('Limits', obj.LimitsX{Cidx}, ... 'Value', obj.LocationX(Cidx), ... 'Label', obj.LabelsX{Cidx}); end % getStandardColumnHeaderData %---------------------------------------- function data = getStandardRowHeaderData(obj, Ridx) %GETSTANDARDROWHEADERDATA Get the standard row header data structure. % DATA = GETSTANDARDROWHEADERDATA(OBJ, RIDX) returns a standard data % structure for the specified row header. The structure must have fields % Limits, Value and Label. % % The standard header data is designed for use with header GUI % objects such as the sharedAxisHeader. data = struct('Limits', obj.LimitsY{Ridx}, ... 'Value', obj.LocationY(Ridx), ... 'Label', obj.LabelsY{Ridx}); end % getStandardRowHeaderData %---------------------------------------- function reset(obj) %RESET Clear cache and recalculate the one-time data. % RESET(OBJ) clears all data that has been cached and recalculates the % data that is created in a single pass. if isempty(obj.MessageService) ... || ~ obj.MessageService.hasData ... || strcmp(obj.MessageService.CurrentSliceDirection, 'weightedsolution') ... || ~obj.MessageService.hasFocusIndex % Set data cache to be empty set(obj, ... 'CacheIsFilled', true, ... 'CellIsCalculated', false(0,0), ... 'ConIsCalculated', false(0,0), ... 'LimitsX', {}, ... 'LimitsY', {}, ... 'LabelsX', {}, ... 'LabelsY', {}, ... 'LocationX', [], ... 'LocationY', [], ... 'SweepX', {}, ... 'SweepY', {}, ... 'NumConstraints', 0, ... 'SweepConEdges', {}, ... 'CellHasSweep', false(0,0)); return end ms = obj.MessageService; RunIdx = ms.getFocusRun; SolIdx = ms.getFocusSolution; Out = ms.getOptimOutput; or = getOptimRunner(Out); % Get free variable values [XPoint, VarNames] = getSingleSolution(Out, RunIdx, SolIdx, 'OutputFormat', 'matrix', ... 'OutputContents', {'FreeVars'}); nFreeVar = length(VarNames); % Get objectives at exact point [YPoint, ObjNames] = getSingleSolution(Out, RunIdx, SolIdx, 'OutputFormat', 'matrix', ... 'OutputContents', {'Objectives'}); nObj= length(ObjNames); % Get Dependency matrix DepMatrix = getDependencyMatrix(or, 'Objective', {}); % Get free value ranges [LB, UB] = getFreeVariableRanges(or,RunIdx); % Cache number of constraints [~, nCon] = numConstraints(or); set(obj, ... 'CacheIsFilled', false, ... 'CellIsCalculated', false(nObj, nFreeVar), ... 'ConIsCalculated', false(1, nFreeVar), ... 'LimitsX', cellfun(@mbcmakelimits, num2cell([LB(:), UB(:)], 2)', 'UniformOutput', false), ... 'LimitsY', repmat({[0 1]}, 1, nObj), ... 'LabelsX', VarNames, ... 'LabelsY', ObjNames, ... 'LocationX', XPoint, ... 'LocationY', YPoint, ... 'SweepX', cell(1, nFreeVar), ... 'SweepY', cell(nObj, nFreeVar), ... 'NumConstraints', nCon, ... 'SweepConEdges', repmat({NaN}, 1, nFreeVar), ... 'CellHasSweep', DepMatrix); % Immediately calculate the initial data. This means we will have some % idea of ylimits from the start obj.pUpdateEvalCache(obj.pGetEvalChunk(1,1)); obj.pUpdateConCache(obj.pGetConChunk(1,1)); obj.pUpdateYLimits; end % reset %---------------------------------------- function updateYLimits(obj) %UPDATEYLIMITS Update y limits of graphs. % UPDATEYLIMITS(OBJ) updates the y limits of the graphs and sends an % event if any have changed. The event data will indicate which rows % have had their limits altered. ylOld = obj.LimitsY; obj.pUpdateYLimits; ylNew = obj.LimitsY; changed = false(size(ylOld)); for n = 1:length(ylOld) changed(n) = ~all(ylOld{n}==ylNew{n}); end if any(changed) Ridx = find(changed); data = struct('Rows', Ridx); evt = xregEventData(data); obj.notify('YLimUpdated', evt); end end % updateYLimits end % public methods methods (Access=protected) %---------------------------------------- function SweepIdx = pGetConChunk(obj, R, C) %#ok<INUSL> %PGETCONCHUNK Get the limits of a block of constraints to evaluate. % PGETCONCHUNK(OBJ, R, C) returns the sweep indices that need constraints % evaluated next given that data is required at cell (R, C). if ~obj.CacheIsFilled && obj.DisplayConstraints % Check data size. For smaller arrays we just calculate it all in one % go. nCon = obj.NumConstraints; nC = obj.getColumnCount; nCells = nCon*nC; if nCells>50 if ~isempty(obj.hTable) && ishandle(obj.hTable) % Provide enough data to fill up the visible size of the table DispSize = obj.hTable.getVisibleSize; C = max(obj.hTable.CurrentColumn, 1); Cfinal = min(C+DispSize(2)-1, nC); else % Calculate 5 columns at once Cfinal = min(C+4, nC); end DataExists = obj.ConIsCalculated(C:Cfinal); SweepIdx = find(~DataExists) + C - 1; else SweepIdx = find(~obj.ConIsCalculated); end else SweepIdx = []; end end % pGetConChunk %---------------------------------------- function SweepIdx = pGetEvalChunk(obj, R, C) %PGETEVALCHUNK Get the limits of a block to evaluate. % PGETEVALCHUNK(OBJ, R, C) returns the sweep indices that should be % evaluated next given that data is required at cell (R, C). if ~obj.CacheIsFilled % Check data size. For smaller arrays we just calculate it all in one % go. nR = obj.getRowCount; nC = obj.getColumnCount; nCells = nR*nC; if nCells>50 if ~isempty(obj.hTable) && ishandle(obj.hTable) % Provide enough data to fill up the visible size of the table DispSize = obj.hTable.getVisibleSize; C = max(obj.hTable.CurrentColumn, 1); Cfinal = min(C+DispSize(2)-1, nC); else % Calculate 5 columns at once Cfinal = min(C+4, nC); end DataExists = all(obj.CellIsCalculated(:, C:Cfinal), 1); SweepIdx = find(~DataExists) + C - 1; else SweepIdx = find(~all(obj.CellIsCalculated, 1)); end else SweepIdx = []; end end % pGetEvalChunk %---------------------------------------- function pUpdateConCache(obj, SweepIdx) %PUPDATECONCACHE Update cached constraint values for specified sweeps. % PUPDATECONCACHE(OBJ, SWEEPIDX) calculates constraint data for the % specified sweeps and updates the cache with the information. if isempty(obj.MessageService) ... || ~obj.MessageService.hasData ... || strcmp(obj.MessageService.CurrentSliceDirection, 'weightedsolution') ... || ~obj.MessageService.hasFocusIndex ... || isempty(SweepIdx) return end ms = obj.MessageService; Out = ms.getOptimOutput; or = getOptimRunner(Out); RunIdx = ms.getFocusRun; [~, nCon] = numConstraints(or); if obj.DisplayConstraints && nCon>0 % Show figure pointer while new data is calculated PR = []; if ~isempty(obj.hTable) && ishandle(obj.hTable) PR = xregGui.PointerRepository; ptrID = PR.stackSetPointer(obj.hTable.Parent, 'watch'); end ConEdges = obj.SweepConEdges; ItemNames = getConstraintNames(or,'inequality'); % Evaluate sweeps of constraint values [ConSweep, XSweep] = evaluateSweep(or, obj.LocationX, 'Constraint', ItemNames, ... 'FixedValueRun', RunIdx, ... 'SweepValues', SweepIdx, ... 'NumSweepPoints', 100); EqItemNames = getConstraintNames(or,'equality'); if ~isempty(EqItemNames) % Evaluate sweeps of equality constraint values ConEqSweep = evaluateSweep(or, obj.LocationX, 'Constraint', EqItemNames, ... 'FixedValueRun', RunIdx, ... 'SweepValues', SweepIdx, ... 'NumSweepPoints', 100); end % Find regions where all constraints are satisfied Tol = getConstraintTol(Out); for n = 1:length(ConSweep) convector = all(ConSweep{n}<Tol, 2); if ~isempty(EqItemNames) % feasible equality constraints convector = convector & all(abs(ConEqSweep{n})<Tol, 2); end ConEdges{SweepIdx(n)} = mbcgui.widget.IntervalPatch1D.convertConstraintVector( ... XSweep{n}, convector); end obj.SweepConEdges = ConEdges; obj.ConIsCalculated(SweepIdx) = true; obj.CacheIsFilled = all(obj.CellIsCalculated(:)) && all(obj.ConIsCalculated); if ~isempty(PR) PR.stackRemovePointer(obj.hTable.Parent, ptrID); end end end % pUpdateConCache %---------------------------------------- function pUpdateEvalCache(obj, SweepIdx) %PUPDATEEVALCACHE Update cached values for specified sweeps. % PUPDATEEVALCACHE(OBJ, SWEEPIDX) calculates sweep data for the specified % sweeps and updates the cache with the information. if isempty(obj.MessageService) ... || ~ obj.MessageService.hasData ... || strcmp(obj.MessageService.CurrentSliceDirection, 'weightedsolution') ... || ~obj.MessageService.hasFocusIndex ... || isempty(SweepIdx) return end % Show figure pointer while new data is calculated PR = []; if ~isempty(obj.hTable) && ishandle(obj.hTable) PR = xregGui.PointerRepository; ptrID = PR.stackSetPointer(obj.hTable.Parent, 'watch'); end ms = obj.MessageService; Out = ms.getOptimOutput; or = getOptimRunner(Out); RunIdx = ms.getFocusRun; % Evaluate sweeps of objective values [YSweep, XSweep] = evaluateSweep(or, obj.LocationX, 'Objective', {}, ... 'FixedValueRun', RunIdx, ... 'SweepValues', SweepIdx, ... 'NumSweepPoints', 100); % Transfer values to cached arrays sweepY = obj.SweepY; sweepX = obj.SweepX; sweepX(SweepIdx) = XSweep; for n = 1:length(SweepIdx) ThisSweep = SweepIdx(n); sweepY(:, ThisSweep) = num2cell(YSweep{n}', 2); end obj.SweepX = sweepX; obj.SweepY = sweepY; obj.CellIsCalculated(:, SweepIdx) = true; obj.CacheIsFilled = all(obj.CellIsCalculated(:)) && all(obj.ConIsCalculated); if ~isempty(PR) PR.stackRemovePointer(obj.hTable.Parent, ptrID); end end % pUpdateEvalCache %---------------------------------------- function pUpdateYLimits(obj) %PUPDATEYLIMITS Update the Y limits. % PUPDATEYLIMITS(OBJ) updates the common set of limits that are used on % the graphs. % Work out the common Y limits for each objective ylims = cell(1, length(obj.LocationY)); AllData = cell2mat(obj.SweepY); for n = 1:length(ylims) ylims{n} = mbcmakelimits(AllData(n, :), 'loose'); end obj.LimitsY = ylims; end % pUpdateYLimits end end % classdef