function[a,r,c] = wide2tall(A,varargin)
% WIDE2TALL 'Unpivot' a matrix into a set of aligned vectors
% Inputs : A, (n*k) matrix
% rows, (n*1) vector (optional)
% cols, (k*1) vector (optional)
% Outputs: (nk*1) vectors a, r, c where a = A(:)
% If a(k) = A(i,j), then
% r(k) = i, c(k) = j if 'rows' and 'cols' are omitted
% r(k) = rows(i), c(k) = j if 'rows' are supplied
% c(k) = cols(j), r(k) = i if 'cols' are supplied
% Example: A = rand(2,3)
% [a,r,c] = wide2tall(A)
% [a,r,c] = wide2tall(A,'rows',[today today+1])
% [a,r,c] = wide2tall(A,'cols',[10 200 30])
% Dimitri Shvorob, dimitri.shvorob@gmail.com, 8/1/08
if ndims(A) ~= 2
error('??? A must be a matrix.')
end
[nrows,ncols] = size(A);
p = inputParser;
p.addParamValue('rows',[],@isvector)
p.addParamValue('cols',[],@isvector)
p.parse(varargin{:});
rows = p.Results.rows(:);
if ~isempty(rows)
assert(length(rows) == nrows,'??? ''rows'' must have as many elements as ''A'' has rows.')
end
cols = p.Results.cols(:);
if ~isempty(cols)
assert(length(cols) == ncols,'??? ''cols'' must have as many elements as ''A'' has columns.')
end
a = A(:);
r = repmat((1:nrows)',ncols,1);
c = kron((1:ncols)',ones(nrows,1));
if ~isempty(rows)
r = rows(r);
end
if ~isempty(cols)
c = cols(c);
end