⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioidx.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
字号:
function [outs, idx, ridx, cidx, lastcolon] = ioidx(S, vsize)
% ioidx  - get indices to perform IO on
%
% FORMAT:       [outs, idx, ridx, cidx, lastcolon] = ioidx(S, vsize)
%
% Input fields:
%
%       S           1x1 struct as used in subsref / subsasgn
%       vsize       1xN double, variable size to index into
%
% Output fields:
%
%       outs        1xN double, output size
%       idx         indices to address
%       ridx        reverse indices (to finally store into memory)
%       cidx        continuity indexes (within idx!)
%       lastcolon   number of highest index with full indexing range

% Version:  v0.6a
% Build:    6121315
% Date:     Dec-13 2006, 3:45 PM CET
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 2 || ...
   ~isstruct(S) || ...
    numel(S) ~= 1 || ...
   ~isfield(S, 'type') || ...
   ~ischar(S.type) || ...
   ~strcmp(S.type(:)', '()') || ...
   ~isfield(S, 'subs') || ...
   ~isa(vsize, 'double') || ...
    numel(vsize) < 2 || ...
    numel(vsize) > 32 || ...
    numel(vsize) ~= size(vsize, 2) || ...
    any(isinf(vsize) | isnan(vsize) | vsize ~= fix(vsize))
    error( ...
        'BVQXtools:BadArgument', ...
        'No or bad S struct or vsize argument given or empty.' ...
    );
end

% get and check S sizes
idx = S.subs(:)';
numidx = length(idx);
if numidx < 1 || ...
    numidx > length(vsize)
    error( ...
        'BVQXtools:BadArgument', ...
        'Invalid size requested.' ...
    );
end

% initialize reverse indexing array
ridx = cell(1, numidx);
cidx = cell(1, numidx);

% initialize output size, start and end idx
outs = ones(1, numidx);

% keep track of "all-indexing" and continuous subscripts
iscnt = true;
iscol = true;
lastcolon = 0;

% iterate over
for sc = 1:numidx

    % remaining size
    if sc < numidx
        remsize = vsize(sc);
    else
        remsize = prod(vsize(sc:end));
    end

    % chars ...
    if ischar(idx{sc})

        % are only accepted as ':'
        if numel(idx{sc}) ~= 1 || ...
            idx{sc} ~= ':'
            error( ...
                'BVQXtools:BadArgument', ...
                'Illegal char indexing in S.' ...
            );
        end

        % as long as prior expressions were complete, update lastcolon
        if iscol
            lastcolon = sc;
        end
        
        % what size for this index
        outs(sc) = remsize;

        % set ridx, cidx entries
        ridx{sc} = ':';
        
        % still contiguous?
        if iscnt
            cidx{sc} = [1; remsize + 1];
        else
            cidx{sc} = [];
        end

        % if more than one index, also re-set idx!
        if numidx > 1
            idx{sc} = 1:remsize;
        end
        
        % don't go on checking
        continue;
    end

    % index size, length and number of elements
    idxsz = size(idx{sc});
    idxln = max(idxsz);
    idxne = prod(idxsz);

    % logical arrays
    if islogical(idx{sc})

        % must be last index, and reject then too large matrices
        if sc < numidx || ...
            idxne > remsize
            error( ...
                'BVQXtools:BadArgument', ...
                'Bad positioned or tool large boolean indexing variable.' ...
            );
        end

        % linearize (find creates a 1-D indexing array) and update idxsz
        idx{sc} = find(idx{sc});
        idxsz = length(idx{sc});

    % reject any other non-numerical indexing
    elseif ~isnumeric(idx{sc})
        error( ...
            'BVQXtools:BadArgument', ...
            'Only '':'', logical and numerical indexing allowed.' ...
        );

    % reject N-D array if not in last subscript
    elseif sc < numidx && ...
        idxln < idxne && ...
        idxne > 0
        error( ...
            'BVQXtools:BadArugment', ...
            'N-D array only allowed as last subscript or too big.' ...
        );
    end

    % get first and last index
    minidx = min(idx{sc}(:));
    maxidx = max(idx{sc}(:));

    % check idx (min, max, argument position, fixed numbers)
    if ~isempty(minidx) && ...
       (minidx < 1 || ...
        maxidx > remsize || ...
        (sc < numidx && maxidx > vsize(sc)) || ...
         any(fix(idx{sc}(:)) ~= idx{sc}(:)))
        error( ...
            'BVQXtools:BadArgument', ...
            'Fixed, numerical indexing within bounds required.' ...
        );
    end

    % check for multi dimensional matrices
    if idxln ~= idxne && ...
        idxne > 0

        % set remaining output size to input size
        outs = [outs(1:sc-1), idxsz];

        % and then linearize input
        idx{sc} = idx{sc}(:)';
    end

    % get sorted array and check uniqueness
    [usz, uszi] = unique(idx{sc});
    idxnn = numel(idx{sc});
    uszne = numel(usz);
    
    % reject double indexing!
    if uszne ~= idxnn

        error( ...
            'BVQXtools:BadArgument', ...
            'Index reusing is not supported for IO.' ...
        );

    % full range
    elseif uszne == remsize

        % update lastcolon property
        if iscol
            lastcolon = sc;
        end

        % set output size accordingly
        if idxln == idxne
            outs(sc) = remsize;
        end
        
        % no sorting required
        if all(usz == idx{sc})
            ridx{sc} = ':';
        else
            ridx{sc} = uszi;
        end
        
        % contiguity index
        if iscnt
            cidx{sc} = [1; remsize + 1];
        else
            cidx{sc} = [];
        end

    % as long as *something* is requested
    elseif ~isempty(usz)

        % stop full indexing here
        iscol = false;

        % set output size according to requested array
        if idxln == idxne
            outs(sc) = uszne;
        end

        % put into idx
        idx{sc} = usz;
        
        % reverse indexing needed
        if any(uszi(:) ~= (1:uszne)')
            ridx{sc} = uszi;
        else
            ridx{sc} = ':';
        end
        
        % contiguous block requested
        if iscnt && ...
           (1 + usz(end) - usz(1)) == uszne

            % take as one block
            cidx{sc} = [1; uszne + 1];

        % prior index contiguous? then find indices where to index reading
        elseif iscnt
            
            % find contiguous blocks
            cidx{sc} = 1 + [0; find(diff(usz(:)) - 1); uszne];

        % otherwise
        else
            
            % take each singly
            cidx{sc} = [];
        end
        
        % stop contiguity tracking
        iscnt = false;
    
    % nothing requested
    else
        idx{sc} = [];
        cidx{sc} = [];
        ridx{sc} = 1;
    end
end

% needed to get size right!
while length(outs) < 2
    outs(end + 1) = 1;
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -