def __init__(self, V, W, gens=None, modulus=None, modulus_qf=None, check=True): r""" Initialize ``self``. TESTS:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: T = TorsionQuadraticModule(ZZ^3, 6*ZZ^3) sage: TestSuite(T).run() """ if check: if V.rank() != W.rank(): raise ValueError("modules must be of the same rank") if V.base_ring() is not ZZ: raise NotImplementedError("only currently implemented over ZZ") if V.inner_product_matrix() != V.inner_product_matrix().transpose( ): raise ValueError( "the cover must have a symmetric inner product") if gens is not None and V.span(gens) + W != V: raise ValueError("provided gens do not generate the quotient") FGP_Module_class.__init__(self, V, W, check=check) if gens is not None: self._gens_user = tuple(self(v) for v in gens) else: # this is taken care of in the .gens method # we do not want this at initialization self._gens_user = None # compute the modulus - this may be expensive if modulus is None or check: # The inner product of two elements `b(v1+W,v2+W)` # is defined `mod (V,W)` num = V.basis_matrix() * V.inner_product_matrix() * W.basis_matrix( ).T self._modulus = gcd(num.list()) if modulus is not None: if check and self._modulus / modulus not in self.base_ring(): raise ValueError("the modulus must divide (V, W)") self._modulus = modulus if modulus_qf is None or check: # The quadratic_product of an element `q(v+W)` is defined # `\mod 2(V,W) + ZZ\{ (w,w) | w in w\}` norm = gcd(self.W().gram_matrix().diagonal()) self._modulus_qf = gcd(norm, 2 * self._modulus) if modulus_qf is not None: if check and self._modulus_qf / modulus_qf not in self.base_ring(): raise ValueError("the modulus_qf must divide (V, W)") self._modulus_qf = modulus_qf
def __init__(self, cover, relations): r""" EXAMPLES:: sage: G = AdditiveAbelianGroup([0]); G # indirect doctest Additive abelian group isomorphic to Z sage: G == loads(dumps(G)) True """ FGP_Module_class.__init__(self, cover, relations)
def __init__(self, cover, relations): r""" EXAMPLE:: sage: G = AdditiveAbelianGroup([0]); G # indirect doctest Additive abelian group isomorphic to Z sage: G == loads(dumps(G)) True """ FGP_Module_class.__init__(self, cover, relations)
def __init__(self, V, W, gens=None, modulus=None, modulus_qf=None, check=True): r""" Initialize ``self``. TESTS:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: T = TorsionQuadraticModule(ZZ^3, 6*ZZ^3) sage: TestSuite(T).run() """ if check: if V.rank() != W.rank(): raise ValueError("modules must be of the same rank") if V.base_ring() is not ZZ: raise NotImplementedError("only currently implemented over ZZ") if V.inner_product_matrix() != V.inner_product_matrix().transpose(): raise ValueError("the cover must have a symmetric inner product") if gens is not None and V.span(gens) + W != V: raise ValueError("provided gens do not generate the quotient") FGP_Module_class.__init__(self, V, W, check=check) if gens is None: self._gens = FGP_Module_class.gens(self) else: self._gens = [self(v) for v in gens] if modulus is not None: if check: # The inner product of two elements `b(v1+W,v2+W)` is defined `mod (V,W)` num = gcd([x.inner_product(y) for x in V.gens() for y in W.gens()]) if num / modulus not in self.base_ring(): raise ValueError("the modulus must divide (V, W)") self._modulus = modulus else: # The inner product of two elements `b(v1+W,v2+W)` is defined `mod (V,W)` self._modulus = gcd([x.inner_product(y) for x in V.gens() for y in W.gens()]) if modulus_qf is not None: if check: # The quadratic_product of an element `q(v+W)` is defined # `\mod 2(V,W) + ZZ\{ (w,w) | w in w\}` norm = gcd(self.W().gram_matrix().diagonal()) num = gcd(norm, 2 * self._modulus) if num / modulus_qf not in self.base_ring(): raise ValueError("the modulus_qf must divide (V, W)") self._modulus_qf = modulus_qf else: # The quadratic_product of an element `q(v+W)` is defined # `\mod 2(V,W) + ZZ\{ (w,w) | w in w\}` norm = gcd(self.W().gram_matrix().diagonal()) self._modulus_qf = gcd(norm, 2 * self._modulus)
def __init__(self, V, W, gens, modulus, modulus_qf): r""" Initialize ``self``. TESTS:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: T = TorsionQuadraticModule(ZZ^3, 6*ZZ^3) sage: TestSuite(T).run() """ FGP_Module_class.__init__(self, V, W, check=True) if gens is not None: self._gens_user = tuple(self(g) for g in gens) else: # this is taken care of in the .gens method # we do not want this at initialization self._gens_user = None self._modulus = modulus self._modulus_qf = modulus_qf
def submodule(self, x): r""" Return the submodule defined by ``x``. The modulus of the inner product is inherited from ``self``. INPUT: - ``x`` -- list, tuple, or FGP module OUTPUT: - a :class:`TorsionQuadraticModule` EXAMPLES:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ,3,matrix.identity(3)*5) sage: T = TorsionQuadraticModule((1/5)*V, V) sage: T Finite quadratic module over Integer Ring with invariants (5, 5, 5) Gram matrix of the quadratic form with values in Q/Z: [1/5 0 0] [ 0 1/5 0] [ 0 0 1/5] sage: T.submodule(T.gens()[:2]) Finite quadratic module over Integer Ring with invariants (5, 5) Gram matrix of the quadratic form with values in Q/Z: [1/5 0] [ 0 1/5] """ T = FGP_Module_class.submodule(self, x) # We need to explicitly set the _modulus and _modulus_qf # else the modulus might increase. T._modulus = self._modulus T._modulus_qf = self._modulus_qf return T
def __init__(self, V, W, gens=None, modulus=None, modulus_qf=None, check=True): r""" Initialize ``self``. TESTS:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: T = TorsionQuadraticModule(ZZ^3, 6*ZZ^3) sage: TestSuite(T).run() """ if check: if V.rank() != W.rank(): raise ValueError("modules must be of the same rank") if V.base_ring() is not ZZ: raise NotImplementedError("only currently implemented over ZZ") if V.inner_product_matrix() != V.inner_product_matrix().transpose( ): raise ValueError( "the cover must have a symmetric inner product") if gens is not None and V.span(gens) + W != V: raise ValueError("provided gens do not generate the quotient") FGP_Module_class.__init__(self, V, W, check=check) if gens is None: self._gens = FGP_Module_class.gens(self) else: self._gens = [self(v) for v in gens] if modulus is not None: if check: # The inner product of two elements `b(v1+W,v2+W)` is defined `mod (V,W)` num = gcd( [x.inner_product(y) for x in V.gens() for y in W.gens()]) if num / modulus not in self.base_ring(): raise ValueError("the modulus must divide (V, W)") self._modulus = modulus else: # The inner product of two elements `b(v1+W,v2+W)` is defined `mod (V,W)` self._modulus = gcd( [x.inner_product(y) for x in V.gens() for y in W.gens()]) if modulus_qf is not None: if check: # The quadratic_product of an element `q(v+W)` is defined # `\mod 2(V,W) + ZZ\{ (w,w) | w in w\}` norm = gcd(self.W().gram_matrix().diagonal()) num = gcd(norm, 2 * self._modulus) if num / modulus_qf not in self.base_ring(): raise ValueError("the modulus_qf must divide (V, W)") self._modulus_qf = modulus_qf else: # The quadratic_product of an element `q(v+W)` is defined # `\mod 2(V,W) + ZZ\{ (w,w) | w in w\}` norm = gcd(self.W().gram_matrix().diagonal()) self._modulus_qf = gcd(norm, 2 * self._modulus)