www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/@xregdesign/applyconstraints.m

    function [des, mode] = applyconstraints(des, mode)
%APPLYCONSTRAINTS Reapply design constraints to current design
%
%  DES = APPLYCONSTRAINTS(DES) reapplies the current constraints to the
%  current design points.  Design points that are not fixed and are not
%  within the constraint envelope are removed.
%
%  DES = APPLYCONSTRAINTS(DES, MODE) specifies how the constraints are
%  re-applied.  MODE may be any one of the following, with the default
%  being 'remove':
%
%  remove       - Points that are outside the constraints are removed.
%  replace      - Points that are outside the constraints are removed and
%                 replaced with new points that are inside the constraints.
%                 The new points will be randomly chosen.
%  interactive  - If there are any points ouside the constraints, a dialog
%                 is displayed that will allow you to choose what to do.
%                 The options available will depend on the design type; you
%                 will always be able to either remove or do nothing.   For
%                 optimal designs you will also be able to replace.  If you
%                 choose to replace then another dialog will be shown that
%                 allows you to choose how to replace the points.
%
%  [DES, MODE] = ... returns the MODE that was used to perform the actual
%  operation.  If you specify 'interactive' as the input MODE, then this
%  return value will indicate what you chose to do in the dialog.  If you
%  chose to do nothing then it will be an empty string.  If no action was
%  required then the string 'none' will be returned.

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

if nargin<2
    mode = 'remove';
end
IsInteractive = strcmpi(mode, 'interactive');

% Get the points that need to be dealt with
PtIdx = iPointsOutsideConstraints(des);

if isempty(PtIdx)
    % There is no work to be done
    mode = 'none';
    return
end

if IsInteractive
    % Ask the user which mode they really want
    mode = iGetModeDlg(des, PtIdx);
end

switch mode
    case 'remove'
        des = delete(des, 'indexed', PtIdx );
    case 'replace'
        if IsInteractive
            des = iReplaceDlg(des, PtIdx);
        else
            des = iReplaceAuto(des, PtIdx);
        end
    otherwise
        % Doing nothing is an option that the interactive mode allows.
        % mode is an empty string in this case.
end




function mode = iGetModeDlg(des, PtIdx)
% Show a dialog that asks the user how they want to apply the constraints
NumPointsOut = length(PtIdx);
if DesignType(des)==1
    msg = ['There are currently ' sprintf('%d',NumPointsOut) ' non-fixed points in ',...
        'the design that are not within the new constraints envelope.  Do you want ',...
        'to remove these points, replace them with new ones or cancel the constraint ',...
        'change?'];
    opts = {'Remove','Replace','Cancel','Replace'};
else
    msg = ['There are currently ' sprintf('%d',NumPointsOut) ' non-fixed points in ',...
        'the design that are not within the new constraints envelope and will be ',...
        'removed.  Do you want to continue with the removal or cancel ',...
        'the constraint change?'];
    opts = {'Continue','Cancel','Continue'};
end
mode = questdlg(msg,'MBC Toolbox',opts{:});
mode = lower(mode);
if strcmp(mode, 'continue')
    mode = 'remove';
elseif strcmp(mode, 'cancel')
    mode = '';
end


function des = iReplaceAuto(des, PtIdx)
% Replace points that are not within the constraints.  
des = delete(des,'indexed',PtIdx);
m = model(des);
[LLim, ULim, Range] = range(m);

% Generate random points and test them against constraints until we have
% enough
NumRequired = length(PtIdx);
nf = nfactors(des);
X = zeros(NumRequired, nf);
LoopCount = 0;
while NumRequired>0  && LoopCount<10
    % Overgenerate by 20% to reduce iterations of this loop, or at least 10
    % points if it is less than that.
    Xnew = rand(max(ceil(1.2*NumRequired), 10), nf);
    Xnew = bsxfun(@plus,  LLim, bsxfun(@times, Range, Xnew));
    in = isInsideNoMemory( des.constraints, Xnew );
    Xnew = Xnew(in, :);
    
    % Because of the over-generation we might end up with more than
    % required.  We don't want to take more than we need
    NumNew = min(size(Xnew, 1), NumRequired);
    
    X(end-NumRequired+1:end-NumRequired+NumNew, :) = Xnew(1:NumNew, :);
    NumRequired = NumRequired-NumNew;
    
    % Maintain a counter so we exit if there is a problem finding
    % points.  This counts the number of times we fail to generate any
    % points that are inside the constraints
    if ~any(in)
        LoopCount = LoopCount+1;
    end
end

% Add points to design
X = code(m, X);
des = augment(des, X, 'points');


function des = iReplaceDlg(des, PtIdx)
% Show the add points dialog to replace points

% Save and reset type info so that the correct option shows up in the add
% dialog
[tp,nm] = DesignType(des);
des = delete(des,'indexed',PtIdx);
des = DesignType(des, tp, nm);

% Display add point dialog
des = gui_addpoints(des,'create','npoints',length(PtIdx));


function PtIdx = iPointsOutsideConstraints(des)
if ~isempty(des.constraints)
    idxFree = freepoints(des);
    Xc = des.design(idxFree,:);
    m = model( des );
    in = isInsideNoMemory( des.constraints, invcode( m, Xc ) );
    PtIdx = idxFree(~in);
else
    PtIdx = [];
end