我想用二元运算(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)
2*Tensor(y, y)应为零(因为我所做的所有计算都是模2,而2%2 == 0).我该如何执行?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)
在已知场上代数的最小投射分辨率的情况下,存在简化计算的定理.尽管如此,它们仍然很乏味,我想停止手动操作.