Cell Subtask

This problem arose when I was answering this question . There must be some stupid mistake that I am making, but I can’t understand what kind of mistake ...

myMatrix = [22 33; 44 55] 

Return:

 >> subsref(myMatrix, struct('type','()','subs',{{[1 2]}} ) ); ans = 22 44 

When using it with cells:

 myCell = {2 3; 4 5} 

Return:

 >> subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) ); ans = 2 % WHATTT?? Shouldn't this be 2 and 4 Matlab?? 

Checking the subsref documentation , we see:

See how MATLAB calls subsref for an expression:

A {1: 2} Syntax A {1: 2} calls B = subsref (A, S), where S.type = '{}' and S.subs = {[1 2]}.

This does not seem to be the case, because the return value of subsref is only the first argument, and not all arguments.

Then if you do this:

 >> [a,b]=subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) ) a = 2 b = 4 % Surprise! 

But this is not the same as myCell {[2 4]}, which will automatically return:

 >> myCell{[1 2]} ans = 2 ans = 4 

Will I need to use subsref with one output for each index that I use to access myCell , or am I missing something?

+4
source share
3 answers

When curly braces ( {} ) are used to index an array of cells , the output is a comma-separated list . This indirectly causes subsref , but the behavior is slightly different from its direct invocation.

subsref itself is technically a function, and a comma-separated list returned by curly braces behaves like a varargout in this case. This means that you must specify a suitable "receiver" for all the desired output results, just like you, with any other function that returns several parameters, otherwise they will be ignored.

+4
source

Do not ask me why, this is what I tried:

 myOutput=subsref(myCell,struct('type','()','subs',{{[1 2]}} ) ) 

pay attention to "type", "()"!

this gives me:

 myOutput = [2] [4] 

with myOutput as a cell. Convert back:

 >> myOutput=cell2mat(subsref(myCell,struct('type','()','subs',{{[1 2]}}))) myOutput = 2 4 

This is just a β€œquick” answer that will require some improvements or some background information ...

+1
source

I continued to investigate @EitanH's answer and was able to find more details.

Yes, it returns a comma separated list, but the subsref function should return a comma separated list only A{:} . Here is an example where functions behave differently, but this is the expected behavior. I would like the .get class .get return a list and one common class function in order to behave like general functions, getting only the first argument from the cell.

 classdef ListReturn properties(Access = private) a end properties(Dependent) getA end methods function self = ListReturn(a) self.a = a; end function varargout = get.getA(self) varargout = {self.a}; end function varargout = getAFcn(self) varargout = {self.a}; end end end 

There is a significant difference when calling functions, just like .get:

 k=[ListReturn(2) ListReturn(3) ListReturn(4) ListReturn(5)] >> k.getAFcn ans = 2 >> k.getA ans = 2 ans = 3 ans = 4 ans = 5 

Thus, it seems that using A{1:2} or A{:} works like a Cell.get() , while subsref works like a general matlab function, returning only one argument when the output arguments are not specified, as one of functions in C,java,C++ . Anyway, I just feel that subsref should work like .get .

+1
source

Source: https://habr.com/ru/post/1498418/


All Articles