From da7b72246cd590ba9b3b3c18997480d237a28ada Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 15 Feb 2026 10:29:40 -0500 Subject: [PATCH] mjo/clan/unital_clan.py: factor out (un)lift for the Vinberg clan --- mjo/clan/unital_clan.py | 44 +++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/mjo/clan/unital_clan.py b/mjo/clan/unital_clan.py index 63fb737..c07404f 100644 --- a/mjo/clan/unital_clan.py +++ b/mjo/clan/unital_clan.py @@ -619,6 +619,24 @@ class VinbergClan(NormalDecomposition): True """ + def _unlift(self, pair): + A,B = pair + R5 = self._vector_space + return ( A[(0,0,1)]*R5((0,0,1)) + + A[(1,0,1)]*R5((1,0,1)) + + A[(1,1,1)]*R5((1,1,1)) + + B[(1,0,1)]*R5((2,0,1)) + + B[(1,1,1)]*R5((2,2,1)) ) + + def _lift(self, v): + M1 = ( self._S2((0,0,1))*v[(0,0,1)] + + self._S2((1,0,1))*v[(1,0,1)] + + self._S2((1,1,1))*v[(1,1,1)] ) + M2 = ( self._S2((0,0,1))*v[(0,0,1)] + + self._S2((1,0,1))*v[(2,0,1)] + + self._S2((1,1,1))*v[(2,2,1)] ) + return (M1,M2) + def __init__(self, scalar_field=QQ, **kwargs): from sage.matrix.matrix_space import MatrixSpace from sage.modules.free_module import VectorSpace @@ -653,36 +671,24 @@ class VinbergClan(NormalDecomposition): (2,2,1) ]) - def unlift(pair): - A,B = pair - return ( A[(0,0,1)]*R5((0,0,1)) + - A[(1,0,1)]*R5((1,0,1)) + - A[(1,1,1)]*R5((1,1,1)) + - B[(1,0,1)]*R5((2,0,1)) + - B[(1,1,1)]*R5((2,2,1)) ) - - def lift(v): - M1 = ( self._S2((0,0,1))*v[(0,0,1)] + - self._S2((1,0,1))*v[(1,0,1)] + - self._S2((1,1,1))*v[(1,1,1)] ) - M2 = ( self._S2((0,0,1))*v[(0,0,1)] + - self._S2((1,0,1))*v[(2,0,1)] + - self._S2((1,1,1))*v[(2,2,1)] ) - return (M1,M2) + # The Clan __init__ does this, but if we do it now then we can + # use the self.lift() and self.unlift() methods to define the + # clan product rather than duplicating them locally. + self._vector_space = R5 def cp(x,y): # up_hat and down_hat need MatrixSpace elements, not # submodules with custom bases, so we need to lift # everything twice. - X1,X2 = lift(x) - Y1,Y2 = lift(y) + X1,X2 = self._lift(x) + Y1,Y2 = self._lift(y) X1 = X1.lift() X2 = X2.lift() Y1 = Y1.lift() Y2 = Y2.lift() Z1 = MatrixClan._down_hat(X1)*Y1 + Y1*MatrixClan._up_hat(X1) Z2 = MatrixClan._down_hat(X2)*Y2 + Y2*MatrixClan._up_hat(X2) - return unlift((self._S2(Z1), self._S2(Z2))) + return self._unlift((self._S2(Z1), self._S2(Z2))) def ip(x,y): two = x.base_ring()(2) -- 2.51.0