| 1 | """ |
|---|
| 2 | Database of Hilbert Polynomials |
|---|
| 3 | """ |
|---|
| 4 | |
|---|
| 5 | ####################################################################### |
|---|
| 6 | |
|---|
| 7 | # Sage: System for Algebra and Geometry Experimentation |
|---|
| 8 | # |
|---|
| 9 | # Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu.au> |
|---|
| 10 | # |
|---|
| 11 | # Distributed under the terms of the GNU General Public License (GPL) |
|---|
| 12 | # |
|---|
| 13 | # The full text of the GPL is available at: |
|---|
| 14 | # |
|---|
| 15 | # http://www.gnu.org/licenses/ |
|---|
| 16 | ####################################################################### |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | import bz2, os |
|---|
| 20 | import sage.misc.misc |
|---|
| 21 | from sage.rings.integer import Integer |
|---|
| 22 | from sage.rings.integer_ring import IntegerRing |
|---|
| 23 | from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing |
|---|
| 24 | |
|---|
| 25 | dblocation = '%s/kohel'%sage.misc.misc.SAGE_DATA |
|---|
| 26 | |
|---|
| 27 | disc_length = 7 |
|---|
| 28 | level_length = 3 |
|---|
| 29 | |
|---|
| 30 | def _dbz_to_integers(name): |
|---|
| 31 | file = '%s/%s'%(dblocation, name) |
|---|
| 32 | if not os.path.exists(file): |
|---|
| 33 | raise RuntimeError, "Class polynomial database file %s not available"%file |
|---|
| 34 | data = bz2.decompress(open(file).read()) |
|---|
| 35 | data = "[" + data.replace("\n",",") + "]" |
|---|
| 36 | return eval(data) |
|---|
| 37 | |
|---|
| 38 | def _pad_int_str(s,n): |
|---|
| 39 | return "0"*(n-len(str(s))) + str(s) |
|---|
| 40 | |
|---|
| 41 | class ClassPolynomialDatabase: |
|---|
| 42 | def _dbpath(self,disc,level=1): |
|---|
| 43 | """ |
|---|
| 44 | TESTS: |
|---|
| 45 | sage: db = HilbertClassPolynomialDatabase() |
|---|
| 46 | sage: db.__getitem__(-23,level=2) |
|---|
| 47 | Traceback (most recent call last): |
|---|
| 48 | ... |
|---|
| 49 | NotImplementedError: Level (= 2) > 1 not yet implemented. |
|---|
| 50 | """ |
|---|
| 51 | if level != 1: |
|---|
| 52 | raise NotImplementedError, "Level (= %s) > 1 not yet implemented."%level |
|---|
| 53 | n1 = 5000*((abs(disc)-1)//5000) |
|---|
| 54 | s1 = _pad_int_str(n1+1,disc_length) |
|---|
| 55 | s2 = _pad_int_str(n1+5000,disc_length) |
|---|
| 56 | subdir = "%s-%s"%(s1,s2) |
|---|
| 57 | discstr = _pad_int_str(abs(disc),disc_length) |
|---|
| 58 | return "PolHeeg/%s/%s/pol.%s.dbz"%(self.model,subdir,discstr) |
|---|
| 59 | |
|---|
| 60 | def __getitem__(self,disc,level=1,var='x'): |
|---|
| 61 | classpol = self._dbpath(disc,level) |
|---|
| 62 | try: |
|---|
| 63 | coeff_list = _dbz_to_integers(classpol) |
|---|
| 64 | except RuntimeError, msg: |
|---|
| 65 | print msg |
|---|
| 66 | raise RuntimeError, \ |
|---|
| 67 | "No database entry for class polynomial of discriminant %s"%disc |
|---|
| 68 | P = PolynomialRing(IntegerRing(),names=var) |
|---|
| 69 | return P(list(coeff_list)) |
|---|
| 70 | |
|---|
| 71 | class HilbertClassPolynomialDatabase(ClassPolynomialDatabase): |
|---|
| 72 | """ |
|---|
| 73 | The database of Hilbert class polynomials. |
|---|
| 74 | |
|---|
| 75 | EXAMPLES: |
|---|
| 76 | sage: db = HilbertClassPolynomialDatabase() |
|---|
| 77 | sage: db[-4] # optional Kohel database required |
|---|
| 78 | x - 1728 |
|---|
| 79 | sage: db[-7] # optional |
|---|
| 80 | x + 3375 |
|---|
| 81 | sage: f = db[-23]; f # optional |
|---|
| 82 | x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 |
|---|
| 83 | sage: f.discriminant().factor() # optional |
|---|
| 84 | -1 * 5^18 * 7^12 * 11^4 * 17^2 * 19^2 * 23 |
|---|
| 85 | sage: db[-23] # optional |
|---|
| 86 | x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 |
|---|
| 87 | """ |
|---|
| 88 | def __init__(self): |
|---|
| 89 | """ |
|---|
| 90 | Initialize the database. |
|---|
| 91 | """ |
|---|
| 92 | self.model = "Cls" |
|---|
| 93 | |
|---|
| 94 | def __repr__(self): |
|---|
| 95 | return "Hilbert class polynomial database" |
|---|
| 96 | |
|---|
| 97 | ###################################################### |
|---|
| 98 | # None of the following are implemented yet. |
|---|
| 99 | ###################################################### |
|---|
| 100 | |
|---|
| 101 | class AtkinClassPolynomialDatabase(ClassPolynomialDatabase): |
|---|
| 102 | """ |
|---|
| 103 | The database of Atkin class polynomials. |
|---|
| 104 | """ |
|---|
| 105 | def __repr__(self): |
|---|
| 106 | return "Atkin class polynomial database" |
|---|
| 107 | |
|---|
| 108 | class WeberClassPolynomialDatabase(ClassPolynomialDatabase): |
|---|
| 109 | """ |
|---|
| 110 | The database of Weber class polynomials. |
|---|
| 111 | """ |
|---|
| 112 | def __repr__(self): |
|---|
| 113 | return "Weber class polynomial database" |
|---|
| 114 | |
|---|
| 115 | class DedekindEtaClassPolynomialDatabase(ClassPolynomialDatabase): |
|---|
| 116 | """ |
|---|
| 117 | The database of Dedekind eta class polynomials. |
|---|
| 118 | """ |
|---|
| 119 | def __repr__(self): |
|---|
| 120 | return "Dedekind eta class polynomial database" |
|---|