R = [cos(pi/3) sin(pi/3); -sin(pi/3) cos(pi/3)]
[i,j]=round([1 1] * R)
returns
i =
-0 1
error: element number 2 undefined in return list
While I want i=0
and j=1
Is there a way to work around that? Or just Octave being stupid?
Octave is not being stupid; it's just that you expect the syntax [a,b] = [c,d]
to result in 'destructuring', but that's not how octave/matlab works. Instead, you are assigning a 'single' output (a matrix) to two variables. Since you are not generating multiple outputs, there is no output to assign to the second variable you specify (i.e. j
) so this is ignored.
Long story short, if you're after a 'destructuring' effect, you can convert your matrix to a cell, and then perform cell expansion to generate two outputs:
[i,j] = num2cell( round( [1 1] * R ) ){:}
Or, obviously, you can collect the output into a single object, and then assign to i
, and j
separately via that object:
[IJ] = round( [1 1] * R ) )
i = IJ(1)
j = IJ(2)
but presumably that's what you're trying to avoid.
Explanation:
The reason [a,b] = bla bla
doesn't work, is because syntactically speaking, the [a,b]
here isn't a normal matrix; it represents a list of variables you expect to assign return values to. If you have a function or operation that returns multiple outputs, then each output will be assigned to each of those variables in turn.
However, if you only pass a single output, and you specified multiple return variables, Octave will assign that single output to the first return variable, and ignore the rest. And since a matrix is a single object, it assigns this to i
, and ignores j
.
Converting the whole thing to a cell allows you to then index it via {:}
, which returns all cells as a comma separated list (this can be used to pass multiple arguments into functions, for instance). You can see this if you just index without capturing - this results in 'two' answers, printed one after another:
num2cell( round( [1 1] * R ) ){:}
% ans = 0
% ans = 1
Note that many functions in matlab/octave behave differently, based on whether you call them with 1 or 2 output arguments. In other words, think of the number of output arguments with which you call a function to be part of its signature! E.g., have a look at the ind2sub
function:
[r] = ind2sub([3, 3], [2,8]) % returns 1D indices
% r = 2 8
[r, ~] = ind2sub([3, 3], [2,8]) % returns 2D indices
% r = 2 2
If destructuring worked the way you assumed on normal matrices, it would be impossible to know if one is attempting to call a function in "two-outputs" mode, or simply trying to call it in "one-output" mode and then destructure the output.