www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optimoutput/ConGraphViewData.m
classdef ConGraphViewData < mbcgui.widget.ScrollTableData %cgoptimgui.ConGraphViewData class % cageview.optimoutput.ConGraphViewData extends mbcgui.widget.ScrollTableData. % % cageview.optimoutput.ConGraphViewData properties: % MessageService - Property is of type 'handle' % hTable - Property is of type 'handle' % CacheIsFilled - Property is of type 'bool' % CellIsCalculated - 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' % LocationLHS - Property is of type 'MATLAB array' % LocationRHS - Property is of type 'MATLAB array' % SweepX - Property is of type 'MATLAB array' % SweepLHS - Property is of type 'MATLAB array' % SweepRHS - Property is of type 'MATLAB array' % ConComparisonType - Property is of type 'MATLAB array' % ConFeasibility - Property is of type 'MATLAB array' % FeasibilityTol - Property is of type 'double' % CellHasSweep - Property is of type 'MATLAB array' % % cageview.optimoutput.ConGraphViewData 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. % resetFeasibility - RESET Recalculate feasibility data. % updateYLimits - Update y limits of graphs. % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (AbortSet, SetObservable) %MESSAGESERVICE Property is of type 'handle' MessageService = []; %HTABLE Property is of type 'handle' hTable = []; %CACHEISFILLED Property is of type 'bool' CacheIsFilled %CELLISCALCULATED Property is of type 'MATLAB array' CellIsCalculated = []; %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 = []; %LOCATIONLHS Property is of type 'MATLAB array' LocationLHS = []; %LOCATIONRHS Property is of type 'MATLAB array' LocationRHS = []; %SWEEPX Property is of type 'MATLAB array' SweepX = []; %SWEEPLHS Property is of type 'MATLAB array' SweepLHS = []; %SWEEPRHS Property is of type 'MATLAB array' SweepRHS = []; %CONCOMPARISONTYPE Property is of type 'MATLAB array' ConComparisonType = []; %CONFEASIBILITY Property is of type 'MATLAB array' ConFeasibility = []; %FEASIBILITYTOL Property is of type 'double' FeasibilityTol %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> 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}, ... 'lhsdata', obj.SweepLHS{R, C}, ... 'rhsdata', obj.SweepRHS{R, C}, ... 'comparisontype', obj.ConComparisonType{R}, ... 'confeas', obj.ConFeasibility(R), ... 'value', obj.LocationX(C), ... 'xlabel', Xlab, ... 'ylabel', Ylab); 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. if obj.ConFeasibility(Ridx) C = get(xregGui.SystemColorsDbl, 'CTRL_BACK'); else C = mbcbdrycolor; end data = struct('Limits', obj.LimitsY{Ridx}, ... 'Value', obj.LocationLHS(Ridx), ... 'Label', obj.LabelsY{Ridx}, ... 'Color', C); 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 i_SetToEmpty(obj); return end ms = obj.MessageService; RunIdx = ms.getFocusRun; SolIdx = ms.getFocusSolution; Out = ms.getOptimOutput; or = getOptimRunner(Out); [nConPerItem, nCon] = numConstraints(or); if nCon==0 i_SetToEmpty(obj); return end % Get free variable values [XPoint, VarNames] = getSingleSolution(Out, RunIdx, SolIdx, 'OutputFormat', 'matrix', ... 'OutputContents', {'FreeVars'}); nFreeVar = length(VarNames); % Get constraint LHS/RHS at exact point [LHSPoint, ConNames] = getSingleSolution(Out, RunIdx, SolIdx, ... 'OutputFormat', 'matrix', ... 'OutputContents', {'ConstraintLHS'}); RHSPoint = getSingleSolution(Out, RunIdx, SolIdx, ... 'OutputFormat', 'matrix', ... 'OutputContents', {'ConstraintRHS'}); % Get Dependency matrix DepMatrix = getDependencyMatrix(or, 'Constraint', {}); % Get free value ranges [LB, UB] = getFreeVariableRanges(or,RunIdx); % Get comparison operator for each constraint item ops = getConstraintOperators(or); idx = zeros(1, nCon); for n = 1:length(nConPerItem) idx(sum(nConPerItem(1:n-1))+1:sum(nConPerItem(1:n))) = n; end ops = ops(idx); set(obj, ... 'CacheIsFilled', false, ... 'CellIsCalculated', false(nCon, nFreeVar), ... 'LimitsX', cellfun(@mbcmakelimits, num2cell([LB(:), UB(:)], 2)', 'UniformOutput', false), ... 'LimitsY', repmat({[0 1]}, 1, nCon), ... 'LabelsX', VarNames, ... 'LabelsY', ConNames, ... 'LocationX', XPoint, ... 'LocationLHS', LHSPoint, ... 'LocationRHS', RHSPoint, ... 'SweepX', cell(1, nFreeVar), ... 'SweepLHS', cell(nCon, nFreeVar), ... 'SweepRHS', cell(nCon, nFreeVar), ... 'ConComparisonType', ops, ... 'CellHasSweep', DepMatrix); % Calculate the constraint feasibility obj.resetFeasibility; % Immediately calculate the initial data. This means we will have some % idea of ylimits from the start obj.pUpdateEvalCache(obj.pGetEvalChunk(1,1)); obj.pUpdateYLimits; end % reset %---------------------------------------- function resetFeasibility(obj) %RESET Recalculate feasibility data. % RESETFEASIBILITY(OBJ) re-calculates just the feasibility data for the % constraints. This enables faster updating of this facet of the display % when the tolerance is altered. if isempty(obj.MessageService) ... || ~ obj.MessageService.hasData ... || strcmp(obj.MessageService.CurrentSliceDirection, 'weightedsolution') ... || ~obj.MessageService.hasFocusIndex return end ms = obj.MessageService; RunIdx = ms.getFocusRun; SolIdx = ms.getFocusSolution; Out = ms.getOptimOutput; % Get constraint feasibility obj.ConFeasibility = getSingleSolution(Out, RunIdx, SolIdx, ... 'OutputFormat', 'matrix', ... 'OutputContents', {'ConstraintFeas'}); % Get new tolerance obj.FeasibilityTol = getConstraintTol(Out); end % resetFeasibility %---------------------------------------- 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 = pGetEvalChunk(obj, R, C) %#ok<INUSL> %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 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 LHS and RHS values values [LHSSweep, XSweep] = evaluateSweep(or, obj.LocationX, 'Constraint', {}, ... 'EvaluationType', 'LHSEvaluate', ... 'FixedValueRun', RunIdx, ... 'SweepValues', SweepIdx, ... 'NumSweepPoints', 100); RHSSweep = evaluateSweep(or, obj.LocationX, 'Constraint', {}, ... 'EvaluationType', 'RHSEvaluate', ... 'FixedValueRun', RunIdx, ... 'SweepValues', SweepIdx, ... 'NumSweepPoints', 100); % Transfer values to cached arrays sweepLHS = obj.SweepLHS; sweepRHS = obj.SweepRHS; sweepX = obj.SweepX; sweepX(SweepIdx) = XSweep; for n = 1:length(SweepIdx) ThisSweep = SweepIdx(n); sweepLHS(:, ThisSweep) = num2cell(LHSSweep{n}', 2); sweepRHS(:, ThisSweep) = num2cell(RHSSweep{n}', 2); end obj.SweepLHS = sweepLHS; obj.SweepRHS = sweepRHS; obj.SweepX = sweepX; obj.CellIsCalculated(:, SweepIdx) = true; obj.CacheIsFilled = all(obj.CellIsCalculated(:)); 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.LabelsY)); AllData = cell2mat([obj.SweepLHS, obj.SweepRHS]); for n = 1:length(ylims) ylims{n} = mbcmakelimits(AllData(n, :), 'loose'); end obj.LimitsY = ylims; end % pUpdateYLimits end end % classdef function i_SetToEmpty(obj) % Set data cache to be empty set(obj, ... 'CacheIsFilled', true, ... 'CellIsCalculated', false(0,0), ... 'LimitsX', {}, ... 'LimitsY', {}, ... 'LabelsX', {}, ... 'LabelsY', {}, ... 'LocationX', [], ... 'LocationLHS', [], ... 'LocationRHS', [], ... 'SweepX', {}, ... 'SweepLHS', {}, ... 'SweepRHS', {}, ... 'ConComparisonType', {}, ... 'CellHasSweep', false(0,0)); end % i_SetToEmpty