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