www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optimoutput/ValuesSurfaceView.m

    classdef ValuesSurfaceView < cageview.optimoutput.Values2dView
    %cageview.optimoutput.ValuesSurfaceView class
    %   cageview.optimoutput.ValuesSurfaceView extends cageview.optimoutput.Values2dView.
    %
    %    cageview.optimoutput.ValuesSurfaceView properties:
    %       Parent - Property is of type 'MATLAB array'
    %       Position - Property is of type 'rect'
    %       Enable - Property is of type 'on/off'
    %       Visible - Property is of type 'on/off'
    %       UserData - Property is of type 'MATLAB array'
    %       Tag - Property is of type 'string'
    %       MessageService - Property is of type 'handle'
    %       Options - Property is of type 'handle vector'
    %       Actions - Property is of type 'handle vector'
    %       UIContextMenu - Property is of type 'MATLAB array'
    %       DisplayData - Property is of type 'ustring'
    %       CanRotate - Property is of type 'bool'
    %       ExtrapolateAll - Property is of type 'bool'
    %       ShowAxesGrid - Property is of type 'bool'
    %       ShowAxesBox - Property is of type 'bool'
    %       HideSurface - Property is of type 'bool'
    %       ShowStems - Property is of type 'bool'
    %
    %    cageview.optimoutput.ValuesSurfaceView methods:
    %       canPrint - Check whether component can be printed
    %       gettitle - Return string to use as title for view
    %       printCopy - Create a printer-friendly copy of OutputObjSurfaceView
    
    %  Copyright 2007-2015 The MathWorks, Inc.
    
    properties (AbortSet, SetObservable)
        %EXTRAPOLATEALL Property is of type 'bool'
        ExtrapolateAll = false;
        %SHOWAXESGRID Property is of type 'bool'
        ShowAxesGrid = true;
        %SHOWAXESBOX Property is of type 'bool'
        ShowAxesBox = false;
        %HIDESURFACE Property is of type 'bool'
        HideSurface = false;
        %SHOWSTEMS Property is of type 'bool'
        ShowStems = false;
    end
    
    properties (Access=protected, AbortSet)
        %HSURFACE Property is of type 'MATLAB array'
        hSurface = [];
        %HREDSTEMS Property is of type 'MATLAB array'
        hRedStems = [];
        %HORANGESTEMS Property is of type 'MATLAB array'
        hOrangeStems = [];
        %HGREENSTEMS Property is of type 'MATLAB array'
        hGreenStems = [];
        %HSTEMMARKERS Property is of type 'MATLAB array'
        hStemMarkers = [];
        %SURFACEACTION Property is of type 'handle'
        SurfaceAction = [];
    end
    
    methods  % constructor block
        function obj = ValuesSurfaceView(varargin)
        %ValuesSurfaceView Constructor for ValuesSurfaceView
        %  OBJ = ValuesSurfaceView(PROP, VALUE) constructs a class that
        %  displays the results of an optimization on a 3-d plot. A surface is
        %  fitted through the optimization results.
        
        % Call the inherited constructor
        obj@cageview.optimoutput.Values2dView(varargin{ : }); % converted super class constructor call
        
        % Default axis values
        set(obj.hSelector.Axes, 'Color', 'w', 'Box', 'on', ...
            'XGrid', 'on', 'YGrid', 'on');
        view(obj.hSelector.Axes, 3);
        
        % Create the surface for unconstrained plots
        obj.hSurface = surface('Parent', obj.hSelector.Axes,...
            'Visible',get(obj.hSelector.Axes, 'Visible'),...
            'FaceLighting','gouraud',...
            'FaceColor','interp',...
            'LineStyle', 'none', ...
            'HitTest', 'off', ...
            'XData', [],...
            'YData', [],...
            'ZData', [],...
            'CData',[]);
        
        % Create option actions
        AG = obj.ViewAction;
        AExtrapAll = mbcgui.actions.ToggleAction({@i_extrapolateallaction, obj}, ...
            '&Extrapolate All');
        AExtrapAll.Selected = obj.ExtrapolateAll;
        AGSurfOpt = mbcgui.actions.ActionGroup('', '&Surface Options');
        AGSurfOpt.MenuType = 'submenu';
        AResetAxes = mbcgui.actions.StatefulAction({@i_resetaxes, obj}, ...
            '&Reset Axes Orientation');
        AShowAxesGrid = mbcgui.actions.ToggleAction({@i_showaxesgridaction, obj}, ...
            '&Show Axes Grid');
        AShowAxesBox = mbcgui.actions.ToggleAction({@i_showaxesboxaction, obj}, ...
            '&Show Axes Box');
        AHideSurface = mbcgui.actions.ToggleAction({@i_hidesurfaceaction, obj}, ...
            '&Hide Surface');
        AShowStems = mbcgui.actions.ToggleAction({@i_showstemsaction, obj}, ...
            '&Show Stems');
        AGSurfOpt.Actions = [AResetAxes AShowAxesGrid AShowAxesBox AHideSurface AShowStems];
        AShowAxesGrid.Selected = obj.ShowAxesGrid;
        AShowAxesBox.Selected = obj.ShowAxesBox;
        AG.Actions = [AG.Actions(:)', AExtrapAll, AGSurfOpt];
        obj.ViewAction = AG;
        
        % Perform initialisation tasks - do not perform super's refresh actions as
        % the super class has already done this.
        obj.pRefreshSurface;
        obj.pRefreshStems;
        
        % Listeners to synchronise the constraint display property and action
        obj.addPropertyListeners(...
            {'ExtrapolateAll', ...
            'ShowAxesGrid', ...
            'ShowAxesBox', ...
            'HideSurface', ...
            'ShowStems'}, ...
            {{@i_extrapolateall, obj}, ...
            {@i_showaxesgrid, obj}, ...
            {@i_showaxesbox, obj}, ...
            {@i_hidesurface, obj}, ...
            {@i_showstems, obj}});
        end  % ValuesSurfaceView
        
    end  % constructor block
    
    methods  % public methods
        %----------------------------------------
        function out = canPrint(obj) %#ok<MANU>
        %CANPRINT Check whether component can be printed
        %  CANPRINT(OBJ) returns true for OutputValues2dView components.
        
        out = true;
        
        end  % canPrint
        
        %----------------------------------------
        function str = gettitle(obj) %#ok<MANU>
        %GETTITLE Return string to use as title for view
        %  STR = GETTITLE(OBJ) returns a string that should be used as a title for
        %  the container the view sits in.
        
        str = 'Results Surface';
        
        end  % gettitle
        
        %----------------------------------------
        function newobj = printCopy(obj, fig)
        %PRINTCOPY Create a printer-friendly copy of OutputObjSurfaceView
        %  LYT = PRINTCOPY(OBJ,FIG)
        
        % Create new axes, position them in the standard location and copy settings
        % from the view axes to the export ones
        AxCopyProps = {'XLim', 'YLim', 'Zlim', 'View', 'Box', 'XGrid', 'YGrid'};
        ExportAx = obj.pCreatePrintableAxes(fig, AxCopyProps);
        
        % Copy the visible optimization results to the new axes
        ExportAx = pCopyLinesToPrintAxes(obj, ExportAx);
        
        % Copy the surface objects to the new axes
        % Handle to surface objects.
        xregGui.HGPlotCopy(obj.hSurface, ExportAx);
        xregGui.HGPlotCopy(obj.hRedStems, ExportAx);
        xregGui.HGPlotCopy(obj.hOrangeStems, ExportAx);
        xregGui.HGPlotCopy(obj.hGreenStems, ExportAx);
        xregGui.HGPlotCopy(obj.hStemMarkers, ExportAx);
        
        % Title the graph
        title(ExportAx, obj.pGetSelector.ZFactorName);
        
        % Add axis labels
        mbcxlabel(ExportAx, obj.pGetSelector.XFactorName, 'Interpreter', 'none');
        mbcylabel(ExportAx, obj.pGetSelector.YFactorName, 'Interpreter', 'none');
        
        newobj = xreglayerlayout(fig, ...
            'border', [65 40 100 30], ...
            'elements', {ExportAx});
        
        end  % printcopy
        
    end  % public methods
    
    methods (Access=protected)
        %----------------------------------------
        function pRefresh(obj)
        %PREFRESH Refresh view
        %   PREFRESH(OBJ) Refresh view in OBJ.
        
        % Call super's refresh to refresh the points
        pRefresh@cageview.optimoutput.Values2dView(obj)
        
        % Now refresh the surface
        obj.pRefreshSurface;
        
        % And refresh the stems from the surface to the optimization results
        obj.pRefreshStems;
        
        
        end  % pRefresh
        
        %----------------------------------------
        function pRefreshStems(obj)
        %PREFRESHSTEMS Refresh the stem lines
        %   PREFRESHSTEMS(OBJ) replots the stem lines that join each optimization
        %   result to the extrapolation surface
        %
        %   See also PREFRESH, PREFRESHSURFACE
        
        % Get the optimization results which are fixed for the current node
        [data, bRedIdx, bOrangeIdx, bGreenIdx] = pGetOutputData(obj);
        
        if obj.hasData && size(data, 2) > 2 && obj.ShowStems
            
            % Get the selected indices
            idxX = obj.hSelector.XFactor;
            idxY = obj.hSelector.YFactor;
            idxZ = obj.hSelector.ZFactor;
            
            % Get the optimization results which the user can alter on the current
            % node
            bAcceptableIdx = pGetUserOutputData(obj);
            [bRedIdx, bOrangeIdx, bGreenIdx, bRedAcceptIdx, bOrangeAcceptIdx, bGreenNotAcceptIdx] = ...
                pGetDisplayIndices(obj, bRedIdx, bOrangeIdx, bGreenIdx, bAcceptableIdx);
            
            % Create a extrapolation surface from optimization data.
            if obj.ExtrapolateAll
                extrapXData = data(:, idxX);
                extrapYData = data(:, idxY);
                extrapZData = data(:, idxZ);
            else
                extrapXData = data(bAcceptableIdx, idxX);
                extrapYData = data(bAcceptableIdx, idxY);
                extrapZData = data(bAcceptableIdx, idxZ);
            end
            if isempty(extrapXData)
                extrapZ = [];
            else
                extrapZ = eval(cgmathsobject,'extrapolate_RBF_points', ...
                    extrapXData, extrapYData, extrapZData, data(:, idxX), data(:, idxY)); %#ok<GTARG>
            end
            
            % Delete any existing stems
            i_deleteStems(obj);
            
            % Update the stems
            if ~isempty(extrapZ)
                
                % Draw the red stems
                idxRed = find(bRedIdx | bRedAcceptIdx);
                nRed = length(idxRed);
                for i = 1:nRed
                    obj.hRedStems(i) = line('Parent', obj.hSelector.Axes,...
                        'Tag', 'RedStem',...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', '-', ...
                        'LineWidth', 1, ...
                        'HitTest', 'off', ...
                        'Color', 'k', ...
                        'XData', [data(idxRed(i),idxX), data(idxRed(i),idxX)], ...
                        'YData', [data(idxRed(i),idxY), data(idxRed(i),idxY)], ...
                        'ZData', [data(idxRed(i),idxZ), extrapZ(idxRed(i))]);
                    obj.hStemMarkers(i) = line('Parent', obj.hSelector.Axes,...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', 'none', ...
                        'Marker', '.', ...
                        'MarkerSize', 14, ...
                        'HitTest', 'off', ...
                        'Color', 'k', ...
                        'XData', data(idxRed(i),idxX), ...
                        'YData', data(idxRed(i),idxY), ...
                        'ZData', extrapZ(idxRed(i)));
                end
                
                
                % Draw the orange stems
                idxOrange = find(bOrangeIdx | bOrangeAcceptIdx);
                nOrange = length(idxOrange);
                for i = 1:nOrange
                    obj.hOrangeStems(i) = line('Parent', obj.hSelector.Axes,...
                        'Tag', 'OrangeStem',...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', '-', ...
                        'LineWidth', 2, ...
                        'HitTest', 'off', ...
                        'Color', 'k', ...
                        'XData', [data(idxOrange(i),idxX), data(idxOrange(i),idxX)], ...
                        'YData', [data(idxOrange(i),idxY), data(idxOrange(i),idxY)], ...
                        'ZData', [data(idxOrange(i),idxZ), extrapZ(idxOrange(i))]);
                    obj.hStemMarkers(nRed + i) = line('Parent', obj.hSelector.Axes,...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', 'none', ...
                        'Marker', '.', ...
                        'MarkerSize', 14, ...
                        'HitTest', 'off', ...
                        'Color', 'k', ...
                        'XData', data(idxOrange(i),idxX), ...
                        'YData', data(idxOrange(i),idxY), ...
                        'ZData', extrapZ(idxOrange(i)));
                end
                
                % Draw the green stems
                idxGreen = find(bGreenIdx | bGreenNotAcceptIdx);
                nGreen = length(idxGreen);
                for i = 1:nGreen
                    obj.hGreenStems(i) = line('Parent', obj.hSelector.Axes,...
                        'Tag', 'GreenStem',...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', '-', ...
                        'LineWidth', 2, ...
                        'HitTest', 'off', ...
                        'Color', 'k', ...
                        'XData', [data(idxGreen(i),idxX), data(idxGreen(i),idxX)], ...
                        'YData', [data(idxGreen(i),idxY), data(idxGreen(i),idxY)], ...
                        'ZData', [data(idxGreen(i),idxZ), extrapZ(idxGreen(i))]);
                    obj.hStemMarkers(nRed + nOrange + i) = line('Parent', obj.hSelector.Axes,...
                        'Visible', get(obj.hSelector.Axes, 'Visible'),...
                        'LineStyle', 'none', ...
                        'Marker', '.', ...
                        'HitTest', 'off', ...
                        'MarkerSize', 14, ...
                        'Color', 'k', ...
                        'XData', data(idxGreen(i),idxX), ...
                        'YData', data(idxGreen(i),idxY), ...
                        'ZData', extrapZ(idxGreen(i)));
                end
                
            end
            
            
        else
            % Delete any existing stems
            i_deleteStems(obj);
            
        end
        end  % pRefreshStems
        
        %----------------------------------------
        function pRefreshSurface(obj)
        %PREFRESHSURFACE Replot the extrapolation surface
        %
        %   PREFRESHSURFACE(OBJ) replots the extrapolation surface.
        
        
        % Get the optimization results which do not change for the current node
        [data, bRedIdx, bOrangeIdx, bGreenIdx] = pGetOutputData(obj);
        
        if obj.hasData && ~obj.HideSurface && ...
                size(data, 2) > 2 && ~isempty(obj.hSurface)
            
            % Get the selected indices
            idxX = obj.hSelector.XFactor;
            idxY = obj.hSelector.YFactor;
            idxZ = obj.hSelector.ZFactor;
            
            % Get the optimization results which the user can alter
            bAcceptableIdx = pGetUserOutputData(obj);
            
            % Create a extrapolation surface from optimization data.
            axes = i_getAxes(data, idxX, idxY);
            if obj.ExtrapolateAll
                extrapXData = data(:, idxX);
                extrapYData = data(:, idxY);
                extrapZData = data(:, idxZ);
            else
                extrapXData = data(bAcceptableIdx, idxX);
                extrapYData = data(bAcceptableIdx, idxY);
                extrapZData = data(bAcceptableIdx, idxZ);
            end
            
            % Update the surface
            if isempty(extrapXData)
                xx = [];
                yy = [];
                zz = [];
                zLim = get(obj.hSelector.Axes, 'ZLim');
            elseif all( abs(extrapZData-mean(extrapZData))<sqrt(eps) )
                % constant data so don't extrapolate
                [xx, yy] = ndgrid(axes{:});
                
                sz=[numel(axes{1}),numel(axes{2})];
                av = mean(extrapZData);
                % put a small perturbation on data so contour draws
                zz= av+ eps(av)*randn(sz) ;
                zLim = mbcmakelimits(av);
            else
                zz = eval(cgmathsobject,'extrapolate_RBF', ...
                    extrapXData, extrapYData, extrapZData, axes{1}, axes{2})'; %#ok<GTARG>
                
                [xx, yy] = ndgrid(axes{:});
                % z-limit generated from extrapolation and optimization results data
                [bRedIdx, bOrangeIdx, bGreenIdx] = pGetDisplayIndices(obj, ...
                    bRedIdx, bOrangeIdx, bGreenIdx, bAcceptableIdx);
                bDisplayIdx = bRedIdx | bOrangeIdx | bGreenIdx;
                zLim = mbcmakelimits([zz(:); data(bDisplayIdx, idxZ)]) + 100*[-eps eps];
            end
            set(obj.hSurface, 'XData', xx, 'YData', yy, 'ZData', zz, ...
                'CData', i_makecdata(zz, zLim));
            set(obj.hSelector.Axes,'ZLim', zLim);
            
        else
            set(obj.hSurface, 'XData', [], 'YData', [], 'ZData', [], 'CData', []);
        end
        end  % pRefreshSurface
        
    end
    
end  % classdef

function i_extrapolateallaction(src, ~, obj)
obj.ExtrapolateAll = src.Selected;
end  % i_extrapolateallaction

function i_extrapolateall(~, ~, obj)

obj.pRefreshSurface;
obj.pRefreshStems;
end  % i_extrapolateall

function i_resetaxes(~, ~, obj)

hSelector = obj.pGetSelector;
view(hSelector.Axes, 3);
end  % i_resetaxes

function i_showaxesgridaction(src, ~, obj)
obj.ShowAxesGrid = src.Selected;
end  % i_showaxesgridaction

function i_showaxesgrid(~, ~, obj)

hSelector = obj.pGetSelector;
if obj.ShowAxesGrid
    gridState = 'on';
else
    gridState = 'off';
end
set(hSelector.Axes, 'XGrid', gridState, 'YGrid', gridState);
end  % i_showaxesgrid

function i_showaxesboxaction(src, ~, obj)
obj.ShowAxesBox = src.Selected;
end  % i_showaxesboxaction

function i_showaxesbox(~, ~, obj)

hSelector = obj.pGetSelector;
if obj.ShowAxesBox
    boxState = 'on';
else
    boxState = 'off';
end
set(hSelector.Axes, 'Box', boxState);
end  % i_showaxesbox

function i_hidesurfaceaction(src, ~, obj)
obj.HideSurface = src.Selected;
end  % i_hidesurfaceaction

function i_hidesurface(~, ~, obj)
obj.pRefreshSurface;
end  % i_hidesurface

function i_showstemsaction(src, ~, obj)
obj.ShowStems = src.Selected;
end  % i_showstemsaction

function i_showstems(~, ~, obj)
obj.pRefreshStems;
end  % i_showstems

function i_deleteStems(obj)
delete(obj.hRedStems);
obj.hRedStems = [];
delete(obj.hOrangeStems);
obj.hOrangeStems = [];
delete(obj.hGreenStems);
obj.hGreenStems = [];
delete(obj.hStemMarkers);
obj.hStemMarkers = [];
end  % i_deleteStems

function cdata = i_makecdata(zdata, clim)
cmap = parula(64);
n = size(cmap,1);
mn = clim(1);
mx = clim(2);

% work out cdata - needs to be one for each vertex (zdata)
edges = (mn:((mx-mn)/n):mx);
[~, bin] = histc(zdata,[-inf edges(2:end-1) inf]);

% Convert bin entries for NaN zdata (bin 0) into using NaN cdata
cmap = [cmap; NaN NaN NaN];
bin(bin==0) = n+1;

cdata = reshape(cmap(bin(:),:), [size(zdata) 3]);
end  % i_makecdata

function axes = i_getAxes(data, idxX, idxY)
axes = cell(1, 2);

% Optimization results
xdata = data(:, idxX);
ydata = data(:, idxY);

% Filter out any infs and NaNs before we create the grid
xdata = xdata(isfinite(xdata));
ydata = ydata(isfinite(ydata));

% Define a 50-by-50 grid for the extrpolation
axes{1} = linspace(min(xdata), max(xdata), 50);
axes{2} = linspace(min(ydata), max(ydata), 50);
end  % i_getAxes