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

时间:2016-12-03 11:25:31

标签: 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

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

-Tensor(a, b) == Tensor(a, b)
2*Tensor(a, b) == 0
Tensor(2*a, b) == 0

我这样做:

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

输出:

(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)
  • 测试#1是正确的。
  • 测试#2的术语2*Tensor(y, y)应该为零(因为我做的所有计算都是模2,而2%2 == 0)。我该如何执行?
  • 测试#3是正确的。
  • 测试#4根本不会乘以不同的Tensor。例如,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

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

0 个答案:

没有答案