Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using subsref, subsasgn and substruct

104 views
Skip to first unread message

MM

unread,
Feb 18, 2009, 5:40:03 PM2/18/09
to
Hi...I created overloaded versions of subsref and substruct functions in MATLAB for my own classes. It seems that my overloaded versions work fine with exceptions to cases such as a.g(i) where I havea structured field followed by its indices ('.' followed by '()' ). How can I circumvent this problem? Is it that I also have to overloaded substruct method? If not, is there any solution to overcome this problem?

Thanks,
MM

Steven Lord

unread,
Feb 19, 2009, 10:18:24 AM2/19/09
to

"MM " <manm...@yahoo.com> wrote in message
news:gni2o3$pbp$1...@fred.mathworks.com...

If your object is a, then the statement x = a.g(i) will call your SUBSREF
method with a as the first input and this as the second [I haven't tested
this, but I'm fairly certain it's correct. If it isn't, it's close.]


substruct('.', 'g', '()', {i})


Take a look at the first example in the M-file help for SUBSTRUCT.

This assumes that a.g(i) does not appear in one of your methods. In a
method of class foo, the SUBSREF or SUBSASGN methods for class foo are not
invoked unless you explicitly call them as a function.

http://www.mathworks.com/support/solutions/data/1-18J9B.html

--
Steve Lord
sl...@mathworks.com


MM

unread,
Feb 19, 2009, 6:18:01 PM2/19/09
to
"Steven Lord" <sl...@mathworks.com> wrote in message <gnjt80$crv$1...@fred.mathworks.com>...
> Hi Steve,

Thanks for your answer. Does it mean that I have to invoke subsref explicitly within the description of an overloaded subsref method? I have the following structure:

%
% B = SUBSREF(A, S) METHOD FOR SUBSCRIPTED REFERENCE
%
% overloaded version of subsref method for signals class
%

function b=subsref(a,s)

switch s.type

case '()'

switch s.subs{:}
case 1
b = a.category;
case 2
b = a.fs;
case 3
b = a.theta;
case 4
b = a.samplespersymbol;
case 5
b = a.d;
case ':'
b.category = a.category;
b.fs = a.fs;
b.theta = a.theta;
b.samplespersymbol = a.samplespersymbol;
b.d = a.d;
otherwise
error('signals.subsref','invalid indexing for signals object');
end
case '.'

switch s.subs

case 'category'
b = a.category;
case 'fs'
b = a.fs;
case 'theta'
b = a.theta;
case 'samplespersymbol'
b = a.samplespersymbol;
case 'd' % mark1
b = a.d;

otherwise
error('signals.subsref','invalid indexing for signals object');
end
otherwise
error('invalid category for indexing! Only arrays and strucures are allowed');

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

I am just wondering if I need to put it after "mark1".

Once again, you suggestion is appreciated.

Thanks,
Manna

=====================================================

Matt

unread,
Feb 19, 2009, 7:28:02 PM2/19/09
to
"MM " <manm...@yahoo.com> wrote in message <gni2o3$pbp$1...@fred.mathworks.com>...

> Hi...I created overloaded versions of subsref and substruct functions in MATLAB for my own classes. It seems that my overloaded versions work fine with exceptions to cases such as a.g(i) where I havea structured field followed by its indices ('.' followed by '()' ). How can I circumvent this problem? Is it that I also have to overloaded substruct method? If not, is there any solution to overcome this problem?
------------------------------------------


I find the tool indexstr.m down at the bottom of this post to be a handy tool
for overloading multi-level indexing in subsref/subsasgn methods. Used in conjunction with eval(), it allows pretty much any indexing expression to be done in two lines or so as follows


%%%%General overloaded subsref method
varargout=subsref(obj,S)

str=indexstr(S); %Converts S into an equivalent indexing expression
%contained in a string.

varargout=eval(['{obj' str '};']) ;

end
%%%%%%%%%%%%%%%%

Note that indexstr() is sometimes more robust than things like builtin('subsref',...) which don't always give the expected behavior, e.g.

>> a.g={1 2 3};
>> [a.g{:}]

ans =

1 2 3


%The following should give the same answer as above but doesn't
>> S=substruct('.', 'g', '{}', {':'});
>> [builtin('subsref',a,S)]

ans =

1


%However, indexstr() with eval() do lead to the correct result
>> eval(['[a' indexstr(S) ']'])
ans =

1 2 3


function str=indexstr(S)
%Given a subscripting structure array S, such as output by substruct() and
%used in indexing methods SUBSREF and SUBSASGN, a single string STR is
%returned bearing a subscript expression equivalent to that expressed
%by S. This is useful when combined with EVAL() to implement overloaded
%SUBSASGN and SUBSREF methods based on
%already-defined subscript operations.
%
%Usage:
%
% str=indexstr(S)
%
%EXAMPLE:
%
% >>a.g={1 2 3};
% >>M=substruct('.', 'g', '{}', {':'});
% >>str=indexstr(M)
%
% str =
%
% .g{M(2).subs{:}}
%
% >>eval(['a' str]) %equivalent to a.g{:}
%
% ans =
%
% 1
%
%
% ans =
%
% 2
%
%
% ans =
%
% 3

%NOTE: When it exists, the INPUTNAME of S is used in generating STR. Otherwise,
% this name defaults to 'S'
%
%
%See also SUBSTRUCT, INPUTNAME


name=inputname(1);

%DEFAULT
if isempty(name), name='S'; end


%%
str='';

for ii=1:length(S)

switch S(ii).type

case '.'

str=[str '.' S(ii).subs];

case '()'

insert=[name '(' num2str(ii) ')'];

str=[str '(' insert '.subs{:})'];

case '{}'

insert=[name '(' num2str(ii) ')'];

str=[str '{' insert '.subs{:}}'];

end

end


Matt

unread,
Feb 19, 2009, 8:10:20 PM2/19/09
to
"Matt " <x...@whatever.com> wrote in message
> %%%%General overloaded subsref method
> varargout=subsref(obj,S)
>
> str=indexstr(S); %Converts S into an equivalent indexing expression
> %contained in a string.
>
> varargout=eval(['{obj' str '};']) ;
>
> end
> %%%%%%%%%%%%%%%%


Sorry, i misarticulated this example. What I meant was, it is often the case when overloading subsref/subsasgn that you want to apply the indexing expression in question to some property of the object within the subsref.m/subsasgn.m code.

In this case, multi-level indexing can be applied to the property using code of the form

%%%%%
varargout=subsref(obj,S)

.....%blablabla

str=indexstr(S); %Converts S into an equivalent indexing expression
%contained in a string.

varargout=eval(['{obj.Property' str '};']) ;


MM

unread,
Feb 20, 2009, 2:40:20 PM2/20/09
to
Hey Matt,

Thanks for your suggestion. I realise that indexstr(S) is a method that is user-defined ('coz could not find it in the toolboxes that i have access to), and it is a sort of string to indices converter method. According to your statement, my question (rephrased) would be "Is there any example of multi-level indexing in MATLAB?". i have not come across anything pertinent to this in help file as MATLAB user documentation provides all sorts of explanation to its methods and their application. i would appreciate it if you can direct me to any other resources.

thank you,
Manna
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

"Matt " <x...@whatever.com> wrote in message <gnkvts$q1u$1...@fred.mathworks.com>...

Matt

unread,
Feb 20, 2009, 4:01:06 PM2/20/09
to
"MM " <manm...@yahoo.com> wrote in message <gnn0v4$bj4$1...@fred.mathworks.com>...

> Hey Matt,
>
> Thanks for your suggestion. I realise that indexstr(S) is a method that is user-defined ('coz could not find it in the toolboxes that i have access to),
------------------------------------------------

Right, but that's why I provided you the code for indexstr(S) in my previous post.


--------------------------------------------------


and it is a sort of string to indices converter method.

---------------------------------------------------

It converts the output of substruct() to an equivalent string.


----------------------------------------------------------------


my question (rephrased) would be "Is there any example of multi-level indexing in MATLAB?".

--------------------------------------------------------------

If you look on pp. 10-12 and 10-13 of the MATLAB Object Oriented Programming manual, an example is given of a subsref method with multi-level indexing.

0 new messages