Ticket #13376: smalljac-4.0.23.patch
File smalljac-4.0.23.patch, 84.4 KB (added by , 9 years ago) |
---|
-
module_list.py
# HG changeset patch # User Pavel Panchekha <me@pavpanchekha.com> # Date 1362951771 14400 # Node ID 3259d69fe5bcd65e01ed73bf8215c091b3f14a74 # Parent ec1fb07db6e23f9fbd4c34f0d48198d08ec76473 [mq]: current diff --git a/module_list.py b/module_list.py
a b 1992 1992 libraries = ["lrcalc"], 1993 1993 depends = [SAGE_LOCAL + "/include/lrcalc/symfcn.h"]), # should include all .h 1994 1994 ) 1995 1996 if is_package_installed('smalljac'): 1997 ext_modules.append( 1998 Extension('sage.libs.smalljac.wrapper2', 1999 sources = ["sage/libs/smalljac/wrapper2.pyx"], 2000 libraries = ["gmp", "m", "smalljac", "ff_poly"]) 2001 ) -
new file sage/libs/smalljac/__init__.py
diff --git a/sage/libs/smalljac/__init__.py b/sage/libs/smalljac/__init__.py new file mode 100644
- + 1 # smalljac -- Drew Sutherland's code for point counting on Jacobians of curves over finite fields 2 # This file is only here to make this directory a Python package -
new file sage/libs/smalljac/all.py
diff --git a/sage/libs/smalljac/all.py b/sage/libs/smalljac/all.py new file mode 100644
- + 1 """ 2 A wrapper module to import the SmallJac class from the Cython Smalljac interface 3 """ 4 5 from wrapper2 import SmallJac -
new file sage/libs/smalljac/defs.pxd
diff --git a/sage/libs/smalljac/defs.pxd b/sage/libs/smalljac/defs.pxd new file mode 100644
- + 1 cdef extern from "smalljac.h": 2 ctypedef void *smalljac_curve_t 3 4 smalljac_curve_t smalljac_curve_init (char *str, int *err) 5 void smalljac_curve_clear (smalljac_curve_t c) 6 char *smalljac_curve_str (smalljac_curve_t c) 7 int smalljac_curve_genus (smalljac_curve_t c) 8 char *smalljac_curve_nf (smalljac_curve_t c) 9 char *smalljac_curve_cm (smalljac_curve_t c) 10 11 long smalljac_Lpolys (smalljac_curve_t c, 12 unsigned long start, 13 unsigned long end, 14 unsigned long flags, 15 int (*callback)(smalljac_curve_t c, unsigned long q, int good, long a[], int n, void *arg), 16 void *arg) 17 long smalljac_parallel_Lpolys (smalljac_curve_t c, 18 unsigned long start, 19 unsigned long end, 20 unsigned long flags, 21 int (*callback)(smalljac_curve_t c, unsigned long q, int good, long a[], int n, void *arg), 22 void *arg) 23 int smalljac_Lpoly (long a[], char *curve_str, unsigned long q, unsigned long flags) 24 25 long smalljac_groups (smalljac_curve_t curve, 26 unsigned long start, 27 unsigned long end, 28 unsigned long flags, 29 int (*callback)(smalljac_curve_t curve, unsigned long q, int good, long m[], int n, void *arg), 30 void *arg) 31 long smalljac_parallel_groups (smalljac_curve_t curve, 32 unsigned long start, 33 unsigned long end, 34 unsigned long flags, 35 int (*callback)(smalljac_curve_t curve, unsigned long q, int good, long m[], int n, void *arg), 36 void *arg) 37 int smalljac_group (long m[], char *curve_str, unsigned long q, unsigned long flags) 38 39 cdef int SMALLJAC_A1_ONLY 40 cdef int SMALLJAC_DEGREE1_ONLY 41 cdef char *SMALLJAC_VERSION_STRING 42 43 cdef int SMALLJAC_INTERNAL_ERROR 44 cdef int SMALLJAC_INVALID_INTERVAL 45 cdef int SMALLJAC_PARSE_ERROR 46 cdef int SMALLJAC_UNSUPPORTED_CURVE 47 cdef int SMALLJAC_SINGULAR_CURVE 48 cdef int SMALLJAC_INVALID_PP 49 cdef int SMALLJAC_WRONG_GENUS 50 cdef int SMALLJAC_INVALID_FLAGS 51 cdef int SMALLJAC_NOT_OVER_Q 52 cdef int SMALLJAC_FILENOTFOUND 53 cdef int SMALLJAC_BADFILE 54 cdef int SMALLJAC_NODATA 55 cdef int SMALLJAC_NOT_OVER_Q 56 57 cdef int SMALLJAC_CURVE_STRING_LEN 58 59 int smalljac_moments (smalljac_curve_t curve, 60 unsigned long start, unsigned long end, 61 double moments[], int n, int m, 62 char STgroup[16], 63 int (*filter_callback)(smalljac_curve_t curve, 64 unsigned long q, 65 void *arg), 66 void *arg) 67 int smalljac_identify_STgroup (smalljac_curve_t c, char STgroup[16], long maxp) -
new file sage/libs/smalljac/util.py
diff --git a/sage/libs/smalljac/util.py b/sage/libs/smalljac/util.py new file mode 100644
- + 1 from sage.rings.integer import Integer 2 3 def parse_limits(limit): 4 """ 5 Parse a bounds specification into a start and end of range. Both 6 the start and end are inclusive. 7 8 EXAMPLES: 9 10 Integers represent the range from zero to themselves, inclusive:: 11 12 >>> parse_limits(7) 13 (0, 7) 14 >>> parse_limits(5) 15 (0, 5) 16 17 Lists represent inclusive ranges:: 18 19 >>> parse_limits([2, 17]) 20 (2, 17) 21 >>> parse_limits([10**5, 12**5]) 22 (100000, 248832) 23 24 Tuples represent exclusive ranges:: 25 26 >>> parse_limits((2, 17)) 27 (3, 16) 28 >>> parse_limits((10**5, 12**5)) 29 (100001, 248831) 30 31 Slices represent standard Python left-inclusive/right-exclusive ranges:: 32 33 >>> parse_limits(slice(2, 17)) 34 (2, 16) 35 >>> parse_limits(slice(10**5, 12**5)) 36 (100000, 248831) 37 """ 38 39 start, end = 0, 0 40 if isinstance(limit, int) or isinstance(limit, Integer): 41 start = 0 42 end = int(limit) 43 elif isinstance(limit, list): 44 start = limit[0] 45 end = limit[-1] 46 elif isinstance(limit, tuple): 47 start = limit[0] + 1 48 end = limit[-1] - 1 49 elif isinstance(limit, slice): 50 start = limit.start 51 end = limit.stop - 1 52 else: 53 raise ValueError("Cannot interpret limits for trace computation", limit) 54 55 if start < 0 or end < 0 or end < start: 56 raise ValueError("Invalid limits; both must be nonnegative, and end must be not less than start") 57 58 return start, end 59 60 def interpret_smalljac_results(res, correction_fn, construct_fn, raw=False, index="primes", container=list): 61 """ 62 Interpret results returned by Smalljac into a more usable form. 63 Results from Smalljac are a list of tuples of prime and value. 64 Returns a container containing tuples of an index and a values for 65 that index. 66 67 INPUT: 68 69 - ``res`` - The results returned by Smalljac 70 - ``correction_fn`` - A function that takes two inputs: a prime 71 ``p`` and a list of values at that prime. Returns a "corrected" 72 version, where ``None`` values have been replaced. Used when Sage 73 already implements fallback routines, such as for trace of Frobenius 74 calculations at primes that produce bad reductions. 75 - ``construct_fn`` - A function that takes a computed value and 76 returns a value to be returned to the user. This might convert 77 Python ``int`` to Sage ``Integer`` objects, or compute the 78 correct format for L-polynomials, or what have you. 79 - ``raw`` - If true, the original Smalljac results are immediately 80 returned, with no additional processing. 81 - ``index`` - A string, either ``"primes"`` or ``"ideals"``. If 82 ``"primes"``, the indexes of the returned pairs are primes (as 83 Sage ``Integer`` objects) and the values are the list of values 84 for that prime. If ``"ideals"``, the indexes are a pair of 85 prime (as a Sage ``Integer``) and a counter value (also as a 86 Sage ``Integer``), and the values are individual values (in 87 other words, passing ``"ideals"`` splits up the list associated 88 with each prime into individual elements of the overall 89 container. 90 - ``container`` - The container all these pairs are passed to. 91 Popular values are ``list`` (the default), in which case you get 92 back a sorted list of these pairs, and ``dict``, in which case 93 you get an unsorted hash table of such pairs. In theory, can be 94 any function that takes a single list as input. 95 96 EXAMPLES: 97 98 >>> res = [(2, [5, 1]), (11, None), (13, [10, 7]), (19, [20, 2])] 99 >>> interpret_smalljac_results(res, lambda p, vals: [2], lambda p, val: str(x)) 100 [(2, ['[5, 1]']), (11, [2]), (13, ['[10, 7]']), (19, ['[20, 2]'])] 101 >>> interpret_smalljac_results(res, lambda p, vals: [4], lambda p, val: str(x)) 102 [(2, ['[5, 1]']), (11, [4]), (13, ['[10, 7]']), (19, ['[20, 2]'])] 103 >>> interpret_smalljac_results(res, lambda p, vals: [2], lambda p, val: val[0]) 104 [(2, [5]), (11, [2]), (13, [10]), (19, [20])] 105 >>> res == interpret_smalljac_results(res, lambda p,v:[2], lambda p,v: v, raw=True) 106 True 107 >>> interpret_smalljac_results(res, lambda p,v:[2], lambda p,v: v, index="ideals") 108 [((2, 0), 5), ((11, 0), 2), ((13, 0), 10), ((19, 0), 20)] 109 >>> interpret_smalljac_results(res, lambda p,v:[2], lambda p,v: v, container=dict) 110 {19: [[20, 2]], 2: [[5, 1]], 11: [2], 13: [[10, 7]]} 111 >>> interpret_smalljac_results(res, lambda p,v:[2], lambda p,v: v, container=lambda x: 1) 112 1 113 """ 114 115 if raw: return res 116 117 def correct_values(p, values): 118 """ Correct in case of bad primes """ 119 if not values.count(None): return values 120 if correction_fn: 121 correct = correction_fn(p, values) 122 else: 123 return values 124 # Mutating copy 125 for i in range(len(values)): 126 values[i] = correct[i] 127 128 def make_value(p, value): 129 if value is None: 130 return None 131 else: 132 return construct_fn(p, value) 133 134 last_p = 0 135 last_p_lst = [] 136 result = [] 137 for p, val in res: 138 if p == last_p: 139 last_p_lst.append(make_value(p, val)) 140 else: 141 correct_values(last_p, last_p_lst) 142 143 last_p = p 144 last_p_lst = [make_value(p, val)] 145 result.append((Integer(p), last_p_lst)) 146 147 # Index by ideals, not primes 148 if index == "ideals": 149 result2 = [] 150 for p, vals in result: 151 for i, val in enumerate(vals): 152 result2.append(((p, Integer(i)), val)) 153 result = result2 154 elif index == "primes": 155 pass 156 else: 157 raise ValueError("Traces cannot be indexed by `%s`; check your `index` parameter" % index) 158 159 return container(result) -
new file sage/libs/smalljac/wrapper2.pyx
diff --git a/sage/libs/smalljac/wrapper2.pyx b/sage/libs/smalljac/wrapper2.pyx new file mode 100644
- + 1 # -*- mode: python -*- 2 from defs cimport * 3 4 cdef extern from "math.h": 5 double sqrt(double x) 6 cdef extern from "stdlib.h": 7 void *malloc(int size) 8 void free(void *) 9 10 cdef int callback_list_single(smalljac_curve_t c, unsigned long p, int good, long a[], int n, void *arg): 11 """ This callback collects a list of single-valued results in arg.tmp """ 12 13 if good: 14 result = (int(p), -a[0]) 15 else: 16 result = (int(p), None) 17 18 (<SmallJac>arg).tmp.append(result) 19 return 1 20 21 cdef int callback_single_single(smalljac_curve_t c, unsigned long p, int good, long a[], int n, void *arg): 22 """ This callback collects a single single-valued result in arg.tmp """ 23 24 if good: 25 (<SmallJac>arg).tmp = -a[0] 26 else: 27 (<SmallJac>arg).tmp = None 28 return 1 29 30 cdef int callback_list_list(smalljac_curve_t c, unsigned long q, int good, long m[], int n, void *arg): 31 """ This callback collects a list of list-valued results in arg.tmp """ 32 33 cdef int i 34 35 if good: 36 lst = [] 37 for i in range(n): 38 lst.append(m[i]) 39 result = (int(q), lst) 40 else: 41 result = (int(q), None) 42 43 (<SmallJac>arg).tmp.append(result) 44 return 1 45 46 cdef int callback_single_list(smalljac_curve_t c, unsigned long q, int good, long m[], int n, void *arg): 47 """ This callback collects a single list-valued result in arg.tmp """ 48 49 cdef int i 50 if good: 51 lst = [] 52 for i in range(n): 53 lst.append(m[i]) 54 else: 55 lst = None 56 57 (<SmallJac>arg).tmp = lst 58 return 1 59 60 cdef int callback_histogram_single(smalljac_curve_t c, unsigned long q, int good, long a[], int n, void *arg): 61 """ 62 This callback collects results into a histogram stored in array[2:]. 63 64 INPUT: 65 66 - ``array[0]`` must be the genus of the curve. 67 - ``array[1]`` must be the number of buckets (the size array, less two). 68 """ 69 70 cdef double val 71 cdef unsigned int bucket 72 cdef unsigned int buckets 73 cdef unsigned int *array = <unsigned int *>arg 74 cdef int genus 75 76 genus = array[0] 77 buckets = array[1] 78 79 if good: 80 val = 0.5 * (0.5 * -a[0] / sqrt(q) / genus + 1) 81 bucket = (<int>(val * buckets)) 82 if bucket >= buckets: 83 print "Anomaly at p=%d: a1=%d, so fraction=%f" % (q, a[0], val) 84 else: 85 array[bucket + 2] += 1 86 87 return 1 88 89 smalljac_version = SMALLJAC_VERSION_STRING 90 91 cdef class SmallJac: 92 cdef smalljac_curve_t c 93 cdef object tmp 94 cdef int genus 95 96 def __cinit__(self): 97 """ 98 Initialize Smalljac curve pointer to the null pointer, for safety. 99 """ 100 101 self.c = <smalljac_curve_t>0 102 103 def __init__(self, v): 104 """ 105 Create a Smalljac curve for an elliptic curve. 106 107 INPUT: 108 109 - ``v`` - A string defining the curve. See Smalljac documentation for format. 110 111 EXAMPLE:: 112 113 >>> SmallJac("[0,1,1,-10,-20]") # optional: smalljac 114 Smalljac curve defined by [0,1,1,-10,-20] 115 116 """ 117 118 curve = str(v) 119 cdef int err 120 121 self.c = smalljac_curve_init(curve, &err) 122 self.genus = smalljac_curve_genus(self.c) 123 self._check_error(err) 124 125 cdef _check_error(self, err): 126 """ 127 Check whether a value is a error code, and if so raise an 128 Exception. If error is one of the standard Smalljac errors, 129 use a descriptive message. Some supported errors cannot 130 actually happen with the functionality currently implemented 131 (the file-based ones). 132 """ 133 134 if err >= 0: 135 return 136 elif err == SMALLJAC_INTERNAL_ERROR: 137 raise RuntimeError("Internal Smalljac Error") 138 elif err == SMALLJAC_INVALID_INTERVAL: 139 raise RuntimeError("Invalid Interval") 140 elif err == SMALLJAC_PARSE_ERROR: 141 raise RuntimeError("Cannot parse arguments") 142 elif err == SMALLJAC_UNSUPPORTED_CURVE: 143 raise RuntimeError("Unsupported curve; must be degree 3 or 5") 144 elif err == SMALLJAC_SINGULAR_CURVE: 145 raise RuntimeError("Curve is singular") 146 elif err == SMALLJAC_INVALID_PP: 147 raise RuntimeError("Not prime power, or too large a prime power, passed where prime power is required") 148 elif err == SMALLJAC_WRONG_GENUS: 149 raise RuntimeError("Only curves of genus 1 and 2 supported") 150 elif err == SMALLJAC_INVALID_FLAGS: 151 raise RuntimeError("Invalid combination of internal bit flags set") 152 elif err == SMALLJAC_FILENOTFOUND: 153 # Should never happen 154 raise RuntimeError("Smalljac couldn't find the specified file") 155 elif err == SMALLJAC_BADFILE: 156 # Should never happen 157 raise RuntimeError("Smalljac couldn't read specified file; is it corrupt?") 158 elif err == SMALLJAC_NODATA: 159 # Should never happen 160 raise RuntimeError("Requested data not in specified file") 161 elif err == SMALLJAC_NOT_OVER_Q: 162 raise RuntimeError("Curve is not defined over QQ") 163 else: 164 raise RuntimeError("Unknown error %s" % err) 165 166 def __repr__(self): 167 """ 168 Print a descriptive message for a Smalljac object. 169 170 EXAMPLE:: 171 172 >>> SmallJac("[0,1,1,-10,-20]") # optional: smalljac 173 Smalljac curve defined by [0,1,1,-10,-20] 174 """ 175 176 return "Smalljac curve defined by %s"%smalljac_curve_str(self.c) 177 178 def __dealloc__(self): 179 """ Clean up memory, such as the curve object itself. """ 180 181 if self.c: 182 smalljac_curve_clear(self.c) 183 184 def ap(self, unsigned long p, unsigned long b=0): 185 """ 186 If only p is given, return trace of Frobenius at p. If both p 187 and b are given, return a list of (key, value) pairs, with 188 keys the primes < b, and values the traces of Frobenius at the 189 good primes, and None at the bad primes, where bad is "bad for 190 the given model". 191 192 EXAMPLE:: 193 194 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 195 >>> s.ap(7) # optional: smalljac 196 -1 197 >>> s.ap(next_prime(2^35)) # optional: smalljac 198 245262 199 >>> s.ap(0, 7) # optional: smalljac 200 [(2, -2), (3, None), (5, -4), (7, -1)] 201 """ 202 203 cdef int err 204 205 if b == 0: 206 # Compute for a single p only 207 err = smalljac_parallel_Lpolys(self.c, p, p, SMALLJAC_A1_ONLY, callback_single_single, <void*>self) 208 else: 209 # Compute for a range of primes, starting with p. 210 self.tmp = [] 211 err = smalljac_parallel_Lpolys(self.c, p, b, SMALLJAC_A1_ONLY, callback_list_single, <void*>self) 212 213 self._check_error(err) 214 return self.tmp 215 216 def sato_tate_buckets(self, unsigned int n, unsigned long a, unsigned long b): 217 """ 218 Produce a histogram of traces of Frobenius, normalized to be 219 between zero and one. 220 221 INPUT: 222 223 - ``n`` - number of buckets 224 - ``a`` and ``b`` - bounds on the primes for which to compute 225 traces of Frobenius, inclusive. 226 227 EXAMPLE: 228 229 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 230 >>> s.sato_tate_buckets(10, 0, 1000) # optional: smalljac 231 [7L, 12L, 22L, 24L, 18L, 17L, 27L, 14L, 14L, 10L] 232 """ 233 234 cdef unsigned long i 235 cdef unsigned int *buckets 236 cdef int err 237 238 buckets = <unsigned int *>(malloc((n + 2) * sizeof(unsigned int))) 239 240 for i in range(n): # Memset would be faster, but it doesn't matter 241 buckets[i+2] = 0 242 243 buckets[0] = self.genus 244 buckets[1] = n 245 246 err = smalljac_parallel_Lpolys(self.c, a, b, SMALLJAC_A1_ONLY, callback_histogram_single, <void*>buckets) 247 248 self.tmp = [] 249 for i in range(n): 250 self.tmp.append(buckets[i + 2]) 251 252 free(buckets) 253 self._check_error(err) 254 return self.tmp 255 256 def group(self, unsigned long p, unsigned long b=0): 257 """ 258 If only p is given, return the group structure of the curve 259 reduced at p. If both p and b are given, return a list of 260 (key, value) pairs, with keys the primes < b, and values are, 261 at bad primes, None, and at good primes is a list of integers 262 m1, m2, ..., representing the group Z/m1Z x Z/m2 x ... 263 264 EXAMPLE:: 265 266 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 267 >>> s.group(7) # optional: smalljac 268 [9] 269 270 This tells us that the curve has group structure Z/9Z when 271 reduced at the finite field of order 7. 272 273 >>> s.group(next_prime(2^35)) # optional: smalljac 274 [34359493160] 275 >>> s.group(0, 7) # optional: smalljac 276 [(2, [5]), (3, None), (5, [10]), (7, [9])] 277 """ 278 279 cdef int err 280 281 if b == 0: 282 # Compute for a single p only 283 err = smalljac_parallel_groups(self.c, p, p, 0, callback_single_list, <void*>self) 284 else: 285 # Compute for a range of primes, starting with p. 286 self.tmp = [] 287 err = smalljac_parallel_groups(self.c, p, b, 0, callback_list_list, <void*>self) 288 289 self._check_error(err) 290 return self.tmp 291 292 def lpoly(self, unsigned long p, unsigned long b=0): 293 """ 294 If only p is given, return the L polynomial of the curve 295 reduced at p. If both p and b are given, return a list of 296 (key, value) pairs, with keys the primes < b, and values are, 297 at bad primes, None, and at good primes is a list of integers 298 m1, m2, ..., representing the L polynomial 299 p^n T^2n + m1 p^n-1 T^2n-1 m2 p^n-1 T^2n-2 + ... + m1 T + 1 300 301 EXAMPLE:: 302 303 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 304 >>> s.lpoly(7) # optional: smalljac 305 [1] 306 307 This tells us that the curve has L-polynomial 7 T^2 + T + 1, 308 where the 1 is the coefficient of T. 309 310 >>> s.lpoly(next_prime(2^35)) # optional: smalljac 311 [-245262] 312 >>> s.lpoly(0, 7) # optional: smalljac 313 [(2, [2]), (3, None), (5, [4]), (7, [1])] 314 """ 315 316 cdef int err 317 318 if b == 0: 319 # Compute for a single p only 320 err = smalljac_parallel_Lpolys(self.c, p, p, 0, callback_single_list, <void*>self) 321 # Compute for a range of primes, starting with p. 322 else: 323 self.tmp = [] 324 err = smalljac_parallel_Lpolys(self.c, p, b, 0, callback_list_list, <void*>self) 325 326 self._check_error(err) 327 return self.tmp 328 329 def moments(self, int moments, unsigned long start, unsigned long end): 330 """ 331 Computes the first few moments of the Sato-Tate distribution. 332 333 INPUT: 334 335 - ``moments`` - The number of moments to compute; at most 11. 336 - ``start`` and ``end`` - the bounds on which reductions to use; inclusive. 337 338 EXAMPLE: 339 340 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 341 >>> s.moments(5, 0, 1000) # optional: smalljac 342 ([1.0, 0.002257165809854347, 0.9692801815679776, 343 -0.06359909058782176, 1.8792555673855094],) 344 345 For a higher-genus curve, will return multiple lists of 346 moments, one for each coefficient of the L-polynomial. 347 348 >>> s = SmallJac("x^5+2x-1") # optional: smalljac 349 >>> s.moments(3, 0, 1000) # optional: smalljac 350 ([1.0, -0.09346091047494341, 1.052736244717573], 351 [1.0, 1.0335517476280245, 2.029919838936752]) 352 """ 353 354 cdef int err 355 356 if moments > 11: raise ValueError("Only up to 11 moments supported for now.") 357 358 cdef double *moment_arr = <double *>malloc(sizeof(double) * moments * self.genus) 359 360 err = smalljac_moments(self.c, start, end, moment_arr, self.genus, moments, 361 NULL, NULL, NULL) 362 363 if err: 364 free(moment_arr) 365 self._check_err(err) 366 # Should never happen 367 raise RuntimeError("Error exists but doesn't exist; please report paradox!") 368 369 a1moments = [] 370 371 cdef int i 372 for i in range(moments): 373 a1moments.append(moment_arr[i]) 374 375 if self.genus == 2: 376 a2moments = [] 377 for i in range(moments): 378 a2moments.append(moment_arr[i + moments]) 379 380 free(moment_arr) 381 return (a1moments, a2moments) 382 else: 383 free(moment_arr) 384 return (a1moments,) 385 386 def guess_group(self, unsigned long max): 387 """ 388 Attempt to guess the Sato-Tate group of a curve, by testing 389 various characteristics of the distribution of L-polynomial 390 coefficients for reductions less than a certain size. May 391 rely on unproven conjectures. May yield incorrect answers (it 392 is, after all, only a guess), but attempts not to. To 393 interpret results, see 394 395 "Sato-Tate distributions and Galois endomorphism modules 396 in genus 2", Francesc Fité, Kiran S. Kedlaya, Victor 397 Rotger, and Andrew V. Sutherland, to appear in Compositio 398 Mathematica, <http://arxiv.org/abs/1110.6638>. 399 400 INPUT: 401 402 - ``max`` - Largest norm of prime the reduction at which is tested. 403 404 EXAMPLE:: 405 406 >>> s = SmallJac("[0,1,1,-10,-20]") # optional: smalljac 407 >>> s.guess_group(1000) # optional: smalljac 408 >>> s.guess_group(100000) # optional: smalljac 409 'SU(2)' 410 >>> s = SmallJac("x^5+2x-1") # optional: smalljac 411 >>> s.guess_group(1000) # optional: smalljac 412 >>> s.guess_group(100000) # optional: smalljac 413 'USp(4)' 414 """ 415 416 cdef int i 417 cdef char STgroup[16] 418 419 i = smalljac_identify_STgroup(self.c, STgroup, max) 420 421 if i: 422 return STgroup 423 else: 424 return None -
sage/schemes/elliptic_curves/ell_finite_field.py
diff --git a/sage/schemes/elliptic_curves/ell_finite_field.py b/sage/schemes/elliptic_curves/ell_finite_field.py
a b 1284 1284 """ 1285 1285 return self.points()[n] 1286 1286 1287 def _smalljac(self): 1288 r""" 1289 Computes and caches the smalljac representation of the given 1290 curve. For internal use only. 1291 1292 EXAMPLE:: 1293 1294 sage: E = EllipticCurve(GF(97), [2,3]) 1295 sage: E._smalljac() # optional: smalljac 1296 Smalljac curve defined by [0,0,0,2,3] 1297 sage: E = EllipticCurve('11a').reduction(17) 1298 sage: E._smalljac() # optional: smalljac 1299 Smalljac curve defined by [0,16,1,7,14] 1300 """ 1301 1302 try: 1303 return self._smalljac_proxy 1304 except AttributeError: 1305 try: 1306 import sage.libs.smalljac.all as smalljac 1307 except ImportError: 1308 raise RuntimeError, "smalljac not installed or inaccessible" 1309 1310 f = "[%s,%s,%s,%s,%s]" % tuple(self.ainvs()) 1311 self._smalljac_proxy = smalljac.SmallJac(f) 1312 return self._smalljac_proxy 1313 1314 def jacobian_structure(self, algorithm="smalljac"): 1315 r""" 1316 Returns the group structure of the group of points on this 1317 elliptic curve. Unlike ``abelian_group``, it does not compute 1318 the generators of the group, just the structure, and is thus 1319 perhaps somewhat less useful. 1320 1321 INPUT: 1322 1323 - ``algorithm`` - either "sage", which uses Sage's abelian 1324 group determination algorithm via ``abelian_group``, or 1325 ``smalljac``, which uses Drew Sutherland's SmallJac library 1326 for the computation. SmallJac is much faster, but can only 1327 be used on degree-1 fields. You can also pass 1328 ``algorithm="all"`` to run both algorithms and verify that 1329 they produce the same results. 1330 1331 OUTPUT: 1332 1333 An abelian group isomorphic to the jacobian of this curve. 1334 1335 EXAMPLES:: 1336 1337 sage: E=EllipticCurve(GF(11),[2,5]) 1338 sage: E.jacobian_structure() # optional: smalljac 1339 Additive abelian group isomorphic to Z/10 1340 sage: E=EllipticCurve(GF(41),[2,5]) 1341 sage: E.jacobian_structure() # optional: smalljac 1342 Additive abelian group isomorphic to Z/2 + Z/22 1343 1344 We can use ``algorithm="all"`` to test multiple 1345 implementations against each other:: 1346 1347 sage: E.jacobian_structure(algorithm="all") # optional: smalljac 1348 Additive abelian group isomorphic to Z/2 + Z/22 1349 """ 1350 1351 from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup 1352 1353 if algorithm == "smalljac": 1354 K = self.base_field() 1355 assert K.degree() == 1, "Smalljac can only find group structures in degree-1 fields" 1356 p = K.cardinality() 1357 proxy = self._smalljac() 1358 structure = proxy.group(p) 1359 return AdditiveAbelianGroup(structure) 1360 elif algorithm == "sage": 1361 g = self.abelian_group() 1362 return AdditiveAbelianGroup(g.generator_orders()) 1363 elif algorithm == "all": 1364 smalljac_results = self.jacobian_structure(algorithm="smalljac") 1365 sage_results = self.jacobian_structure(algorithm="sage") 1366 1367 # If the orders were given in different orders, testing 1368 # two groups for equality can give incorrect results 1369 smalljac_order = sorted(g.additive_order() for g in smalljac_results.gens()) 1370 sage_order = sorted(g.additive_order() for g in sage_results.gens()) 1371 assert smalljac_order == sage_order, "An error has occured and smalljac and Sage's results do not match" 1372 return smalljac_results 1373 else: 1374 raise ValueError("Unknown algorithm `%s`" % algorithm) 1375 1287 1376 def abelian_group(self, debug=False): 1288 1377 r""" 1289 1378 Returns the abelian group structure of the group of points on this -
sage/schemes/elliptic_curves/ell_number_field.py
diff --git a/sage/schemes/elliptic_curves/ell_number_field.py b/sage/schemes/elliptic_curves/ell_number_field.py
a b 2121 2121 degrees.extend(newdegs) 2122 2122 k = k+1 2123 2123 2124 raise NotImplementedError, "Not all isogenies implemented over general number fields." 2124 raise NotImplementedError, "Not all isogenies implemented over general number fields." 2125 2126 def aplists(self, limit, algorithm="smalljac", container=list, index="primes", raw=False): 2127 """ 2128 Computes the traces of Frobenius at the prime ideals of the 2129 base number field, sorted by the norm of these ideals. The 2130 structure of the return values depends on the ``format`` 2131 argument. So far, this method requires the Smalljac library. 2132 2133 INPUT: 2134 2135 - ``limit`` - either an integer, in which case the prime 2136 ideals will have norm less than this limit, or [a, b], in 2137 which case the prime ideals with norms between ``a`` and 2138 ``b`, inclusive, are used. 2139 2140 - ``algorithm`` - so far, only "smalljac" is supported, which 2141 uses Drew Sutherland's smalljac library for elliptic curve 2142 structure computation. 2143 2144 - The remainder (``container``, ``index``, ``raw``) 2145 define the format of the result. By default, the return 2146 value looks like this: 2147 2148 [(9, [2]), (11, [4, -4]), (19, [-4, 4]), (31, [4, 8])] 2149 2150 This describes the fact that 9 does not split, and its prime 2151 ideal has trace of Frobeneus 2; that 11 splits, and its two 2152 prime ideals have traces 4 and -4; and so on. 2153 2154 Instead of a list of tuples, one can choose a dictionary, 2155 mapping norms to traces, by changing ``container`` to 2156 ``dict`` (in fact, any value for container is just called 2157 with the list of pairs). 2158 2159 Instead of pairs of norms and lists of traces, you can have 2160 each trace have its own pair, with the first element being a 2161 pair of norm and index, yielding a result such as: 2162 2163 [((9, 0), 2), ((11, 0), 4), ((11, 0), -4), ...] 2164 2165 This is chosen with ``index="ideals"``. 2166 2167 By default, all integers above are Sage Integers. If this 2168 is a performance or memory problem, you likely want 2169 ``raw=True``. 2170 2171 Finally, for performance or memory reasons, you can turn off 2172 all post-processing by by setting ``raw`` to ``True``. This 2173 overrides all other arguments and returns a list formatted 2174 like so: 2175 2176 [(9, 2), (11, None), (11, -4), (19, 4), (19, -4), ...] 2177 2178 All integers are python integers. This last mode is by far 2179 the fastest, especially for large ranges of prime norms, but 2180 is also often the hardest to use for other computation. It 2181 is often used internally. Note that, among other things, 2182 using only raw data means that bad primes will have the 2183 trace ``None``, instead of the correct trace, since it is 2184 not SmallJac, but Sage, that does that computation. 2185 2186 OUTPUT: 2187 2188 A list of traces of Frobenius, with the precise format defined 2189 by the ``container``, ``index``, and ``raw`` keywords. 2190 2191 EXAMPLES: 2192 2193 We can find the traces of Frobenius up to a given prime:: 2194 2195 sage: ec = EllipticCurve('11a') 2196 sage: ec.aplists(15) # optional: smalljac 2197 [(2, [-2]), (3, [-1]), (5, [1]), (7, [-2]), (11, [None]), (13, [4])] 2198 2199 Or in any arbitrary range:: 2200 2201 sage: ec.aplists([15, 40]) # optional: smalljac 2202 [(17, [-2]), (19, [0]), (23, [-1]), (29, [0]), (31, [7]), (37, [3])] 2203 2204 Curves over number fields are also supported:: 2205 2206 sage: K.<a> = NumberField(x^2 - x - 1) 2207 sage: ec2 = EllipticCurve(K, [a, -a+1, 0, -4, 3*a-5]) 2208 sage: ec2.aplists([15, 50]) # optional: smalljac 2209 [(19, [-4, 4]), (29, [-2, 6]), (31, [-8, 8]), (41, [2, -6]), (49, [2])] 2210 2211 You can choose to separate each ideal, instead of combining them by norm:: 2212 2213 sage: ec2.aplists([15, 30], index="ideals") # optional: smalljac 2214 [((19, 0), -4), ((19, 1), 4), ((29, 0), -2), ((29, 1), 6)] 2215 2216 You can also choose a dictionary representation, though this 2217 of course destroys the ordering:: 2218 2219 sage: ec2.aplists([15, 50], container=dict) # optional: smalljac 2220 {41: [2, -6], 49: [2], 19: [-4, 4], 29: [-2, 6], 31: [-8, 8]} 2221 sage: ec2.aplists([15, 30], container=dict, index="ideals") # optional: smalljac 2222 {(19, 0): -4, (29, 1): 6, (19, 1): 4, (29, 0): -2} 2223 2224 Finally, the raw results are useful for large-scale statistics:: 2225 2226 sage: bsum = __builtins__.sum 2227 sage: bsum(ap for p, ap in ec.aplists(100000, raw=True) if ap) # optional: smalljac 2228 4837 2229 sage: bsum(ap for p, ap in ec2.aplists(100000, raw=True) if ap) # optional: smalljac 2230 5289 2231 2232 Note that the equivalent non-SmallJac code for that last 2233 example returns a different answer:: 2234 2235 sage: bsum(ec.aplist(100000)) 2236 4838 2237 2238 This is because our curve has a bad reduction at 11, and we 2239 aren't adding it its trace. 2240 """ 2241 2242 import sage.libs.smalljac.util as util 2243 2244 start, end = util.parse_limits(limit) 2245 2246 if algorithm == "smalljac": 2247 proxy = self._smalljac() 2248 res = proxy.ap(start, end) 2249 2250 O = self.base_ring().ring_of_integers() 2251 def get_aps(p, aps): 2252 if hasattr(O.ideal(p), "factor"): 2253 factors = [ideal for ideal, exponent in O.ideal(p).factor()] 2254 else: 2255 factors = [p] 2256 2257 out = [] 2258 for ideal in factors: 2259 try: 2260 out.append(self.reduction(ideal).trace_of_frobenius()) 2261 except (AttributeError, ValueError): # Bad reduction 2262 out.append(None) 2263 return out 2264 def make_int(p, v): 2265 return Integer(v) 2266 2267 return util.interpret_smalljac_results( 2268 res, correction_fn=get_aps, construct_fn=make_int, 2269 raw=raw, index=index, container=container) 2270 else: 2271 raise ValueError("Algorithm %s not defined" % algorithm) 2272 2273 def aps(self, p): 2274 """ 2275 Returns a list of the traces of Frobenius of this elliptic 2276 curve when reduced at prime ideals of norm ``p``. 2277 2278 INPUT: 2279 2280 - ``p`` - The integer prime at which to reduce. 2281 2282 OUTPUT: 2283 2284 A list of traces of Frobenius, or None if there was a bad 2285 reduction. 2286 2287 EXAMPLES: 2288 2289 We can take a curve and find traces:: 2290 2291 sage: ec = EllipticCurve('11a') 2292 sage: ec.aps(next_prime(10^6)) # optional: smalljac 2293 [284] 2294 sage: ec.aps(next_prime(10^9)) # optional: smalljac 2295 [-1962] 2296 2297 Curves over quadratic number fields are also supported:: 2298 2299 sage: K.<a> = NumberField(x^2 - x - 1) 2300 sage: ec2 = EllipticCurve(K, [a, -a+1, 0, -4, 3*a-5]) 2301 sage: ec2.aps(9949) # optional: smalljac 2302 [-162, -34] 2303 """ 2304 2305 res = self.aplists([p, p]) 2306 2307 if len(res) == 0 or res[0][0] != p: 2308 raise ValueError("%d is not a prime (over the chosen field)" % p) 2309 2310 return res[0][1] # [0] extracts the prime we care about, [1] extracts the list of traces 2311 2312 def grouplists(self, limit, algorithm="smalljac", container=list, index="primes", raw=False): 2313 r""" 2314 Computes the group structure of reductions at the prime ideals 2315 of the base number field, sorted by the norm of these ideals. 2316 So far, this method requires the Smalljac library. 2317 2318 INPUT: 2319 2320 - ``limit`` - either an integer, in which case the prime 2321 ideals will have norm less than this limit, or [a, b], in 2322 which case the prime ideals with norms between ``a`` and 2323 ``b`, inclusive, are used. 2324 2325 - ``algorithm`` - so far, only "smalljac" is supported, which 2326 uses Drew Sutherland's smalljac library for elliptic curve 2327 structure computation. 2328 2329 - The remainder (``container``, ``index``, and ``raw``) define 2330 the format of the result; see ``EllipticCurve.aplists`` for 2331 a description. 2332 2333 OUTPUT: 2334 2335 A list of group structures of Jacobians at various primes; the 2336 format is precisely specified by the ``container``, ``index``, 2337 and ``raw`` arguments. If a curve has a bad reduction at a prime, 2338 ``None`` is instead returned. 2339 2340 EXAMPLES:: 2341 2342 sage: ec = EllipticCurve('11a') 2343 sage: ec.grouplists(10) # optional: smalljac 2344 [(2, [Additive abelian group isomorphic to Z/5]), 2345 (3, [Additive abelian group isomorphic to Z/5]), 2346 (5, [Additive abelian group isomorphic to Z/5]), 2347 (7, [Additive abelian group isomorphic to Z/10])] 2348 2349 sage: ec.grouplists([50, 60]) # optional: smalljac 2350 [(53, [Additive abelian group isomorphic to Z/2 + Z/30]), (59, [Additive abelian group isomorphic to Z/55])] 2351 2352 The raw results are suitable for larger-scale statistics:: 2353 2354 sage: def jac_checksum(poly): 2355 ... ec = EllipticCurve(poly) 2356 ... sum = __builtins__.sum 2357 ... return sum(sum(gs) for p, gs in ec.grouplists([3, 10000], raw=True) if gs) 2358 sage: jac_checksum([4, 7]) # optional: smalljac 2359 5179039 2360 sage: jac_checksum('11a') # optional: smalljac 2361 4121837 2362 sage: jac_checksum('37b') # optional: smalljac 2363 3455881 2364 """ 2365 2366 from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup 2367 import sage.libs.smalljac.util as util 2368 2369 start, end = util.parse_limits(limit) 2370 2371 if algorithm == "smalljac": 2372 proxy = self._smalljac() 2373 res = proxy.group(start, end) 2374 2375 O = self.base_ring().ring_of_integers() 2376 def get_group(p, gps): 2377 if hasattr(O.ideal(2), "factor"): # Not the rationals 2378 factors = [ideal for ideal, exponent in O.ideal(p).factor()] 2379 else: # Only in the case of QQ 2380 factors = [p] 2381 2382 out = [] 2383 for ideal in factors: 2384 try: 2385 out.append(self.reduction(ideal).jacobian_structure()) 2386 except AttributeError: 2387 out.append(None) 2388 return out 2389 2390 def make_group(p, v): 2391 return AdditiveAbelianGroup(v) 2392 2393 return util.interpret_smalljac_results( 2394 res, correction_fn=get_group, construct_fn=make_group, 2395 raw=raw, index=index, container=container) 2396 else: 2397 raise ValueError("Algorithm %s not defined" % algorithm) 2398 2399 def lpolylists(self, limit, algorithm="smalljac", container=list, index="primes", normalize=False, raw=False): 2400 r""" 2401 Computes the L-polynomials of reductions at the prime ideals 2402 of the base number field, sorted by the norm of these ideals. 2403 So far, this method requires the Smalljac library. 2404 2405 INPUT: 2406 2407 - ``limit`` - either an integer, in which case the prime 2408 ideals will have norm less than this limit, or [a, b], in 2409 which case the prime ideals with norms between ``a`` and 2410 ``b`, inclusive, are used. 2411 2412 - ``normalize`` - whether to return normalized L-polynomials. 2413 By default, non-normalized L-polynomials are returned. 2414 2415 - ``algorithm`` - so far, only "smalljac" is supported, which 2416 uses Drew Sutherland's smalljac library for elliptic curve 2417 structure computation. 2418 2419 - The remainder (``container``, ``index``, and ``raw``) define 2420 the format of the result; see ``EllipticCurve.aplists`` for 2421 a description. 2422 2423 OUTPUT: 2424 2425 A list of L-polynomials of reductions at various primes; the 2426 format is precisely specified by the ``container``, ``index``, 2427 and ``raw`` arguments. If a curve has a bad reduction at a 2428 prime, ``None`` is instead returned. 2429 2430 EXAMPLES: 2431 2432 We can construct an elliptic curve and find its L-polynomial:: 2433 2434 sage: E = EllipticCurve('11a') 2435 sage: E.lpolylists([89, 89]) # optional: smalljac 2436 [(89, [89*T^2 - 15*T + 1])] 2437 2438 Or we can use a range:: 2439 2440 sage: E.lpolylists([80, 100]) # optional: smalljac 2441 [(83, [83*T^2 + 6*T + 1]), (89, [89*T^2 - 15*T + 1]), (97, 2442 [97*T^2 + 7*T + 1])] 2443 2444 We can ask for normalized L-polynomials instead:: 2445 2446 sage: E.lpolylists([89, 89], normalize=True) # optional: smalljac 2447 [(89, [T^2 - 1.58999682000954*T + 1.00000000000000])] 2448 2449 Number fields are also supported:: 2450 2451 sage: K.<a> = NumberField(x^2 - x - 1) 2452 sage: E2 = EllipticCurve(K, [a, -a+1, 0, -4, 3*a-5]) 2453 sage: E2.lpolylists([80, 100]) # optional: smalljac 2454 [(89, [89*T^2 + 14*T + 1, 89*T^2 - 2*T + 1])] 2455 """ 2456 2457 from sage.rings.polynomial.polynomial_ring import PolynomialRing_field 2458 from sage.rings.real_mpfr import RR 2459 from sage.rings.rational_field import QQ 2460 from math import sqrt 2461 import sage.libs.smalljac.util as util 2462 2463 start, end = util.parse_limits(limit) 2464 2465 if algorithm == "smalljac": 2466 proxy = self._smalljac() 2467 res = proxy.lpoly(start, end) 2468 2469 if normalize: 2470 polynomial_ring = PolynomialRing_field(RR, 'T') 2471 else: 2472 polynomial_ring = PolynomialRing_field(QQ, 'T') 2473 t = polynomial_ring.gens()[0] # I don't want a T 2474 2475 def make_lpoly(p, coeffs): 2476 if not normalize: 2477 a1 = coeffs[0] 2478 return p*t**2 + a1*t + 1 2479 else: 2480 a1 = coeffs[0] 2481 a1 /= sqrt(p) 2482 return t**2 + a1*t + 1 2483 2484 def get_lpoly(p, coeffs): 2485 aps = self.aps(p) 2486 2487 out = [] 2488 for ap in aps: 2489 if not normalize: 2490 out.append(p*t**2 - ap*t + 1) 2491 else: 2492 ap /= sqrt(p) 2493 out.append(p*t**2 - ap*t + 1) 2494 return out 2495 2496 return util.interpret_smalljac_results( 2497 res, correction_fn=get_lpoly, construct_fn=make_lpoly, 2498 raw=raw, index=index, container=container) 2499 else: 2500 raise ValueError("Algorithm %s not defined" % algorithm) 2501 2502 def _smalljac(self): 2503 """ 2504 Computes and caches the smalljac representation of the given 2505 curve. For internal use only. 2506 2507 EXAMPLES:: 2508 2509 sage: E = EllipticCurve('11a') 2510 sage: E._smalljac() # optional: smalljac 2511 Smalljac curve defined by [0,-1,1,-10,-20] 2512 sage: K.<a> = NumberField(x^2 - x - 1) 2513 sage: E = EllipticCurve(K, [a, -a+1, 0, -4, 3*a-5]) 2514 sage: E._smalljac() # optional: smalljac 2515 Smalljac curve defined by [a, -a + 1, 0, -4, 3*a - 5] / (a^2 - a - 1) 2516 """ 2517 2518 try: 2519 return self._smalljac_proxy 2520 except AttributeError: 2521 try: 2522 import sage.libs.smalljac.all as smalljac 2523 except ImportError: 2524 raise RuntimeError, "smalljac not installed or inaccessible" 2525 2526 k = self.base_ring() 2527 gen = k.gen() 2528 var = str(gen) 2529 cpoly = gen.charpoly().change_variable_name(var) 2530 f = "[%s, %s, %s, %s, %s]" % tuple(self.ainvs()) 2531 f = "%s / (%s)" % (f, cpoly) 2532 self._smalljac_proxy = smalljac.SmallJac(f) 2533 return self._smalljac_proxy 2534 2535 def trace_histogram(self, limit, buckets=None): 2536 """ 2537 Computes the traces of reductions of this curve at all primes 2538 in a range, and returns how many, normalized, fell in each 2539 of ``buckets`` buckets from -2 to 2. 2540 2541 INPUT: 2542 2543 - ``limits`` - Either an integer, meaning all primes below that 2544 integer are used, or a list of ``[start, end]``, in which 2545 case all primes from ``start`` to ``end``, inclusive, are 2546 used. 2547 2548 - ``buckets`` - How many buckets to split the range $[-2, 2]$ 2549 into. By default, the number of buckets is the square root 2550 of the range size. 2551 2552 OUTPUT: 2553 2554 A list of integers, as many as the ``buckets`` parameter, 2555 denoting the number of trace values fell into that bucket for 2556 primes in the given range. 2557 2558 EXAMPLES: 2559 2560 We can take an elliptic curve and compute a histogram for it:: 2561 2562 sage: E1 = EllipticCurve([4,7]) 2563 sage: E1.trace_histogram(100) # optional: smalljac 2564 [0, 1, 2, 1, 3, 8, 2, 4, 2, 1] 2565 2566 In this case, the default choice of 10 buckets was made. 2567 Instead, you can specify the number of bucket manually:: 2568 2569 sage: E1.trace_histogram(100000, buckets=10) # optional: smalljac 2570 [529, 849, 1059, 1193, 1201, 1153, 1133, 1092, 876, 505] 2571 2572 You can choose a range that starts anywhere, not just at 1:: 2573 2574 sage: E1.trace_histogram([1000, 2000], buckets=10) # optional: smalljac 2575 [11, 13, 12, 14, 14, 14, 17, 11, 20, 8] 2576 2577 This is generally useful for making histograms; a quick way to 2578 do this is with ``bar_chart``, though custom graphing code 2579 will look better. :: 2580 2581 sage: bar_chart(E1.trace_histogram(100000), width=1) #optional: smalljac 2582 """ 2583 2584 import sage.libs.smalljac.util as util 2585 from math import sqrt 2586 2587 start, end = util.parse_limits(limit) 2588 2589 if buckets is None: 2590 range_size = end - start + 1 2591 buckets = int(sqrt(range_size)) 2592 2593 return map(Integer, 2594 self._smalljac().sato_tate_buckets(buckets, start, end)) 2595 2596 def moments(self, limits, moments=11): 2597 """ 2598 Compute the moments of the distributions of the coefficients 2599 of the L-polynomials of this curve, reduced at primes in a 2600 range. 2601 2602 INPUT: 2603 2604 - ``limits`` - Either an integer, meaning all primes below that 2605 integer are used, or a list of ``[start, end]``, in which 2606 case all primes from ``start`` to ``end``, inclusive, are 2607 used. 2608 2609 - ``moments`` - How many moments to return; fewer moments 2610 might be faster to compute. For now, at most 10 moments can 2611 be computed. 2612 2613 OUTPUT: 2614 2615 A tuple whose first element is a list of moments of the 2616 distribution of the $a_1$ coefficients of L-polynomials of 2617 this curve, starting from the zeroth moment being 0. The list 2618 is as long as ``moments``; that is, if ``moments`` is 5, only 2619 the zero through fourth moments are returned. 2620 2621 .. NOTE:: 2622 A tuple is returned for polymorphism with the 2623 hyperelliptic curve method of the same name 2624 2625 EXAMPLES: 2626 2627 You can request the moments of an arbitrary curve:: 2628 2629 sage: ec = EllipticCurve('37b') 2630 sage: ec.moments(100000) # optional: smalljac 2631 ([1.0, -0.003018470650554107, 0.9999566856391424, 2632 -0.017815838483148164, 1.993903401871212, 2633 -0.06113842272925238, 4.963581622954891, 2634 -0.20681637970442066, 13.83188351590207, 2635 -0.7065524181435564, 41.306996429058835],) 2636 2637 You can request fewer moments if you wish:: 2638 2639 sage: ec.moments(10000, moments=3) # optional: smalljac 2640 ([1.0, -0.000812699651702702, 0.9890134939436471],) 2641 2642 Or compute in any range:: 2643 2644 sage: ec.moments([1000, 2000], moments=5) # optional: smalljac 2645 ([1.0, -0.008380482644508922, 0.9721022301822473, 2646 -0.16345224489884563, 1.8856843129225396],) 2647 2648 Number fields are also supported:: 2649 2650 sage: K.<a> = NumberField(x^2 - x - 1) 2651 sage: ec2 = EllipticCurve(K, [a, -a+1, 0, -4, 3*a-5]) 2652 sage: ec2.moments([1000, 2000], moments=5) # optional: smalljac 2653 ([1.0, -0.047677896726755147, 0.9514627444845026, 2654 -0.20252616280144933, 1.7720971308862585],) 2655 2656 Rounding the moments should produce a recognizable sequence:: 2657 2658 sage: map(round, ec.moments(100000)[0]) # optional: smalljac 2659 [1.0, -0.0, 1.0, -0.0, 2.0, -0.0, 5.0, -0.0, 14.0, -1.0, 41.0] 2660 """ 2661 2662 import sage.libs.smalljac.util as util 2663 2664 start, end = util.parse_limits(limits) 2665 if moments > 11: 2666 raise ValueError("Only up to 11 moments supported for now.") 2667 2668 return self._smalljac().moments(moments, start, end) 2669 2670 def guess_sato_tate_group(self, limit=None): 2671 """ 2672 Provide a preliminary guess toward the Sato-Tate group 2673 corresponding to this curve, by considering its reduction at 2674 primes up to a certain limit. 2675 2676 INPUT: 2677 2678 - ``limit`` - The maximal prime considered. The search may 2679 terminate earlier if an answer is found. Or, ``None``, to 2680 use an implementation-defined (but very large) maximum. 2681 2682 OUTPUT: 2683 2684 A string containing the name of the corresponding Sato-Tate 2685 group. If no provisional identification can be made, returns 2686 ``None``. 2687 2688 .. TODO: 2689 - Should output a textual description of the Sato-Tate group 2690 2691 EXAMPLES: 2692 2693 Just create a hyperelliptic curve of genus 2 and call 2694 ``guess_sato_tate_group`` to start it off:: 2695 2696 sage: ec = EllipticCurve('11a') 2697 sage: ec.guess_sato_tate_group(100000) # optional: smalljac 2698 'SU(2)' 2699 sage: ec = EllipticCurve([0, 1]) 2700 sage: ec.guess_sato_tate_group(100000) # optional: smalljac 2701 'N(U(1))' 2702 sage: K.<a> = NumberField(x^2 + 3) 2703 sage: ec = EllipticCurve(K, [0, 1]) 2704 sage: ec.guess_sato_tate_group(100000) # optional: smalljac 2705 'U(1)' 2706 2707 The above are the only three possibilities (for genus 1). 2708 """ 2709 2710 if limit is None: 2711 limit = 0 2712 2713 return self._smalljac().guess_group(limit) -
sage/schemes/elliptic_curves/ell_rational_field.py
diff --git a/sage/schemes/elliptic_curves/ell_rational_field.py b/sage/schemes/elliptic_curves/ell_rational_field.py
a b 750 750 return self.__database_curve 751 751 752 752 753 def Np(self, p ):753 def Np(self, p, algorithm="pari"): 754 754 r""" 755 The number of points on `E` modulo `p`. 755 The number of points on `E` modulo `p`. The ``algorithm`` 756 argument is the same as that for ``ap``. 756 757 757 758 INPUT: 758 759 … … 761 762 762 763 OUTPUT: 763 764 764 (int) The number of points on the reduction of `E` modulo `p`765 (int) The number of points on the reduction of `E` modulo `p` 765 766 (including the singular point when `p` is a prime of bad 766 767 reduction). 767 768 … … 784 785 1000000000000001426441464441649 785 786 """ 786 787 if self.conductor() % p == 0: 787 return p + 1 - self.ap(p )788 return p+1 - self.ap(p )788 return p + 1 - self.ap(p, algorithm=algorithm) 789 return p+1 - self.ap(p, algorithm=algorithm) 789 790 790 791 #def __pari_double_prec(self): 791 792 # EllipticCurve_number_field._EllipticCurve__pari_double_prec(self) … … 884 885 # Etc. 885 886 #################################################################### 886 887 887 def aplist(self, n, python_ints=False ):888 def aplist(self, n, python_ints=False, algorithm="pari"): 888 889 r""" 889 890 The Fourier coefficients `a_p` of the modular form 890 891 attached to this elliptic curve, for all primes `p\leq n`. … … 896 897 897 898 - ``python_ints`` - bool (default: False); if True 898 899 return a list of Python ints instead of Sage integers. 900 901 - ``algorithm`` - std (default: "pari") 902 903 - "pari" - Use PARI's implementation of ellaplist 904 905 - "smalljac" - Use the smalljac library, if installed 899 906 900 907 901 908 OUTPUT: list of integers … … 915 922 <type 'sage.rings.integer.Integer'> 916 923 sage: type(e.aplist(13, python_ints=True)[0]) 917 924 <type 'int'> 918 """ 919 e = self.pari_mincurve() 920 v = e.ellaplist(n, python_ints=True) 921 if python_ints: 925 926 We can pass ``algorithm="smalljac"`` to use the smalljac 927 library; this is generally much faster. 928 929 sage: e.aplist(13, algorithm="smalljac") # optional: smalljac 930 [-2, -3, -2, -1, -5, -2] 931 """ 932 933 if algorithm == "pari": 934 e = self.pari_mincurve() 935 v = e.ellaplist(n, python_ints=True) 936 if python_ints: 937 return v 938 else: 939 return [Integer(a) for a in v] 940 elif algorithm == "smalljac": 941 proxy = self._smalljac() 942 aps = proxy.ap(0, n) 943 944 v = [] 945 for p, ap in aps: 946 if ap is None: 947 # Sage already deals with this case well enough 948 ap = self.ap(p, algorithm="pari") 949 if not python_ints: ap = int(ap) 950 v.append(ap) 951 else: 952 if python_ints: ap = Integer(ap) 953 v.append(ap) 954 922 955 return v 956 elif algorithm == "all": 957 aplist1 = self.aplist(n, python_ints=python_ints, algorithm="pari") 958 aplist2 = self.aplist(n, python_ints=python_ints, algorithm="smalljac") 959 if aplist1 != aplist2: 960 raise ArithmeticError("PARI and smalljac disagree (%s, %s)", aplist1, aplist2) 961 return aplist1 923 962 else: 924 return [Integer(a) for a in v] 925 926 963 raise RuntimeError, "algorithm '%s' is not known."%algorithm 927 964 928 965 def anlist(self, n, python_ints=False): 929 966 """ … … 1377 1414 else: 1378 1415 raise ValueError, "algorithm %s not defined"%algorithm 1379 1416 1417 def _smalljac(self): 1418 r""" 1419 Computes and caches the smalljac representation of the given 1420 curve. For internal use only. 1421 1422 EXAMPLES:: 1423 1424 sage: E = EllipticCurve('11a') 1425 sage: E._smalljac() # optional: smalljac 1426 Smalljac curve defined by [0,-1,1,-10,-20] 1427 """ 1428 1429 try: 1430 return self._smalljac_proxy 1431 except AttributeError: 1432 try: 1433 import sage.libs.smalljac.all as smalljac 1434 except ImportError: 1435 raise RuntimeError, "smalljac not installed or inaccessible" 1436 1437 f = "[%s,%s,%s,%s,%s]" % tuple(self.ainvs()) 1438 self._smalljac_proxy = smalljac.SmallJac(f) 1439 return self._smalljac_proxy 1380 1440 1381 1441 def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, limbigprime=30): 1382 1442 r""" … … 2501 2561 """ 2502 2562 return Integer(self.pari_mincurve().ellak(n)) 2503 2563 2504 def ap(self, p ):2564 def ap(self, p, algorithm="pari"): 2505 2565 """ 2506 2566 The p-th Fourier coefficient of the modular form corresponding to 2507 2567 this elliptic curve, where p is prime. 2508 2568 2569 - ``algorithm`` - std (default: "pari") 2570 2571 - "pari" - Use PARI's implementation of ellaplist 2572 2573 - "smalljac" - Use the smalljac library, if installed 2574 2575 2509 2576 EXAMPLES:: 2510 2577 2511 2578 sage: E=EllipticCurve('37a1') 2512 2579 sage: [E.ap(p) for p in prime_range(50)] 2513 2580 [-2, -3, -2, -1, -5, -2, 0, 0, 2, 6, -4, -1, -9, 2, -9] 2514 """ 2581 2582 If the ``smalljac`` libary is installed, we can use it:: 2583 2584 sage: [E.ap(p, algorithm="smalljac") for p in prime_range(50)] # optional: smalljac 2585 [-2, -3, -2, -1, -5, -2, 0, 0, 2, 6, -4, -1, -9, 2, -9] 2586 """ 2587 2515 2588 if not arith.is_prime(p): 2516 2589 raise ArithmeticError, "p must be prime" 2517 return Integer(self.pari_mincurve().ellap(p)) 2590 2591 if algorithm == "pari": 2592 return Integer(self.pari_mincurve().ellap(p)) 2593 elif algorithm == "smalljac": 2594 proxy = self._smalljac() 2595 ap = proxy.ap(p) 2596 if ap is None: 2597 # Let PARI handle the icky case 2598 return self.ap(p, algorithm="pari") 2599 else: 2600 return Integer(ap) 2601 elif algorithm == "all": 2602 pari_results = self.ap(p, algorithm="pari") 2603 smalljac_results = self.ap(p, algorithm="smalljac") 2604 assert pari_results == smalljac_results, "An error has occured, and SmallJac's and PARI's results are not the same" 2605 return smalljac_results 2518 2606 2519 2607 def quadratic_twist(self, D): 2520 2608 """ … … 4683 4771 """ 4684 4772 return self.conductor().is_squarefree() 4685 4773 4686 def is_ordinary(self, p, ell=None ):4774 def is_ordinary(self, p, ell=None, algorithm="pari"): 4687 4775 """ 4688 4776 Return True precisely when the mod-p representation attached to 4689 this elliptic curve is ordinary at ell. 4777 this elliptic curve is ordinary at ell. The ``algorithm`` 4778 argument has the same values as that for ``aplist``. 4690 4779 4691 4780 INPUT: 4692 4781 … … 4708 4797 """ 4709 4798 if ell is None: 4710 4799 ell = p 4711 return self.ap(ell ) % p != 04800 return self.ap(ell, algorithm=algorithm) % p != 0 4712 4801 4713 4802 def is_good(self, p, check=True): 4714 4803 """ … … 4768 4857 ell = p 4769 4858 return self.is_good(p) and not self.is_ordinary(p, ell) 4770 4859 4771 def supersingular_primes(self, B ):4860 def supersingular_primes(self, B, algorithm="pari"): 4772 4861 """ 4773 4862 Return a list of all supersingular primes for this elliptic curve 4774 up to and possibly including B. 4863 up to and possibly including B. The ``algorithm`` argument has 4864 the same values as that for ``aplist``. 4775 4865 4776 4866 EXAMPLES:: 4777 4867 … … 4797 4887 sage: e.supersingular_primes(1) 4798 4888 [] 4799 4889 """ 4800 v = self.aplist(max(B, 3) )4890 v = self.aplist(max(B, 3), algorithm=algorithm) 4801 4891 P = rings.prime_range(max(B,3)+1) 4802 4892 N = self.conductor() 4803 4893 return [P[i] for i in [0,1] if P[i] <= B and v[i]%P[i]==0 and N%P[i] != 0] + \ 4804 4894 [P[i] for i in range(2,len(v)) if v[i] == 0 and N%P[i] != 0] 4805 4895 4806 def ordinary_primes(self, B ):4896 def ordinary_primes(self, B, algorithm="pari"): 4807 4897 """ 4808 4898 Return a list of all ordinary primes for this elliptic curve up to 4809 and possibly including B. 4899 and possibly including B. The ``algorithm`` argument has the same 4900 values as that for ``aplist``. 4810 4901 4811 4902 EXAMPLES:: 4812 4903 … … 4829 4920 sage: e.ordinary_primes(1) 4830 4921 [] 4831 4922 """ 4832 v = self.aplist(max(B, 3) 4923 v = self.aplist(max(B, 3), algorithm=algorithm) 4833 4924 P = rings.prime_range(max(B,3) +1) 4834 4925 return [P[i] for i in [0,1] if P[i] <= B and v[i]%P[i]!=0] +\ 4835 4926 [P[i] for i in range(2,len(v)) if v[i] != 0] -
sage/schemes/hyperelliptic_curves/hyperelliptic_g2_finite_field.py
diff --git a/sage/schemes/hyperelliptic_curves/hyperelliptic_g2_finite_field.py b/sage/schemes/hyperelliptic_curves/hyperelliptic_g2_finite_field.py
a b 13 13 class HyperellipticCurve_g2_finite_field( 14 14 hyperelliptic_g2_generic.HyperellipticCurve_g2_generic, 15 15 hyperelliptic_finite_field.HyperellipticCurve_finite_field): 16 pass17 16 17 def _smalljac(self): 18 r""" 19 Computes and caches the smalljac representation of the given 20 curve. For internal use only. 21 22 EXAMPLES:: 23 24 sage: R.<x> = GF(next_prime(10^5))[] 25 sage: hec = HyperellipticCurve(x^5 + 17*x^4 - 318*x^3 + 2*x - 17) 26 sage: hec._smalljac() # optional: smalljac 27 Smalljac curve defined by x^5 + 17*x^4 + 99685*x^3 + 2*x + 99986 28 """ 29 30 try: 31 return self._smalljac_proxy 32 except AttributeError: 33 try: 34 import sage.libs.smalljac.all as smalljac 35 except ImportError: 36 raise RuntimeError, "smalljac not installed or inaccessible" 37 38 f, h = self.hyperelliptic_polynomials() 39 assert h == 0, "SmallJac can only does with hyperelliptic polynomials in Weirstrass form" 40 s = str(f) 41 self._smalljac_proxy = smalljac.SmallJac(s) 42 return self._smalljac_proxy 43 44 def jacobian_structure(self, algorithm="smalljac"): 45 r""" 46 Returns the group structure of the group of points on this 47 elliptic curve. Unlike ``abelian_group``, it does not compute 48 the generators of the group, just the structure, and is thus 49 perhaps somewhat less useful. 50 51 INPUT: 52 53 - ``algorithm`` - so far, only ``"smalljac"`` is supported, 54 which uses Drew Sutherland's SmallJac library for the 55 computation. SmallJac can only be used on degree-1 fields. 56 57 OUTPUT: 58 59 An ``AdditiveAbelianGroup`` representing the group structure 60 of the jacobian of the curve. 61 62 EXAMPLES: 63 64 We can take an arbitrary curve and ask for the jacobian's 65 structure:: 66 67 sage: R.<x> = GF(next_prime(10^5))[] 68 sage: hec = HyperellipticCurve(x^5 + 17*x^4 - 318*x^3 + 2*x - 17) 69 sage: hec.jacobian_structure() # optional: smalljac 70 Additive abelian group isomorphic to Z/2 + Z/4974328512 71 """ 72 73 from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup 74 75 if algorithm == "smalljac": 76 K = self.base_ring() 77 assert K.degree() == 1, "Smalljac can only find group structures in degree-1 fields" 78 p = K.cardinality() 79 proxy = self._smalljac() 80 structure = proxy.group(p) 81 return AdditiveAbelianGroup(structure) 82 else: 83 raise ValueError("Unknown algorithm `%s`" % algorithm) -
sage/schemes/hyperelliptic_curves/hyperelliptic_g2_rational_field.py
diff --git a/sage/schemes/hyperelliptic_curves/hyperelliptic_g2_rational_field.py b/sage/schemes/hyperelliptic_curves/hyperelliptic_g2_rational_field.py
a b 9 9 #***************************************************************************** 10 10 11 11 import hyperelliptic_g2_generic, hyperelliptic_rational_field 12 from sage.rings.integer import Integer 12 13 13 14 class HyperellipticCurve_g2_rational_field( 14 15 hyperelliptic_g2_generic.HyperellipticCurve_g2_generic, 15 16 hyperelliptic_rational_field.HyperellipticCurve_rational_field): 16 pass 17 18 def _smalljac(self): 19 r""" 20 Computes and caches the smalljac representation of the given 21 curve. For internal use only. 22 23 EXAMPLES:: 24 25 sage: R.<x> = QQ[] 26 sage: hec = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 27 sage: hec._smalljac() # optional: smalljac 28 Smalljac curve defined by x^5 + 2*x^4 - x^3 - 3*x^2 - x 29 sage: hec = HyperellipticCurve(x^5 + 17*x^4 - 318*x^3 + 2*x - 17) 30 sage: hec._smalljac() # optional: smalljac 31 Smalljac curve defined by x^5 + 17*x^4 - 318*x^3 + 2*x - 17 32 """ 33 34 try: 35 return self._smalljac_proxy 36 except AttributeError: 37 try: 38 import sage.libs.smalljac.all as smalljac 39 except ImportError: 40 raise RuntimeError, "smalljac not installed or inaccessible" 41 42 f, h = self.hyperelliptic_polynomials() 43 assert h == 0, "SmallJac can only does with hyperelliptic polynomials in Weirstrass form" 44 s = str(f) 45 self._smalljac_proxy = smalljac.SmallJac(s) 46 return self._smalljac_proxy 47 48 def aplists(self, limit, algorithm="smalljac", container=list, index="primes", raw=False): 49 """ 50 Computes the traces of Frobenius at the prime ideals of the 51 base number field, sorted by the norm of these ideals. So 52 far, this method requires the Smalljac library. 53 54 INPUT: 55 56 - ``limit`` - either an integer, in which case the prime 57 ideals will have norm less than this limit, or [a, b], in 58 which case the prime ideals with norms between ``a`` and 59 ``b`, inclusive, are used. 60 61 - ``algorithm`` - so far, only "smalljac" is supported, which 62 uses Drew Sutherland's smalljac library for elliptic curve 63 structure computation. 64 65 - The remainder (``container``, ``index``, and ``raw``) define 66 the format of the result; see ``EllipticCurve.aplists`` for 67 a description. 68 69 OUTPUT: 70 71 A list of traces of Frobenius at various primes; the format is 72 precisely specified by the ``container``, ``index``, and 73 ``raw`` arguments. If a curve has a bad reduction at a prime, 74 ``None`` is instead returned. 75 76 EXAMPLES: 77 78 We can find the trace of Frobenius at a given prime: 79 80 sage: R.<x> = QQ[] 81 sage: hec = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 82 sage: hec.aplists([17, 17]) # optional: smalljac 83 [(17, [-9])] 84 85 Or in a range: 86 87 sage: hec.aplists(100) # optional: smalljac 88 [(2, [None]), (3, [-1]), (5, [3]), (7, [None]), (11, [-3]), (13, [0]), 89 (17, [-9]), (19, [-7]), (23, [15]), (29, [-12]), (31, [-5]), (37, [5]), 90 (41, [0]), (43, [0]), (47, [-3]), (53, [9]), (59, [-9]), (61, [15]), 91 (67, [9]), (71, [0]), (73, [3]), (79, [-9]), (83, [24]), (89, [-21]), 92 (97, [0])] 93 sage: hec.aplists([50, 100]) # optional: smalljac 94 [(53, [9]), (59, [-9]), (61, [15]), (67, [9]), (71, [0]), (73, [3]), 95 (79, [-9]), (83, [24]), (89, [-21]), (97, [0])] 96 97 The raw results are suitable for large-scale statistics: 98 99 sage: __builtins__.sum(ap for p, ap in hec.aplists(10^4, raw=True) if ap) # optional: smalljac 100 1900 101 sage: __builtins__.sum(ap for p, ap in hec.aplists(2 * 10^4, raw=True) if ap) # optional: smalljac 102 1925 103 sage: __builtins__.sum(ap for p, ap in hec.aplists(3 * 10^4, raw=True) if ap) # optional: smalljac 104 5451 105 """ 106 107 import sage.libs.smalljac.util as util 108 109 start, end = util.parse_limits(limit) 110 111 if algorithm == "smalljac": 112 proxy = self._smalljac() 113 res = proxy.ap(start, end) 114 115 def make_int(p, v): 116 return Integer(v) 117 118 return util.interpret_smalljac_results( 119 res, correction_fn=None, construct_fn=make_int, 120 raw=raw, index=index, container=container) 121 else: 122 raise ValueError("Algorithm %s not defined" % algorithm) 123 124 def aps(self, p): 125 """ 126 Returns a list of traces of Frobenius when this elliptic curve 127 is reduced at prime ideals of norm ``p``. 128 129 INPUT: 130 131 - ``p`` - The integer prime at which to reduce. 132 133 OUTPUT: 134 135 A list of traces of Frobenius, or None if there was a bad 136 reduction. 137 138 EXAMPLES: 139 140 We can take a curve and find arbitrary traces:: 141 142 sage: R.<x> = QQ[] 143 sage: hec = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 144 sage: hec.aps(17) # optional: smalljac 145 [-9] 146 sage: hec.aps(next_prime(10^6)) # optional: smalljac 147 [909] 148 sage: hec.aps(next_prime(10^8)) # optional: smalljac 149 [27651] 150 """ 151 152 res = self.aplists([p, p]) 153 154 return res[0][1] # [0] extracts the prime we care about, [1] extracts the list of traces 155 156 def grouplists(self, limit, algorithm="smalljac", container=list, index="primes", raw=False): 157 r""" 158 Computes the group structure of reductions at the prime ideals 159 of the base number field, sorted by the norm of these ideals. 160 So far, this method requires the Smalljac library. 161 162 INPUT: 163 164 - ``limit`` - either an integer, in which case the prime 165 ideals will have norm less than this limit, or [a, b], in 166 which case the prime ideals with norms between ``a`` and 167 ``b`, inclusive, are used. 168 169 - ``algorithm`` - so far, only "smalljac" is supported, which 170 uses Drew Sutherland's smalljac library for elliptic curve 171 structure computation. 172 173 - The remainder (``container``, ``index``, and ``raw``) define 174 the format of the result; see ``EllipticCurve.aplists`` for 175 a description. 176 177 OUTPUT: 178 179 A list of group structures of Jacobians at various primes; the 180 format is precisely specified by the ``container``, ``index``, 181 and ``raw`` arguments. If a curve has a bad reduction at a prime, 182 ``None`` is instead returned. 183 184 EXAMPLES: 185 186 You can construct a hyperelliptic curve and ask for its 187 Jacobian's group structure at a certain prime:: 188 189 sage: R.<x> = QQ[] 190 sage: hec = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 191 sage: hec.grouplists([17, 17]) # optional: smalljac 192 [(17, [Additive abelian group isomorphic to Z/4 + Z/124])] 193 194 195 Check for larger group lists; 4 elements 196 197 sage: hec2 = HyperellipticCurve(x^5 + x) 198 sage: hec2.grouplists([17, 17]) # optional: smalljac 199 [(17, [Additive abelian group isomorphic to Z/2 + Z/2 + Z/12 + Z/12])] 200 201 Or in a range:: 202 203 sage: hec.grouplists([80, 100]) # optional: smalljac 204 [(83, [Additive abelian group isomorphic to Z/2 + Z/2 + Z/36 + Z/36]), 205 (89, [Additive abelian group isomorphic to Z/8 + Z/1256]), 206 (97, [Additive abelian group isomorphic to Z/2 + Z/2 + Z/2 + Z/1158])] 207 208 The raw results are suitable for larger-scale statistics:: 209 210 sage: def jac_checksum(poly): 211 ... hec = HyperellipticCurve(poly) 212 ... sum = __builtins__.sum 213 ... return sum(sum(gs) for p, gs in hec.grouplists([3, 10000], raw=True) if gs) 214 sage: jac_checksum(x^5-x) # optional: smalljac 215 2083547730 216 sage: jac_checksum(x^5+5*x^3+5*x) # optional: smalljac 217 18393758619 218 sage: jac_checksum(x^5+1) # optional: smalljac 219 19340969888 220 sage: jac_checksum(x^5+x^3+2*x) # optional: smalljac 221 12945578110 222 sage: jac_checksum(x^5-10*x^2-9*x+2) # optional: smalljac 223 12917177585 224 sage: jac_checksum(x^5+3*x^4+4*x^2-9*x+1) # optional: smalljac 225 12614952542 226 sage: jac_checksum(x^5-x+1) # optional: smalljac 227 28462483128 228 """ 229 230 from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup 231 import sage.libs.smalljac.util as util 232 233 start, end = util.parse_limits(limit) 234 235 if algorithm == "smalljac": 236 proxy = self._smalljac() 237 res = proxy.group(start, end) 238 239 def make_group(p, v): 240 return AdditiveAbelianGroup(v) 241 242 return util.interpret_smalljac_results( 243 res, correction_fn=None, construct_fn=make_group, 244 raw=raw, index=index, container=container) 245 else: 246 raise ValueError("Algorithm %s not defined" % algorithm) 247 248 def lpolylists(self, limit, normalize=False, algorithm="smalljac", container=list, index="primes", raw=False): 249 r""" 250 Computes the L-polynomials of reductions at the prime ideals 251 of the base number field, sorted by the norm of these ideals. 252 So far, this method requires the Smalljac library. 253 254 INPUT: 255 256 - ``limit`` - either an integer, in which case the prime 257 ideals will have norm less than this limit, or ``[a, b]``, 258 in which case the prime ideals with norms between ``a`` and 259 ``b`, inclusive, are used. 260 261 - ``normalize`` - whether to return normalized L-polynomials. 262 By default, non-normalized L-polynomials are returned. 263 264 - ``algorithm`` - so far, only "smalljac" is supported, which 265 uses Drew Sutherland's smalljac library for elliptic curve 266 structure computation. 267 268 - The remainder (``container``, ``index``, and ``raw``) define 269 the format of the result; see ``EllipticCurve.aplists`` for 270 a description. 271 272 OUTPUT: 273 274 A list of L-polynomials of reductions at various primes; the 275 format is precisely specified by the ``container``, ``index``, 276 and ``raw`` arguments. If a curve has a bad reduction at a 277 prime, ``None`` is instead returned. 278 279 EXAMPLES: 280 281 You can construct a hyperelliptic curve and ask for its 282 L-polynomials at a certain prime: 283 284 sage: R2.<y> = QQ[] 285 sage: E = HyperellipticCurve(y^5 + 2*y^4 - y^3 - 3*y^2 - y) 286 sage: E.lpolylists([89, 89]) # optional: smalljac 287 [(89, [7921*T^4 + 1869*T^3 + 236*T^2 + 21*T + 1])] 288 289 Or in a range: 290 291 sage: E.lpolylists([80, 90]) # optional: smalljac 292 [(83, [6889*T^4 - 1992*T^3 + 310*T^2 - 24*T + 1]), 293 (89, [7921*T^4 + 1869*T^3 + 236*T^2 + 21*T + 1])] 294 295 You can also get normalized L-polynomials: 296 297 sage: E.lpolylists([80, 100], normalize=True) # optional: smalljac 298 [(83, [T^4 - 2.63434223975257*T^3 + 3.00000000000000*T^2 - 299 2.63434223975257*T + 1.00000000000000]), 300 (89, [T^4 + 2.22599554801336*T^3 + 2.00000000000000*T^2 + 301 2.22599554801336*T + 1.00000000000000]), 302 (97, [T^4 - 2.00000000000000*T^2 + 1.00000000000000])] 303 """ 304 305 from sage.rings.polynomial.polynomial_ring import PolynomialRing_field 306 from sage.rings.real_mpfr import RR 307 from sage.rings.rational_field import QQ 308 from math import sqrt 309 import sage.libs.smalljac.util as util 310 311 start, end = util.parse_limits(limit) 312 313 if algorithm == "smalljac": 314 proxy = self._smalljac() 315 res = proxy.lpoly(start, end) 316 317 if normalize: 318 polynomial_ring = PolynomialRing_field(RR, 'T') 319 else: 320 polynomial_ring = PolynomialRing_field(QQ, 'T') 321 t = polynomial_ring.gens()[0] # I don't want a T 322 323 def make_lpoly(p, coeffs): 324 if not normalize: 325 a1, a2 = coeffs 326 return p**2*t**4 + a1*p*t**3 + a2*t**2 + a1*t + 1 327 else: 328 a1, a2 = coeffs 329 a2 /= p 330 a1 /= sqrt(p) 331 return t**4 + a1*t**3 + a2*t**2 + a1*t + 1 332 333 return util.interpret_smalljac_results( 334 res, correction_fn=None, construct_fn=make_lpoly, 335 raw=raw, index=index, container=container) 336 else: 337 raise ValueError("Algorithm %s not defined" % algorithm) 338 339 def trace_histogram(self, limit, buckets=None): 340 """ 341 Computes the traces of reductions of this curve at all primes 342 in a range, and returns how many, normalized, fell in each 343 of ``buckets`` buckets from -2 to 2. 344 345 INPUT: 346 347 - ``limits`` - Either an integer, meaning all primes below that 348 integer are used, or a list of ``[start, end]``, in which 349 case all primes from ``start`` to ``end``, inclusive, are 350 used. 351 352 - ``buckets`` - How many buckets to split the range $[-2, 2]$ 353 into. By default, the number of buckets is the square root 354 of the range size. 355 356 OUTPUT: 357 358 A list of integers, as many as the ``buckets`` parameter, 359 denoting the number of trace values fell into that bucket for 360 primes in the given range. 361 362 EXAMPLES: 363 364 We can take a hyperelliptic curve and compute a histogram for it:: 365 366 sage: R.<x> = QQ[] 367 sage: E3 = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 368 sage: E3.trace_histogram(100) # optional: smalljac 369 [0L, 0L, 4L, 4L, 2L, 6L, 4L, 1L, 2L, 0L] 370 371 In this case, the default choice of 10 buckets was made. 372 Instead, you can specify the number of bucket manually:: 373 374 sage: E3.trace_histogram(100000, buckets=10) # optional: smalljac 375 [126L, 401L, 722L, 1317L, 1420L, 3098L, 1255L, 722L, 403L, 126L] 376 377 You can choose a range that starts anywhere, not just at 1:: 378 379 sage: E3.trace_histogram([1000, 2000], buckets=10) # optional: smalljac 380 [6L, 7L, 5L, 17L, 16L, 45L, 23L, 5L, 8L, 3L] 381 382 This is generally useful for making histograms; a quick way to 383 do this is with ``bar_chart``, though custom graphing code 384 will look better. :: 385 386 sage: bar_chart(E3.trace_histogram(100000), width=1) 387 """ 388 389 import sage.libs.smalljac.util as util 390 from math import sqrt 391 392 start, end = util.parse_limits(limit) 393 394 if buckets is None: 395 range_size = end - start + 1 396 buckets = int(sqrt(range_size)) 397 398 return map(Integer, 399 self._smalljac().sato_tate_buckets(buckets, start, end)) 400 401 def moments(self, limits, moments=11): 402 """ 403 Compute the moments of the distributions of the coefficients 404 of the L-polynomials of this curve, reduced at primes in a 405 range. 406 407 INPUT: 408 409 - ``limits`` - Either an integer, meaning all primes below that 410 integer are used, or a list of ``[start, end]``, in which 411 case all primes from ``start`` to ``end``, inclusive, are 412 used. 413 414 - ``moments`` - How many moments to return; fewer moments 415 might be faster to compute. For now, at most 10 moments can 416 be computed. 417 418 OUTPUT: 419 420 A tuple whose first element is a list of moments of the 421 distribution of the $a_1$ coefficients of L-polynomials of 422 this curve, starting from the zeroth moment being 0, and whose 423 second element is a similar list for the $a_2$ coefficients. 424 The list is as long as ``moments``; that is, if ``moments`` is 425 5, only the zero through fourth moments are returned. 426 427 EXAMPLES: 428 429 You can request the moments of an arbitrary curve:: 430 431 sage: R.<x> = QQ[] 432 sage: he = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 433 sage: he.moments(10000) # optional: smalljac 434 ([1.0, -0.012809677791304501, 2.0318601033357764, 435 -0.022492869661964197, 12.332650329303904, 436 -0.08293711910285241, 104.79583112542458, 437 1.4982847405159512, 1046.380403999994, 58.11982235337913, 438 11453.36487528555], 439 [0.0, 1.0190697892939953, 4.013283796035834, 440 11.252490719416159, 45.18973261805002, 441 179.65488417712342, 796.9073238931065, 442 3636.7510997563845, 17306.79323001631, 84297.73197858929, 443 419658.09474476246]) 444 445 You can request fewer moments if you wish:: 446 447 sage: he.moments(10000, moments=3) # optional: smalljac 448 ([1.0, -0.012809677791304501, 2.0318601033357764], 449 [0.0, 1.0190697892939953, 4.013283796035834]) 450 451 Or compute in any range:: 452 453 sage: he.moments([1000, 2000], moments=5) # optional: smalljac 454 ([1.0, 0.012019115191429789, 2.360758977244879, 455 0.7305838739637142, 17.033614832007466], 456 [0.0, 1.0981854467458285, 4.588416007826706, 457 14.81342939310661, 62.822935207983335]) 458 """ 459 460 import sage.libs.smalljac.util as util 461 462 start, end = util.parse_limits(limits) 463 if moments > 11: 464 raise ValueError("Only up to 11 moments supported for now.") 465 466 return self._smalljac().moments(moments, start, end) 467 468 def guess_sato_tate_group(self, limit=None): 469 """ 470 Provide a preliminary guess toward the Sato-Tate group 471 corresponding to this curve, by considering its reduction at 472 primes up to a certain limit. 473 474 INPUT: 475 476 - ``limit`` - The maximal prime considered. The search may 477 terminate earlier if an answer is found. Or, ``None``, to 478 use an implementation-defined (but very large) maximum. 479 480 OUTPUT: 481 482 A string containing the name of the corresponding Sato-Tate 483 group. To interpret these, a copy of "Sato-Tate distributions 484 and Galois endomorphism modules in genus 2", [fkrs]_, may be 485 helpful. If no provisional identification can be made, 486 returns ``None`` 487 488 .. TODO: 489 - Should output a textual description of the Sato-Tate group 490 491 EXAMPLES: 492 493 Just create a hyperelliptic curve of genus 2 and call 494 ``guess_sato_tate_group`` to start it off:: 495 496 sage: R.<x> = QQ[] 497 sage: he = HyperellipticCurve(x^5 + 2*x^4 - x^3 - 3*x^2 - x) 498 sage: he.guess_sato_tate_group(100000) # long time - 4 seconds, optional: smalljac 499 'E_6' 500 sage: he = HyperellipticCurve(x^5 + x) 501 sage: he.guess_sato_tate_group(100000) # optional: smalljac 502 'D_{2,1}' 503 sage: he = HyperellipticCurve(x^5 + 2*x) 504 sage: he.guess_sato_tate_group(100000) # optional: smalljac 505 'D_{4,1}' 506 """ 507 508 if limit is None: 509 limit = 0 510 511 return self._smalljac().guess_group(limit) -
setup.py
diff --git a/setup.py b/setup.py
a b 944 944 'sage.libs.cremona', 945 945 'sage.libs.mpmath', 946 946 'sage.libs.lcalc', 947 'sage.libs.smalljac', 947 948 948 949 'sage.logic', 949 950