gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/@tall/private/stringCellstr.m

    function out = stringCellstr(fcn, fcnArgs, in, outClass)
%stringCellstr shared implementation for tall/string and tall/cellstr
%   OUT = stringCellstr(FCN, FCNARGS, IN, OUTCLASS) applies FCN(IN,FCNARGS{:}),
%   producing output of class OUTCLASS.
%
%   This function handles the 'special' behaviour of CHAR data in functions like
%   CELLSTR and STRING. Empty CHAR array inputs to both CELLSTR and STRING
%   return scalar outputs. Therefore, special measures must be taken to ensure
%   that empty CHAR chunks and inputs are handled correctly. Unfortunately, this
%   means that tall/string and tall/cellstr involve reduction for CHAR inputs.

% Copyright 2016 The MathWorks, Inc.

assert(istall(in));
inAdaptor  = in.Adaptor;
outAdaptor = matlab.bigdata.internal.adaptors.getAdaptorForType(outClass);

if isempty(inAdaptor.Class) || strcmp(inAdaptor.Class, 'char')
    % Unknown type or definitely CHAR data. Switch behaviour based on whether we
    % know the tall size.
    
    inTallSize = getSizeInDim(inAdaptor, 1);
    if inTallSize > 0
        % Here we need to apply the correctly-slicefun-compatible version of FCN, and
        % then fix up the output size.
        out = slicefun(@(x) iSliceFun(fcn, x, fcnArgs{:}), in);
        % Tall size is known and non-zero - the output from the slice-ified version of
        % FCN is acceptable. We also know that the output tall size matches the
        % input tall size.
        outAdaptor = copyTallSize(outAdaptor, inAdaptor);
    else
        % Here we need to do something special. Call 'head' to work out if the data is
        % empty - broadcast that to a partitionfun call which can emit the
        % correct result if the data is truly empty.
        inHead = matlab.bigdata.internal.broadcast(head(in, 1));
        out = partitionfun(@(info, x, xh) iPartitionFun(info, x, xh, fcn, fcnArgs), in, inHead);
    end    
else
    % Non-CHAR cases preserve the full size of the input.
    out = elementfun(@(x) fcn(x, fcnArgs{:}), in);
    outAdaptor = copySizeInformation(outAdaptor, inAdaptor);
end
out.Adaptor = outAdaptor;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [hasFinished, out] = iPartitionFun(info, in, inHead, fcn, fcnArgs)
if info.PartitionId == 1 && isempty(inHead)
    out = fcn(inHead, fcnArgs{:});
    hasFinished = true;
else
    out = iSliceFun(fcn, in, fcnArgs{:});
    hasFinished = info.IsLastChunk;
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function outSlice = iSliceFun(fcn, in, varargin)
outSlice = fcn(in, varargin{:});
if size(in, 1) == 0 && size(outSlice, 1) ~= 0
    % Fix up the slice
    trailingIdxs = repmat({':'}, ndims(outSlice) - 1);
    outSlice = outSlice([], trailingIdxs{:});
end
end