How to define new methods on existing matlab classes?

Hi, I would like to define, for my own use, new methods for some matlab classes such as cell, struct, among others.
for instance I would like to be able to do
c=a+b, where both a and b are cell arrays.
Is there any way to do that?
Thanks

 Accepted Answer

You could create an @cell folder and in it create a plus method. Or you could use celladd like Sebastian suggested which is probably a better and faster idea. If you're specifically interested in adding cells, then look into gadd already written in the Neural Network Toolbox.

1 Comment

Hi Sean,
I was reluctant in trying this as I heard it only worked for old-style matlab classes. But testing it, it seems to work just as I want it to. Perhaps this is because the classes I am extending are built in...
Thanks a lot

Sign in to comment.

More Answers (2)

Sure you can! You just have to create a method named "plus" in your class, as shown here:
- Sebastian

3 Comments

Hi Sebastian,
Thanks for the reply. The problem is that my new classes should have the same names as matlab's classes. I just would like to expand the functionalities of existing classes to suit my needs.
In other words, if I create a "plus" method, how do I get it to work on matlab's cell objects?
Oh. Not sure if that is possible -- and if it is, it would involve messing with the source code.
I would suggest making some other auxiliary function called celladd which does the operations you want. So instead of using the + operator, you would just say something like
>> c = celladd(a,b);
Another alternative, depending on what exactly you want to implement, is to use the cellfun function which operates on individual elements of a cell array.
- Sevasruab
Hi Sebastian,
Creating a separate function is a solution that is feasible and I use it extensively elsewhere but does not overloads the basic operations as I would like to be able to do. Instead of using c=celladd(a,b), I would like to be able to just write c=a+b.
Creating a different object is not a solution either because then I will be dealing with, precisely, different objects from the ones I want to extent operations for.
Thanks,

Sign in to comment.

Cedric
Cedric on 11 Aug 2015
Edited: Cedric on 11 Aug 2015
Generally speaking, you cannot do it. You cannot subclass MATLAB fundamental classes.
You may want to try building your own class (e.g. MyCell), define/declare a cell array property (e.g. MyCell.cellArray), and apply/transfer the indexing of the object to this property (so data{8} is returning data.cellArray{8} when data = MyCell()). You will be able to go quite far with that: write your own class, overload SUBSASGN, SUBSREF, etc, but you will hit a wall associated with multiple undocumented limitations of MATLAB OOP.
The first is the NUMEL issue that has been reported for years on forums; you will want to overload NUMEL so it is applied to the cellArray property) but you won't be able to do it, because the overload of NUMEL is called by MATLAB for computing nargout in SUBSREF (and not the built-in NUMEL). This means that if you define MyCell.numel in a way that returns numel(obj.cellArray), it will fail returning the correct value when called by MATLAB for defining nargout in SUBSREF.
Then you may be tempted to solve the issue by writing in the doc of your function that NUMEL is not supported so users don't use it (and so you don't have to overload it). But you will hit other walls, which make it impossible to manage curly-bracket indexing properly. One reason, and this is my guess, is that MATLAB parses some indexing expressions instead of performing them, and even if you overloaded SUBSREF and SUBSASGN in a way that manages these situations properly, you will get error messages like "indexing cell array on non cell blabla". You will see that for example when you try to nest objects of your class. Finally, if you find tricks for bypassing this type of limitations (which would lead you very far in implementing very inefficient SUBSAGN and SUBSREF, that "cascade back" indexing operations with SUBASGN having to call SUBSREF (and its cascades) in its own cascade ;-)), you will be caught back later by errors associated with all the tricks that you had to implement e.g. when implementing accessors for properties, which add a level of complexity/parsing/difficulty.
My conclusion is that it is fun to develop if you don't need a robust solution, if you are not under a tough deadline, if you want to learn: e.g. if you want to learn how to overload SUBASGN and SUBSREF for managing basic situations, you can define a class of objects which do not support NUMEL, cannot be nested, etc. Otherwise, just create a function for adding built-in cell arrays.

6 Comments

Hi Cedric,
Thank you very much for an exhaustive answer. I found out that by simply creating a folder @cell, I could add all kinds of methods I wanted. It seems to work well, which came to me as a surprise because my first thought was that this old trick only worked in old versions of matlab. My suspicion is that the classes I am trying to extend are builtin and therefore not written in the new style of matlab classes. That probably explains the reason why it is possible to extend them in that way. Of course I could be wrong, but at least for now things seem to work well.
Again thank you for your input.
My pleasure Patrick, I'd love to see some of these limitations being addressed by TMW, but I am using pre-2015b now and they are still here ;-)
This statement "You cannot subclass MATLAB fundamental classes." is not completely true. You can subclass SOME built-in types, but not all. CELL is one that you cannot, mainly (IMO) because cell arrays are really general and so getting overloads right in all possible scenarios would be very tricky.
So given that, Patrick, I'm curious what you're trying to overload + for cells to do. I would personally shy away from trying to define or redefine the operators for any of the built-in types, but particularly for cell (see the generality argument above.)
Cedric
Cedric on 11 Aug 2015
Edited: Cedric on 11 Aug 2015
Sorry Steven, you're right, I should have given the reference! By the way, do you know the reason why it isn't the built-in NUMEL that is called by MATLAB for defining nargout in SUBSREF, but the overload?
Does this page from the documentation answer that question? Your object may have a different definition of "size" than the built-in.
For instance, consider if you had a scalar object that contained data and you wanted MATLAB to consider the size of that object to be the size of the contained data, NOT the size of the container it was in. You also wanted indexing to extract the appropriate piece of that object. The built-in NUMEL on the scalar object would return 1 and the built-in SIZE would return [1 1]. [You could call the built-in functions using BUILTIN.] The overloaded NUMEL and SIZE could take the amount of data contained in the object into account.
This is not a theoretical scenario, either; there are objects in MATLAB today that do this.
The doc page mentions that MATLAB calls the overloaded NUMEL to define nargout and nargin in SUBSREF and SUBSASGN respectively, but it doesn't explain why. I have been overloading NUMEL for the reason that you mention, but counting the number of input or output arguments, as far as I can say, is related to the call (CSLs associated with {}-indexing) and not to the objects internals (?) So why giving this task to the overload?

Sign in to comment.

Categories

Find more on Construct and Work with Object Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!