Implement custom data type in Sympy

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.

 # a, b, c, d are non-commutative Tensor(a, b) * Tensor(c, d) == Tensor(a*c, d*b) # yes, in this order 

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.

+5
source share

Source: https://habr.com/ru/post/1260755/


All Articles