在Sympy中实现自定义数据类型

Pas*_*ist 5 python math sympy

我想用二元运算(Tensor)执行计算,该运算带有两个非交换参数,将它们转换成类似对的东西,然后当我乘以这些对时做有趣的事情.

# a, b, c, d are non-commutative
Tensor(a, b) * Tensor(c, d) == Tensor(a*c, d*b)  # yes, in this order
Run Code Online (Sandbox Code Playgroud)

此外,我希望所有整数常量取模2.

-Tensor(a, b) == Tensor(a, b)
2*Tensor(a, b) == 0
Tensor(2*a, b) == 0
Run Code Online (Sandbox Code Playgroud)

我这样做了:

import sympy as sp
from sympy.core.expr import Expr

class Tensor(Expr):
    __slots__ = ['is_commutative']

    def __new__(cls, l, r):
        l = sp.sympify(l)
        r = sp.sympify(r)
        obj = Expr.__new__(cls, l, r)
        obj.is_commutative = False
        return obj

    def __neg__(self):
        return self

    def __mul__(self, other):
        if isinstance(other, Tensor):
            return Tensor(self.args[0] * other.args[0], other.args[1] * self.args[1])
        elif other.is_number:
            if other % 2 == 0:
                return 0
            else:
                return self
        else:
            return sp.Mul(self, other)


x, y = sp.symbols('x, y', commutative=False)

Ym = Tensor(y, 1) - Tensor(1, y)
Yp = Tensor(y, 1) + Tensor(1, y)
Xm = Tensor(x, 1) - Tensor(1, x)

d1 = Ym * Yp + Xm * 0
print(d1)
print(sp.expand(d1))

d2 = Xm * Ym
print(d2)
print(sp.expand(d2))
Run Code Online (Sandbox Code Playgroud)

输出:

(Tensor(1, y) + Tensor(y, 1))**2
Tensor(1, y**2) + 2*Tensor(y, y) + Tensor(y**2, 1)
(Tensor(1, x) + Tensor(x, 1))*(Tensor(1, y) + Tensor(y, 1))
Tensor(1, x)*Tensor(1, y) + Tensor(1, x)*Tensor(y, 1) + Tensor(x, 1)*Tensor(1, y) + Tensor(x, 1)*Tensor(y, 1)
Run Code Online (Sandbox Code Playgroud)
  • 测试#1是正确的.
  • 测试#2的术语2*Tensor(y, y)应为零(因为我所做的所有计算都是模2,而2%2 == 0).我该如何执行?
  • 测试#3是正确的.
  • 测试#4根本不会增加不同的Tensors.Tensor(1, x)*Tensor(1, y)应该是Tensor(1, y*x),例如.我该如何执行?

上下文(如果你对我为什么这样做感兴趣):

这用于计算char=2场上代数的双模分辨率.R场上代数的双模分辨率K是相同代数R在其包络代数上的最小投影分辨率R?R^op.这op意味着"乘法在相反的方向上工作".包络代数在代数上有左右动作:

(a?b)*r == a*r*b
r*(a?b) == b*r*a
Run Code Online (Sandbox Code Playgroud)

在已知场上代数的最小投射分辨率的情况下,存在简化计算的定理.尽管如此,它们仍然很乏味,我想停止手动操作.