I am new to object-oriented programming. This question seems to resemble previously asked ones, but with one big difference to which I did not find a solution yet:
How do I set up a new class of variables, using object-oriented programming in Matlab, which will behave similarly to a matrix (2D array... ), but for which the rows/columns will be numbered {-2,-1,0,1...} (instead of only {1,2,3...})?
I want to be able to use all the regular vector operations that Matlab offers on this new class. What will be the method to address the values in this variable (e.g., A[-1,2]=... like for a normal array? A.-1.2=...?) ? How would I perform simple A. * B (element-by-element multiplication of vectors in Matlab)? And A(:,5). * B(-1,:)'?
You can subclass the builtin double
class which will give you the majority of your functionality. With respect to indexing, you'll just have to write your own subsref
and subsasgn
methods.
Since you've subclassed double
, all normal matrix operations (such as element-wise multiplication, cumsum
, etc.) will continue to work as expected.
Something like this should work.
classdef mymatrix < double
methods
function self = mymatrix(varargin)
% Constructor that simply calls the double constructor
self@double(varargin{:});
end
function res = subsref(self, subs)
% Call the usual subsref after modifying the subscripts
res = subsref@double(self, correctsubs(self, subs));
end
function res = subsasgn(self, subs, val)
% Call the usual subsasgn after modifying the subscripts
res = subsasgn@double(self, correctsubs(self, subs), val);
end
end
methods (Access = 'private')
function subs = correctsubs(self, subs)
% Function for converting subscripts
for k = 1:numel(subs)
% Only process () references and non-linear indices
if ~isequal(subs(k).type, '()')
continue
end
% Figure out the center of the matrix
mid = ceil(size(self) / 2);
% For each subscript, if it's numeric then add the middle
% shift amount to it to turn it into a normal subscript
for m = 1:numel(subs(k).subs)
if isnumeric(subs(k).subs{m})
subs(k).subs{m} = subs(k).subs{m} + mid(m);
end
end
end
end
end
end
You could then use this exactly like how you describe.
m1 = mymatrix(magic(3));
m2 = mymatrix(magic(3));
% All normal matrix operations will work
m3 = m1 .* m2;
cumsum(m1, 1);
% You can also perform your special indexing
m4 = m1(:,-1);