Nick
Nick

Reputation: 2432

Is it possible to derive a class from a MATLAB builtin type?

I'm experimenting with the idea of creating a read-only matrix type, one that could be passed to existing code and be used like any other matrix, but assignment to a sub-range is prohibited:

>> x = ReadOnlyMatrix(...);  % pass in a regular matrix to construct it
>> y = x * 3;  % x can be used like any other matrix
>> x(1,:) = 0; % error! x is read-only

I can not find any working examples or documentation for deriving from class 'double'. Is it possible and can someone provide a small example?

Upvotes: 3

Views: 105

Answers (1)

As I already stated in a comment, I'm not very familiar with matlab classes. However, I tried to tackle your problem none the less. As I've asked in a comment, I'll ask again: why not try to derive a class from double as you would from any other class (and override some methods as @rayryeng suggested)?

Here's what I came up with:

classdef myDouble < double
   methods
       function x = myDouble(inval)
           if nargin == 0
               inval = nan;
           end
           x@double(inval);
       end

       function varargout = subsasgn(varargin)
           error('Type myDouble does not support indexing on the lhs!');
       end
   end
end

This defines a very simple class myDouble derived from the class double. It has a constructor which initializes the object to any double array (or NaN for an empty call), and overrides the subsasgn method of doubles which is responsible for assignments of the kind A(I)=B.

Since I didn't override the disp method (for now, to keep matters clear), the default appearance is a bit verbose. Default initialization:

>> myvar = myDouble()

myvar = 

  myDouble

  double data:
   NaN

  Methods, Superclasses

Initializing with an array:

>> myvar = myDouble(magic(3))

myvar = 

  myDouble

  double data:
     8     1     6
     3     5     7
     4     9     2

  Methods, Superclasses

Using the array as a matrix:

>> myvar.^2

ans =

    64     1    36
     9    25    49
    16    81     4

>> diag(myvar)

ans =

     8
     5
     2

You can see that all the operations and methods which are defined in the double superclass seem to work, but return objects of class double (which is both understandable and useful).

We can also access subarrays:

>> myvar(2,:)

ans = 

  myDouble

  double data:
     3     5     7

  Methods, Superclasses

which will return an object of the same type.

So let's try overwriting some elements:

>> myvar(2,2) = 3
Error using myDouble/subsasgn (line 11)
Type myDouble does not support indexing on the lhs!

>> myvar(2,:) = [3; 2]
Error using myDouble/subsasgn (line 11)
Type myDouble does not support indexing on the lhs!

>> myvar  %make sure it's intact '

myvar = 

  myDouble

  double data:
     8     1     6
     3     5     7
     4     9     2

  Methods, Superclasses

The overridden subsasgn method does what it should: it throws an error, regardless of whether the input would be a valid assignment with double arrays (in the latter example: it wouldn't).

I also threw in a rudimentary disp method to make our class more sneaky:

       function disp(obj)
           disp(double(obj));
       end

The resulting output compared to an actual double:

>> magic(3)

ans =

     8     1     6
     3     5     7
     4     9     2

>> myDouble(magic(3))

ans = 

     8     1     6
     3     5     7
     4     9     2

Upvotes: 4

Related Questions