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

    classdef ObjectiveActions < handle
    %ObjectiveActions actions for setting up objectives
    
    %  Copyright 2005-2016 The MathWorks, Inc.
    
    properties (SetAccess=private)
        %MessageService storage for message service
        MessageService
        %AllActions action group all objective actions
        AllActions
        
        %Add add an objective
        Add
        %Edit edit currently selected objective
        Edit
        %Delete delete current objective
        Delete
        %Rename rename current objective
        Rename
        %AddBoundary add boundart constraint associated with objective expression
        AddBoundary 
        %AssignOpPointSet assign an application point set
        AssignOpPointSet
        %ClearOpPointSet clear application point set
        ClearOpPointSet
    end
    
    properties (Access=private)
        %Listeners storage for listeners
        Listeners
    end
    
    methods
        
        function obj = ObjectiveActions(ms)
        %PMAKEACTIONS Create the actions for the object
        %
        %  PMAKEACTIONS(OBJ) is called during construction to create the list's
        %  actions.
        
        obj.MessageService = ms;
        
        obj.Add = mbcgui.actions.StatefulAction(@(src, evt) obj.onAddItem, '&Add Objective...', ...
            'Add a new objective', cgrespath('optimnewobjective.bmp'));
        obj.Edit =  mbcgui.actions.StatefulAction(@(src, evt) obj.onEditItem, '&Edit Objective...', ...
            'Edit objective');
        obj.Delete = mbcgui.actions.StatefulAction(@(src, evt) obj.onDeleteItem, '&Delete Objective', ...
            'Delete objective');
        obj.Rename = mbcgui.actions.StatefulAction(@(src, evt) obj.onRenameItem, '&Rename Objective...', ...
            'Rename objective');
        
        stdActions = mbcgui.actions.ActionGroup;
        stdActions.MenuType = 'separate';
        stdActions.Actions = [obj.Add obj.Edit obj.Delete obj.Rename];
        
        set(stdActions, 'Enabled', false);
        
        bdActions = mbcgui.actions.ActionGroup;
        bdActions.MenuType = 'separate';
        obj.AddBoundary = mbcgui.actions.StatefulAction(@(src, evt) obj.onAddBoundaryConstraint, ...
            'Add Boundary to Constraints', 'Add a Boundary Constraint');
        bdActions.Actions = obj.AddBoundary;
        obj.AddBoundary.enableStateChange('Label');
        set(bdActions, 'Enabled', false);
        
        obj.AssignOpPointSet =  mbcgui.actions.StatefulAction(@(src, evt) obj.onAssignOpPointSet, ...
            '&Select Application Point Set...', 'Select application point set');
        obj.ClearOpPointSet = mbcgui.actions.StatefulAction(@(src, evt) obj.onClearOpPointSet, ...
            '&Clear Application Point Set', 'Clear application point set');
        
        opActions = mbcgui.actions.ActionGroup;
        opActions.MenuType = 'separate';
        opActions.Actions = [obj.AssignOpPointSet obj.ClearOpPointSet];
        set(opActions, 'Enabled', false);
        
        obj.AllActions =  mbcgui.actions.ActionGroup([],'&Objectives');
        obj.AllActions.MenuType = 'submenu';
        obj.AllActions.Actions = [stdActions, bdActions, opActions];
        
        obj.Listeners = [event.listener(ms,'SetupChanged',@obj.pCheckActionStatus);
            event.listener(ms,'ObjectiveChanged',@obj.pCheckActionStatus);
            event.listener(ms,'DatasetChanged',@obj.pCheckActionStatus);
            event.proplistener(ms,ms.findprop('SelectedObjective'),'PostSet',@obj.pCheckActionStatus)];
        
        end  % pMakeActions
    end
    
    methods 
        
        %----------------------------------------
        function onAddBoundaryConstraint(obj)
        %onAddBoundaryConstraint Add the objective's boundary constraint
        %   onAddBoundaryConstraint(OBJ) adds the objective's boundary constraint to
        %   the optimization. If the objective has no boundary model, the menu item
        %   should be disabled.
        
        ms = obj.MessageService;
        if ms.hasData
            optim = ms.getOptim;
            opts = getSetup(optim);
            objLabels = getObjectiveLabels(opts);
            thisObjLabel = objLabels(ms.SelectedObjective);
            optim = addBoundaryConstraint(optim, thisObjLabel);
            % Update the optimization: this will redraw the UI too.
            ms.setOptim(optim, 'constraint');
        end
        
        end  % onAddBoundaryConstraint
        
        %----------------------------------------
        function onAddItem(obj)
        %onAddItem Add an item to the optimization
        %  onAddItem(OBJ) is called to add a new item to the optimization.
        
        ms = obj.MessageService;
        if ms.hasData
            optim = ms.getOptim;
            optim = addObjectiveFunc(optim);
            [optim, ok] = guiObjectiveEditor(optim, getNumObjectives(optim), ms.ProjectPointer);
            if ok
                % Update the optimization: this will redraw the UI too.
                ms.setOptim(optim, 'objective');
            end
        end
        
        end  % onAddItem
        
        %----------------------------------------
        function onAssignOpPointSet(obj)
        %onAssignOpPointSet assign operating point set for current constraint
        %  onAssignOpPointSet(OBJ)
        
        ms = obj.MessageService;
        if ms.hasData && ms.SelectedObjective>0
            optim = ms.getOptim;
            [optim, ok] = guiAppPointEditor(optim, 'objective', ms.SelectedObjective, ms.ProjectPointer);
            if ok
                % Update the optimization: this will redraw the UI too.
                ms.setOptim(optim, 'Dataset');
            end
        end
        
        end  % onAssignOpPointSet
        
        %----------------------------------------
        function onClearOpPointSet(obj)
        %onClearOpPointSet clear operating point set for current constraint
        %  onClearOpPointSet(OBJ)
        
        ms = obj.MessageService;
        if ms.hasData && ms.SelectedObjective>0
            optim = ms.getOptim;
            DS = getOptimDatasets(optim);
            DS = DS.editObjective(ms.SelectedObjective,xregpointer);
            optim = setOptimDatasets(optim,DS);
            optim = cleanupOppoints(optim);
            % Update the optimization: this will redraw the UI too.
            ms.setOptim(optim, 'Dataset');
        end
        
        end  % onClearOpPointSet
        
        %----------------------------------------
        function onDeleteItem(obj)
        %onDeleteItem Remove an item from the optimization
        %  onDeleteItem(OBJ) is called when an item should be removed from the
        %  optimization.
        
        ms = obj.MessageService;
        if ms.hasData && ms.SelectedObjective>0
            optim = ms.getOptim;
            optim = deleteObjectiveFunc(optim, ms.SelectedObjective);
            
            % Update the optimization: this will redraw the UI too.
            ms.setOptim(optim, 'objective');
        end
        
        end  % onDeleteItem
        
        %----------------------------------------
        function onEditItem(obj)
        %onEditItem Edit an item
        %  onEditItem(OBJ) is called when the currently selected item is
        %  double-clicked or otherwise activated.  If the item is editable, an
        %  appropriate dialog should be displayed for editing it.
        
        ms = obj.MessageService;
        if ms.hasData && ms.SelectedObjective>0 && ~isempty(ms.ProjectPointer)
            optim = ms.getOptim;
            [optim, ok] = guiObjectiveEditor(optim, ms.SelectedObjective, ms.ProjectPointer);
            if ok
                % Update the optimization: this will redraw the UI too.
                obj.MessageService.setOptim(optim, 'objective');
                % Update the boundary constraint menu label
                obj.pSetVariableMenuItemNames;
            end
        end
        
        end  % onEditItem
        
        %----------------------------------------
        function onRenameItem(obj)
        %onRenameItem Rename an item in the optimization
        %   onRenameItem(OBJ) is called to rename an item in the optimization.
        
        ms = obj.MessageService;
        if ms.hasData && ms.SelectedObjective>0
            optim = ms.getOptim;
            
            objectives = getObjectiveFunc(optim);
            oldName = getName(objectives{ms.SelectedObjective});
            helperStr = sprintf('Enter new name for %s:', oldName);
            % Set the number of columns (i.e. characters that are visible in the edit
            % box) for inputdlg.
            % nCol = 35 tries to ensure that the dialog title is not truncated.
            % length(oldName)+25 tries to ensure the helper string is not wrapped.
            nCol = max(35, length(oldName)+25);
            newName = inputdlg(helperStr, 'Rename Objective', [1 nCol], {oldName});
            try
                if isempty(newName)
                    % If newName is empty, then the user has pressed cancel in
                    % inputdlg. This is ok, just return the unaltered optim.
                else
                    optim = renameObjective(optim, oldName, newName{1});
                end
                ok = true;
            catch
                msgLine1 = 'Could not rename item. ';
                msgLine2 = 'The name must be a valid MATLAB variable name and be unique among objectives and constraints.';
                errstr = sprintf('%s%s', msgLine1, msgLine2);
                hError = errordlg(errstr, 'Rename Objective', 'modal');
                waitfor(hError);
                ok = false;
            end
            
            if ok
                % Update the optimization: this will redraw the UI too.
                ms.setOptim(optim, 'objective');
            end
        end
        end  % onRenameItem        
        
        
        %----------------------------------------
        function pCheckActionStatus(obj,~,~)
        %PCHECKACTIONSTATUS Update the enable status of the object's actions
        %  PCHECKACTIONSTATUS(OBJ)
        
        ms = obj.MessageService;
        if ms.hasData
            set(obj.AllActions, 'Enabled', true);
            
            optim = obj.MessageService.getOptim;
            opts = getSetup(optim);
            obj.Add.Enabled = canAddObjective(opts);
            if ms.SelectedObjective>0  && ms.SelectedObjective<=numObjectives(opts)
                obj.Edit.Enabled = (numObjectives(opts)>0);
                obj.Delete.Enabled = canRemoveObjective(opts);
                obj.Rename.Enabled = canRename(opts);
                obj.AddBoundary.Enabled = ...
                    canAddConstraint(opts) && i_hasBoundary(optim, ms.SelectedObjective);
                
                DS = getOptimDatasets(optim);
                % can only add application point set problems for sum problems. The
                % check canAddOperatingPointSet is a fast check for most
                % algorithms. Searching for data sets is slower but
                % is necessary when the number of data sets is fixed.
                AppPointStatus = isSumProblem(optim) && ...
                    (canAddOperatingPointSet(opts) || ~isempty(findDatasets(DS,optim,ms.ProjectPointer)));
                set(obj.AssignOpPointSet,'Enabled',AppPointStatus)
                set(obj.ClearOpPointSet,'Enabled',~isnull(DS.Objectives(ms.SelectedObjective)))
                
            else
                
                set(obj.AllActions, 'Enabled', false);
                obj.Add.Enabled = true;
            end
            
        else
            set(obj.AllActions, 'Enabled', false);
        end
        end  % pCheckActionStatus
        
        %----------------------------------------
        function pSetVariableMenuItemNames(obj)
        %PSETVARIABLEMENUITEMNAMES Set menu item names
        %   PSETVARIABLEMENUITEMNAMES(OBJ) sets the names of any menu items that
        %   are dependent on the current selection.
        
        % Update name of boundary model menu
        pMod = obj.pGetObjectiveExpression;
        if isvalid(pMod)
            objName = [pMod.getname, ' '];
        else
            objName = '';
        end
        bdMenuName = sprintf('Add %sBoundary to Constraints', objName);
        obj.AddBoundary.Label = bdMenuName;
        end  % pSetVariableMenuItemNames        
        
        %----------------------------------------
        function pExpr = pGetObjectiveExpression(obj)
        %PGETOBJECTIVEEXPRESSION Return the current objective expression
        %   PEXPR = PGETOBJECTIVEEXPRESSION(OBJ) returns the expression in the
        %   current objective
        
        
        ms = obj.MessageService;
        if ms.SelectedObjective
            optim = ms.getOptim;
            allObj = getObjectiveFunc(optim);
            thisObj = allObj{ms.SelectedObjective};
            try
                pExpr = getExpression(thisObj);
                % Ensure that a single expression (or null) is returned
                if isempty(pExpr)
                    pExpr = null(xregpointer);
                else
                    pExpr = pExpr(1);
                end
            catch
                % May implement an objective in the future that does not implement
                % getExpression
                pExpr = null(xregpointer);
            end
        else
            pExpr = null(xregpointer);
        end
        end  % pGetObjectiveExpression        
        
    end
    
end

function hasBoundary = i_hasBoundary(optim, objIdx)

allObj = getObjectiveFunc(optim);
thisObj = allObj{objIdx};
pMod = getExpression(thisObj);
hasBoundary = ~isnull(pMod) && isa(pMod.info, 'cgmodexpr') ...
    && concheck(pMod.info);
end  % i_hasBoundary