www.gusucode.com > mbcexpr 工具箱 matlab 源码程序 > mbcexpr/@cgexpr/evaluatesequential.m

    function Y = evaluatesequential(obj, pSeq, dSeqNomValues, func, logicalflag)
%EVALUATESEQUENTIAL Evaluate expression over each input
%
%  Y = EVALUATESEQUENTIAL(OBJ, SEQPTRS, SETPOINTS, QUANTITY) evaluates the
%  expression OBJ across each of the vector inputs listed in SEQPTRS in
%  sequence, while holding the rest of the inputs at a set value specified
%  by its entry in SETPOINTS.  The return value Y is a cell array the same
%  length as SEQPTRS containing the evaluation results as each input vector
%  in turn is evaluated.   QUANTITY is an optional parameter to specify
%  which aspect of the expression to evaluate and may be one of 'value',
%  'pev' or 'constraint' or a function handle to a function with the syntax
%  Y = FUNC(OBJ).
%
%  If QUANTITY is not specified then 'value' is assumed.
%
%  Y = EVALUATESEQUENTIAL(OBJ, SEQPTRS, SETPOINTS, QUANTITY, LOGICAL)
%  indicates whether the function evaluation will return logical values
%  (LOGICAL=true).
%
%  All other pointers in the inports list that are not in SEQPTRS must not
%  contain vectors unless they are dependent on one of the pointers in
%  SEQPTRS.  All of the SEQPTRS must be independent of each other.
%
%  Example:
%
%    M is a model with 4 inputs: L, N, A, E.
%    L is a vector of length 10 with values (1:10).
%    N is a vector of length 20 with values (1:20).
%    A and E have scalar values.
%
%    The call Y = EVALUATESEQUENTIAL(M, [L N], [5, 15]) will construct the
%    following inputs for L and N:
%
%    L = [(1:10)  repmat(5, 1,20)];
%    N = [repmat(15, 1, 10)  (1:20)];
%
%    and then call i_eval on M.  The output Y will be a cell array with the
%    first cell containing the evaluation results as L is varied and the
%    second cell containing the results as N is varied:
%
%    Y =
%        [1x10 double]
%        [1x20 double]
%
%
%  See also CGEXPR/EVALUATE, CGEXPR/EVALUATEGRID.

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


if nargin<3
    error(message('mbc:cgexpr:InvalidArgument7'));
end

if length(dSeqNomValues) ~= length(pSeq)
    error(message('mbc:cgexpr:InvalidArgument8'));
end

if isinport(obj)
    error(message('mbc:cgexpr:InvalidArgument9'));
end

% Get evaluation function flag
if nargin<4
    func = @i_eval;
else
    if ischar(func)
        nQuant = strcmpi(func, {'value', 'pev', 'constraint'});
        if ~any(nQuant)
            % Convert the string to a function handle
            func = str2func(func);
        elseif nQuant(1)
            func = @i_eval;
        elseif nQuant(2)
            func = @peveval;
        else
            func = @ceval;
        end
    end
end

if nargin<5
    logicalflag = false;
end

pInputs = getinports(obj);

% Check that the inputs are all independent of each other
if ~cgisindependentvars(pSeq)
    error(message('mbc:cgexpr:InvalidArgument10'));
end

% Find the pointers that are not sequential variables or dependent on the
% sequential variables (this includes the sequential pointers themselves).
% All of these remaining pointers must be scalars.
pInputs = pInputs(cgisindependentvars(pInputs, pSeq));
bScalar = pveceval(pInputs, @isscalar);
if ~all([bScalar{:}])
    error(message('mbc:cgexpr:InvalidArgument11'));
end

% Check that the expanded input formation won't consume too much memory.
% If it looks too big then the evaluation is split into an evaluation for
% each separate input.  These evaluations are unchecked for size so if an
% individual input is set too large there may still be memory problems
dValues = pveceval(pSeq, @getvalue);
dims = cellfun('length', dValues);
nElements = sum(dims);

% LIMIT is the limit on the number of input elements
LIMIT = 2^16;
if (nElements*length(pSeq)) < LIMIT
    dSeqValues = cell(size(dValues));
    nCumElements = [0 cumsum(dims)];
    for n = 1:length(pSeq)
        inputvect = repmat(dSeqNomValues(n), nElements, 1);
        inputvect((nCumElements(n)+1):nCumElements(n+1)) = dValues{n}(:);
        dSeqValues{n} = inputvect;
    end
    passign(pSeq, parrayeval(pSeq, @setvalue, {dSeqValues}));
    % Pre-allocating the output automatically corrects the rare cases where
    % the output of i_eval is scalar even when the grid inputs are vectors.
    if logicalflag
        dYValues = false(nElements, 1);
    else
        dYValues = zeros(nElements, 1);
    end
    dYValues(:) = func(obj);

    clear('dSeqValues');
    Y = cell(length(pSeq),1);
    for n = 1:length(pSeq)
        Y{n} = dYValues((nCumElements(n)+1):nCumElements(n+1));
    end
else
    % Set the inputs to their nominal values
    passign(pSeq, parrayeval(pSeq, @setvalue, {num2cell(dSeqNomValues)}));
    Y = cell(length(pSeq),1);
    for n = 1:length(pSeq)
        pSeq(n).info = pSeq(n).setvalue(dValues{n});
        if logicalflag
            YValue = false(size(dValues{n}));
        else
            YValue = zeros(size(dValues{n}));
        end
        YValue(:) = func(obj);
        Y{n} = YValue;
        pSeq(n).info = pSeq(n).setvalue(dSeqNomValues(n));
    end
end

passign(pSeq, parrayeval(pSeq, @setvalue, {dValues}));