function y=interlace(a,b,ind,dim) %INTERLACE Insert Subarrays into Array. % INTERLACE(A,B,IND,DIM) inserts the array B into array A after all indices % given in the vector IND along dimension DIM. If DIM is not given, DIM is % set equal to the first nonsingleton dimension of A. B and A must have the % same class. Numeric, logical, and character classes are supported. B must % have the same dimensions as A along all dimensions except DIM or B must % be a scalar that is expanded to the correct size. When IND(k)=0, the % array B is placed before the first index in A. % % INTERLACE(A,C,IND,DIM) where C is a cell array containing length(IND) % cells, inserts the contents of the k-th cell C{k} after the k-th index % IND(k). % % Examples: % INTERLACE(ones(3,4),1:4,2) produces [1 1 1 1 % 1 1 1 1 % 1 2 3 4 % 1 1 1 1] % % INTERLACE(ones(3,4),[5 6 7],[1 2 3],2) produces an error since B must be % a column since DIM=2 is the column dimension % % INTERLACE(ones(3,4),[5;6;7],[1 2 3],2) produces [1 5 1 5 1 5 1 % 1 6 1 6 1 6 1 % 1 7 1 7 1 7 1] % INTERLACE(ones(3,4),8,[0 3],1) produces [8 8 8 8 % 1 1 1 1 % 1 1 1 1 % 1 1 1 1 % 8 8 8 8] % % INTERLACE(ones(3,4),zeros(2,4),1) produces [1 1 1 1 % 0 0 0 0 % 0 0 0 0 % 1 1 1 1 % 1 1 1 1] % % INTERLACE(ones(3,4),{1:4, 4:-1:1},[1 3],1) produces [1 1 1 1 % 1 2 3 4 % 1 1 1 1 % 1 1 1 1 % 4 3 2 1] % % INTERLACE(ones(3,4),{[5;6;7],6,7},[1 1 3],2) produces [1 5 6 1 1 7 1 % 1 6 6 1 1 7 1 % 1 7 6 1 1 7 1] % % See also REPMAT, CAT % D.C. Hanselman, University of Maine, Orono, ME 04469 % MasteringMatlab@yahoo.com % Mastering MATLAB 7 % 2006-02-19 if nargin<3 error('interlace:NotEnoughInputArguments','Three or Four Inputs Required.') end asiz=size(a); % gather data about input A aclass=class(a); adims=ndims(a); if nargin==3 dim=find(asiz>1,1); end if isequal(aclass,'cell') || isequal(aclass,'struct') error('interlace:ClassNotSupported','Cell and Struct Inputs Not Supported.') end if isempty(dim) || numel(dim)~=1 || fix(dim)~=dim || dim<1 || dim>adims error('interlace:DimOutofRange','DIM Invalid.') end ind=ind(:); % make IND a vector lind=length(ind); N=asiz(dim); % length of A along chosen dimension n=(1:N)'; % index along chosen DIM asiz(dim)=1; if isempty(ind) || any(ind>N|ind<0) error('interlace:IndexOutofBounds','IND Value Out of Bounds.') end if iscell(b) % stretch input cell C to a column c=b(:); else % convert input B to cell for convenience c=repmat({b},lind,1); end if length(c)~=lind error('interlace:ArgumentMisMatch','Size of IND Must Match Size of C.') end notdim=true(1,adims); notdim(dim)=false; % true for dimensions other than DIM perm=[dim:adims 1:dim-1]; % permutation vector a=permute(a,perm); % make DIM first dimension a=reshape(a,N,[]); % make A 2D ac=cell(N,1); for k=1:N % places rows of A into cells ac{k}=a(k,:); end for k=1:lind % determine size and class of inputs if ~isequal(class(c{k}),aclass) error('interlace:ClassConflict','B or C Must Have Same Class as A') end sc=[size(c{k}) ones(1,adims-ndims(c{k}))]; if all(sc==1) % scalar expansion c{k}=repmat(c{k},asiz); elseif any(sc(notdim)~=asiz(notdim)) % check conformity error('interlace:ArgumentMisMatch',... 'Contents of B or C Incorrect Size for A.') end tmp=permute(c{k},perm); c{k}=reshape(tmp,size(tmp,1),[]); % reshape to 2D like ac end yc=[ac;c]; % stack cells [idx,idx]=sort([n;ind]); % sort indices of A and IND yc=yc(idx); % apply sort to A and C y=cat(1,yc{:}); % convert back to array from cell asiz(dim)=size(y,1); % new size along DIM y=reshape(y,asiz(perm)); % put result back in original form y=ipermute(y,perm); % inverse permute dimensions