| 6299 | def hilbert_symbol(self, a, b, P = None): |
| 6300 | r""" |
| 6301 | Returns the Hilbert symbol `(a,b)_P` for a prime P of self |
| 6302 | and non-zero elements a and b of self. |
| 6303 | If P is omitted, return the global Hilbert symbol `(a,b)` instead. |
| 6304 | |
| 6305 | INPUT: |
| 6306 | |
| 6307 | - ``a, b`` -- elements of self |
| 6308 | - ``P`` -- prime ideal of self |
| 6309 | |
| 6310 | OUTPUT: |
| 6311 | |
| 6312 | If a or b is zero, returns 0. |
| 6313 | |
| 6314 | If a and b are non-zero and P is specified, returns |
| 6315 | the Hilbert symbol `(a,b)_P`, which is 1 if the equation |
| 6316 | `a x^2 + b y^2 = 1` has a solution in the completion of |
| 6317 | self at P, and is -1 otherwise. |
| 6318 | |
| 6319 | If a and b are non-zero and P is unspecified, returns 1 |
| 6320 | if the equation has a solution in self and -1 otherwise. |
| 6321 | |
| 6322 | EXAMPLES:: |
| 6323 | |
| 6324 | sage: K.<a> = NumberField(x^2 - 23) |
| 6325 | sage: O = K.maximal_order() |
| 6326 | sage: K.hilbert_symbol(a, a+5, 5*O) |
| 6327 | 1 |
| 6328 | sage: K.hilbert_symbol(a+1, 13, (-a-6)*O) |
| 6329 | -1 |
| 6330 | sage: [emb1, emb2] = K.embeddings(AA) |
| 6331 | sage: K.hilbert_symbol(a, -1, emb1) |
| 6332 | -1 |
| 6333 | sage: K.hilbert_symbol(a, -1, emb2) |
| 6334 | 1 |
| 6335 | |
| 6336 | Principal ideals P can be given by generators:: |
| 6337 | |
| 6338 | sage: K.<a> = NumberField(x^5 - 23) |
| 6339 | sage: pi = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11 |
| 6340 | sage: K.hilbert_symbol(a, a+5, pi) |
| 6341 | 1 |
| 6342 | sage: rho = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11 |
| 6343 | sage: K.hilbert_symbol(a, a+5, rho) |
| 6344 | 1 |
| 6345 | |
| 6346 | Primes above 2:: |
| 6347 | |
| 6348 | sage: K.<a> = NumberField(x^5 - 23) |
| 6349 | sage: O = K.maximal_order() |
| 6350 | sage: p = [p[0] for p in (2*O).factor() if p[0].norm() == 16][0] |
| 6351 | sage: K.hilbert_symbol(a, a+5, p) |
| 6352 | 1 |
| 6353 | sage: K.hilbert_symbol(a, 2, p) |
| 6354 | 1 |
| 6355 | sage: K.hilbert_symbol(-1, a-2, p) |
| 6356 | -1 |
| 6357 | |
| 6358 | Various real fields are allowed:: |
| 6359 | |
| 6360 | sage: K.<a> = NumberField(x^3+x+1) |
| 6361 | sage: K.hilbert_symbol(a/3, 1/2, K.embeddings(RDF)[0]) |
| 6362 | 1 |
| 6363 | sage: K.hilbert_symbol(a/5, -1, K.embeddings(RR)[0]) |
| 6364 | -1 |
| 6365 | sage: [K.hilbert_symbol(a, -1, e) for e in K.embeddings(AA)] |
| 6366 | [-1] |
| 6367 | |
| 6368 | Real embeddings are not allowed to be disguised as complex embeddings:: |
| 6369 | |
| 6370 | sage: K.<a> = QuadraticField(5) |
| 6371 | sage: K.hilbert_symbol(-1, -1, K.embeddings(CC)[0]) |
| 6372 | Traceback (most recent call last): |
| 6373 | ... |
| 6374 | ValueError: Possibly real place (=Ring morphism: |
| 6375 | From: Number Field in a with defining polynomial x^2 - 5 |
| 6376 | To: Complex Field with 53 bits of precision |
| 6377 | Defn: a |--> -2.23606797749979) given as complex embedding in hilbert_symbol. Is it real or complex? |
| 6378 | sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0]) |
| 6379 | Traceback (most recent call last): |
| 6380 | ... |
| 6381 | ValueError: Possibly real place (=Ring morphism: |
| 6382 | From: Number Field in a with defining polynomial x^2 - 5 |
| 6383 | To: Algebraic Field |
| 6384 | Defn: a |--> -2.236067977499790?) given as complex embedding in hilbert_symbol. Is it real or complex? |
| 6385 | sage: K.<b> = QuadraticField(-5) |
| 6386 | sage: K.hilbert_symbol(-1, -1, K.embeddings(CDF)[0]) |
| 6387 | 1 |
| 6388 | sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0]) |
| 6389 | 1 |
| 6390 | |
| 6391 | a and b do not have to be integral or coprime:: |
| 6392 | |
| 6393 | sage: K.<i> = QuadraticField(-1) |
| 6394 | sage: O = K.maximal_order() |
| 6395 | sage: K.hilbert_symbol(1/2, 1/6, 3*O) |
| 6396 | 1 |
| 6397 | sage: p = 1+i |
| 6398 | sage: K.hilbert_symbol(p,p,p*O) |
| 6399 | -1 |
| 6400 | sage: K.hilbert_symbol(1/3, 1/5, 1+i) |
| 6401 | 1 |
| 6402 | sage: L = QuadraticField(5, 'a') |
| 6403 | sage: L.hilbert_symbol(-3, -1/2, 2) |
| 6404 | 1 |
| 6405 | |
| 6406 | a non-principal ideal P:: |
| 6407 | |
| 6408 | sage: K.<a> = QuadraticField(-5) |
| 6409 | sage: P = K.ideal(3).factor()[0][0] |
| 6410 | sage: P.is_principal() |
| 6411 | False |
| 6412 | sage: K.hilbert_symbol(a, a+3, P) |
| 6413 | 1 |
| 6414 | |
| 6415 | Various other examples:: |
| 6416 | |
| 6417 | sage: K.<a> = NumberField(x^3+x+1) |
| 6418 | sage: K.hilbert_symbol(-6912, 24, -a^2-a-2) |
| 6419 | 1 |
| 6420 | sage: K.<a> = NumberField(x^5-23) |
| 6421 | sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853) |
| 6422 | sage: Q = K.ideal(-7*a^4 + 13*a^3 - 13*a^2 - 2*a + 50) |
| 6423 | sage: b = -a+5 |
| 6424 | sage: K.hilbert_symbol(a,b,P) |
| 6425 | -1 |
| 6426 | sage: K.hilbert_symbol(a,b,Q) |
| 6427 | 1 |
| 6428 | sage: K.<a> = NumberField(x^5-23) |
| 6429 | sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853) |
| 6430 | sage: b = a+5 |
| 6431 | sage: K.hilbert_symbol(a, b, P) |
| 6432 | -1 |
| 6433 | sage: K.hilbert_symbol(a, 2, P) |
| 6434 | -1 |
| 6435 | sage: K.hilbert_symbol(a+5, 2, P) |
| 6436 | -1 |
| 6437 | |
| 6438 | AUTHOR: |
| 6439 | |
| 6440 | - Aly Deines (2010-08-19): part of the doctests |
| 6441 | |
| 6442 | - Marco Streng (2010-12-06) |
| 6443 | """ |
| 6444 | if a == 0 or b == 0: |
| 6445 | return ZZ(0) |
| 6446 | if P != None: |
| 6447 | if sage.rings.all.is_RingHomomorphism(P): |
| 6448 | if not P.domain() == self: |
| 6449 | raise ValueError, "Domain of P (=%s) should be self (=%s) in self.hilbert_symbol" % (P, self) |
| 6450 | codom = P.codomain() |
| 6451 | one = ZZ(1) |
| 6452 | from sage.rings.all import (is_ComplexField, AA, CDF, QQbar, |
| 6453 | is_ComplexIntervalField, is_RealField, |
| 6454 | is_RealIntervalField, RDF) |
| 6455 | if is_ComplexField(codom) or is_ComplexIntervalField(codom) or \ |
| 6456 | codom is CDF or codom is QQbar: |
| 6457 | if P(self.gen()).imag() == 0: |
| 6458 | raise ValueError, "Possibly real place (=%s) given as complex embedding in hilbert_symbol. Is it real or complex?" % P |
| 6459 | return one |
| 6460 | if is_RealField(codom) or codom is RDF or codom is AA: |
| 6461 | if P(a) > 0 or P(b) > 0: |
| 6462 | return one |
| 6463 | return -one |
| 6464 | if P in self: |
| 6465 | P = P*self.maximal_order() |
| 6466 | if not is_NumberFieldIdeal(P): |
| 6467 | raise ValueError, "P (=%s) should be an ideal or real or complex embedding in hilbert_symbol" % str(P) |
| 6468 | if not P.number_field() == self: |
| 6469 | raise ValueError, "P (=%s) should be an ideal of self (=%s) in hilbert_symbol, not of %s" % (P, self, P.number_field()) |
| 6470 | if not P.is_prime(): |
| 6471 | raise ValueError, "Non-prime ideal P (=%s) in hilbert_symbol" % P |
| 6472 | k = pari(self) |
| 6473 | if P != None: |
| 6474 | P = k.idealfactor(pari(P))[0,0] |
| 6475 | a = pari(self(a)) |
| 6476 | b = pari(self(b)) |
| 6477 | return ZZ(pari(self).nfhilbert(a, b, P)) |
| 6478 | |
| 6479 | |
| 6480 | |