2
votes

To vectorize a matrix in MATLAB, you can execute this simple command:

A = reshape(1:9, 3, 3)
% A =
% [1 4 7]
% [2 5 8]
% [3 6 9]

b = A(:)
% b = [1 2 3 4 5 6 7 8 9]'

But how about if you have a matrix that you want to first slice, then vectorize? How do you go about doing this without assigning to a temporary variable?

Let's say A is now:

A = reshape(1:27, 3, 3, 3)
% A(:,:,1) =
% [1 4 7]
% [2 5 8]
% [3 6 9]    

% A(:,:,2) =
% [10 13 16]
% [11 14 17]
% [12 15 18] 

% A(:,:,3) =
% [19 22 25]
% [20 23 26]
% [21 24 27] 

If you run

b = A(:,:,1)(:)
% Error: ()-indexing must appear last in an index expression.

Is there some function, vectorize(A) that gives this functionality?

b = vectorize(A(:,:,1))
% b = [1 2 3 4 5 6 7 8 9]'

Or if not a function, is there an alternative method than

tmp = A(:,:,1)
b = tmp(:)

Thanks in advance for the guidance!

3
After posting, I realize b = reshape(A(:,:,1), 1, size(A,1) * size(A,2)) also does the trick. Is this the most elegant solution? - marcman
I think your question is just a variation of this: stackoverflow.com/questions/3627107/… This issue keeps coming up in MATLAB, and the short answer is to use a temporary variable. - Matthew Gunn

3 Answers

4
votes

If only elegance could be measured, but here's one to get through the night -

A(1:numel(A(:,:,1))).'
2
votes

This is a function that I've seen many seasoned Matlab users add to their code hoard by hand:

function A = vectorize(A)
A = A(:);
% save this code as vectorize.m

Once you've got vectorize.m on your path, then you can do what you want in one line.

You can define the function inline if you prefer:

vectorize = inline( 'A(:)' );

but then of course you have to ensure that that's in memory for every session.

If for some reason it's unacceptable to write and save your own functions to disk (if so, I wonder how your sanity ever survives using Matlab, but it takes all sorts...) then the following code snippet is a one-liner that uses only builtins, works for arbitrarily high-dimensional A, and is still not too unreadable:

reshape( A, numel(A), 1 )

Note that this, in common with (:) but contrary to what you assume in your question, produces a column vector. Its disadvantage is that A must already be assigned in the workspace, and that assignment may require one extra line. By contrast, the function version can work even on unnamed outputs of other operations—e.g.:

A = vectorize( randn(5) + magic(5) )
0
votes

One-liner for arbitrary indices.

i=3; 
A((i-1)*numel(A(:,:,i))+(1:numel(A(:,:,i)))).'