www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/@cgtradeoffnode/autoTradeoff.m

    function [obj, hasrun] = autoTradeoff(obj)
%AUTOTRADEOFF Perform an automated trade off
%
%  [OBJ, HASRUN] = AUTOTRADEOFF(OBJ) automatically performs a trade-off
%  using an optimization algorithm selected by the user.  The output HASRUN
%  indicates whether the optimization was completed or whether the user
%  cancelled at some point

%  Copyright 2000-2010 The MathWorks, Inc. and Ford Global Technologies, Inc.


hasrun = false;
pTableInputs = pGetTableInputs(obj);

% Choose an optimization 
[optimnode, ok] = i_ChooseOptimization(obj, pTableInputs);
if ~ok
    return
end

% Ask user how they want to define the points that should be run and return
% the selection as a list of datakeys
OldKeyTable = obj.DataKeyTable;
[obj, datakeys, ok] = i_SelectTradeoffPoints(obj);
if ~ok
    return
elseif isempty(datakeys)
    h = warndlg('There are no table cells defined by your selection.', ...
        'Automated Tradeoff Warning', 'modal');
    waitfor(h);
    return
end
xregpointer(obj);

% Snap all inputs to the selected points
pSetInputsAt(obj, datakeys);

% Set up and run the optimization
[pInputs, data, OK] = ...
    i_SetUpandRunOptim(optimnode, pTableInputs, obj, datakeys);

% Update the tradeoff if the optimization ran successfully
if OK > 0
    % For each optimized point, set the data into the inputs and save the
    % values of all of the tradeoff inputs.  We only need to use the
    % optimized data for inputs that are actually in the tradeoff.
    pAll = [pGetTableInputs(obj), pGetOtherInputs(obj)];
    if ~isempty(pAll)
        DataColumnIndex = findptrs(pAll, pInputs);
        hAll = infoarray(pAll);
        
        NPTS = max(size(data{1}));
        for r = 1:NPTS
            % For each trade off cell selected
            for m = 1:length(hAll)
                % For each free/fixed variable
                if DataColumnIndex(m) > 0
                    thisdata = data{DataColumnIndex(m)}(r, 1);
                else
                    % This trade off variable is not in the optimization.
                    % Use the value from the trade off store, or the set
                    % point if the store is empty.
                    thisdata = getstorevalue(hAll{m}, obj.ObjectKey, ...
                        datakeys(r));
                    if isempty(thisdata)
                        thisdata = getnomvalue(hAll{m});                        
                    end
                end
                hAll{m} = setstorevalue(hAll{m}, obj.ObjectKey, ...
                    datakeys(r), thisdata);
            end
        end
        passign(pAll, hAll);
    end
    
    % Mark each of these points as having been saved
    obj.DataKeyTable = incrementSaveCounter(obj.DataKeyTable, datakeys);
    
    % Apply filling action to all of these points that have a table link
    [TableIndex, HasLink] = getTableFromDatakey(obj.DataKeyTable, datakeys);
    pSetInputsAt(obj, datakeys(HasLink));
    captureTableFillAt(obj, getTable(obj, 'all'), TableIndex{:});    
    
    xregpointer(obj);
    hasrun = true;
else
    % Restore tradeoff object to initial state.  This will undo any changes
    % to the saved data point list
    obj.DataKeyTable = OldKeyTable;
    xregpointer(obj);
end

%-------------------------------------------------------------------------|
function [obj, datakeys, ok] = i_SelectTradeoffPoints(obj)
%-------------------------------------------------------------------------|

% Pop up a small dialog asking the user which points to run the
% optimisation on.  The user can select:
%
%  (1) Multimodel sites (appears only for multimodels, becomes the default)
%  (2) All table region cells (standard default)
%  (3) All table cells
%  (4) Previously saved tradeoff points (enabled only when there are some)

% Check for multimodels
pTableInfo = getAllTableData(obj);
pMask = pTableInfo(~isnull(pTableInfo(:, 3)), 3);
IsMM = pveceval(pMask, @isSwitchExpr);
IsMM = [IsMM{:}];

% Check for existence of regions in any tables
HasRegion = pveceval(pTableInfo(:,1), @anyExtrapolationRegions);
HasRegion = [HasRegion{:}];

% Check for previous tradeoff points
HasSavedPoints = length(obj.DataKeyTable) > 0 && ...
    any(hasTableLink(obj.DataKeyTable));  

if any(IsMM)
    opts = {'Valid model operating points'; ...
        'All table cells that are in a region'; ...
        'All table cells'; ...
        'Previously saved Tradeoff points'};
    DefaultValue = 1;
    OptionsEnable = [true; any(HasRegion); true; HasSavedPoints];
else
    opts = {'All table cells that are in a region'; ...
        'All table cells'; ...
        'Previously saved Tradeoff points'};
    if any(HasRegion)
        DefaultValue = 1;
    else
        DefaultValue = 2;
    end
    OptionsEnable = [any(HasRegion); true; HasSavedPoints];
end

figh = xregdialog('Name', 'Select Points to Optimize', ...
    'Resize', 'off');
xregcenterfigure(figh, [350 170]);

txt = uicontrol('Parent', figh, ...
    'Style', 'text', ...
    'HorizontalAlignment', 'left', ...
    'String', 'Please select the set of points that you want to optimize:');
rbg = xregGui.rbgroup('Parent', figh, ...
    'nx', 1, 'ny', length(opts), ...
    'string', opts, ...
    'Selected', DefaultValue, ...
    'EnableArray', OptionsEnable);
% Workaround bug in rbgroup
set(rbg, 'Selected', DefaultValue);
hOK = uicontrol('Parent', figh, ...
    'Style', 'pushbutton', ...
    'String', 'OK', ...
    'Callback', @(src,evt)set(figh, 'Tag', 'ok', 'Visible', 'off') );
hCancel = uicontrol('Parent', figh, ...
    'Style', 'pushbutton', ...
    'String', 'Cancel', ...
    'Callback', @(src,evt)set(figh, 'Tag', 'cancel', 'Visible', 'off') );

lyt = xreggridbaglayout(figh, ...
    'packstatus', 'off', ...
    'dimension', [4 3], ...
    'rowsizes', [17 20*length(opts) -1 25], ...
    'colsizes', [-1 65 65], ...
    'gapx', 7, ...
    'border', [7 7 7 10], ...
    'mergeblock', {[1 1], [1 3]}, ...
    'mergeblock', {[2 2], [1 3]}, ...
    'elements', {txt, rbg, [],[],[],[],[],hOK, [],[],[],hCancel});
figh.LayoutManager = lyt;
set(lyt, 'packstatus', 'on');

figh.showDialog(hOK);

if strcmp(get(figh, 'Tag'), 'ok')
    sel = get(rbg, 'Selected');
    if any(IsMM)
        sel = sel - 1;
    end
    switch sel
        case 0
            [obj, datakeys] = i_getswitchpoints(obj);
        case 1
            [obj, datakeys] = i_getregions(obj);
        case 2
            [obj, datakeys] = i_getalltable(obj);
        case 3
            [obj, datakeys] = i_getcurrent(obj);
    end
    ok = true;
else
    datakeys = [];
    ok = false;
end  
delete(figh);
drawnow('expose');


function [obj, datakeys] = i_getswitchpoints(obj)
if numTables(obj)>0
    pTableData = getAllTableData(obj);
    setInputsAt(obj, 'table', 1, 1);
    OK = pTableData(1,1).setinportsforcells;
    pInp = pGetTableInputs(obj);
    if OK
        msk = false(pTableData(1,1).getTableSize);
        for n = 1:size(pTableData,1)
            if ~isnull(pTableData(n,3)) && pTableData(n,3).isSwitchExpr
                msk = msk | pTableData(n,3).getSwitchGrid(pInp);
            end
        end
        
        [R, C] = find(msk);
        new = ~containsTable(obj.DataKeyTable, R, C);

        % Add data keys for new input settings
        obj.DataKeyTable = addTableDatakeys(obj.DataKeyTable, R(new), C(new));
        
        % Get the datakeys for all cells required
        datakeys = getDatakeyFromTable(obj.DataKeyTable, R, C);
    else
        datakeys = [];
    end
else
    datakeys = [];
end

function [obj, datakeys] = i_getregions(obj)
if numTables(obj)>0
    % Form OR-ed mask from all table regions
    pT = getTable(obj, 'all');
    msk = false(pT(1).getTableSize);
    for n = 1:length(pT)
        msk = msk | pT(n).getExtrapolationRegions;
    end

    [R, C] = find(msk);
    new = ~containsTable(obj.DataKeyTable, R, C);

    % Add data keys for new input settings
    obj.DataKeyTable = addTableDatakeys(obj.DataKeyTable, R(new), C(new));
    
    % Get the datakeys for all cells required
    datakeys = getDatakeyFromTable(obj.DataKeyTable, R, C);
else
    datakeys = [];
end

function [obj, datakeys] = i_getalltable(obj)
if numTables(obj)>0
    sz = obj.Tables(1).getTableSize;
    [R, C] = ndgrid(1:sz(1), 1:sz(2));
    new = ~containsTable(obj.DataKeyTable, R, C);
    
    % Add data keys for new input settings
    obj.DataKeyTable = addTableDatakeys(obj.DataKeyTable, R(new), C(new));
    
    % Get the datakeys for all cells required
    datakeys = getDatakeyFromTable(obj.DataKeyTable, R(:), C(:));
else
    datakeys = [];
end

function [obj, datakeys] = i_getcurrent(obj)
datakeys = getAllDatakeys(obj.DataKeyTable);
inds = isPointSaved(obj.DataKeyTable) & hasTableLink(obj.DataKeyTable);
datakeys = datakeys(inds);

%-------------------------------------------------------------------------|
function [chosenNode, ok] = i_ChooseOptimization(obj, axesVariables)
%-------------------------------------------------------------------------|
% if the user clicks cancel, ok is returned as false
chosenNode = [];
ok = false;

% get the optimization nodes from the cage browser
proj = project(obj);
optimNodes = filterbytype(proj, cgtypes.cgoptimtype);
nOptimNodes = length( optimNodes );

% Get the optim objects/ptrs from the optimNodes
optimPtr = null(xregpointer, size(optimNodes));

% What are appropriate optimization objects? 
%
% The list of all optimization objects in the project is filtered. To be 
% eligible for selection:
% 1) The object must be fully linked, that is, the optimization must be
%    ready to run (toolbar button enabled). The exception to this is when
%    the primary  operating point set has not been linked yet
% 2) The variables in the axes of the tradeoff tables must not be free 
%    variables in the optimization, e.g., if one of the axes is speed, then 
%    speed cannot be a free variable.
% 3) The axes variables must both be members of the set of optimization fixed
%    variables
% 4) The optimization must be contain length one variables per run
% (formerly known as the point-by-point case) or contain one run only (the
% sum/global case)
allowedOptims = true(nOptimNodes, 1);
for i = 1:nOptimNodes, 
    [optimPtr(i), pFixed] = i_getOptimInfo(optimNodes{i});
    hOptim = optimPtr(i).info;
    % Check that the object is fully linked. 
    canRun = checkrun(optimPtr(i).info, 'fullcheck');
    if ~canRun,
        allowedOptims(i) = false;
    end

    % Check free variables
    valuePtrs = get(hOptim, 'values' );
    if anymember(valuePtrs, axesVariables),
        allowedOptims(i) = false;
    end
    
    % Optimization must contain both axes variables as fixed variables
    if ~all(ismember(axesVariables, pFixed))
        allowedOptims(i) = false;
    end
    
    % Optimization must be 
    % EITHER:
    % 1 run with all variables (free and fixed) of equal length
    % OR:
    % N runs with all variables of length 1
    olddata = getinitialvaluedata(hOptim);
    varlen = cellfun('size', olddata, 2);
    varlen = unique(varlen);
    NRUNS = getNumRuns(hOptim);
    % Suitable 1 run problems
    suitableOneRun = (NRUNS == 1 && numel(varlen) == 1);
    % Suitable N run problems
    suitableManyRun = (NRUNS > 1 && max(varlen) == 1);
    if ~(suitableOneRun || suitableManyRun)
        allowedOptims(i) = false;        
    end
   
end

% Remove the optimizations that can't be used
optimNodes = optimNodes(allowedOptims);
nOptimNodes = length( optimNodes );

if nOptimNodes == 0,
    % There are no optimizations available
    xregerror( 'Automated Tradeoff Error', ['There are no optimizations '...
            'in this session that are compatible with this Tradeoff. Please '...
            'go to optimization to create one.'] );
    return
end

pOptimNodes = null(xregpointer, size(optimNodes));
for n = 1:numel(optimNodes)
    pOptimNodes(n) = address(optimNodes{n});
end

% Ask the user which optimization they want to use
figh = xregdialog('Name', 'Automated Tradeoff');
xregcenterfigure(figh, [350 200]);

txt = uicontrol('Parent', figh, ...
    'Style', 'text', ...
    'HorizontalAlignment', 'left', ...
    'String', 'Select an optimization to run:');
hList = cgoptimgui.optimList('Parent', figh, ...
    'Items', pOptimNodes, ...
    'SelectedItem', pOptimNodes(1));
hOK = uicontrol('Parent', figh, ...
    'Style', 'pushbutton', ...
    'String', 'OK', ...
    'Callback', @(src,evt)set(figh, 'Tag', 'ok', 'Visible', 'off') );
hCancel = uicontrol('Parent', figh, ...
    'Style', 'pushbutton', ...
    'String', 'Cancel', ...
    'Callback', @(src,evt)set(figh, 'Tag', 'cancel', 'Visible', 'off') );

lyt = xreggridbaglayout(figh, ...
    'packstatus', 'off', ...
    'dimension', [4 3], ...
    'rowsizes', [17 -1 7 25], ...
    'colsizes', [-1 65 65], ...
    'gapx', 7, ...
    'border', [7 7 7 10], ...
    'mergeblock', {[1 1], [1 3]}, ...
    'mergeblock', {[2 2], [1 3]}, ...
    'elements', {txt, hList, [],[],[],[],[],hOK, [],[],[],hCancel});
figh.LayoutManager = lyt;
set(lyt, 'packstatus', 'on');

figh.showDialog(hOK);

tg = get(figh, 'Tag');
if strcmp(tg, 'ok')
    ok = true;
    chosenNode = info(hList.SelectedItem);
end
delete(figh);
drawnow('expose');

%-------------------------------------------------------------------------|
function [outputPtrs, outputData, OK] = i_SetUpandRunOptim(optimnode, pAxes, to, datakeys)
%-------------------------------------------------------------------------|

% Get optim information
[pOptim, pFixed, pFree] = i_getOptimInfo(optimnode);
[olddata, pAll] = getinitialvaluedata(pOptim.info, [pFree, pFixed]);
NRUNOLD = getNumRuns(pOptim.info);
NALL = length(pAll);

% Set the number of runs
axesIdx = findptrs(pAxes, pAll);
axesfixedlen = cellfun('size', olddata(axesIdx), 2);
NPTSOLD = axesfixedlen(1);
NPTS = length(datakeys);
if NPTSOLD > 1
    % Sum optim
    NRUN = 1;
else
    % Point optim (or a sum with unit length vars)
    NRUN = NPTS;
end
pOptim.info = setNumRuns(pOptim.info, NRUN);

% Create the input data for the optim based on the tradeoff
newdata = pveceval(pAll, @get, 'setpoint');
newdata = [newdata{:}];
newdata = repmat(newdata, NPTS, 1);

% Set the chosen breakpoints in the input data
tableIdx = getTableFromDatakey(to.DataKeyTable, datakeys);
pTab = getTable(to, 1);
OK = setinportsforcells(pTab.info, tableIdx{1}, tableIdx{2});
if ~OK
    return
end
axisdata = pveceval(pAxes, @getvalue);
axisdata = cellfun(@(x)x(:), axisdata, 'UniformOutput', false);
newdata(:, axesIdx) = [axisdata{:}];

% Get the current value settings in the trade off
pTOVars = pGetOtherInputs(to);
hTOVars = infoarray(pTOVars);
todata = zeros(NPTS, length(hTOVars));
idxCanUseTO = true(NPTS, 1);
for r = 1:NPTS
    for i = 1:length(hTOVars)
        tmp = getstorevalue(hTOVars{i}, to.ObjectKey, datakeys(r));
        if isempty(tmp)
            idxCanUseTO(r) = false;
        else
            todata(r, i) = tmp;
        end
    end
end

% Find fixed/free in trade off values 
idxOtherVars = setdiff(1:NALL, axesIdx);
inds = findptrs(pAll(idxOtherVars), pTOVars);

% Get the data for the fixed/free variables. If available, use settings
% from trade off and use set point otherwise.
newdata(idxCanUseTO, idxOtherVars(inds > 0)) = ...
    todata(idxCanUseTO, inds(inds > 0));

% Put data in correct form for optim
newdata = num2cell(newdata, 1);
if NRUN == 1
    newdata = cellfun(@(x)(x(:))', newdata, 'UniformOutput', false);
end

% Set the run points for the optim
for i = 1:NALL
    pOptim.info = setinitialvaluedata(pOptim.info, pAll(i), 1:NRUN, newdata{i});
end

% Run the optimization
[OK, unused, optimout] = run(pOptim.info, true);

% Extract the information for passing back to tradeoff
if OK > 0
    outFreePtrs = getfreevalues(pOptim.info);
    NSOL = getNumSolutions(optimout);
    selsol = ceil(NSOL/2);    
    outFreeVals = getSolution(optimout, selsol);   
    outFreeVals = cellfun(@(x)x(:), outFreeVals, 'UniformOutput', false);
    newdata = cellfun(@(x)x(:), newdata, 'UniformOutput', false);
    outputPtrs = [outFreePtrs, pAll];
    outputData = [outFreeVals, newdata];
else
    outputPtrs = null(xregpointer,0);
    outputData = [];
end

% Reset the old run points for the optim
pOptim.info = setNumRuns(pOptim.info, NRUNOLD);
for i = 1:NALL
    pOptim.info = setinitialvaluedata(pOptim.info, pAll(i), 1:NRUNOLD, olddata{i});
end

%--------------------------------------------------------------------------
function [pOptim, pFixed, pFree] = i_getOptimInfo(optimnode)
%--------------------------------------------------------------------------

% Get the optimization object
pOptim = getdata(optimnode); 

% Save the current run points for the optim
pFixed = getfixedvalues(pOptim.info);
pFree = getfreevalues(pOptim.info);