You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab可交换超复数类如何重载基础函数实现逐元素运算?

可交换超复数类实现与逐元素运算符重载问题

项目背景

我正在编写**可交换超复数(commutative hypercomplex number)**类。
首先说明:若已有相关实现,请告知。 我暂未找到对应实现,注:四元数(Quaternion)已有官方实现,但不具备交换性。
我希望复刻Matlab对实数、复数的全部操作能力,将其扩展到超复数场景。目前我采用自定义类的方案实现,若有更优的实现方法,欢迎告知。
现有大量面向复数的代码,我的核心目标是通过合理的运算符重载,让这些现有程序无需修改即可适配超复数运算,该成果可服务于大量相关领域开发者。
本实现的核心数学原理参考Ablamowicz1996年发表的《Clifford Algebras with Numeric and Symbolic Computations》。

现有实现进展

目前我的超复数类已支持基础运算:我已重载了mtimes(a,b) = a*b操作,示例如下:

A = MyClass(1);
B = MyClass(2);
A*B; % ->可正常运行

核心问题

我遇到的核心问题是:例如在2D场景下,我希望能够运行[A B C].*[D ; E]这类运算,同时兼容Matlab原生的逐元素运算规则,支持任意维度的兼容尺寸数组运算,且采用我自定义的*运算规则。例如针对尺寸兼容但不相等的矩阵:

A = [1 2 3]; B = [1;2]

原生Matlab运行结果为:

A.*B    
ans =

 1     2     3
 2     4     6

该规则在N维数组尺寸兼容时同样生效。请问我该如何重载times(a,b) = a.*b、power、rdivide等函数,实现和原生Matlab一致的逐元素运算行为?

现有代码

以下是我当前的类实现代码:

classdef Hypercomplex < handle
    properties (SetAccess = public, GetAccess = public)
        A
    end
    properties (SetAccess = private, GetAccess = private)
        eps,nu,e1,e2
    end
    
    methods
        function s = Hypercomplex(Z)             %% 构造函数
            % Z可为实数、复数或超复数
            if isa(Z,'Hypercomplex')            % 输入为超复数
                s = Z;
            elseif ~isreal(Z) && length(Z) == 1 % 输入为复数
                s = Hypercomplex([real(Z) imag(Z) 0 0]);
            elseif isreal(Z) && length(Z) < 5
                s.A = zeros(1,4);
                for ii = 1:length(Z)            % 输入为向量
                    s.A(ii) = Z(ii);
                end
            end
        end
        function s = epsnu(s)
            s.eps = (s.A(1) - s.A(4)) + 1i*(s.A(2)+s.A(3));
            s.nu  = (s.A(1) + s.A(4)) + 1i*(s.A(2)-s.A(3));
        end
        function s = e1e2(s)
            s.e1 = Hypercomplex([0.5 0 0 -0.5]);
            s.e2 = Hypercomplex([0.5 0 0  0.5]);
        end
        %% 重载函数
        function out = cos(a)
            a.epsnu.e1e2;
            out = cos(a.eps)*a.e1 + cos(a.nu)*a.e2;
            % 后续还可实现sin、exp、sqrt等函数
        end
        
        function out = mtimes(a,b) % '*'运算符
            a = Hypercomplex(a).epsnu;
            b = Hypercomplex(b).epsnu;
            eps12 = 0.5*(a.eps * b.eps);% 复数乘法
            nu12  = 0.5*(a.nu  * b.nu );% 复数乘法
            
            h1 = Hypercomplex([real(eps12) imag(eps12) imag(eps12) -real(eps12)]);
            h2 = Hypercomplex([real(nu12)  imag(nu12) -imag(nu12)   real(nu12) ]);
            out = h1+h2;
        end
        function out = mrdivide(a,b)
            a = Hypercomplex(a);
            b = Hypercomplex(b);
            out = a * b.inverse;
        end
        function s = inverse(s)
            s = Hypercomplex(s).epsnu.e1e2;
            s = 1/(s.eps)*s.e1 + 1/(s.nu)*s.e2;
        end
        function out = plus(a,b)
            a = Hypercomplex(a);
            b = Hypercomplex(b);
            out = Hypercomplex(a.A + b.A);
        end
        function out = minus(a,b)
            a = Hypercomplex(a);
            b = Hypercomplex(b);
            out = Hypercomplex(a.A - b.A);
        end
    end
end

运算示例

运算示例(i^2 = -1):

>> Ni =  Hypercomplex([0 1 0 0]) ;
>> Ni*Ni
  Hypercomplex with properties:

    A: [-1 0 0 0]

可交换超复数实现原理


解决方案

你可以借助Matlab内置的数组隐式扩展机制,结合逐元素调用已实现的标量超复数运算逻辑,实现符合原生规则的逐元素运算符重载,具体实现方案如下:

重载times函数(对应.*运算符)

在类的methods块中添加如下代码即可直接使用,该实现会自动适配Matlab原生的隐式尺寸扩展规则,支持任意维度兼容的数组运算,且复用你已写好的超复数乘法逻辑,无需重复开发数学计算部分:

function out = times(a,b)
    % 统一将输入转为Hypercomplex类型的元胞数组,支持混合实数、复数输入
    a = arrayfun(@Hypercomplex, a, 'UniformOutput', false);
    b = arrayfun(@Hypercomplex, b, 'UniformOutput', false);
    % 逐元素调用已实现的mtimes标量乘法,自动匹配尺寸扩展规则
    out = cell2mat(arrayfun(@(x,y) mtimes(x{1}, y{1}), a, b, 'UniformOutput', false));
end

重载其他逐元素运算符

其余power(对应.^)、rdivide(对应./)等运算符的重载逻辑完全一致,只需替换内部调用的运算函数即可:

重载power函数示例

function out = power(a, b)
    a = arrayfun(@Hypercomplex, a, 'UniformOutput', false);
    b = arrayfun(@Hypercomplex, b, 'UniformOutput', false);
    % 逐元素调用你后续实现的超复数标量幂运算函数即可
    out = cell2mat(arrayfun(@(x,y) hypercomplex_pow(x{1}, y{1}), a, b, 'UniformOutput', false));
end

重载rdivide函数示例

function out = rdivide(a, b)
    a = arrayfun(@Hypercomplex, a, 'UniformOutput', false);
    b = arrayfun(@Hypercomplex, b, 'UniformOutput', false);
    % 直接复用已实现的mrdivide标量除法逻辑
    out = cell2mat(arrayfun(@(x,y) mrdivide(x{1}, y{1}), a, b, 'UniformOutput', false));
end

性能优化建议

如果需要提升高维数组的运算效率,可以将arrayfun遍历逻辑替换为向量化操作,直接对所有超复数实例的A属性批量计算,避免循环开销。


内容的提问来源于stack exchange,提问作者ApneaDeepBlue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:36:01