I want to do some calculations with a binary operation ( Tensor ) that takes two non-commutative arguments, converts them into something like a pair, and then does funny things when I multiply these pairs.
In addition, I want all integer constants to be accepted modulo 2.
-Tensor(a, b) == Tensor(a, b) 2*Tensor(a, b) == 0 Tensor(2*a, b) == 0
My shot at the same time:
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))
Output:
(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)
- Test number 1 is correct.
- Test No. 2 has the term
2*Tensor(y, y) , which should be zero (since I do all the calculations modulo 2 and 2% 2 == 0). How to do it? - Test number 3 is correct.
- Test No. 4 does not propagate different
Tensor . Tensor(1, x)*Tensor(1, y) should be Tensor(1, y*x) , for example. How to do it?
Context (if you are interested in why I am doing this):
This is to calculate the bimodal resolution of the algebra over the field char=2 . The bimodule resolution of the algebra R over the field K is the minimal projective resolution of the same algebra R over its enveloping algebra RβR^op . Here op means that multiplication works in the opposite direction. The enveloping algebra has both left and right actions on the algebra:
(aβb)*r == a*r*b r*(aβb) == b*r*a
There is a theorem that simplifies calculations in the case when the minimal projective resolution of an algebra over a field is known. However, they are rather tedious, and I want to stop doing them manually.