def brown_invariant(self): r""" Return the Brown invariant of this torsion quadratic form. Let `(D,q)` be a torsion quadratic module with values in `\QQ / 2 \ZZ`. The Brown invariant `Br(D,q) \in \Zmod{8}` is defined by the equation .. MATH:: \exp \left( \frac{2 \pi i }{8} Br(q)\right) = \frac{1}{\sqrt{D}} \sum_{x \in D} \exp(i \pi q(x)). The Brown invariant is additive with respect to direct sums of torsion quadratic modules. OUTPUT: - an element of `\Zmod{8}` EXAMPLES:: sage: L = IntegralLattice("D4") sage: D = L.discriminant_group() sage: D.brown_invariant() 4 We require the quadratic form to be defined modulo `2 \ZZ`:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ,3,matrix.identity(3)) sage: T = TorsionQuadraticModule((1/10)*V, V) sage: T.brown_invariant() Traceback (most recent call last): ... ValueError: the torsion quadratic form must have values in QQ / 2 ZZ """ if self._modulus_qf != 2: raise ValueError("the torsion quadratic form must have values in " "QQ / 2 ZZ") from sage.quadratic_forms.genera.normal_form import collect_small_blocks brown = IntegerModRing(8).zero() for p in self.annihilator().gen().prime_divisors(): q = self.primary_part(p).normal_form() q = q.gram_matrix_quadratic() L = collect_small_blocks(q) for qi in L: brown += _brown_indecomposable(qi, p) return brown
def brown_invariant(self): r""" Return the Brown invariant of this torsion quadratic form. Let `(D,q)` be a torsion quadratic module with values in `\QQ / 2 \ZZ`. The Brown invariant `Br(D,q) \in \Zmod{8}` is defined by the equation .. MATH:: \exp \left( \frac{2 \pi i }{8} Br(q)\right) = \frac{1}{\sqrt{D}} \sum_{x \in D} \exp(i \pi q(x)). The Brown invariant is additive with respect to direct sums of torsion quadratic modules. OUTPUT: - an element of `\Zmod{8}` EXAMPLES:: sage: L = IntegralLattice("D4") sage: D = L.discriminant_group() sage: D.brown_invariant() 4 We require the quadratic form to be defined modulo `2 \ZZ`:: sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ,3,matrix.identity(3)) sage: T = TorsionQuadraticModule((1/10)*V, V) sage: T.brown_invariant() Traceback (most recent call last): ... ValueError: The torsion quadratic form must have values in\QQ / 2\ZZ """ if self._modulus_qf != 2: raise ValueError("The torsion quadratic form must have values in" "\QQ / 2\ZZ") from sage.quadratic_forms.genera.normal_form import collect_small_blocks brown = IntegerModRing(8).zero() for p in self.annihilator().gen().prime_divisors(): q = self.primary_part(p).normal_form() q = q.gram_matrix_quadratic() L = collect_small_blocks(q) for qi in L: brown += _brown_indecomposable(qi,p) return brown