www.gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/@tall/private/computeElementwiseSize.m
function out = computeElementwiseSize(out, in) % Try to set the sizes of the outputs given a set of inputs. IN must be a % cell array, OUT can be one array or a cell array of arrays. % Copyright 2016 The MathWorks, Inc. cellOut = iscell(out); if ~cellOut out = {out}; end if numel(in)==1 % Unary, so the first input must be tall and we can copy the size to all outputs. for idx = 1:numel(out) out{idx}.Adaptor = copySizeInformation(out{idx}.Adaptor, in{1}.Adaptor); end if ~cellOut out = out{1}; end return; end % For all other cases, we need to combine results from multiple input % adaptors. inAdaptors = cellfun(@iGetAdaptor, in, 'UniformOutput', false); % Tall dimension is special. Even if unknown, we would like to propagate % whether it is preserved so that if we later discover the size it will % become known. tallSize = cellfun(@(x) x.getSizeInDim(1), inAdaptors); unknownTallSizes = isnan(tallSize); if any(unknownTallSizes) % At least one is unknown. We can only propagate if the unknown ones % are all the same unknown size and the rest are unit. inIdx = find(unknownTallSizes,1,'first'); tallSizeIds = cellfun( @(x) x.TallSize.Id, inAdaptors ); if all(tallSize(~unknownTallSizes))==1 ... && all(tallSizeIds(unknownTallSizes) == tallSizeIds(inIdx)) % Propagate tall size for outIdx = 1:numel(out) out{outIdx}.Adaptor = copyTallSize(out{outIdx}.Adaptor, inAdaptors{inIdx}); end end else % All sizes known. Check they are compatible and if so, propagate the % non-unit one. [~,inIdx] = iCheckOneDim(tallSize); if inIdx>0 % Will be zero if incompatible for outIdx = 1:numel(out) out{outIdx}.Adaptor = copyTallSize(out{outIdx}.Adaptor, inAdaptors{inIdx}); end end end % Now deal with the small sizes % If any input has an unknown number of dimensions, the best we can do is % try to determine the tall size, since the small sizes will be unknown. ndims = cellfun(@(x) x.NDims, inAdaptors); if any(isnan(ndims)) % Unknown dimensionality, nothing more we can do. else ndims = max(ndims); % We allow unity dimension expansion, so can build up dimensions % one-by-one. localSz = nan(1,ndims-1); for dim=2:ndims thisDim = cellfun(@(x) getSizeInDim(x,dim), inAdaptors); localSz(dim-1) = iCheckOneDim(thisDim); end % If any dimension was incompatible, we get a NaN. In that case, leave the % dimensions unknown. If all OK, set the small sizes of the output. if ~any(isnan(localSz)) for outIdx = 1:numel(out) out{outIdx}.Adaptor = setSmallSizes(out{outIdx}.Adaptor, localSz); end end end if ~cellOut out = out{1}; end end function a = iGetAdaptor(val) a = matlab.bigdata.internal.adaptors.getAdaptor(val); % Adaptors always have unknown tall size. If genuinely local, set it back % to a known value. if ~istall(val) a = resetTallSize(a, size(val,1)); end end function [dim,idx] = iCheckOneDim(dims) % Determine the output size given a set of input sizes in one dimension. To % be compatible, all sizes must be known and must match or be 1. dim = nan; % Default to "unknown" idx = 0; if any(isnan(dims)) return; end % Find the first non-zero value idx = find(dims~=1, 1, 'first'); if isempty(idx) % All one idx = 1; dim = 1; return end % Compare values. Only set the output if they are all compatible. allowedVals = [1, dims(idx)]; if all(ismember(dims, allowedVals)) dim = dims(idx); end end