1 from __future__
import division
22 A class of number field. 24 def __init__(self, polynomial, precompute=False):
26 Initialize a number field with given polynomial coefficients 29 ring.Field.__init__(self)
39 return_str =
'%s(%s)' % (self.__class__.__name__, self.
polynomial)
44 Output composite field of self and other. 46 common_options = {
"coeffring": rational.theIntegerRing,
47 "number_of_variables": 2}
48 flist = [((d, 0), c)
for (d, c)
in enumerate(self.
polynomial)]
49 f = multiutil.polynomial(flist, **common_options)
50 g =
zpoly(other.polynomial)
51 diff = multiutil.polynomial({(1, 0): 1, (0, 1):-1}, **common_options)
52 compos = f.resultant(g(diff), 0)
57 Return (approximate) solutions of self.polynomial. 58 We can discriminate the conjugate field of self by these values. 60 if not hasattr(self,
"conj"):
67 Compute the discriminant of self.polynomial. 68 (The output is not field disc of self but disc of self.polynomial.) 71 Obasis, disc = round2.round2(self) 72 A = [algfield.MatAlgNumber(obasis[0][i]) for i in range(degree)] 73 return disc(A) <--- real disc of self field. 76 if not hasattr(self,
"poldisc"):
79 for i
in range(degree):
80 for j
in range(degree):
82 traces.append(s.trace())
89 Return the integer ring of self (using round2 module) 91 if not hasattr(self,
"integer_basis"):
100 Return the (field) discriminant of self (using round2 module) 102 if not hasattr(self,
"discriminant"):
111 Return the j-th basis of self. 119 Using Strum's algorithm, compute the signature of self. 120 Algorithm 4.1.11 in Cohen's Book 122 if not hasattr(self,
"sign"):
130 d_minpoly = minpoly.differentiate()
131 A = minpoly.primitive_part()
132 B = d_minpoly.primitive_part()
135 pos_at_inf = A.leading_coefficient() > 0
136 pos_at_neg = pos_at_inf == (degree & 1)
141 deg = A.degree() - B.degree()
142 residue = A.pseudo_mod(B)
144 raise ValueError(
"not squarefree")
145 if B.leading_coefficient() > 0
or deg & 1:
148 degree_res = residue.degree()
149 pos_at_inf_of_res = residue.leading_coefficient() > 0
151 if pos_at_inf_of_res != pos_at_inf:
152 pos_at_inf =
not pos_at_inf
155 if pos_at_inf_of_res != (pos_at_neg == (degree_res & 1 == 0)):
156 pos_at_neg =
not pos_at_neg
161 return (r_1, (degree - r_1) >> 1)
163 A, B = B, residue.scalar_exact_division(g*(h**deg))
164 g = abs(A.leading_coefficient())
168 h = g**deg // h**(deg - 1)
173 Given a polynomial f i.e. a field self, output some polynomials 174 defining subfield of self, where self is a field defined by f. 175 Algorithm 4.4.11 in Cohen's book. 185 BaseList.append(AlgInt)
192 s = BaseList[i]*BaseList[j]
193 traces.append(s.trace())
198 f.append(
zpoly(Basis[i]))
203 m += f[i](sigma[k])*f[j](sigma[k].conjugate())
204 traces.append(m.real)
207 M = matrix.createMatrix(n, n, traces)
208 S = matrix.unitMatrix(n)
209 L = lattice.LLL(S, M)[0]
217 base_cor += BaseList[v]*L.compo[v][i]
218 Ch_Basis.append(base_cor)
223 coeff = Ch_Basis[i].ch_basic().getCharPoly()
224 C.append(
zpoly(coeff))
229 diff_C = C[i].differentiate()
230 gcd_C = C[i].subresultant_gcd(diff_C)
237 Determine whether self.basis is integral basis of self field. 240 if squarefree.trial_division(abs(D)):
244 if squarefree.trial_division(abs(D) >> 2)
and (D >> 2) & 3 != 1:
251 Determine whether self/other is Galois field. 254 return "Can not determined" 260 Determine whether A is field element of self field or not. 273 Return characteristic of the field (it is always zero). 279 createElement returns an element of the field with seed. 282 if isinstance(seed[0], list):
283 if isinstance(seed[0][0], list):
288 raise NotImplementedError
290 raise NotImplementedError
294 Report whether another ring contains the field as a subring. 296 if self
is other
or self.isSubField(other):
298 raise NotImplementedError(
"don't know how to tell")
302 Report whether the field is a superring of another ring. 306 elif other.issubring(rational.theRationalField):
308 raise NotImplementedError(
"don't know how to tell")
319 raise NotImplementedError
324 if self.
_one is None:
329 one = property(_getOne,
None,
None,
"multiplicative unit.")
333 if self.
_zero is None:
338 zero = property(_getZero,
None,
None,
"additive unit.")
343 The class for algebraic number. 345 def __init__(self, valuelist, polynomial, precompute=False):
346 if len(polynomial) != len(valuelist[0])+1:
354 Gcd = gcd.gcd_of_list(self.
coeff)
355 GCD = gcd.gcd(Gcd[0], self.
denom)
365 return_str =
'%s(%s, %s)' % (self.__class__.__name__, [self.
coeff, self.
denom], self.
polynomial)
371 coeff.append(-self.
coeff[i])
376 other (integer) -> BasicAlgNumber (over self.field) 383 other (rational) -> BasicAlgNumber (over self.field) 389 if isinstance(other, BasicAlgNumber):
390 d = self.
denom*other.denom
394 other.denom*self.
coeff[i] + self.
denom*other.coeff[i])
396 elif isinstance(other, (int, long)):
401 return NotImplemented
409 if isinstance(other, BasicAlgNumber):
410 d = self.
denom*other.denom
413 h =
zpoly(other.coeff)
414 j = (g * h).pseudo_mod(f)
417 elif isinstance(other, (int, long)):
418 Coeff = [i*other
for i
in self.
coeff]
421 GCD = gcd.gcd(other.numerator, self.
denom)
422 denom = self.
denom * other.denominator
423 mul = other.numerator
430 return NotImplemented
435 d = self.
denom**exponent
439 j = pow(g, exponent, f)
441 j = pow(g, exponent, f) % mod
458 denom_list.append(icoeff[i].denominator)
461 new_denom = gcd.lcm(new_denom, denom_list[i])
462 icoeff = [icoeff[i].numerator * new_denom // icoeff[i].denominator
for i
in range(self.
degree)]
471 d = self.
denom * k.denom
472 j = (g * h).monic_mod(f)
476 __div__ = __truediv__
477 __floordiv__ = __truediv__
481 Return (approximate) solutions of self.polynomial. 482 We can discriminate the conjugate field of self by these values. 484 if not hasattr(self,
"conj"):
490 Return the approximations of all conjugates of self. 492 if not hasattr(self,
"approx"):
504 Return the characteristic polynomial of self 505 by compute products of (x-self^{(i)}). 507 if not hasattr(self,
"charpoly"):
509 P = uniutil.polynomial({0:-Conj[0], 1:1}, ring.getRing(Conj[0]))
511 P *= uniutil.polynomial({0:-Conj[i], 1:1},
512 ring.getRing(Conj[i]))
515 if hasattr(P[i],
"real"):
516 charcoeff.append(int(math.floor(P[i].real + 0.5)))
518 charcoeff.append(int(math.floor(P[i] + 0.5)))
524 Return the algebraic number field contained self. 530 Compute the trace of self in K. 536 for k
in range(1, n):
538 for i
in range(1, k):
543 for j
in range(len(tlist)):
544 t += tlist[j] * self.
coeff[j]
555 Compute the norm of self in K. 565 if isinstance(R, int):
575 Determine whether self is an algebraic integer or not. 578 if isinstance(Norm, int):
585 Change style to MatAlgNumber. 597 The class for algebraic number represented by matrix. 606 stbasis = [0] * self.
degree 609 List.append([- polynomial[i]
for i
in range(self.
degree)])
617 basis1.append(List[l + self.
degree][j])
618 elif j == self.
degree - 1:
619 basis2 = [List[l + self.
degree][j] * - polynomial[k]
for k
in range(self.
degree)]
621 basis.append(basis1[i] + basis2[i])
628 basis3.append([self.
coeff[j] * k
for k
in List[j+flag]])
647 for i
in range(mat.row):
648 coeff.append(mat[0][i])
655 elif not isinstance(other, MatAlgNumber):
656 return NotImplemented
657 mat = self.
matrix + other.matrix
659 for i
in range(mat.row):
660 coeff.append(mat[i+1][1])
669 elif not isinstance(other, MatAlgNumber):
670 return NotImplemented
671 mat = self.
matrix - other.matrix
673 for i
in range(mat.row):
674 coeff.append(mat[i+1][1])
678 if isinstance(other, MatAlgNumber):
679 mat = self.
matrix * other.matrix
683 return NotImplemented
685 for i
in range(mat.row):
686 coeff.append(mat[i+1][1])
694 elif not isinstance(other, MatAlgNumber):
695 return NotImplemented
696 other_mat = other.matrix.copy()
697 other_mat.toFieldMatrix()
698 mat = other_mat.inverse(self.
matrix)
700 for i
in range(mat.row):
701 coeff.append(mat[i+1][1])
704 __div__ = __truediv__
705 __floordiv__ = __truediv__
708 mat = self.
matrix ** other
710 for i
in range(mat.row):
711 coeff.append(mat[i+1][1])
715 (self.
matrix).toFieldMatrix()
718 for i
in range(inv.row):
719 coeff.append(inv[i+1][1])
723 return (self.
matrix).determinant()
730 Return the algebraic number field contained self. 737 if not isinstance(self.
coeff[i], int):
738 denom *= gcd.lcm(denom, (self.
coeff[i]).denominator)
741 if isinstance(self.
coeff[i], int):
742 coeff.append(self.
coeff[i] * denom)
744 coeff.append(int((self.
coeff[i]).numerator * denom / (self.
coeff[i]).denominator))
749 Return prime decomposition of (p) over Q[x]/(polynomial). 752 field_disc = field.field_discriminant()
753 if (field.disc() // field_disc) % p != 0:
760 prime decomposition by factoring polynomial 767 if len(factor) == 1
and factor[0][1] == 1:
768 return [(p_alg , 1 )]
771 for i
in range(len(factor)):
774 if factor[i][0][j] == 0:
777 basis_list.append(factor[i][0][j].toInteger())
780 return [( (p_alg, dlist_ele[0]), dlist_ele[1] )
for dlist_ele
in dlist]
784 main step of prime decomposition 787 raise NotImplementedError
791 Change 'a' to be an element of field K defined polynomial 793 if isinstance(a, (int, long)):
794 coeff = [a] + [0] * (len(polynomial) - 2)
797 coeff = [a.numerator] + [0] * (len(polynomial) - 2)
801 coeff = [0, 1] + [0] * (deg - 2)
803 polynomial = [a[-2], 1]
805 for j
in range(deg - 2, -1, -1):
806 polynomial.insert(0, a[j] * mul)
814 Compute the discriminant of a_i, where A=[a_1,...,a_n] 821 list.append(s.trace())
822 M = matrix.createMatrix(n, n, list)
823 return M.determinant()
827 Return a rational coefficient polynomial constructed from given 828 coeffs. The coeffs is a list of coefficients in ascending order. 831 return uniutil.polynomial(terms, rational.theRationalField)
835 Return an integer coefficient polynomial constructed from given 836 coeffs. The coeffs is a list of coefficients in ascending order. 838 return uniutil.polynomial(enumerate(coeffs), rational.theIntegerRing)
842 Return a Z_p coefficient polynomial constructed from given 843 coeffs. The coeffs is a list of coefficients in ascending order.