www.gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/+matlab/+bigdata/+internal/+adaptors/GeneralArrayParenIndexingMixin.m

    %GeneralArrayParenIndexingMixin mixin for standard array-based indexing

% Copyright 2016 The MathWorks, Inc.

classdef GeneralArrayParenIndexingMixin
    methods
        function out = subsrefParens(obj, pa, szPa, S)
            outPa = subsrefParensImpl(pa, szPa, S);
            out   = tall(outPa, resetSizeInformation(obj));
        end
        function out = subsasgnParens(obj, pa, ~, S, b)
        %subasgnParens Implementation of subsasgn for () case (non-deleting)
        %   outPa = subsasgnParens(inPa, szPa, S, b)
        %   outPa and inPa are PartitionedArrays, S is the substruct, b is the right-hand side.

            if numel(S) ~= 1
                % a(1,2).foo = 3 or similar.
                error(message('MATLAB:bigdata:array:SubsasgnParensSingleLevel'));
            end

            subs = S.subs;

            isColonSubscript = cellfun(@matlab.bigdata.internal.util.isColonSubscript, subs);
            if ~isColonSubscript(1) && ~istall(subs{1})
                error(message('MATLAB:bigdata:array:SubsasgnFirstDimTallOrColon'));
            end
            if istall(subs{1})
                subs{1} = tall.validateType(subs{1}, 'subsasgn', {'logical'}, 1);
            end
            if istall(b)
                % Can't support this because of tall dimension size mismatch.
                error(message('MATLAB:bigdata:array:SubsasgnTallRHSNotSupported'));
            elseif isscalar(b)
                % If there's more than one subscript, we must have precisely the same number as
                % there are dimensions.
                if ~isnan(obj.NDims) && numel(subs) > 1 && obj.NDims ~= numel(S.subs)
                    error(message('MATLAB:bigdata:array:SubsasgnInvalidNumberOfSubscripts'));
                end
                
                if istall(subs{1})
                    pa = slicefun(@(pa, filter) iApplyScalar(pa, b, filter, subs{2:end}), pa, hGetValueImpl(subs{1}));
                else
                    pa = slicefun(@(pa) iApplyScalar(pa, b, subs{:}), pa);
                end
            else
                error(message('MATLAB:bigdata:array:SubsasgnValueMustBeScalarOrTall'));
            end

            out = tall(pa, resetSizeInformation(obj));
        end
        
        function out = subsasgnParensDeleting(obj, pa, szPa, S)
        %subsasgnParensDeleting Deleting subsasgn implementation for tall arrays

            isColonSubscript = cellfun(@matlab.bigdata.internal.util.isColonSubscript, S.subs);
            isEmptyNonTallSubscript = cellfun(@isempty, S.subs(2:end));

            numColons = sum(isColonSubscript);
            numSubs   = numel(S.subs);

            if numColons == numSubs
                % Need to return empty of the right size and class. We must use CHUNKFUN as the
                % result is going to be a different size in the tall dimension.
                pa = chunkfun(@(x) iDeleteAll(x, S.subs{:}), pa);
            elseif numColons ~= numSubs - 1
                % All other cases require only a single non-colon subscript
                error(message('MATLAB:bigdata:array:SubsasgnDeletingTooManyNonColons'));
            elseif any(isEmptyNonTallSubscript)
                % There's an empty subscript - do nothing
            elseif istall(S.subs{1})
                % Here we defer to subsref to do the work by negating the subscript.
                tallSubscript = S.subs{1};
                ss = substruct('()', {~tallSubscript, S.subs{2:end}});
                pa = subsrefParensImpl(pa, szPa, ss);
            elseif numSubs == 1 && ~isColonSubscript(1)
                % Deleting using a single non-tall subscript - not supported
                error(message('MATLAB:bigdata:array:SubsasgnDeletingInvalidTallSubscript'))
            else
                % Finally, we must have a colon in first place ...
                assert(isColonSubscript(1));

                if ~isnan(obj.NDims) && obj.NDims ~= numel(S.subs)
                    error(message('MATLAB:bigdata:array:SubsasgnInvalidNumberOfSubscripts'));
                end

                % ... and we delete the non-tall dimensions.
                pa = slicefun(@(x) iDeleteNonTall(x, S.subs{:}), pa);
            end
            out   = tall(pa, resetSizeInformation(obj));
        end
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function A = iApplyScalar(A, B, varargin)
% We allow:
% 1. One logical subscript with dimensions matching A
% 2. One logical subscript if A is a vector
% 3. One colon subscript
% 4. Number of subscripts matches ndims A, first subscript must be logical or colon
    if numel(varargin)==1
        if isequal(size(varargin{1}), size(A)) || ...
                matlab.bigdata.internal.util.isColonSubscript(varargin{1})
            % (1) or (3), OK
        else
            % (2), only OK if A is a vector and numel(subs)==numel(A)
            isNDVector = (sum(size(A)~=1) == 1); % Only one non-unity dimension
            
            if ~isNDVector || numel(A) ~= numel(varargin{1})
                error(message('MATLAB:bigdata:array:SubsasgnSingleSubDims'));
            end
        end
    else
        % (4) Check that we have one subscript per dimension
        if ndims(A) ~= numel(varargin)
            error(message('MATLAB:bigdata:array:SubsasgnInvalidNumberOfSubscripts'));
        end
    end

    % Resolve end markers for this chunk. Here we rely on the fact that the number
    % of subscripts must match the dimensionality of A.
    for idx = 2:numel(varargin)
        if isa(varargin{idx}, 'matlab.bigdata.internal.util.EndMarker')
            varargin{idx} = varargin{idx}.resolve(size(A), idx);
        end
    end
    
    A(varargin{:}) = B;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Used for the case where the subscripts are known up front.
function x = iDeleteAll(x, varargin)
    x(varargin{:}) = [];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Used for the case where we're deleting only in the non-tall dimension.
function x = iDeleteNonTall(x, varargin)
    if numel(varargin) ~= ndims(x)
        % Get here for tx = tall(rand(3,3,3));
        % tx(:,1) = []
        error(message('MATLAB:bigdata:array:SubsasgnInvalidNumberOfSubscripts'));
    end
    x(varargin{:}) = [];
end