www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/@cgoptimexprgroup/evaluateItems.m

    function out = evaluateItems(obj, X, ItemInd)
%EVALUATEITEMS Evaluate the expressions for the specified items
%
%   OUT = EVALUATEITEMS(OBJ, X, ITEMIND) evaluates the expressions that are
%   required for the items specified in ITEMIND, using the input values in
%   X.  X must be a cell array with each cell containing a matrix of input
%   data.  The rows of these matrices correspond to separate evaluation
%   sets; each matrix should have the same number of rows.  Differing
%   numbers of columns are allowed so long as they as the differing lengths
%   are not used as inputs to a given output expression.  OUT is a cell
%   array the same length as ITEMIND with each cell containing a cell array
%   of matrices, one for each expression associated with that item.  The
%   output matrices will have the same number of rows as the input ones.

%   Copyright 2005-2009 The MathWorks, Inc.


if nargin<3 || isequal(ItemInd,1:length(obj.ExpressionsPerItem))
    ItemInd = 1:length(obj.ExpressionsPerItem);
    OutputInd = 1:sum(obj.ExpressionsPerItem);
else
    % Convert ItemInd to Expression output indices
    OutputIndBreaks = [1 cumsum(obj.ExpressionsPerItem)+1];
    OutputInd = zeros(1, sum(obj.ExpressionsPerItem(ItemInd)));
    k = 1;
    for n = ItemInd
        len = obj.ExpressionsPerItem(n);
        OutputInd(k:k+len-1) = OutputIndBreaks(n):(OutputIndBreaks(n+1)-1);
        k = k+len;
    end
end

ChainOutputs = getOutputIndices(obj);
OutputInd = ChainOutputs(OutputInd);

% Get the inputs needed for each output expression
InputDep = getRequiredInputs(obj, OutputInd);

NumRows = cellfun('size', X, 1);
if any(NumRows~=NumRows(1))
    error(message('mbc:cgoptimexprgroup:InvalidArgument'));
end
NumRows = NumRows(1);

InputSizes = cellfun('size', X, 2);

% Work out the expected size of each output from its inputs, plus check
% whether any scalar expansion is expected to occur in each output
% expression
OutputSizes = zeros(size(OutputInd));
NeedsScalarExpansion = false;
for n = 1:length(OutputSizes)
    if ~isempty(InputDep{n})
        OutputSizes(n) = max(InputSizes(InputDep{n}));
        NeedsScalarExpansion = NeedsScalarExpansion ...
            || any(InputSizes(InputDep{n})~=OutputSizes(n));
    else
        OutputSizes(n) = 1;
    end
end

% Decide whether to loop over expressions or evaluate all at once
DoExpressionLoop = false;

% If duplicate point removal is turned on and there are outputs of different
% lengths then expression looping is often quicker as this will allow
% duplicate point removal to be done.
if getCompressInputData(obj) && hasMultipleValues(OutputSizes)
    DoExpressionLoop = true;
end

% If there are multiple rows and scalar expansion is expected in an
% expression then we will have to loop over expressions to do the scalar
% expansion per row manually.  (For cases where the scalar expansion
% requirements of the various outputs do not clash this could be done
% without requiring an evaluation loop but this has not been implemented)
if ~DoExpressionLoop && NumRows>1 && NeedsScalarExpansion
    DoExpressionLoop = true;
end

% Perform evaluations
if DoExpressionLoop
    % Need to loop over the evaluation expressions since the scalar
    % expansion for one may interfere with that for another.
     
    % Initialise output data
    outdata = cell(size(OutputInd));

    % Loop over expressions to be evaluated
    for n = 1:length(outdata)
        % Initialise evaluation data cell
        Xeval = cell(size(X));

        % Repmat the relevant inputs in the right way
        if OutputSizes(n)>1
            for m = InputDep{n}
                if InputSizes(m)==1
                    x = repmat(X{m}.', OutputSizes(n), 1);
                else
                    x = X{m}.';
                end
                Xeval{m} = x(:);
            end
        else
            % All-scalar inputs - can use original X values here
            Xeval(InputDep{n}) = X(InputDep{n});
        end
        
        y = chaineval(obj, Xeval, OutputInd(n));
        y = y{1};
        
        if isscalar(y)
            % Repmat the result up to the expected output size
            outdata{n} = repmat(y, NumRows, OutputSizes(n));
        else
            % Reshape the data in the right way
            outdata{n} = reshape(y, OutputSizes(n), NumRows).';
        end
    end
    
else
    % Can pack all of the relevant input data into single vectors and do the
    % evaluation in one go.  Inputs that are not required are emptied.
    AllDeps = unique([InputDep{:}]);
    if ~isempty(AllDeps)
        X(~ismember(1:length(X), AllDeps)) = {[]};
        for n = AllDeps
            if size(X{n},2)~=1
                % convert to column vector
                x = X{n}.';
                X{n} = x(:);
            end
        end
    end
    
    outdata = chaineval(obj, X, OutputInd);
    
    % Unpack the output vectors into matrices of the correct size
    if NumRows~=1 || any(OutputSizes~=1)
        for n = 1:length(outdata)
            y = outdata{n};
            if isscalar(y)
                % Repmat the result up to the expected output size
                outdata{n} = repmat(y, NumRows, OutputSizes(n));
            else
                % Reshape the data in the right way
                outdata{n} = reshape(y, OutputSizes(n), NumRows).';
            end
        end
    end
end

% Split the output matrices into groups for each specified item
out = cell(size(ItemInd));
k = 1;
len = obj.ExpressionsPerItem(ItemInd);
for n = 1:length(out)
    out{n} = outdata(k:(k+len(n)-1));
    k = k + len(n);
end



function ret = hasMultipleValues(Data)
ret = false;
mx = max(Data);
if ~isempty(mx)
    ret = ~all(Data==mx);
end