%RESHAPEC change size in COLUMN-ROW order
%
% - RESHAPE changes the size of a matrix in
% row-column order.
% - RESHAPEC changes the size of a matrix in
% column-row order.
% in particular, RESHAPEC converts a ND matrix
% according to MATLAB's display convention.
%
% see also: reshape, permute, ipermute, shiftdim, squeeze
%
%SYNTAX
%-------------------------------------------------------------------------------
% M2D = RESHAPEC(MND);
% MND = RESHAPEC(M2D,NDSIZE);
% MND = RESHAPEC(MND,NDSIZE);
% MND = RESHAPEC(...,SIZE(1),SIZE(2),...,SIZE(N));
%
%INPUT
%-------------------------------------------------------------------------------
% MND : ND-matrix
% M2D : 2D-matrix
% NDSIZE: array of new dimensions of MND or M2D
% - the first number is #rows
% - may include any number of singletons
% SIZE(): new size of dimension(X)
% - dimension(1) is #rows
% - one dimension can be a []
% - may include any number of singletons
% - may itself be a row or column vector
%
%OUTPUT
%-------------------------------------------------------------------------------
% M2D : 2D conversion of MND following ML's display convention
% MND : ND conversion of MND or M2D according to NDSIZE or SIZE(1:N)
%
%NOTES
%-------------------------------------------------------------------------------
% - RESHAPEC(MND) is a short cut for
% RESHAPE(MND,[],#columns)
% - if only one dimension is defined, the #columns will be
% computed for a 2D matrix
% - the original matrix is returned if an error occurs
%
%EXAMPLE
%-------------------------------------------------------------------------------
% ns=[2,4,3,1,2];
% m=rand(ns);
% m2d=reshapec(m);
% mnd=reshapec(m2d,2,4,[3,1].',2);
% isequal(m,mnd)
% % ans = 1
%FEX
% uncat duane hanselman
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=10173&objectType=FILE
% catdim andreas hoechner
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15990&objectType=FILE
%
% created:
% us 11-Jun-2008 us@neurol.unizh.ch
% modified:
% us 12-Jun-2008 21:36:48
%-------------------------------------------------------------------------------
function nd=reshapec(nd,ns,varargin)
% user needs help
if ~nargin
help(mfilename);
return;
end
% determine dimension of input
dn=ndims(nd);
switch nargin
% user wants to convert ND(ndims) to 2D or ND(new_ndims)
case 1
if dn > 2
nd=CALL_reshapec(nd);
end
% user wants to resize ND(ndims) to ND(new_ndims)
case 2
[tf,ns]=CALL_check(nd,ns);
if ~tf
return;
end
if dn > 2
nd=CALL_reshapec(nd);
end
nd=CALL_2dnd(nd,ns);
% user wants to resize ND(ndims) to ND(new_ndims) including one possible []
otherwise
% - convert input arguments
arg=cellfun(@(x) x(:).',varargin,'uni',false);
ie=cellfun(@isempty,arg);
arg(ie)={nan};
arg=num2cell(cat(2,arg{:}));
% - first arg may be empty!
if isempty(ns)
ns=[{nan},arg];
else
ns=[num2cell(ns),arg];
end
% - has a []
ie=cellfun(@isnan,ns);
if any(ie)
if sum(ie) > 1
disp(sprintf('RESHAPEC> ERROR: too many occurrences of []'));
return;
end
ns{ie}=numel(nd)./prod(cat(2,ns{~ie}));
ns=cat(2,ns{:});
[tf,ns]=CALL_check(nd,ns);
if ~tf
return;
end
else
ns=cat(2,ns{:});
end
nd=reshapec(nd,ns);
end
end
%-------------------------------------------------------------------------------
function nd=CALL_reshapec(nd)
ns=size(nd);
nd=permute(nd,[1,3:numel(ns),2]);
nd=reshape(nd,[],ns(2));
end
%-------------------------------------------------------------------------------
function nd=CALL_2dnd(nd,ns)
nd=reshape(nd.',ns([2,1,3:numel(ns)]));
nd=permute(nd,[2,1,3:numel(ns)]);
end
%-------------------------------------------------------------------------------
function [tf,ns]=CALL_check(nd,ns)
tf=false;
if isempty(ns)
return;
end
% only #ROWS selected
% - try to compute #COLUMNS for 2D display
if numel(ns) == 1
ns=[ns,numel(nd)/ns];
end
% check validity of sizes
np=prod(ns);
if any(ns~=fix(ns))
os=sprintf('%.2f ',size(nd));
ns=sprintf('%.2f ',ns);
disp(sprintf('RESHAPEC> ERROR: cannot find a valid new size'));
disp(sprintf('RESHAPEC> old: %.2f = %s',numel(nd),os));
disp(sprintf('RESHAPEC> new: %.2f = %s',np,ns));
return;
end
if ~isequal(numel(nd),prod(ns))
os=sprintf('%d ',size(nd));
ns=sprintf('%d ',ns);
disp(sprintf('RESHAPEC> ERROR: cannot convert sizes!'));
disp(sprintf('RESHAPEC> old : %5d = %s',numel(nd),os));
disp(sprintf('RESHAPEC> new : %5d = %s',np,ns));
return;
end
tf=true;
end
%-------------------------------------------------------------------------------