www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/@sweepset/sweepsample.m

    function ssOut = sweepsample(ssIn, expressions, outputs)
%SWEEPSAMPLE "Resample command" evaluation for sweepsets
%
%  SSOUT = SWEEPSAMPLE(SSIN, EXPRESSIONS, VARNAMESOUT)
%
%  EXPRESSIONS is a cell array of strings
%  VARNAMESOUT is a cell array of cell-strings and strings.
%
%  SSIN is the input sweepset and SSOUT is the output sweepset. The
%  resampled variables VARNAMEOUT will be added to SSOUT. The number of
%  elements in EXPRESSIONS must exactly match the number of strings in
%  VARNAMESOUT.
%
%  This function evaluates the strings or inline expressions in EXPRESSIONS
%  in order to create a sweepset SSOUT which is derived from SSIN. The
%  individual expressions reference variables using the format in.VARNAMEIN
%  for a variable in the input sweepset, out.VARNAMEOUT for a variable in
%  the output sweepset and 'x' specifically to reference VARNAMEOUT in the
%  input, if it exists or empty otherwise. This  allows the same resample
%  command to be applied to many variables if their name is the same in the
%  input and output sweepsets.
%
%  Example expressions :
%    
%    interp1(in.TIME, in.VAR1, out.TIME);
%    interp1(in.TIME, x, out.TIME);
%    myFunc(in.A, out.B, in.C, out.D);
%
%  See also SWEEPSET/SWEEPEVAL.

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


% Check that expressions and varNames are the same length
if numel(expressions) ~= numel(outputs)
    error(message('mbc:sweepset:InvalidArgument21'));
end

% We need to deal with a general case of the variable outputs - this is a
% cell array of either char or cell arrays of char. This allows the user of
% this function to group variables that should be calculated in a
% vectorised way. This ensures that rather than looping over variables one
% at a time, a group of variables can be calculated simultaneously.

% Find out which output variables are cell arrays and which are chars
outputIsCell = cellfun('isclass', outputs, 'cell');
% Deal with something like { {'a' 'b' 'c'} {'a'} 'b' 'c' {'d' 'e'}} here
if any(outputIsCell)
    % Find the numel in each element of the cell array
    outputSizes = cellfun('prodofsize', outputs);
    
    % Treat all the non-cells as of size 1 - this then gives us the total
    % number of strings in the array
    outputSizes(~outputIsCell) = 1;
    
    % Preinitialise the outputVariables cell array
    outputVariables = cell(1, sum(outputSizes));
    
    % Calculate the start index for each element from the outputs array in
    % the outputVariables array
    outputStartIndex = cumsum([1 outputSizes]);
    
    % Iterate over the outputs choosing how to put it's elements into outputVariables
    for i = 1:numel(outputs)
        if outputIsCell(i)
            outputVariables(outputStartIndex(i):outputStartIndex(i+1)-1) = outputs{i}(:);
        else
            outputVariables(outputStartIndex(i)) = outputs(i);
        end
    end
else
    % All char so copy - this is just a quick version of the above
    outputVariables = outputs;
    outputStartIndex = 1:numel(outputVariables)+1;
end

% Ensure that the outputVariables are valid and unique names - this ensures
% they can be used as field names in a sstructure
outputVariables = generateValidUniqueNames(outputVariables);

% Convert the sweepset in to an appropriate in structure - this is an array
% of 1 x numTests with fields labeled by variable names. To do this first
% construct a numFieldnames by numTests cell array and populate with the
% data, then convert this to a structure
inputVariables = {ssIn.var.name};

numOutputVariables = numel(outputVariables);
numTests = length(ssIn.xregdataset);
% How many groupings of outputs
numOutputs = numel(outputs);

% Create the input cell array - this will get converted to a struct later
inSweepsByCell = cell(numTests, 1);
% Get the starting indices of the tests in the data array
inputStartIndex = [tstart(ssIn), numRecords( ssIn )+1];
data = ssIn.data;
% Look at doing this with a mex-function later
for i = 1:numTests
    inSweepsByCell{i} = data(inputStartIndex(i):inputStartIndex(i+1)-1, :);
end
in = pFillCellFromArray(data, tsizes(ssIn, 1, true));
in = in';
% Convert the cell array to a structured array
in = cell2struct(in, inputVariables);
% Make the appropriate output structure
defaultOut = cell2struct(cell(numOutputVariables, 1), outputVariables);
% Define the output matrix that will contain the resampled data
out = cell(numTests, 1);

% To deal with the 'x' variable we need to know which output variables are
% also in the input variables
if isequal(outputVariables, inputVariables)
    isCommon = true(1, numOutputVariables);
    originalLocation = 1:numOutputVariables;
    IDENTICAL_OUTPUT_VARIABLES = true;
else
    [isCommon, originalLocation] = ismember(outputVariables, inputVariables);
    IDENTICAL_OUTPUT_VARIABLES = false;
end

% Now we should iterate over variables and tests to actually do the
% resampling
for i = 1:numTests
    thisIn = in(i);
    % We are going to mess around with the internals of this variable
    % inside mex-functions so lets make sure that it's a deep copy that
    % no one else thinks is theirs.
    thisOut = pDeepCopy(defaultOut);
    thisSweepIn = inSweepsByCell{i};
    for j = 1:numOutputs
        exp = expressions{j};
        x = [];
        % Evaluation routine for cell input
        if outputIsCell(j)
            thisOutputIndex = outputStartIndex(j):outputStartIndex(j+1)-1;
            if all(isCommon(thisOutputIndex))
                x = thisSweepIn(:, originalLocation(thisOutputIndex));
            end
        % Evaluation routine for char input
        else
            thisOutputIndex = outputStartIndex(j);
            if isCommon(thisOutputIndex)
                x = thisSweepIn(:, originalLocation(thisOutputIndex));
            end
        end
        y = iInternalEval(exp, x, thisIn, thisOut);
        if isempty( y )
            error(message('mbc:sweepset:InvalidResampleExpression', exp));
        end

        try
            pFillStructFromArray(thisOut, uint32(thisOutputIndex), y);
        catch e
            % The error message produced by "pFillStructFromArray" is not
            % so helpful
            error( e.identifier, ...
                'Failed to evaluate expression "%s": returned a matrix with %d columns but a matrix with %d columns was expected.', ...
                exp, size( y, 2 ), numel( thisOutputIndex ) );
        end
        if j == 1
            arrayOut = zeros(size(y, 1), numOutputVariables);
        end
        arrayOut(:, thisOutputIndex) = y;
    end
    out{i} = arrayOut;
end

% Need to transform out into a sweepset
% Get the sizes of each output sweep
outputSweepSizes = cellfun('size', out, 1);
outputData = vertcat(out{:});
outputNrec = size(outputData, 1);

if all(isCommon)
    ssOut = ssIn;    
    if ~IDENTICAL_OUTPUT_VARIABLES
        % Need to reorder the outputVariables
        ssOut.var = ssOut.var(originalLocation);
    end
    ssOut.baddata = sparse(outputNrec, size(outputData, 2));
    ssOut.data = outputData;
    ssOut.guid = guidarray(outputNrec);
    ssOut.xregdataset = xregdataset(testnum(ssIn.xregdataset), ...
        -ones(size(outputSweepSizes)), outputSweepSizes);
else
    error(message('mbc:sweepset:NotIdenticalOutputVariables'))
end

% Force the sweep guids to be the same
ssOut.guid = forceGroupArray(ssOut.guid, getSweepGuids(ssIn), outputSweepSizes);


function functionReturn = iInternalEval(evalString, x, in, out)
% Inputs x, in and out might be used by the expression string that we
% evaluate here.
try
    functionReturn = eval(evalString);
catch ME
    error(message('mbc:sweepset:InvalidResampleExpression1', evalString, ME.message));
end