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

    function out = chaineval(obj, X, OutIdx)
%CHAINEVAL Evaluate specified expression chain items
%
%   OUT = CHAINEVAL(OBJ, X, OUTIDX) provides the basic chain evaluation
%   functionality for the expression group.  This method may be used by
%   subclasses that need to provide more specialised evaluation mechanisms.
%   Users of cgexprgroup should use the evaluate method for normal
%   expression evaluation.

%   Copyright 2005-2009 The MathWorks, Inc.


CellsToEval = false(size(obj.ExprArray));
if nargin<3 || isequal(OutIdx, obj.Outports)
    OutIdx = obj.Outports;
    CellsToEval(:) = true;
else
    [IsCachedOut, CachedOutIdx] = ismember(OutIdx, obj.Outports);
    if all(IsCachedOut)
        CellsToEval(unique([obj.OutportRequiredIndices{CachedOutIdx}])) = true;
    else
        OtherOutIdx = pGetEvaluationIndices(obj.InputIndices, OutIdx(~IsCachedOut));
        CellsToEval(unique([obj.OutportRequiredIndices{CachedOutIdx(IsCachedOut)}, OtherOutIdx{:}])) = true;
    end
end

if isempty(OutIdx)
    out = {};
    return
end

expr = obj.ExprArray;
evalFcn = obj.EvaluationFunctions;
inputLoc = obj.InputIndices;
maxUsed = obj.MaxIndices;

xSize = cellfun('prodofsize', X);
N = max(xSize);
if isempty(N)
    N = 0;
end

% Can only easily remove duplicates if all input data is scalar or the same
% length - if it is not we would have to remove duplicates in groups and
% deal with several different sets of re-expansion indices.
RemoveDups = obj.RemoveDuplicateInputData && all(xSize==N | xSize==1 | xSize==0);

if RemoveDups
    XAll = zeros(N, length(X));
    for n = 1:length(X)
        if ~isempty(X{n})
            XAll(:, n) = X{n}(:);
        end
    end
    
    [XAll, ~, ExpandIdx] = unique(XAll, 'rows');
    
    for n = 1:length(X)
        if ~isempty(X{n}) && ~isscalar(X{n}) 
            % Don't allow scalar inputs to be expanded out unnecessarily
            X{n} = XAll(:, n);
        end
    end
end


% Reduce memory for 'large' evals only
ReduceMemory = obj.ReduceMemory && N*sum(CellsToEval)>1e3;

% Create a cell array to store the evaluation of each expression in
evalstore = cell(size(expr));

% Put required inputs into the evaluation
inpUsed = obj.Inports>0;
evalstore(obj.Inports(inpUsed)) = X(inpUsed);

% Work out types of each expression
NotIsInport = true(size(evalstore));
NotIsInport(obj.Inports(inpUsed)) = false;
NotIsOutport = true(size(evalstore));
NotIsOutport(obj.Outports) = false;

for n = find(NotIsInport & CellsToEval)
    evalstore{n} = evalFcn{n}(expr{n} , evalstore(inputLoc{n}));

    if ReduceMemory && any(n>=maxUsed & NotIsOutport)
        % clear values which are not required
        evalstore(n>=maxUsed & NotIsOutport) = {[]};
    end
end

out = evalstore(OutIdx);

if RemoveDups
    % Need to re-expand the outputs to be the same length as the original
    % inputs.  This is done in a subfunction to avoid performance problems
    % associated with the anonymous function workspace.
    out = i_expandall(out, ExpandIdx);
end


function out = i_expandall(out, ExpandIdx)
out = cellfun(@(x) i_expand(x, ExpandIdx), out, 'UniformOutput', false);


function x = i_expand(x, idx)
if ~isscalar(x)
    x = x(idx);
end