Matlab 中的面向对象编程:为具有负索引的二维数组设置新的 class

Object-oriented programing in Matlab: Set up new class for 2D arrays, with negative indices

我是面向对象编程的新手。这个问题似乎类似于以前问过的问题,但有一个很大的不同,我还没有找到解决方案:

如何使用 Matlab 中的面向对象编程设置新的 class 变量,其行为类似于矩阵(二维数组...),但 rows/columns 将被编号为 {-2,-1,0,1...}(而不仅仅是 {1,2,3...})?

我希望能够在这个新 class 上使用 Matlab 提供的所有常规矢量运算。解决此变量中的值的方法是什么(例如,A[-1,2]=...就像普通数组一样?A.-1.2=...?)?我将如何执行简单的 A. * B(Matlab 中向量的逐元素乘法)?和 A(:,5)。 * B(-1,:)'?

您可以子class 内置 double class,这将为您提供大部分功能。关于索引,您只需编写自己的 subsrefsubsasgn 方法。

由于您已经class编辑了double,所有正常的矩阵运算(例如element-wise乘法、cumsum等)将继续作为预期。

像这样的东西应该有用。

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

然后您可以完全按照您描述的方式使用它。

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);