Why does MATLAB not allow this assignment with the + operator?

5 vues (au cours des 30 derniers jours)
Daniel Bridges
Daniel Bridges le 30 Jan 2018
Commenté : Walter Roberson le 1 Fév 2018
Please see these results:
K>> [EndX,EndY,EndZ] = size(planneddose)
EndX =
135
EndY =
180
EndZ =
129
K>> size(planneddose)+[1 1 1]
ans =
136 181 130
K>> [EndX,EndY,EndZ] = size(planneddose)+[1 1 1]
Error using +
Too many output arguments.
I understand what is shown here is some functionality that calls multiple outputs for multiple inputs, whereas size(...)+[...] returns only a single array, but I think this use is intuitive and MATLAB should add it as a feature in the next release. (That is to say, I encounter this problem fairly often...) Is there a better way to accomplish this task, or must I add 1 to each using three additional commands?
  7 commentaires
Greg
Greg le 30 Jan 2018
Modifié(e) : Greg le 30 Jan 2018
" This is not intuitive." I argue that it is intuitive. Intuition is devoid of experience (and many of us have difficulty remembering out MATLAB years before experience tempered our intuition). A large number of things that make no programming sense are still completely intuitive - our intuition is allowed to be mistaken.
Daniel Bridges
Daniel Bridges le 31 Jan 2018
I must spend more time taking in what you are teaching me about MATLAB mechanics, but as far as semantics go, I do again agree with Greg -- the question at hand is whether we want MATLAB to be an efficient, powerful tool, or easy for beginners to use. I think MathWorks has done a good job balancing these goals (not long ago I gave up on R -- no time to learn all the syntax and new commands, and excessive documentation, even documentation about documentation, unlike MathWorks' concise documentation database), and so I don't mind the strong rebuttal here that size() + [...] shouldn't work (i.e. that arrays and comma-separated lists remain distinct).

Connectez-vous pour commenter.

Réponse acceptée

Walter Roberson
Walter Roberson le 30 Jan 2018
Consider this:
planneddose = zeros(135, 130, 129, 2);
[EndX,EndY,EndZ] = size(planneddose) %works
EndX =
135
EndY =
130
EndZ =
258
>> size(planneddose)+[1 1 1]
Matrix dimensions must agree.
and consider
planneddose = zeros(135,130);
[EndX,EndY,EndZ] = size(planneddose)
EndX =
135
EndY =
130
EndZ =
1
>> size(planneddose)+[1 1 1]
Matrix dimensions must agree.
But in both cases assigning size(planneddose) to three variables was legal.
This is because size() looks at the number of output arguments to figure out the values it should output. In the case of three outputs, it outputs the first two dimensions into the first two variables and it outputs the product of all remaining dimensions in the third variable. This does not mean that the size "is" three dimensions: it is how size is defined. In the case of a single output, it outputs the individual dimensions as a vector, giving all of non-scalar leading dimensions explicitly, minimum two dimensions.
The case of size(planneddose)+[1 1 1] is the single output case, so it outputs a vector of values, of whatever length is appropriate. If you try to assign the resulting vector to three variables you have a problem because you do not have three sources.
There is no way in MATLAB to say that you want multiple outputs of a call or expression to be grouped together into individual elements of some data structure that you can then manipulate as if only a single variable had been returned. You cannot, for example, write
{size(planneddose)}
to get a cell array of the individual outputs from planneddose: this call will consider size() to have a single output so would create a cell array with a single element which is a vector of the dimensions. You cannot select a single output other than the first output either -- no way to do the equivalent of
function {local c; [~, c, ~] = size(planneddose); return c}
as an expression -- no way to write size(planneddose)#2 + 1 to get the second output and add 1 to it. You can have multiple assignments only in the case where the left hand side of an assignment has multiple outputs and the right hand size is a single call or single expansion.

Plus de réponses (2)

Star Strider
Star Strider le 30 Jan 2018
This works:
planneddose = rand(135, 130, 129); % Create Matrix
Out = num2cell(size(planneddose) + [1 1 1]);
[EndX,EndY,EndZ] = Out{:}
It definitely takes the long way round to accomplish it!
  14 commentaires
Greg
Greg le 1 Fév 2018
There is definitely a run-on sentence problem, which is why almost any style guide - regardless of language - encourages one executable command per line. Personally, I see no problem in putting a +1 on the same line as the size call, but I wouldn't go further than that.
Walter Roberson
Walter Roberson le 1 Fév 2018
APL was notorious as being a "write-only language" because of the difficulty of figuring out what someone else's APL code meant. It was quite powerful, and you could do amazing things in one line with it, but understanding them afterwards was a bit of a challenge.

Connectez-vous pour commenter.


KSSV
KSSV le 30 Jan 2018
[EndX,EndY,EndZ] = deal(size(planneddose)+[1 1 1])
  2 commentaires
Greg
Greg le 30 Jan 2018
Modifié(e) : Greg le 30 Jan 2018
I thought the same thing at first. That copies the same 1x3 output to all three variables.
Daniel Bridges
Daniel Bridges le 30 Jan 2018
Greg is correct. KSSV, the goal was to add 1 to each element with only one element stored per variable. Your solution copies all three values to each element.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Startup and Shutdown dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by