def is_hyperbolic(self, p): r""" Check if the quadratic form is a sum of hyperbolic planes over the `p`-adic numbers `\QQ_p` or over the real numbers `\RR`. REFERENCES: This criteria follows from Cassels's "Rational Quadratic Forms": - local invariants for hyperbolic plane (Lemma 2.4, p58) - direct sum formulas (Lemma 2.3, p58) INPUT: - `p` -- a prime number > 0 or `-1` for the infinite place OUTPUT: boolean EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) sage: Q.is_hyperbolic(-1) False sage: Q.is_hyperbolic(2) False sage: Q.is_hyperbolic(3) False sage: Q.is_hyperbolic(5) ## Here -1 is a square, so it's true. True sage: Q.is_hyperbolic(7) False sage: Q.is_hyperbolic(13) ## Here -1 is a square, so it's true. True """ ## False for odd-dim'l forms if self.dim() % 2: return False ## True for the zero form if not self.dim(): return True ## Compare local invariants ## Note: since the dimension is even, the extra powers of 2 in ## self.det() := Det(2*Q) don't affect the answer! m = ZZ(self.dim() // 2) if p == -1: return self.signature() == 0 if p == 2: return (QQ(self.det() * (-1)**m).is_padic_square(p) and self.hasse_invariant(p) == (-1)**m.binomial(2) ) # here -1 is hilbert_symbol(-1,-1,2) return (QQ(self.det() * (-1)**m).is_padic_square(p) and self.hasse_invariant(p) == 1)
def is_hyperbolic(self, p): r""" Check if the quadratic form is a sum of hyperbolic planes over the `p`-adic numbers `\QQ_p` or over the real numbers `\RR`. REFERENCES: This criteria follows from Cassels's "Rational Quadratic Forms": - local invariants for hyperbolic plane (Lemma 2.4, p58) - direct sum formulas (Lemma 2.3, p58) INPUT: - `p` -- a prime number > 0 or `-1` for the infinite place OUTPUT: boolean EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) sage: Q.is_hyperbolic(-1) False sage: Q.is_hyperbolic(2) False sage: Q.is_hyperbolic(3) False sage: Q.is_hyperbolic(5) ## Here -1 is a square, so it's true. True sage: Q.is_hyperbolic(7) False sage: Q.is_hyperbolic(13) ## Here -1 is a square, so it's true. True """ ## False for odd-dim'l forms if self.dim() % 2: return False ## True for the zero form if not self.dim(): return True ## Compare local invariants ## Note: since the dimension is even, the extra powers of 2 in ## self.det() := Det(2*Q) don't affect the answer! m = ZZ(self.dim() // 2) if p == -1: return self.signature() == 0 if p == 2: return (QQ(self.det() * (-1) ** m).is_padic_square(p) and self.hasse_invariant(p) == (-1) ** m.binomial(2)) # here -1 is hilbert_symbol(-1,-1,2) return (QQ(self.det() * (-1) ** m).is_padic_square(p) and self.hasse_invariant(p) == 1)