Why does MATLAB not allow this assignment with the + operator?
Mostrar comentarios más antiguos
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 comentarios
Greg
el 30 de En. de 2018
Was going to suggest deal but I don't think it works for numeric vectors the way you want it to.
Greg
el 30 de En. de 2018
My follow-up question what's wrong with the 1x3 and just index rather than three distinct variables?
Andrew Newell
el 30 de En. de 2018
I don't think it's likely to be added as a feature.
size(v)
returns a numeric vector, while
[x,y,z] = size(v)
probably uses the equivalent of varargout, which is a cell array. You'd have to modify arithmetic operations so something like
{2,3,4} + [1 1 1]
was allowed. But then they would have to choose - should the sum be cell or numeric?
" but I think this use is intuitive and MATLAB should add it as a feature in the next release."
This is not intuitive, for the same reasons that are discussed here:
Because comma-separated lists are equivalent, no matter how they are generated (i.e. written explicitly, or generated from cell array or struct expansion), and regardless of whether they are used as for input or output arguments, then your proposal would mean writing
max(3,2+1)
= 3
but instead expecting this to be equivalent to
max(4,3)
= 4
Ouch. Your proposal make any operation that occurs inside a comma-separated list apply to all of its values, which instantly makes lots of operations totally illogical. Of course + is just syntactical sugar for the binary function plus, so all other binary (or more?) functions would also have to follow this rule:
regexp('abc',strcat('a','b'))
would be equivalent to
regexp('abcb','ab')
Well, that would certainly make using MATLAB much more... adventurous.
Note that not only that, but this proposal would mean a very major change to how MATLAB works: functions (such as the plus in your example) are currently defined for inputs which are objects of some particular classes, but what you are proposing would mean that comma-separated lists themselves would have to become valid input objects. Currently they are not any kind of object at all (at least, not explicitly in the documented syntax). So this would be a major departure from how MATLAB is actually designed/documented because it would require creating a "comma-separated list" object class, and rewriting all functions to be able to handle this new class. I doubt that this would be worth the effort, for such small (and inconsistent) syntax changes that you request.
"That is to say, I encounter this problem fairly often..."
You probably should be using indexing more, rather than splitting up data into separate variables. In general keeping data together makes working with it easier (even trivial things like indices), and makes it easy to write code that automatically adjusts to different array sizes, etc.
Walter Roberson
el 30 de En. de 2018
"Because comma-separated lists are equivalent, no matter how they are generated (i.e. written explicitly, or generated from cell array or struct expansion),"
Not completely true:
>> [A,B] = 3,5
Too many output arguments.
>> C = {3,5}
C =
1×2 cell array
{[3]} {[5]}
>> [A,B] = C{:}
A =
3
B =
5
" 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
el 31 de En. de 2018
Respuesta aceptada
Más respuestas (2)
Star Strider
el 30 de En. de 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 comentarios
Daniel Bridges
el 31 de En. de 2018
Editada: Daniel Bridges
el 31 de En. de 2018
Star Strider
el 31 de En. de 2018
My pleasure.
Walter Roberson
el 31 de En. de 2018
Though it is not clear this is a "better" way of writing than three separate variables. A different way, yes. Every time I write num2cell just to be able to {:} it for comma list expansion, I feel grungy, that I have written ugly code.
Star Strider
el 31 de En. de 2018
I just considered it a fun problem, and to see if I could develop a solution for it.
Operating on each output separately is certainly more efficient, and what I would write.
Greg
el 31 de En. de 2018
I hope the 1x3 vector output and indexing is what you would write.
Star Strider
el 31 de En. de 2018
Same thing, essentially.
Daniel Bridges
el 1 de Feb. de 2018
Star Strider
el 1 de Feb. de 2018
Editada: Star Strider
el 1 de Feb. de 2018
It could be applicable in certain situations. It would be a one-off, so it would likely be as efficient other more explicit methods. (I have not timed it.)
In most circumstances, I would simply do:
spd = size(planneddose);
NewSize = spd + [1 1 1];
then use the elements of ‘NewSize’ as necessary, remembering what the elements were, not even breaking them out into their separate components. If I wanted the row size, I would use ‘NewSize(1)’, and so for the other dimensions.
There is a certain satisfaction in the challenge of being able to do something like this in two lines of code.
Greg
el 1 de Feb. de 2018
" non-MATLAB proofreader" sounds kind of like asking an artist to check your science homework.
Walter Roberson
el 1 de Feb. de 2018
deal() applied to a cell assigns the same value to all of the outputs. You have to deal() a comma separated list (explicit or through expansion) to get different outputs. deal() is not magic -- you can look at the code for it.
Daniel Bridges
el 1 de Feb. de 2018
Star Strider
el 1 de Feb. de 2018
Noted. Corrected.
Greg
el 1 de Feb. de 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
el 1 de Feb. de 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.
KSSV
el 30 de En. de 2018
[EndX,EndY,EndZ] = deal(size(planneddose)+[1 1 1])
Categorías
Más información sobre Logical en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!