Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

split a list into several variables in matlab

Tags:

matlab

If I have a short list (let's say two or three elements) I would like to have function that split it in several variables. Something like that:

li=[42 43];
[a b]=split(li)
 --> a=42
 --> b=43

I am looking for some way to make my code shorter in matlab. This one would be nice in some situations For instance:

positions=zeros(10,3);
positions= [....];
[x y z]=split(max(positions,1))

instead of doing:

pos=max(positions,1)
x=pos(1);
y=pos(2);
z=pos(3);
like image 604
Oli Avatar asked Dec 22 '11 00:12

Oli


2 Answers

The only way I know of to do this is to use deal. However this works with cell arrays only, or explicit arguments in to deal. So if you want to deal matrices/vectors, you have to convert to a cell array first with num2cell/mat2cell. E.g.:

% multiple inputs
[a b]   = deal(42,43) % a=2, b=3
[x y z] = deal( zeros(10,1), zeros(10,1), zeros(10,1) )

% vector input
li  = [42 43];
lic = num2cell(li);
[a b]=deal(lic{:}) % unforunately can't do num2cell(li){:}
% a=42, b=43

% matrix input
positions  = zeros(10,3);
% create cell array, one column each
positionsc = mat2cell(positions,10,[1 1 1]);
[x y z]    = deal(positionsc{:})

The first form is nice (deal(x,y,...)) since it doesn't require you to explicitly make the cell array.

Otherwise I reckon it's not worth using deal when you have to convert your matrices to cell arrays only to convert them back again: just save the overhead. In any case, it still takes 3 lines: first to define the matrix (e.g. li), then to convert to cell (lic), then to do the deal (deal(lic{:})).

If you really wanted to reduce the number of lines there's a solution in this question where you just make your own function to do it, repeated here, and modified such that you can define an axis to split over:

function varargout = split(x,axis)
% return matrix elements as separate output arguments
% optionally can specify an axis to split along (1-based).
% example: [a1,a2,a3,a4] = split(1:4)
% example: [x,y,z] = split(zeros(10,3),2)
if nargin < 2
    axis = 2; % split along cols by default
end
dims=num2cell(size(x));
dims{axis}=ones([1 dims{axis}]);
    varargout = mat2cell(x,dims{:});
end

Then use like this:

[a b]  = split([41 42])
[x y z]= split(zeros(10,3), 2) % each is a 10x1 vector
[d e]  = split(zeros(2,5), 1)  % each is a 1x5 vector

It still does the matrix -> cell -> matrix thing though. If your vectors are small and you don't do it within a loop a million times you should be fine though.

like image 126
mathematical.coffee Avatar answered Nov 10 '22 11:11

mathematical.coffee


You can extract the values in the list into different variables with

li = [42 43 44];
tmp = num2cell(li);
[a b c] = deal(tmp{:})

a =
    42
b =
    43
c =
    44
like image 41
Ivan Navarrete Avatar answered Nov 10 '22 12:11

Ivan Navarrete