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