1

Following this response, I set out to do something similar for datasets.

The plus function mentioned in that answer, I got working fine for cell arrays by putting the plus.m in an @cell-folder. However on trying the exact same (slightly different implementation) in a @dataset-folder, Matlab still gives an "undefined" error for both Dataset+Dataset and plus(Dataset,Dataset).

What am I getting wrong?

Edit 1

In the current directory, there is the folder @dataset (same place as the working @cell folder), containing the file plus.m containing the code:

function C = plus(A,B)
% assuming same size, valid type, etc.
C = zeros(size(A));
for i = 1:size(A,2)
    C(:,i) = A.(i) + B.(i);
end
end

In the command prompt, try:

ds = dataset({1,'a'},{2,'b'});
ds+ds

Matlab throws the error: Undefined function 'plus' for input arguments of type 'dataset'.

Edit 2

Summary of workarounds

The short version is Daniels answer below. A write-up of the alternative options can be found here. In short, they present the options below (for overloading functions in general - not all solutions will allow the use of a standard operator such as '+' - here described for the present issue). None of them solves my problem, but could be used as workarounds.

  1. Define a new function that takes the desired class as arguments -- ala dsplus(ds,ds)
  2. Define a new plus function, in which you catch and handle classes that you want to implement functionality for, and reroute others to the built-in.
  3. Daniels suggestion.
  4. Make a new mydataset class inheriting from from dataset (classdef mySym < sym)
  5. Make a new mydataset class using composition (i.e. include the built-in dataset as a property of the mydataset class)

I would add a 6.th option: Leave Matlab and learn Python. An option that by the day looks increasingly appealing.

Community
  • 1
  • 1
AdamAL
  • 1,571
  • 2
  • 14
  • 25

2 Answers2

1

The documentation is not clear to me, but this is likely the intended behaviour. The first thing to realize is that the cell and dataset classes are different. The dataset class is defined in an @-folder and dataset.m begins with classdef. Between R2008a, when the classdef OO system was introduced, and R2012a the documentation read:

Only One @-Folder per Class

For classes defined using the new classdef keyword, an @-folder shadows all @-folders that occur after it on the MATLAB path. Classes defined in @-folders must locate all class files in that single folder. However, classes defined in @-folders continue to take precedence over functions and scripts having the same name, even those function and scripts that come before them on the path.

In R2012b (i.e., MATLAB 8.0) the documentation changed to:

Previous Behavior of Classes Defined in @-Folders

In MATLAB Versions 5 through 7, @-folders do not shadow other @-folders having the same name, but residing in later path folders. Instead, the class is defined by the combination of methods from all @-folders having the same name. This is no longer true.

Note that for backward compatibility, classes defined in @-folders always take precedence over functions and scripts having the same name, even those that come before them on the path.

I have now read the documentation a number of times and I still have no idea what changed between R2012a and R2012b. None of this applies to the cell class since it is not defined in an @folder.

StrongBad
  • 869
  • 6
  • 16
1

The ability to extend a class by defining methods in a different @-folder is a feature of the old object object system, the one based on struct (pre MATLAB 7.6).

The current OOP system (classdef-style) does not support this, since @-folders will shadow other @-folders with the same name (according to which one appears first on the path).

Now cell (which is a builtin type/class) is apparently based on the old system, since you can define a @cell/plus.m function anywhere on the path and it works.

However dataset is a class defined in the new system (classdef) so you cannot extend it that way, unless of course you place your function inside the toolbox's own directory (you'll need to rehash the toolbox path afterwards for it to take effect).

>> which dataset
C:\Program Files\MATLAB\R2013a\toolbox\shared\statslib\@dataset\dataset.m
Amro
  • 123,847
  • 25
  • 243
  • 454