Source code for flatsurf.geometry.mega_wollmilchsau

# ****************************************************************************
#  This file is part of sage-flatsurf.
#
#       Copyright (C) 2016-2019 Vincent Delecroix
#                     2016-2019 W. Patrick Hooper
#                          2023 Julian Rüth
#
#  sage-flatsurf is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 2 of the License, or
#  (at your option) any later version.
#
#  sage-flatsurf is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with sage-flatsurf. If not, see <https://www.gnu.org/licenses/>.
# ****************************************************************************
from sage.groups.group import Group
from sage.categories.groups import Groups
from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.element import MultiplicativeGroupElement
from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra
from sage.rings.integer_ring import ZZ

from flatsurf.geometry.origami import AbstractOrigami

_Q = QuaternionAlgebra(-1, -1)
_i, _j, _k = _Q.gens()


[docs] class MegaWollmilchsauGroupElement(MultiplicativeGroupElement):
[docs] @staticmethod def quat_to_tuple(r): r"""Convert an element in the quaternion algebra to a quadruple""" if isinstance(r, int): return (r, 0, 0, 0) else: return (r[0], r[1], r[2], r[3])
[docs] @staticmethod def wedge(r1, r2): r"""Wedge two quaterions. Returns an integer.""" x = MegaWollmilchsauGroupElement.quat_to_tuple(r1) y = MegaWollmilchsauGroupElement.quat_to_tuple(r2) return -x[0] * y[3] + x[1] * y[2] - x[2] * y[1] + x[3] * y[0]
def __init__(self, parent, i, r, q): if parent is None: raise ValueError("The parent must be provided") # I should assert that the element lives in the domain of the group. if i not in ZZ: raise ValueError if r not in _Q: raise ValueError # Actually q should be in {1,-1,-i,i,j,-j,k,-k}. I'm not testing for that. if q not in _Q: raise ValueError # There is one more condition. The group doesn't have full image... self._i = i self._r = r self._q = q self._parent = parent MultiplicativeGroupElement.__init__(self, parent) def _repr_(self): return "[" + str(self._i) + ", " + str(self._r) + ", " + str(self._q) + "]" def _cmp_(self, other): return ( (self._i > other._i - self._i < other._i) or (self._r > other._r - self._r < other._r) or (self._q > other._q - self._q < other._q) ) def _mul_(self, m): return MegaWollmilchsauGroupElement( self._parent, self._i + m._i + MegaWollmilchsauGroupElement.wedge(self._r, self._q * m._r), self._r + self._q * m._r, self._q * m._q, ) def __invert__(self): q1 = ~self._q r1 = -(q1 * self._r) i1 = -(self._i + MegaWollmilchsauGroupElement.wedge(r1, q1 * self._r)) return MegaWollmilchsauGroupElement(self._parent, i1, r1, q1) def _div_(self, m): return self._mul_(m.__invert__()) def __hash__(self): return ( 67 * hash(self._i) + 23 * hash(MegaWollmilchsauGroupElement.quat_to_tuple(self._r)) - 17 * hash(MegaWollmilchsauGroupElement.quat_to_tuple(self._q)) )
[docs] class MegaWollmilchsauGroup(UniqueRepresentation, Group): Element = MegaWollmilchsauGroupElement def _element_constructor_(self, *args, **kwds): if len(args) != 1: return self.element_class(self, *args, **kwds) x = args[0] return self.element_class(self, x, **kwds) def __init__(self): Group.__init__(self, category=Groups().Infinite()) def _repr_(self): return "MegaWollmilchsauGroup"
[docs] def a(self): return self.element_class(self, 0, 1, _i)
[docs] def b(self): return self.element_class(self, 0, 1, _j)
[docs] def one(self): return self.element_class(self, 0, 0, 1)
[docs] def gens(self): return (self.a(), self.b())
[docs] def is_abelian(self): return False
def _an_element_(self): return self.a()
[docs] def some_elements(self): return [self.a(), self.b()]
def _test_relations(self, **options): tester = self._tester(**options) a, b = self.gens() e = self.one() tester.assertEqual(a**4, e) tester.assertEqual(b**4, e) tester.assertEqual((a * b) ** 4, e) tester.assertEqual((a / b) ** 4, e) tester.assertEqual((a * a * b) ** 4, e) tester.assertEqual((a * a / b) ** 4, e) tester.assertNotEqual((a * b / a / b) ** 2, e)
[docs] class MegaWollmilchsau(AbstractOrigami): def __init__(self): self._G = self._domain = MegaWollmilchsauGroup() self._a, self._b = self._G.gens() self._ai = ~self._a self._bi = ~self._b
[docs] def up(self, label): return self._b * label
[docs] def down(self, label): return self._bi * label
[docs] def right(self, label): return self._a * label
[docs] def left(self, label): return self._ai * label
def _repr_(self): return "MegaWollmilchsau Origami"