| 1 | """ |
|---|
| 2 | PARI C-library interface |
|---|
| 3 | |
|---|
| 4 | AUTHORS: |
|---|
| 5 | -- William Stein (2006-03-01): updated to work with PARI 2.2.12-beta |
|---|
| 6 | (this involved changing almost every doc strings, among other |
|---|
| 7 | things; the precision behavior of PARI seems to change |
|---|
| 8 | from any version to the next...). |
|---|
| 9 | -- William Stein (2006-03-06): added newtonpoly |
|---|
| 10 | -- Justin Walker: contributed some of the function definitions |
|---|
| 11 | -- Gonzalo Tornaria: improvements to conversions; much better error handling. |
|---|
| 12 | |
|---|
| 13 | EXAMPLES: |
|---|
| 14 | sage: pari('5! + 10/x') |
|---|
| 15 | (120*x + 10)/x |
|---|
| 16 | sage: pari('intnum(x=0,13,sin(x)+sin(x^2) + x)') |
|---|
| 17 | 85.18856819515268446242866615 # 32-bit |
|---|
| 18 | 85.188568195152684462428666150825866897 # 64-bit |
|---|
| 19 | sage: f = pari('x^3-1') |
|---|
| 20 | sage: v = f.factor(); v |
|---|
| 21 | [x - 1, 1; x^2 + x + 1, 1] |
|---|
| 22 | sage: v[0] # indexing is 0-based unlike in GP. |
|---|
| 23 | [x - 1, x^2 + x + 1]~ |
|---|
| 24 | sage: v[1] |
|---|
| 25 | [1, 1]~ |
|---|
| 26 | |
|---|
| 27 | Arithmetic obeys the usual coercion rules. |
|---|
| 28 | sage: type(pari(1) + 1) |
|---|
| 29 | <type 'sage.libs.pari.gen.gen'> |
|---|
| 30 | sage: type(1 + pari(1)) |
|---|
| 31 | <type 'sage.libs.pari.gen.gen'> |
|---|
| 32 | """ |
|---|
| 33 | |
|---|
| 34 | import math |
|---|
| 35 | import types |
|---|
| 36 | import operator |
|---|
| 37 | import sage.structure.element |
|---|
| 38 | from sage.structure.element cimport ModuleElement, RingElement, Element |
|---|
| 39 | from sage.structure.parent cimport Parent |
|---|
| 40 | |
|---|
| 41 | #include '../../ext/interrupt.pxi' |
|---|
| 42 | include 'pari_err.pxi' |
|---|
| 43 | include 'setlvalue.pxi' |
|---|
| 44 | include '../../ext/stdsage.pxi' |
|---|
| 45 | |
|---|
| 46 | cdef extern from "convert.h": |
|---|
| 47 | cdef void ZZ_to_t_INT( GEN *g, mpz_t value ) |
|---|
| 48 | |
|---|
| 49 | # Make sure we don't use mpz_t_offset before initializing it by |
|---|
| 50 | # putting in a value that's likely to provoke a segmentation fault, |
|---|
| 51 | # rather than silently corrupting memory. |
|---|
| 52 | cdef long mpz_t_offset = 1000000000 |
|---|
| 53 | |
|---|
| 54 | # The unique running Pari instance. |
|---|
| 55 | cdef PariInstance pari_instance, P |
|---|
| 56 | #pari_instance = PariInstance(200000000, 500000) |
|---|
| 57 | #pari_instance = PariInstance(100000000, 500000) |
|---|
| 58 | #pari_instance = PariInstance(75000000, 500000) |
|---|
| 59 | #pari_instance = PariInstance(50000000, 500000) |
|---|
| 60 | pari_instance = PariInstance(8000000, 500000) |
|---|
| 61 | P = pari_instance # shorthand notation |
|---|
| 62 | |
|---|
| 63 | # so Galois groups are represented in a sane way |
|---|
| 64 | # See the polgalois section of the PARI users manual. |
|---|
| 65 | new_galois_format = 1 |
|---|
| 66 | |
|---|
| 67 | cdef pari_sp mytop, initial_bot, initial_top |
|---|
| 68 | |
|---|
| 69 | # keep track of the stack |
|---|
| 70 | cdef pari_sp stack_avma |
|---|
| 71 | |
|---|
| 72 | # real precision |
|---|
| 73 | cdef unsigned long prec |
|---|
| 74 | prec = GP_DATA.fmt.sigd |
|---|
| 75 | |
|---|
| 76 | # Also a copy of PARI accessible from external pure python code. |
|---|
| 77 | pari = pari_instance |
|---|
| 78 | |
|---|
| 79 | # temp variables |
|---|
| 80 | cdef GEN t0,t1,t2,t3,t4 |
|---|
| 81 | t0heap = [0]*5 |
|---|
| 82 | |
|---|
| 83 | cdef t0GEN(x): |
|---|
| 84 | global t0 |
|---|
| 85 | t0 = P.toGEN(x, 0) |
|---|
| 86 | |
|---|
| 87 | cdef t1GEN(x): |
|---|
| 88 | global t1 |
|---|
| 89 | t1 = P.toGEN(x, 1) |
|---|
| 90 | |
|---|
| 91 | cdef t2GEN(x): |
|---|
| 92 | global t2 |
|---|
| 93 | t2 = P.toGEN(x, 2) |
|---|
| 94 | |
|---|
| 95 | cdef t3GEN(x): |
|---|
| 96 | global t3 |
|---|
| 97 | t3 = P.toGEN(x, 3) |
|---|
| 98 | |
|---|
| 99 | cdef t4GEN(x): |
|---|
| 100 | global t4 |
|---|
| 101 | t4 = P.toGEN(x, 4) |
|---|
| 102 | |
|---|
| 103 | cdef object Integer |
|---|
| 104 | |
|---|
| 105 | cdef void late_import(): |
|---|
| 106 | global Integer |
|---|
| 107 | |
|---|
| 108 | if Integer is not None: |
|---|
| 109 | return |
|---|
| 110 | |
|---|
| 111 | import sage.rings.integer |
|---|
| 112 | Integer = sage.rings.integer.Integer |
|---|
| 113 | |
|---|
| 114 | global mpz_t_offset |
|---|
| 115 | mpz_t_offset = sage.rings.integer.mpz_t_offset_python |
|---|
| 116 | |
|---|
| 117 | cdef class gen(sage.structure.element.RingElement): |
|---|
| 118 | """ |
|---|
| 119 | Python extension class that models the PARI GEN type. |
|---|
| 120 | """ |
|---|
| 121 | def __init__(self): |
|---|
| 122 | self.b = 0 |
|---|
| 123 | self._parent = P |
|---|
| 124 | |
|---|
| 125 | def parent(self): |
|---|
| 126 | return pari_instance |
|---|
| 127 | |
|---|
| 128 | cdef void init(self, GEN g, pari_sp b): |
|---|
| 129 | """ |
|---|
| 130 | g -- PARI GEN |
|---|
| 131 | b -- pointer to memory chunk where PARI gen lives |
|---|
| 132 | (if nonzero then this memory is freed when the object |
|---|
| 133 | goes out of scope) |
|---|
| 134 | """ |
|---|
| 135 | self.g = g |
|---|
| 136 | self.b = b |
|---|
| 137 | self._parent = P |
|---|
| 138 | |
|---|
| 139 | def __dealloc__(self): |
|---|
| 140 | if self.b: |
|---|
| 141 | sage_free(<void*> self.b) |
|---|
| 142 | |
|---|
| 143 | def __repr__(self): |
|---|
| 144 | return P.GEN_to_str(self.g) |
|---|
| 145 | |
|---|
| 146 | def __hash__(self): |
|---|
| 147 | return hash(P.GEN_to_str(self.g)) |
|---|
| 148 | |
|---|
| 149 | def _testclass(self): |
|---|
| 150 | import test |
|---|
| 151 | T = test.testclass() |
|---|
| 152 | T._init(self) |
|---|
| 153 | return T |
|---|
| 154 | |
|---|
| 155 | cdef GEN _gen(self): |
|---|
| 156 | return self.g |
|---|
| 157 | |
|---|
| 158 | def list(self): |
|---|
| 159 | if typ(self.g) == t_POL: |
|---|
| 160 | raise NotImplementedError, \ |
|---|
| 161 | "please report, t_POL.list() is broken, should not be used!" |
|---|
| 162 | if typ(self.g) == t_SER: |
|---|
| 163 | raise NotImplementedError, \ |
|---|
| 164 | "please report, t_SER.list() is broken, should not be used!" |
|---|
| 165 | #return list(self.Vecrev()) |
|---|
| 166 | return list(self.Vec()) |
|---|
| 167 | |
|---|
| 168 | def __reduce__(self): |
|---|
| 169 | """ |
|---|
| 170 | EXAMPLES: |
|---|
| 171 | sage: f = pari('x^3 - 3') |
|---|
| 172 | sage: loads(dumps(f)) == f |
|---|
| 173 | True |
|---|
| 174 | """ |
|---|
| 175 | s = str(self) |
|---|
| 176 | import sage.libs.pari.gen_py |
|---|
| 177 | return sage.libs.pari.gen_py.pari, (s,) |
|---|
| 178 | |
|---|
| 179 | cdef ModuleElement _add_c_impl(self, ModuleElement right): |
|---|
| 180 | _sig_on |
|---|
| 181 | return P.new_gen(gadd(self.g, (<gen>right).g)) |
|---|
| 182 | |
|---|
| 183 | def _add_unsafe(gen self, gen right): |
|---|
| 184 | """ |
|---|
| 185 | VERY FAST addition of self and right on stack (and leave on |
|---|
| 186 | stack) without any type checking. |
|---|
| 187 | |
|---|
| 188 | Basically, this is often about 10 times faster than just typing "self + right". |
|---|
| 189 | The drawback is that (1) if self + right would give an error in PARI, it will |
|---|
| 190 | totally crash SAGE, and (2) the memory used by self + right is *never* |
|---|
| 191 | returned -- it gets allocated on the PARI stack and will never be freed. |
|---|
| 192 | |
|---|
| 193 | EXAMPLES: |
|---|
| 194 | sage: pari(2)._add_unsafe(pari(3)) |
|---|
| 195 | 5 |
|---|
| 196 | """ |
|---|
| 197 | global mytop |
|---|
| 198 | cdef GEN z |
|---|
| 199 | cdef gen w |
|---|
| 200 | z = gadd(self.g, right.g) |
|---|
| 201 | w = PY_NEW(gen) |
|---|
| 202 | w.init(z,0) |
|---|
| 203 | mytop = avma |
|---|
| 204 | return w |
|---|
| 205 | |
|---|
| 206 | cdef ModuleElement _sub_c_impl(self, ModuleElement right): |
|---|
| 207 | _sig_on |
|---|
| 208 | return P.new_gen(gsub(self.g, (<gen> right).g)) |
|---|
| 209 | |
|---|
| 210 | def _sub_unsafe(gen self, gen right): |
|---|
| 211 | """ |
|---|
| 212 | VERY FAST subtraction of self and right on stack (and leave on |
|---|
| 213 | stack) without any type checking. |
|---|
| 214 | |
|---|
| 215 | Basically, this is often about 10 times faster than just typing "self - right". |
|---|
| 216 | The drawback is that (1) if self - right would give an error in PARI, it will |
|---|
| 217 | totally crash SAGE, and (2) the memory used by self + right is *never* |
|---|
| 218 | returned -- it gets allocated on the PARI stack and will never be freed. |
|---|
| 219 | |
|---|
| 220 | EXAMPLES: |
|---|
| 221 | sage: pari(2)._sub_unsafe(pari(3)) |
|---|
| 222 | -1 |
|---|
| 223 | """ |
|---|
| 224 | global mytop |
|---|
| 225 | cdef GEN z |
|---|
| 226 | cdef gen w |
|---|
| 227 | z = gsub(self.g, right.g) |
|---|
| 228 | w = PY_NEW(gen) |
|---|
| 229 | w.init(z, 0) |
|---|
| 230 | mytop = avma |
|---|
| 231 | return w |
|---|
| 232 | |
|---|
| 233 | cdef RingElement _mul_c_impl(self, RingElement right): |
|---|
| 234 | _sig_on |
|---|
| 235 | return P.new_gen(gmul(self.g, (<gen>right).g)) |
|---|
| 236 | |
|---|
| 237 | def _mul_unsafe(gen self, gen right): |
|---|
| 238 | """ |
|---|
| 239 | VERY FAST multiplication of self and right on stack (and leave on |
|---|
| 240 | stack) without any type checking. |
|---|
| 241 | |
|---|
| 242 | Basically, this is often about 10 times faster than just typing "self * right". |
|---|
| 243 | The drawback is that (1) if self - right would give an error in PARI, it will |
|---|
| 244 | totally crash SAGE, and (2) the memory used by self + right is *never* |
|---|
| 245 | returned -- it gets allocated on the PARI stack and will never be freed. |
|---|
| 246 | |
|---|
| 247 | EXAMPLES: |
|---|
| 248 | sage: pari(2)._mul_unsafe(pari(3)) |
|---|
| 249 | 6 |
|---|
| 250 | """ |
|---|
| 251 | global mytop |
|---|
| 252 | cdef GEN z |
|---|
| 253 | cdef gen w |
|---|
| 254 | z = gmul(self.g, right.g) |
|---|
| 255 | w = PY_NEW(gen) |
|---|
| 256 | w.init(z, 0) |
|---|
| 257 | mytop = avma |
|---|
| 258 | return w |
|---|
| 259 | |
|---|
| 260 | cdef RingElement _div_c_impl(self, RingElement right): |
|---|
| 261 | _sig_on |
|---|
| 262 | return P.new_gen(gdiv(self.g, (<gen>right).g)) |
|---|
| 263 | |
|---|
| 264 | def _div_unsafe(gen self, gen right): |
|---|
| 265 | """ |
|---|
| 266 | VERY FAST division of self and right on stack (and leave on |
|---|
| 267 | stack) without any type checking. |
|---|
| 268 | |
|---|
| 269 | Basically, this is often about 10 times faster than just typing "self / right". |
|---|
| 270 | The drawback is that (1) if self - right would give an error in PARI, it will |
|---|
| 271 | totally crash SAGE, and (2) the memory used by self + right is *never* |
|---|
| 272 | returned -- it gets allocated on the PARI stack and will never be freed. |
|---|
| 273 | |
|---|
| 274 | EXAMPLES: |
|---|
| 275 | sage: pari(2)._div_unsafe(pari(3)) |
|---|
| 276 | 2/3 |
|---|
| 277 | """ |
|---|
| 278 | global mytop |
|---|
| 279 | cdef GEN z |
|---|
| 280 | cdef gen w |
|---|
| 281 | z = gdiv(self.g, right.g) |
|---|
| 282 | w = PY_NEW(gen) |
|---|
| 283 | w.init(z, 0) |
|---|
| 284 | mytop = avma |
|---|
| 285 | return w |
|---|
| 286 | |
|---|
| 287 | ################################################################# |
|---|
| 288 | |
|---|
| 289 | def _mod(gen self, gen other): |
|---|
| 290 | _sig_on |
|---|
| 291 | return P.new_gen(gmod(self.g, other.g)) |
|---|
| 292 | |
|---|
| 293 | def __mod__(self, other): |
|---|
| 294 | if isinstance(self, gen) and isinstance(other, gen): |
|---|
| 295 | return self._mod(other) |
|---|
| 296 | return sage.structure.element.bin_op(self, other, operator.mod) |
|---|
| 297 | |
|---|
| 298 | def __pow__(self, n, m): |
|---|
| 299 | t0GEN(self) |
|---|
| 300 | t1GEN(n) |
|---|
| 301 | _sig_on |
|---|
| 302 | return P.new_gen(gpow(t0, t1, prec)) |
|---|
| 303 | |
|---|
| 304 | def __neg__(gen self): |
|---|
| 305 | _sig_on |
|---|
| 306 | return P.new_gen(gneg(self.g)) |
|---|
| 307 | |
|---|
| 308 | def __xor__(gen self, n): |
|---|
| 309 | raise RuntimeError, "Use ** for exponentiation, not '^', which means xor\n"+\ |
|---|
| 310 | "in Python, and has the wrong precedence." |
|---|
| 311 | |
|---|
| 312 | def __rshift__(gen self, long n): |
|---|
| 313 | _sig_on |
|---|
| 314 | return P.new_gen(gshift(self.g, -n)) |
|---|
| 315 | |
|---|
| 316 | def __lshift__(gen self, long n): |
|---|
| 317 | _sig_on |
|---|
| 318 | return P.new_gen(gshift(self.g, n)) |
|---|
| 319 | |
|---|
| 320 | def __invert__(gen self): |
|---|
| 321 | _sig_on |
|---|
| 322 | return P.new_gen(ginv(self.g)) |
|---|
| 323 | |
|---|
| 324 | ########################################### |
|---|
| 325 | # ACCESS |
|---|
| 326 | ########################################### |
|---|
| 327 | #def __getattr__(self, attr): |
|---|
| 328 | def getattr(self, attr): |
|---|
| 329 | t0GEN(str(self) + '.' + str(attr)) |
|---|
| 330 | return self.new_gen(t0) |
|---|
| 331 | |
|---|
| 332 | def __getitem__(gen self, n): |
|---|
| 333 | """ |
|---|
| 334 | Return a *copy* of the nth entry. |
|---|
| 335 | |
|---|
| 336 | The indexing is 0-based, like in Python. However, *copying* |
|---|
| 337 | the nth entry instead of returning reference is different |
|---|
| 338 | than what one usually does in Python. However, we do it |
|---|
| 339 | this way for consistency with the PARI/GP interpreter, which |
|---|
| 340 | does make copies. |
|---|
| 341 | |
|---|
| 342 | EXAMPLES: |
|---|
| 343 | sage: p = pari('1 + 2*x + 3*x^2') |
|---|
| 344 | sage: p[0] |
|---|
| 345 | 1 |
|---|
| 346 | sage: p[2] |
|---|
| 347 | 3 |
|---|
| 348 | sage: p[100] |
|---|
| 349 | 0 |
|---|
| 350 | sage: p[-1] |
|---|
| 351 | 0 |
|---|
| 352 | sage: q = pari('x^2 + 3*x^3 + O(x^6)') |
|---|
| 353 | sage: q[3] |
|---|
| 354 | 3 |
|---|
| 355 | sage: q[5] |
|---|
| 356 | 0 |
|---|
| 357 | sage: q[6] |
|---|
| 358 | Traceback (most recent call last): |
|---|
| 359 | ... |
|---|
| 360 | IndexError: index out of bounds |
|---|
| 361 | sage: m = pari('[1,2;3,4]') |
|---|
| 362 | sage: m[0] |
|---|
| 363 | [1, 3]~ |
|---|
| 364 | sage: m[1,0] |
|---|
| 365 | 3 |
|---|
| 366 | sage: l = pari('List([1,2,3])') |
|---|
| 367 | sage: l[1] |
|---|
| 368 | 2 |
|---|
| 369 | sage: s = pari('"hello, world!"') |
|---|
| 370 | sage: s[0] |
|---|
| 371 | 'h' |
|---|
| 372 | sage: s[4] |
|---|
| 373 | 'o' |
|---|
| 374 | sage: s[12] |
|---|
| 375 | '!' |
|---|
| 376 | sage: s[13] |
|---|
| 377 | Traceback (most recent call last): |
|---|
| 378 | ... |
|---|
| 379 | IndexError: index out of bounds |
|---|
| 380 | sage: v = pari('[1,2,3]') |
|---|
| 381 | sage: v[0] |
|---|
| 382 | 1 |
|---|
| 383 | sage: c = pari('Col([1,2,3])') |
|---|
| 384 | sage: c[1] |
|---|
| 385 | 2 |
|---|
| 386 | sage: sv = pari('Vecsmall([1,2,3])') |
|---|
| 387 | sage: sv[2] |
|---|
| 388 | 3 |
|---|
| 389 | sage: type(sv[2]) |
|---|
| 390 | <type 'int'> |
|---|
| 391 | sage: tuple(pari(3/5)) |
|---|
| 392 | (3, 5) |
|---|
| 393 | sage: tuple(pari('1 + 5*I')) |
|---|
| 394 | (1, 5) |
|---|
| 395 | sage: tuple(pari('Qfb(1, 2, 3)')) |
|---|
| 396 | (1, 2, 3) |
|---|
| 397 | sage: pari(57)[0] |
|---|
| 398 | Traceback (most recent call last): |
|---|
| 399 | ... |
|---|
| 400 | TypeError: unindexable object |
|---|
| 401 | |
|---|
| 402 | """ |
|---|
| 403 | if typ(self.g) in (t_INT, t_REAL, t_PADIC, t_QUAD): |
|---|
| 404 | # these are definitely scalar! |
|---|
| 405 | raise TypeError, "unindexable object" |
|---|
| 406 | |
|---|
| 407 | if typ(self.g) in (t_INTMOD, t_POLMOD): |
|---|
| 408 | # if we keep going we would get: |
|---|
| 409 | # [0] = modulus |
|---|
| 410 | # [1] = lift to t_INT or t_POL |
|---|
| 411 | # do we want this? maybe the other way around? |
|---|
| 412 | raise TypeError, "unindexable object" |
|---|
| 413 | |
|---|
| 414 | #if typ(self.g) in (t_FRAC, t_RFRAC): |
|---|
| 415 | # generic code gives us: |
|---|
| 416 | # [0] = numerator |
|---|
| 417 | # [1] = denominator |
|---|
| 418 | |
|---|
| 419 | #if typ(self.g) == t_COMPLEX: |
|---|
| 420 | # generic code gives us |
|---|
| 421 | # [0] = real part |
|---|
| 422 | # [1] = imag part |
|---|
| 423 | |
|---|
| 424 | #if type(self.g) in (t_QFR, t_QFI): |
|---|
| 425 | # generic code works ok |
|---|
| 426 | |
|---|
| 427 | if typ(self.g) == t_POL: |
|---|
| 428 | return self.polcoeff(n) |
|---|
| 429 | |
|---|
| 430 | if typ(self.g) == t_SER: |
|---|
| 431 | bound = valp(self.g) + lg(self.g) - 2 |
|---|
| 432 | if n >= bound: |
|---|
| 433 | raise IndexError, "index out of bounds" |
|---|
| 434 | return self.polcoeff(n) |
|---|
| 435 | |
|---|
| 436 | if isinstance(n, tuple): |
|---|
| 437 | if typ(self.g) != t_MAT: |
|---|
| 438 | raise TypeError, "an integer is required" |
|---|
| 439 | if len(n) != 2: |
|---|
| 440 | raise TypeError, "index must be an integer or a 2-tuple (i,j)" |
|---|
| 441 | i, j = n[0], n[1] |
|---|
| 442 | if i < 0 or i >= self.nrows(): |
|---|
| 443 | raise IndexError, "row index out of bounds" |
|---|
| 444 | if j < 0 or j >= self.ncols(): |
|---|
| 445 | raise IndexError, "column index out of bounds" |
|---|
| 446 | return P.new_ref(gmael(self.g,j+1,i+1), self) |
|---|
| 447 | |
|---|
| 448 | if n < 0 or n >= glength(self.g): |
|---|
| 449 | raise IndexError, "index out of bounds" |
|---|
| 450 | if typ(self.g) == t_LIST: |
|---|
| 451 | return P.new_ref(gel(self.g,n+2), self) |
|---|
| 452 | if typ(self.g) == t_STR: |
|---|
| 453 | return chr( (<char *>(self.g+1))[n] ) |
|---|
| 454 | if typ(self.g) == t_VECSMALL: |
|---|
| 455 | return self.g[n+1] |
|---|
| 456 | return P.new_ref(gel(self.g,n+1), self) |
|---|
| 457 | |
|---|
| 458 | |
|---|
| 459 | def __getslice__(self, Py_ssize_t i, Py_ssize_t j): |
|---|
| 460 | """ |
|---|
| 461 | EXAMPLES: |
|---|
| 462 | sage: v = pari(xrange(20)) |
|---|
| 463 | sage: v[2:5] |
|---|
| 464 | [2, 3, 4] |
|---|
| 465 | sage: v[:] |
|---|
| 466 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|---|
| 467 | sage: v[10:] |
|---|
| 468 | [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|---|
| 469 | sage: v[:5] |
|---|
| 470 | [0, 1, 2, 3, 4] |
|---|
| 471 | sage: v |
|---|
| 472 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|---|
| 473 | sage: v[-1] |
|---|
| 474 | Traceback (most recent call last): |
|---|
| 475 | ... |
|---|
| 476 | IndexError: index out of bounds |
|---|
| 477 | sage: v[:-3] |
|---|
| 478 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] |
|---|
| 479 | sage: v[5:] |
|---|
| 480 | [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
|---|
| 481 | """ |
|---|
| 482 | cdef long l, k |
|---|
| 483 | l = glength(self.g) |
|---|
| 484 | if j >= l: j = l |
|---|
| 485 | if i < 0: i = 0 |
|---|
| 486 | if j <= i: return P.vector(0) |
|---|
| 487 | v = P.vector(j-i) |
|---|
| 488 | for k from i <= k < j: |
|---|
| 489 | v[k-i] = self[k] |
|---|
| 490 | return v |
|---|
| 491 | |
|---|
| 492 | def gen_length(gen self): |
|---|
| 493 | return lg(self.g) |
|---|
| 494 | |
|---|
| 495 | def __setitem__(gen self, n, y): |
|---|
| 496 | r""" |
|---|
| 497 | Set the nth entry to a reference to y. |
|---|
| 498 | |
|---|
| 499 | \begin{notice} |
|---|
| 500 | \begin{itemize} |
|---|
| 501 | \item There is a known BUG: If v is a vector and entry i of v is a vector, |
|---|
| 502 | \code{v[i][j] = x} |
|---|
| 503 | should set entry j of v[i] to x. Instead it sets it to nonsense. |
|---|
| 504 | I do not understand why this occurs. The following is a safe way |
|---|
| 505 | to do the same thing: |
|---|
| 506 | \code{tmp = v[i]; tmp[j] = x } |
|---|
| 507 | |
|---|
| 508 | \item The indexing is 0-based, like everywhere else in Python, but |
|---|
| 509 | \emph{unlike} in GP/PARI. |
|---|
| 510 | |
|---|
| 511 | \item Assignment sets the nth entry to a reference to y, |
|---|
| 512 | assuming y is an object of type gen. This is the same |
|---|
| 513 | as in Python, but \emph{different} than what happens in the |
|---|
| 514 | gp interpreter, where assignment makes a copy of y. |
|---|
| 515 | |
|---|
| 516 | \item Because setting creates references it is \emph{possible} to |
|---|
| 517 | make circular references, unlike in GP. Do \emph{not} do |
|---|
| 518 | this (see the example below). If you need circular |
|---|
| 519 | references, work at the Python level (where they work |
|---|
| 520 | well), not the PARI object level. |
|---|
| 521 | \end{itemize} |
|---|
| 522 | \end{notice} |
|---|
| 523 | |
|---|
| 524 | EXAMPLES: |
|---|
| 525 | sage: v = pari(range(10)) |
|---|
| 526 | sage: v |
|---|
| 527 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
|---|
| 528 | sage: v[0] = 10 |
|---|
| 529 | sage: w = pari([5,8,-20]) |
|---|
| 530 | sage: v |
|---|
| 531 | [10, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
|---|
| 532 | sage: v[1] = w |
|---|
| 533 | sage: v |
|---|
| 534 | [10, [5, 8, -20], 2, 3, 4, 5, 6, 7, 8, 9] |
|---|
| 535 | sage: w[0] = -30 |
|---|
| 536 | sage: v |
|---|
| 537 | [10, [-30, 8, -20], 2, 3, 4, 5, 6, 7, 8, 9] |
|---|
| 538 | sage: t = v[1]; t[1] = 10 # don't do v[1][1] !!! (because of mysterious BUG...) |
|---|
| 539 | sage: v |
|---|
| 540 | [10, [-30, 10, -20], 2, 3, 4, 5, 6, 7, 8, 9] |
|---|
| 541 | sage: w |
|---|
| 542 | [-30, 10, -20] |
|---|
| 543 | |
|---|
| 544 | Finally, we create a circular reference: |
|---|
| 545 | sage: v = pari([0]) |
|---|
| 546 | sage: w = pari([v]) |
|---|
| 547 | sage: v |
|---|
| 548 | [0] |
|---|
| 549 | sage: w |
|---|
| 550 | [[0]] |
|---|
| 551 | sage: v[0] = w |
|---|
| 552 | sage: # Now there is a circular reference. Trying to access v[0] will crash SAGE. |
|---|
| 553 | |
|---|
| 554 | """ |
|---|
| 555 | cdef gen x |
|---|
| 556 | _sig_on |
|---|
| 557 | x = pari(y) |
|---|
| 558 | if isinstance(n, tuple): |
|---|
| 559 | try: |
|---|
| 560 | self.refers_to[n] = x |
|---|
| 561 | except TypeError: |
|---|
| 562 | self.refers_to = {n:x} |
|---|
| 563 | i = n[0] |
|---|
| 564 | j = n[1] |
|---|
| 565 | if i < 0 or i >= self.nrows(): |
|---|
| 566 | raise IndexError, "row i(=%s) must be between 0 and %s"%(i,self.nrows()) |
|---|
| 567 | if j < 0 or j >= self.ncols(): |
|---|
| 568 | raise IndexError, "column j(=%s) must be between 0 and %s"%(j,self.ncols()) |
|---|
| 569 | (<GEN>(self.g)[j+1])[i+1] = <long> x.g |
|---|
| 570 | return |
|---|
| 571 | |
|---|
| 572 | if n < 0 or n >= glength(self.g): |
|---|
| 573 | raise IndexError, "index (%s) must be between 0 and %s"%(n,glength(self.g)-1) |
|---|
| 574 | |
|---|
| 575 | # so python memory manager will work correctly |
|---|
| 576 | # and not free x if PARI part of self is the |
|---|
| 577 | # only thing pointing to it. |
|---|
| 578 | try: |
|---|
| 579 | self.refers_to[n] = x |
|---|
| 580 | except TypeError: |
|---|
| 581 | self.refers_to = {n:x} |
|---|
| 582 | |
|---|
| 583 | if typ(self.g) == t_POL: |
|---|
| 584 | n = n + 1 |
|---|
| 585 | (self.g)[n+1] = <long>(x.g) |
|---|
| 586 | |
|---|
| 587 | def __len__(gen self): |
|---|
| 588 | return glength(self.g) |
|---|
| 589 | |
|---|
| 590 | |
|---|
| 591 | |
|---|
| 592 | ########################################### |
|---|
| 593 | # comparisons |
|---|
| 594 | # I had to rewrite PARI's compare, since |
|---|
| 595 | # otherwise trapping signals and other horrible, |
|---|
| 596 | # memory-leaking and slow stuff occurs. |
|---|
| 597 | ########################################### |
|---|
| 598 | |
|---|
| 599 | def __richcmp__(left, right, int op): |
|---|
| 600 | return (<Element>left)._richcmp(right, op) |
|---|
| 601 | |
|---|
| 602 | cdef int _cmp_c_impl(left, Element right) except -2: |
|---|
| 603 | """ |
|---|
| 604 | Comparisons |
|---|
| 605 | |
|---|
| 606 | First uses PARI's cmp routine; if it decides the objects are |
|---|
| 607 | not comparable, it then compares the underlying strings (since |
|---|
| 608 | in Python all objects are supposed to be comparable). |
|---|
| 609 | |
|---|
| 610 | EXAMPLES: |
|---|
| 611 | sage: a = pari(5) |
|---|
| 612 | sage: b = 10 |
|---|
| 613 | sage: a < b |
|---|
| 614 | True |
|---|
| 615 | sage: a <= b |
|---|
| 616 | True |
|---|
| 617 | sage: a <= 5 |
|---|
| 618 | True |
|---|
| 619 | sage: a > b |
|---|
| 620 | False |
|---|
| 621 | sage: a >= b |
|---|
| 622 | False |
|---|
| 623 | sage: a >= pari(10) |
|---|
| 624 | False |
|---|
| 625 | sage: a == 5 |
|---|
| 626 | True |
|---|
| 627 | sage: a is 5 |
|---|
| 628 | False |
|---|
| 629 | |
|---|
| 630 | sage: pari(2.5) > None |
|---|
| 631 | False |
|---|
| 632 | sage: pari(3) == pari(3) |
|---|
| 633 | True |
|---|
| 634 | sage: pari('x^2 + 1') == pari('I-1') |
|---|
| 635 | False |
|---|
| 636 | sage: pari(I) == pari(I) |
|---|
| 637 | True |
|---|
| 638 | """ |
|---|
| 639 | return gcmp_sage(left.g, (<gen>right).g) |
|---|
| 640 | |
|---|
| 641 | def copy(gen self): |
|---|
| 642 | return P.new_gen(forcecopy(self.g)) |
|---|
| 643 | |
|---|
| 644 | ########################################### |
|---|
| 645 | # Conversion --> Python |
|---|
| 646 | # Try to convert to a meaningful python object |
|---|
| 647 | # in various ways |
|---|
| 648 | ########################################### |
|---|
| 649 | |
|---|
| 650 | def list_str(gen self): |
|---|
| 651 | """ |
|---|
| 652 | Return str that might correctly evaluate to a Python-list. |
|---|
| 653 | """ |
|---|
| 654 | s = str(self) |
|---|
| 655 | if s[:4] == "Mat(": |
|---|
| 656 | s = "[" + s[4:-1] + "]" |
|---|
| 657 | s = s.replace("~","") |
|---|
| 658 | if s.find(";") != -1: |
|---|
| 659 | s = s.replace(";","], [") |
|---|
| 660 | s = "[" + s + "]" |
|---|
| 661 | return eval(s) |
|---|
| 662 | else: |
|---|
| 663 | return eval(s) |
|---|
| 664 | |
|---|
| 665 | def __hex__(gen self): |
|---|
| 666 | """ |
|---|
| 667 | Return the hexadecimal digits of self in lower case. |
|---|
| 668 | |
|---|
| 669 | EXAMPLES: |
|---|
| 670 | sage: print hex(pari(0)) |
|---|
| 671 | 0 |
|---|
| 672 | sage: print hex(pari(15)) |
|---|
| 673 | f |
|---|
| 674 | sage: print hex(pari(16)) |
|---|
| 675 | 10 |
|---|
| 676 | sage: print hex(pari(16938402384092843092843098243)) |
|---|
| 677 | 36bb1e3929d1a8fe2802f083 |
|---|
| 678 | sage: print hex(long(16938402384092843092843098243)) |
|---|
| 679 | 0x36bb1e3929d1a8fe2802f083L |
|---|
| 680 | sage: print hex(pari(-16938402384092843092843098243)) |
|---|
| 681 | -36bb1e3929d1a8fe2802f083 |
|---|
| 682 | """ |
|---|
| 683 | cdef GEN x |
|---|
| 684 | cdef long lx, *xp |
|---|
| 685 | cdef long w |
|---|
| 686 | cdef char *s, *sp |
|---|
| 687 | cdef char *hexdigits |
|---|
| 688 | hexdigits = "0123456789abcdef" |
|---|
| 689 | cdef int i, j |
|---|
| 690 | cdef int size |
|---|
| 691 | x = self.g |
|---|
| 692 | if typ(x) != t_INT: |
|---|
| 693 | raise TypeError, "gen must be of PARI type t_INT" |
|---|
| 694 | if not signe(x): |
|---|
| 695 | return "0" |
|---|
| 696 | lx = lgefint(x)-2 # number of words |
|---|
| 697 | size = lx*2*BYTES_IN_LONG |
|---|
| 698 | s = <char *>sage_malloc(size+2) # 1 char for sign, 1 char for '\0' |
|---|
| 699 | sp = s + size+1 |
|---|
| 700 | sp[0] = 0 |
|---|
| 701 | xp = int_LSW(x) |
|---|
| 702 | for i from 0 <= i < lx: |
|---|
| 703 | w = xp[0] |
|---|
| 704 | for j from 0 <= j < 2*BYTES_IN_LONG: |
|---|
| 705 | sp = sp-1 |
|---|
| 706 | sp[0] = hexdigits[w & 15] |
|---|
| 707 | w = w>>4 |
|---|
| 708 | xp = int_nextW(xp) |
|---|
| 709 | # remove leading zeros! |
|---|
| 710 | while sp[0] == c'0': |
|---|
| 711 | sp = sp+1 |
|---|
| 712 | if signe(x) < 0: |
|---|
| 713 | sp = sp-1 |
|---|
| 714 | sp[0] = c'-' |
|---|
| 715 | k = sp |
|---|
| 716 | sage_free(s) |
|---|
| 717 | return k |
|---|
| 718 | |
|---|
| 719 | def __int__(gen self): |
|---|
| 720 | """ |
|---|
| 721 | Return Python int. Very fast, and if the number is too large to |
|---|
| 722 | fit into a C int, a Python long is returned instead. |
|---|
| 723 | |
|---|
| 724 | EXAMPLES: |
|---|
| 725 | |
|---|
| 726 | sage: int(pari(0)) |
|---|
| 727 | 0 |
|---|
| 728 | sage: int(pari(10)) |
|---|
| 729 | 10 |
|---|
| 730 | sage: int(pari(-10)) |
|---|
| 731 | -10 |
|---|
| 732 | sage: int(pari(123456789012345678901234567890)) |
|---|
| 733 | 123456789012345678901234567890L |
|---|
| 734 | sage: int(pari(-123456789012345678901234567890)) |
|---|
| 735 | -123456789012345678901234567890L |
|---|
| 736 | sage: int(pari(2^31-1)) |
|---|
| 737 | 2147483647 |
|---|
| 738 | sage: int(pari(-2^31)) |
|---|
| 739 | -2147483648 |
|---|
| 740 | """ |
|---|
| 741 | cdef GEN x |
|---|
| 742 | cdef long lx, *xp |
|---|
| 743 | if typ(self.g)==t_POL and self.poldegree()<=0: |
|---|
| 744 | # this is a work around for the case that e.g. |
|---|
| 745 | # GF(q).random_element() returns zero, which is of type |
|---|
| 746 | # t_POL(MOD) |
|---|
| 747 | x = polcoeff0(self.g,0,self.get_var(-1)) |
|---|
| 748 | else: |
|---|
| 749 | x = self.g |
|---|
| 750 | if typ(x) != t_INT: |
|---|
| 751 | raise TypeError, "gen must be of PARI type t_INT or t_POL of degree 0" |
|---|
| 752 | if not signe(x): |
|---|
| 753 | return 0 |
|---|
| 754 | lx = lgefint(x)-3 # take 1 to account for the MSW |
|---|
| 755 | xp = int_MSW(x) |
|---|
| 756 | # special case 1 word so we return int if it fits |
|---|
| 757 | if not lx: |
|---|
| 758 | if signe(x) | xp[0] > 0: # both positive |
|---|
| 759 | return xp[0] |
|---|
| 760 | elif signe(x) & -xp[0] < 0: # both negative |
|---|
| 761 | return -xp[0] |
|---|
| 762 | i = <ulong>xp[0] |
|---|
| 763 | while lx: |
|---|
| 764 | xp = int_precW(xp) |
|---|
| 765 | i = i << BITS_IN_LONG | <ulong>xp[0] |
|---|
| 766 | lx = lx-1 |
|---|
| 767 | if signe(x) > 0: |
|---|
| 768 | return i |
|---|
| 769 | else: |
|---|
| 770 | return -i |
|---|
| 771 | # NOTE: Could use int_unsafe below, which would be much faster, but |
|---|
| 772 | # the default PARI prints annoying stuff to the screen when |
|---|
| 773 | # the number is large. |
|---|
| 774 | |
|---|
| 775 | def int_unsafe(gen self): |
|---|
| 776 | """ |
|---|
| 777 | Returns int form of self, but raises an exception if int does |
|---|
| 778 | not fit into a long integer. |
|---|
| 779 | |
|---|
| 780 | This is about 5 times faster than the usual int conversion. |
|---|
| 781 | """ |
|---|
| 782 | return gtolong(self.g) |
|---|
| 783 | |
|---|
| 784 | def intvec_unsafe(self): |
|---|
| 785 | """ |
|---|
| 786 | Returns Python int list form of entries of self, but raises an |
|---|
| 787 | exception if int does not fit into a long integer. Here self |
|---|
| 788 | must be a vector. |
|---|
| 789 | """ |
|---|
| 790 | cdef int n, L |
|---|
| 791 | cdef object v |
|---|
| 792 | cdef GEN g |
|---|
| 793 | g = self.g |
|---|
| 794 | if typ(g) != t_VEC: |
|---|
| 795 | raise TypeError, "gen must be of PARI type t_VEC" |
|---|
| 796 | |
|---|
| 797 | L = glength(g) |
|---|
| 798 | v = [] |
|---|
| 799 | for n from 0 <= n < L: |
|---|
| 800 | v.append(gtolong(<GEN> (g[n+1]))) |
|---|
| 801 | return v |
|---|
| 802 | |
|---|
| 803 | def python_list_small(gen self): |
|---|
| 804 | """ |
|---|
| 805 | Return a Python list of the PARI gens. This object must be of |
|---|
| 806 | type t_VECSMALL, and the resulting list contains python 'int's |
|---|
| 807 | |
|---|
| 808 | EXAMPLES: |
|---|
| 809 | sage: v=pari([1,2,3,10,102,10]).Vecsmall() |
|---|
| 810 | sage: w = v.python_list_small() |
|---|
| 811 | sage: w |
|---|
| 812 | [1, 2, 3, 10, 102, 10] |
|---|
| 813 | sage: type(w[0]) |
|---|
| 814 | <type 'int'> |
|---|
| 815 | """ |
|---|
| 816 | cdef long n |
|---|
| 817 | if typ(self.g) != t_VECSMALL: |
|---|
| 818 | raise TypeError, "Object (=%s) must be of type t_VECSMALL."%self |
|---|
| 819 | V = [] |
|---|
| 820 | m = glength(self.g) |
|---|
| 821 | for n from 0 <= n < m: |
|---|
| 822 | V.append(self.g[n+1]) |
|---|
| 823 | return V |
|---|
| 824 | |
|---|
| 825 | def python_list(gen self): |
|---|
| 826 | """ |
|---|
| 827 | Return a Python list of the PARI gens. This object must be of |
|---|
| 828 | type t_VEC |
|---|
| 829 | |
|---|
| 830 | INPUT: None |
|---|
| 831 | OUTPUT: |
|---|
| 832 | list -- Python list whose elements are the |
|---|
| 833 | elements of the input gen. |
|---|
| 834 | EXAMPLES: |
|---|
| 835 | sage: v=pari([1,2,3,10,102,10]) |
|---|
| 836 | sage: w = v.python_list() |
|---|
| 837 | sage: w |
|---|
| 838 | [1, 2, 3, 10, 102, 10] |
|---|
| 839 | sage: type(w[0]) |
|---|
| 840 | <type 'sage.libs.pari.gen.gen'> |
|---|
| 841 | """ |
|---|
| 842 | if typ(self.g) != t_VEC: |
|---|
| 843 | raise TypeError, "Object (=%s) must be of type t_VEC."%self |
|---|
| 844 | cdef long n, m |
|---|
| 845 | cdef gen t |
|---|
| 846 | m = glength(self.g) |
|---|
| 847 | V = [] |
|---|
| 848 | for n from 0 <= n < m: |
|---|
| 849 | t = P.new_ref(<GEN> (self.g[n+1]), V) |
|---|
| 850 | V.append(t) |
|---|
| 851 | return V |
|---|
| 852 | |
|---|
| 853 | def python(self, precision=0, bits_prec=None): |
|---|
| 854 | """ |
|---|
| 855 | Return Python eval of self. |
|---|
| 856 | """ |
|---|
| 857 | if not bits_prec is None: |
|---|
| 858 | precision = int(bits_prec * 3.4) + 1 |
|---|
| 859 | import sage.libs.pari.gen_py |
|---|
| 860 | cdef long orig_prec |
|---|
| 861 | if precision: |
|---|
| 862 | orig_prec = P.get_real_precision() |
|---|
| 863 | P.set_real_precision(precision) |
|---|
| 864 | x = sage.libs.pari.gen_py.python(self) |
|---|
| 865 | P.set_real_precision(orig_prec) |
|---|
| 866 | return x |
|---|
| 867 | else: |
|---|
| 868 | return sage.libs.pari.gen_py.python(self) |
|---|
| 869 | |
|---|
| 870 | def _sage_(self, precision=0): |
|---|
| 871 | """ |
|---|
| 872 | Return SAGE version of self. |
|---|
| 873 | """ |
|---|
| 874 | import sage.libs.pari.gen_py |
|---|
| 875 | cdef long orig_prec |
|---|
| 876 | if precision: |
|---|
| 877 | orig_prec = P.get_real_precision() |
|---|
| 878 | P.set_real_precision(precision) |
|---|
| 879 | x = sage.libs.pari.gen_py.python(self) |
|---|
| 880 | P.set_real_precision(orig_prec) |
|---|
| 881 | return x |
|---|
| 882 | else: |
|---|
| 883 | return sage.libs.pari.gen_py.python(self) |
|---|
| 884 | |
|---|
| 885 | def _eval_(gen self): |
|---|
| 886 | return self.python() |
|---|
| 887 | |
|---|
| 888 | def __long__(gen self): |
|---|
| 889 | """ |
|---|
| 890 | Return Python long. |
|---|
| 891 | """ |
|---|
| 892 | return long(int(self)) |
|---|
| 893 | |
|---|
| 894 | def __float__(gen self): |
|---|
| 895 | """ |
|---|
| 896 | Return Python float. |
|---|
| 897 | """ |
|---|
| 898 | cdef double d |
|---|
| 899 | _sig_on |
|---|
| 900 | d = gtodouble(self.g) |
|---|
| 901 | _sig_off |
|---|
| 902 | return d |
|---|
| 903 | |
|---|
| 904 | def __nonzero__(self): |
|---|
| 905 | """ |
|---|
| 906 | EXAMPLES: |
|---|
| 907 | sage: pari('1').__nonzero__() |
|---|
| 908 | True |
|---|
| 909 | sage: pari('x').__nonzero__() |
|---|
| 910 | True |
|---|
| 911 | sage: bool(pari(0)) |
|---|
| 912 | False |
|---|
| 913 | sage: a = pari('Mod(0,3)') |
|---|
| 914 | sage: a.__nonzero__() |
|---|
| 915 | False |
|---|
| 916 | """ |
|---|
| 917 | return not gcmp0(self.g) |
|---|
| 918 | |
|---|
| 919 | |
|---|
| 920 | ########################################### |
|---|
| 921 | # arith1.c |
|---|
| 922 | ########################################### |
|---|
| 923 | def isprime(gen self, flag=0): |
|---|
| 924 | """ |
|---|
| 925 | isprime(x, flag=0): Returns True if x is a PROVEN prime |
|---|
| 926 | number, and False otherwise. |
|---|
| 927 | |
|---|
| 928 | INPUT: |
|---|
| 929 | flag -- int |
|---|
| 930 | 0 (default): use a combination of algorithms. |
|---|
| 931 | 1: certify primality using the Pocklington-Lehmer Test. |
|---|
| 932 | 2: certify primality using the APRCL test. |
|---|
| 933 | OUTPUT: |
|---|
| 934 | bool -- True or False |
|---|
| 935 | |
|---|
| 936 | EXAMPLES: |
|---|
| 937 | sage: pari(9).isprime() |
|---|
| 938 | False |
|---|
| 939 | sage: pari(17).isprime() |
|---|
| 940 | True |
|---|
| 941 | sage: n = pari(561) # smallest Carmichael number |
|---|
| 942 | sage: n.isprime() # not just a pseudo-primality test! |
|---|
| 943 | False |
|---|
| 944 | sage: n.isprime(1) |
|---|
| 945 | False |
|---|
| 946 | sage: n.isprime(2) |
|---|
| 947 | False |
|---|
| 948 | """ |
|---|
| 949 | _sig_on |
|---|
| 950 | t = bool(gisprime(self.g, flag) != stoi(0)) |
|---|
| 951 | _sig_off |
|---|
| 952 | return t |
|---|
| 953 | |
|---|
| 954 | def hclassno(gen n): |
|---|
| 955 | """ |
|---|
| 956 | Computes the Hurwitz-Kronecker class number of n. |
|---|
| 957 | |
|---|
| 958 | EXAMPLES: |
|---|
| 959 | sage: pari(-10007).hclassno() |
|---|
| 960 | 77 |
|---|
| 961 | sage: pari(-3).hclassno() |
|---|
| 962 | 1/3 |
|---|
| 963 | """ |
|---|
| 964 | _sig_on |
|---|
| 965 | return P.new_gen(hclassno(n.g)) |
|---|
| 966 | |
|---|
| 967 | def ispseudoprime(gen self, flag=0): |
|---|
| 968 | """ |
|---|
| 969 | ispseudoprime(x, flag=0): Returns True if x is a pseudo-prime |
|---|
| 970 | number, and False otherwise. |
|---|
| 971 | |
|---|
| 972 | INPUT: |
|---|
| 973 | flag -- int |
|---|
| 974 | 0 (default): checks whether x is a Baillie-Pomerance-Selfridge-Wagstaff pseudo prime (strong Rabin-Miller pseudo prime for base 2, followed by strong Lucas test for the sequence (P,-1), P smallest positive integer such that P^2 - 4 is not a square mod x). |
|---|
| 975 | > 0: checks whether x is a strong Miller-Rabin pseudo prime for flag randomly chosen bases (with end-matching to catch square roots of -1). |
|---|
| 976 | |
|---|
| 977 | OUTPUT: |
|---|
| 978 | bool -- True or False |
|---|
| 979 | |
|---|
| 980 | EXAMPLES: |
|---|
| 981 | sage: pari(9).ispseudoprime() |
|---|
| 982 | False |
|---|
| 983 | sage: pari(17).ispseudoprime() |
|---|
| 984 | True |
|---|
| 985 | sage: n = pari(561) # smallest Carmichael number |
|---|
| 986 | sage: n.ispseudoprime() # not just any old pseudo-primality test! |
|---|
| 987 | False |
|---|
| 988 | sage: n.ispseudoprime(2) |
|---|
| 989 | False |
|---|
| 990 | """ |
|---|
| 991 | cdef GEN z |
|---|
| 992 | _sig_on |
|---|
| 993 | z = gispseudoprime(self.g, flag) |
|---|
| 994 | _sig_off |
|---|
| 995 | return bool(gcmp(z, stoi(0))) |
|---|
| 996 | |
|---|
| 997 | def ispower(gen self, k=None): |
|---|
| 998 | r""" |
|---|
| 999 | Determine whether or not self is a perfect k-th power. |
|---|
| 1000 | If k is not specified, find the largest k so that self |
|---|
| 1001 | is a k-th power. |
|---|
| 1002 | |
|---|
| 1003 | NOTE: There is a BUG in the PARI C-library function (at least |
|---|
| 1004 | in PARI 2.2.12-beta) that is used to implement this function! |
|---|
| 1005 | This is in GP: |
|---|
| 1006 | \begin{verbatim} |
|---|
| 1007 | ? p=nextprime(10^100); n=p^100; m=p^2; m^50==n; ispower(n,50) |
|---|
| 1008 | \end{verbatim} |
|---|
| 1009 | |
|---|
| 1010 | INPUT: |
|---|
| 1011 | k -- int (optional) |
|---|
| 1012 | |
|---|
| 1013 | OUTPUT: |
|---|
| 1014 | power -- int, what power it is |
|---|
| 1015 | g -- what it is a power of |
|---|
| 1016 | |
|---|
| 1017 | EXAMPLES: |
|---|
| 1018 | sage: pari(9).ispower() |
|---|
| 1019 | (2, 3) |
|---|
| 1020 | sage: pari(17).ispower() |
|---|
| 1021 | (1, 17) |
|---|
| 1022 | sage: pari(17).ispower(2) |
|---|
| 1023 | (False, None) |
|---|
| 1024 | sage: pari(17).ispower(1) |
|---|
| 1025 | (1, 17) |
|---|
| 1026 | sage: pari(2).ispower() |
|---|
| 1027 | (1, 2) |
|---|
| 1028 | """ |
|---|
| 1029 | cdef int n |
|---|
| 1030 | cdef GEN x |
|---|
| 1031 | |
|---|
| 1032 | _sig_on |
|---|
| 1033 | if k is None: |
|---|
| 1034 | _sig_on |
|---|
| 1035 | n = isanypower(self.g, &x) |
|---|
| 1036 | if n == 0: |
|---|
| 1037 | _sig_off |
|---|
| 1038 | return 1, self |
|---|
| 1039 | else: |
|---|
| 1040 | return n, P.new_gen(x) |
|---|
| 1041 | else: |
|---|
| 1042 | k = int(k) |
|---|
| 1043 | t0GEN(k) |
|---|
| 1044 | _sig_on |
|---|
| 1045 | n = ispower(self.g, t0, &x) |
|---|
| 1046 | if n == 0: |
|---|
| 1047 | _sig_off |
|---|
| 1048 | return False, None |
|---|
| 1049 | else: |
|---|
| 1050 | return k, P.new_gen(x) |
|---|
| 1051 | |
|---|
| 1052 | ########################################### |
|---|
| 1053 | # 1: Standard monadic or dyadic OPERATORS |
|---|
| 1054 | ########################################### |
|---|
| 1055 | def divrem(gen x, y, var=-1): |
|---|
| 1056 | """ |
|---|
| 1057 | divrem(x, y, {v}): Euclidean division of x by y giving as a |
|---|
| 1058 | 2-dimensional column vector the quotient and the |
|---|
| 1059 | remainder, with respect to v (to main variable if v is |
|---|
| 1060 | omitted). |
|---|
| 1061 | """ |
|---|
| 1062 | t0GEN(y) |
|---|
| 1063 | _sig_on |
|---|
| 1064 | return P.new_gen(divrem(x.g, t0, P.get_var(var))) |
|---|
| 1065 | |
|---|
| 1066 | def lex(gen x, y): |
|---|
| 1067 | """ |
|---|
| 1068 | |
|---|
| 1069 | lex(x,y): Compare x and y lexicographically (1 if x>y, 0 if |
|---|
| 1070 | x==y, -1 if x<y) |
|---|
| 1071 | |
|---|
| 1072 | """ |
|---|
| 1073 | t0GEN(y) |
|---|
| 1074 | _sig_on |
|---|
| 1075 | return lexcmp(x.g, t0) |
|---|
| 1076 | |
|---|
| 1077 | def max(gen x, y): |
|---|
| 1078 | """ |
|---|
| 1079 | max(x,y): Return the maximum of x and y. |
|---|
| 1080 | """ |
|---|
| 1081 | t0GEN(y) |
|---|
| 1082 | _sig_on |
|---|
| 1083 | return P.new_gen(gmax(x.g, t0)) |
|---|
| 1084 | |
|---|
| 1085 | def min(gen x, y): |
|---|
| 1086 | """ |
|---|
| 1087 | min(x,y): Return the minumum of x and y. |
|---|
| 1088 | """ |
|---|
| 1089 | t0GEN(y) |
|---|
| 1090 | _sig_on |
|---|
| 1091 | return P.new_gen(gmin(x.g, t0)) |
|---|
| 1092 | |
|---|
| 1093 | def shift(gen x, long n): |
|---|
| 1094 | """ |
|---|
| 1095 | shift(x,n): shift x left n bits if n>=0, right -n bits if n<0. |
|---|
| 1096 | """ |
|---|
| 1097 | return P.new_gen(gshift(x.g, n)) |
|---|
| 1098 | |
|---|
| 1099 | def shiftmul(gen x, long n): |
|---|
| 1100 | """ |
|---|
| 1101 | shiftmul(x,n): Return the product of x by $2^n$. |
|---|
| 1102 | """ |
|---|
| 1103 | return P.new_gen(gmul2n(x.g, n)) |
|---|
| 1104 | |
|---|
| 1105 | def moebius(gen x): |
|---|
| 1106 | """ |
|---|
| 1107 | moebius(x): Moebius function of x. |
|---|
| 1108 | """ |
|---|
| 1109 | return P.new_gen(gmu(x.g)) |
|---|
| 1110 | |
|---|
| 1111 | def sign(gen x): |
|---|
| 1112 | """ |
|---|
| 1113 | sign(x): Return the sign of x, where x is of type integer, real |
|---|
| 1114 | or fraction. |
|---|
| 1115 | """ |
|---|
| 1116 | # Pari throws an error if you attempt to take the sign of |
|---|
| 1117 | # a complex number. |
|---|
| 1118 | _sig_on |
|---|
| 1119 | return gsigne(x.g) |
|---|
| 1120 | |
|---|
| 1121 | def vecmax(gen x): |
|---|
| 1122 | """ |
|---|
| 1123 | vecmax(x): Return the maximum of the elements of the vector/matrix x, |
|---|
| 1124 | """ |
|---|
| 1125 | _sig_on |
|---|
| 1126 | return P.new_gen(vecmax(x.g)) |
|---|
| 1127 | |
|---|
| 1128 | |
|---|
| 1129 | def vecmin(gen x): |
|---|
| 1130 | """ |
|---|
| 1131 | vecmin(x): Return the maximum of the elements of the vector/matrix x, |
|---|
| 1132 | """ |
|---|
| 1133 | _sig_on |
|---|
| 1134 | return P.new_gen(vecmin(x.g)) |
|---|
| 1135 | |
|---|
| 1136 | |
|---|
| 1137 | |
|---|
| 1138 | ########################################### |
|---|
| 1139 | # 2: CONVERSIONS and similar elementary functions |
|---|
| 1140 | ########################################### |
|---|
| 1141 | |
|---|
| 1142 | |
|---|
| 1143 | def Col(gen x): |
|---|
| 1144 | """ |
|---|
| 1145 | Col(x): Transforms the object x into a column vector. |
|---|
| 1146 | |
|---|
| 1147 | The vector will have only one component, except in the |
|---|
| 1148 | following cases: |
|---|
| 1149 | |
|---|
| 1150 | * When x is a vector or a quadratic form, the resulting |
|---|
| 1151 | vector is the initial object considered as a column |
|---|
| 1152 | vector. |
|---|
| 1153 | |
|---|
| 1154 | * When x is a matrix, the resulting vector is the column of |
|---|
| 1155 | row vectors comprising the matrix. |
|---|
| 1156 | |
|---|
| 1157 | * When x is a character string, the result is a column of |
|---|
| 1158 | individual characters. |
|---|
| 1159 | |
|---|
| 1160 | * When x is a polynomial, the coefficients of the vector |
|---|
| 1161 | start with the leading coefficient of the polynomial. |
|---|
| 1162 | |
|---|
| 1163 | * When x is a power series, only the significant |
|---|
| 1164 | coefficients are taken into account, but this time by |
|---|
| 1165 | increasing order of degree. |
|---|
| 1166 | |
|---|
| 1167 | INPUT: |
|---|
| 1168 | x -- gen |
|---|
| 1169 | OUTPUT: |
|---|
| 1170 | gen |
|---|
| 1171 | EXAMPLES: |
|---|
| 1172 | sage: pari('1.5').Col() |
|---|
| 1173 | [1.500000000000000000000000000]~ # 32-bit |
|---|
| 1174 | [1.5000000000000000000000000000000000000]~ # 64-bit |
|---|
| 1175 | sage: pari([1,2,3,4]).Col() |
|---|
| 1176 | [1, 2, 3, 4]~ |
|---|
| 1177 | sage: pari('[1,2; 3,4]').Col() |
|---|
| 1178 | [[1, 2], [3, 4]]~ |
|---|
| 1179 | sage: pari('"SAGE"').Col() |
|---|
| 1180 | ["S", "A", "G", "E"]~ |
|---|
| 1181 | sage: pari('3*x^3 + x').Col() |
|---|
| 1182 | [3, 0, 1, 0]~ |
|---|
| 1183 | sage: pari('x + 3*x^3 + O(x^5)').Col() |
|---|
| 1184 | [1, 0, 3, 0]~ |
|---|
| 1185 | """ |
|---|
| 1186 | _sig_on |
|---|
| 1187 | return P.new_gen(gtocol(x.g)) |
|---|
| 1188 | |
|---|
| 1189 | def List(gen x): |
|---|
| 1190 | """ |
|---|
| 1191 | List(x): transforms the PARI vector or list x into a list. |
|---|
| 1192 | |
|---|
| 1193 | EXAMPLES: |
|---|
| 1194 | sage: v = pari([1,2,3]) |
|---|
| 1195 | sage: v |
|---|
| 1196 | [1, 2, 3] |
|---|
| 1197 | sage: v.type() |
|---|
| 1198 | 't_VEC' |
|---|
| 1199 | sage: w = v.List() |
|---|
| 1200 | sage: w |
|---|
| 1201 | List([1, 2, 3]) |
|---|
| 1202 | sage: w.type() |
|---|
| 1203 | 't_LIST' |
|---|
| 1204 | """ |
|---|
| 1205 | _sig_on |
|---|
| 1206 | return P.new_gen(gtolist(x.g)) |
|---|
| 1207 | |
|---|
| 1208 | def Mat(gen x): |
|---|
| 1209 | """ |
|---|
| 1210 | Mat(x): Returns the matrix defined by x. |
|---|
| 1211 | |
|---|
| 1212 | * If x is already a matrix, a copy of x is created and |
|---|
| 1213 | returned. |
|---|
| 1214 | |
|---|
| 1215 | * If x is not a vector or a matrix, this function returns a |
|---|
| 1216 | 1x1 matrix. |
|---|
| 1217 | |
|---|
| 1218 | * If x is a row (resp. column) vector, this functions |
|---|
| 1219 | returns a 1-row (resp. 1-column) matrix, *unless* all |
|---|
| 1220 | elements are column (resp. row) vectors of the same |
|---|
| 1221 | length, in which case the vectors are concatenated |
|---|
| 1222 | sideways and the associated big matrix is returned. |
|---|
| 1223 | |
|---|
| 1224 | INPUT: |
|---|
| 1225 | x -- gen |
|---|
| 1226 | OUTPUT: |
|---|
| 1227 | gen -- a PARI matrix |
|---|
| 1228 | |
|---|
| 1229 | EXAMPLES: |
|---|
| 1230 | sage: x = pari(5) |
|---|
| 1231 | sage: x.type() |
|---|
| 1232 | 't_INT' |
|---|
| 1233 | sage: y = x.Mat() |
|---|
| 1234 | sage: y |
|---|
| 1235 | Mat(5) |
|---|
| 1236 | sage: y.type() |
|---|
| 1237 | 't_MAT' |
|---|
| 1238 | sage: x = pari('[1,2;3,4]') |
|---|
| 1239 | sage: x.type() |
|---|
| 1240 | 't_MAT' |
|---|
| 1241 | sage: x = pari('[1,2,3,4]') |
|---|
| 1242 | sage: x.type() |
|---|
| 1243 | 't_VEC' |
|---|
| 1244 | sage: y = x.Mat() |
|---|
| 1245 | sage: y |
|---|
| 1246 | Mat([1, 2, 3, 4]) |
|---|
| 1247 | sage: y.type() |
|---|
| 1248 | 't_MAT' |
|---|
| 1249 | |
|---|
| 1250 | sage: v = pari('[1,2;3,4]').Vec(); v |
|---|
| 1251 | [[1, 3]~, [2, 4]~] |
|---|
| 1252 | sage: v.Mat() |
|---|
| 1253 | [1, 2; 3, 4] |
|---|
| 1254 | sage: v = pari('[1,2;3,4]').Col(); v |
|---|
| 1255 | [[1, 2], [3, 4]]~ |
|---|
| 1256 | sage: v.Mat() |
|---|
| 1257 | [1, 2; 3, 4] |
|---|
| 1258 | """ |
|---|
| 1259 | _sig_on |
|---|
| 1260 | return P.new_gen(gtomat(x.g)) |
|---|
| 1261 | |
|---|
| 1262 | def Mod(gen x, y): |
|---|
| 1263 | """ |
|---|
| 1264 | Mod(x, y): Returns the object x modulo y, denoted Mod(x, y). |
|---|
| 1265 | |
|---|
| 1266 | The input y must be a an integer or a polynomial: |
|---|
| 1267 | |
|---|
| 1268 | * If y is an INTEGER, x must also be an integer, a rational |
|---|
| 1269 | number, or a p-adic number compatible with the modulus y. |
|---|
| 1270 | |
|---|
| 1271 | * If y is a POLYNOMIAL, x must be a scalar (which is not a polmod), |
|---|
| 1272 | a polynomial, a rational function, or a power series. |
|---|
| 1273 | |
|---|
| 1274 | WARNING: This function is not the same as x % y, the result of |
|---|
| 1275 | which is an integer or a polynomial. |
|---|
| 1276 | |
|---|
| 1277 | INPUT: |
|---|
| 1278 | x -- gen |
|---|
| 1279 | y -- integer or polynomial |
|---|
| 1280 | |
|---|
| 1281 | OUTPUT: |
|---|
| 1282 | gen -- intmod or polmod |
|---|
| 1283 | |
|---|
| 1284 | EXAMPLES: |
|---|
| 1285 | sage: z = pari(3) |
|---|
| 1286 | sage: x = z.Mod(pari(7)) |
|---|
| 1287 | sage: x |
|---|
| 1288 | Mod(3, 7) |
|---|
| 1289 | sage: x^2 |
|---|
| 1290 | Mod(2, 7) |
|---|
| 1291 | sage: x^100 |
|---|
| 1292 | Mod(4, 7) |
|---|
| 1293 | sage: x.type() |
|---|
| 1294 | 't_INTMOD' |
|---|
| 1295 | |
|---|
| 1296 | sage: f = pari("x^2 + x + 1") |
|---|
| 1297 | sage: g = pari("x") |
|---|
| 1298 | sage: a = g.Mod(f) |
|---|
| 1299 | sage: a |
|---|
| 1300 | Mod(x, x^2 + x + 1) |
|---|
| 1301 | sage: a*a |
|---|
| 1302 | Mod(-x - 1, x^2 + x + 1) |
|---|
| 1303 | sage: a.type() |
|---|
| 1304 | 't_POLMOD' |
|---|
| 1305 | """ |
|---|
| 1306 | t0GEN(y) |
|---|
| 1307 | _sig_on |
|---|
| 1308 | return P.new_gen(gmodulcp(x.g,t0)) |
|---|
| 1309 | |
|---|
| 1310 | def Pol(self, v=-1): |
|---|
| 1311 | """ |
|---|
| 1312 | Pol(x, {v}): convert x into a polynomial with main variable v |
|---|
| 1313 | and return the result. |
|---|
| 1314 | |
|---|
| 1315 | * If x is a scalar, returns a constant polynomial. |
|---|
| 1316 | |
|---|
| 1317 | * If x is a power series, the effect is identical |
|---|
| 1318 | to \kbd{truncate}, i.e.~it chops off the $O(X^k)$. |
|---|
| 1319 | |
|---|
| 1320 | * If x is a vector, this function creates the polynomial |
|---|
| 1321 | whose coefficients are given in x, with x[0] |
|---|
| 1322 | being the leading coefficient (which can be zero). |
|---|
| 1323 | |
|---|
| 1324 | WARNING: This is *not* a substitution function. It will not |
|---|
| 1325 | transform an object containing variables of higher priority |
|---|
| 1326 | than v: |
|---|
| 1327 | sage: pari('x+y').Pol('y') |
|---|
| 1328 | Traceback (most recent call last): |
|---|
| 1329 | ... |
|---|
| 1330 | PariError: (8) |
|---|
| 1331 | |
|---|
| 1332 | INPUT: |
|---|
| 1333 | x -- gen |
|---|
| 1334 | v -- (optional) which variable, defaults to 'x' |
|---|
| 1335 | OUTPUT: |
|---|
| 1336 | gen -- a polynomial |
|---|
| 1337 | EXAMPLES: |
|---|
| 1338 | sage: v = pari("[1,2,3,4]") |
|---|
| 1339 | sage: f = v.Pol() |
|---|
| 1340 | sage: f |
|---|
| 1341 | x^3 + 2*x^2 + 3*x + 4 |
|---|
| 1342 | sage: f*f |
|---|
| 1343 | x^6 + 4*x^5 + 10*x^4 + 20*x^3 + 25*x^2 + 24*x + 16 |
|---|
| 1344 | |
|---|
| 1345 | sage: v = pari("[1,2;3,4]") |
|---|
| 1346 | sage: v.Pol() |
|---|
| 1347 | [1, 3]~*x + [2, 4]~ |
|---|
| 1348 | """ |
|---|
| 1349 | _sig_on |
|---|
| 1350 | return P.new_gen(gtopoly(self.g, P.get_var(v))) |
|---|
| 1351 | |
|---|
| 1352 | def Polrev(self, v=-1): |
|---|
| 1353 | """ |
|---|
| 1354 | Polrev(x, {v}): Convert x into a polynomial with main variable |
|---|
| 1355 | v and return the result. This is the reverse of Pol if x is a |
|---|
| 1356 | vector, otherwise it is identical to Pol. By "reverse" we mean |
|---|
| 1357 | that the coefficients are reversed. |
|---|
| 1358 | |
|---|
| 1359 | INPUT: |
|---|
| 1360 | x -- gen |
|---|
| 1361 | OUTPUT: |
|---|
| 1362 | gen -- a polynomial |
|---|
| 1363 | EXAMPLES: |
|---|
| 1364 | sage: v = pari("[1,2,3,4]") |
|---|
| 1365 | sage: f = v.Polrev() |
|---|
| 1366 | sage: f |
|---|
| 1367 | 4*x^3 + 3*x^2 + 2*x + 1 |
|---|
| 1368 | sage: v.Pol() |
|---|
| 1369 | x^3 + 2*x^2 + 3*x + 4 |
|---|
| 1370 | sage: v.Polrev('y') |
|---|
| 1371 | 4*y^3 + 3*y^2 + 2*y + 1 |
|---|
| 1372 | |
|---|
| 1373 | Note that Polrev does *not* reverse the coefficients of a polynomial! |
|---|
| 1374 | sage: f |
|---|
| 1375 | 4*x^3 + 3*x^2 + 2*x + 1 |
|---|
| 1376 | sage: f.Polrev() |
|---|
| 1377 | 4*x^3 + 3*x^2 + 2*x + 1 |
|---|
| 1378 | sage: v = pari("[1,2;3,4]") |
|---|
| 1379 | sage: v.Polrev() |
|---|
| 1380 | [2, 4]~*x + [1, 3]~ |
|---|
| 1381 | """ |
|---|
| 1382 | _sig_on |
|---|
| 1383 | return P.new_gen(gtopolyrev(self.g, P.get_var(v))) |
|---|
| 1384 | |
|---|
| 1385 | def Qfb(gen a, b, c, D=0): |
|---|
| 1386 | """ |
|---|
| 1387 | Qfb(a,b,c,{D=0.}): Returns the binary quadratic form |
|---|
| 1388 | $$ |
|---|
| 1389 | ax^2 + bxy + cy^2. |
|---|
| 1390 | $$ |
|---|
| 1391 | The optional D is 0 by default and initializes Shanks's |
|---|
| 1392 | distance if $b^2 - 4ac > 0$. |
|---|
| 1393 | |
|---|
| 1394 | NOTE: Negative definite forms are not implemented, so use their |
|---|
| 1395 | positive definitine counterparts instead. (I.e., if f is a |
|---|
| 1396 | negative definite quadratic form, then -f is positive |
|---|
| 1397 | definite.) |
|---|
| 1398 | |
|---|
| 1399 | INPUT: |
|---|
| 1400 | a -- gen |
|---|
| 1401 | b -- gen |
|---|
| 1402 | c -- gen |
|---|
| 1403 | D -- gen (optional, defaults to 0) |
|---|
| 1404 | OUTPUT: |
|---|
| 1405 | gen -- binary quadratic form |
|---|
| 1406 | EXAMPLES: |
|---|
| 1407 | sage: pari(3).Qfb(7, 2) |
|---|
| 1408 | Qfb(3, 7, 2, 0.E-250) # 32-bit |
|---|
| 1409 | Qfb(3, 7, 2, 0.E-693) # 64-bit |
|---|
| 1410 | """ |
|---|
| 1411 | t0GEN(b); t1GEN(c); t2GEN(D) |
|---|
| 1412 | _sig_on |
|---|
| 1413 | return P.new_gen(Qfb0(a.g, t0, t1, t2, prec)) |
|---|
| 1414 | |
|---|
| 1415 | |
|---|
| 1416 | def Ser(gen x, v=-1): |
|---|
| 1417 | """ |
|---|
| 1418 | Ser(x,{v=x}): Create a power series from x with main variable v |
|---|
| 1419 | and return the result. |
|---|
| 1420 | |
|---|
| 1421 | * If x is a scalar, this gives a constant power series with |
|---|
| 1422 | precision given by the default series precision, as returned |
|---|
| 1423 | by get_series_precision(). |
|---|
| 1424 | |
|---|
| 1425 | * If x is a polynomial, the precision is the greatest of |
|---|
| 1426 | get_series_precision() and the degree of the polynomial. |
|---|
| 1427 | |
|---|
| 1428 | * If x is a vector, the precision is similarly given, and |
|---|
| 1429 | the coefficients of the vector are understood to be the |
|---|
| 1430 | coefficients of the power series starting from the |
|---|
| 1431 | constant term (i.e.~the reverse of the function Pol). |
|---|
| 1432 | |
|---|
| 1433 | WARNING: This is *not* a substitution function. It will not |
|---|
| 1434 | transform an object containing variables of higher priority than v. |
|---|
| 1435 | |
|---|
| 1436 | INPUT: |
|---|
| 1437 | x -- gen |
|---|
| 1438 | v -- PARI variable (default: x) |
|---|
| 1439 | OUTPUT: |
|---|
| 1440 | gen -- PARI object of PARI type t_SER |
|---|
| 1441 | EXAMPLES: |
|---|
| 1442 | sage: pari(2).Ser() |
|---|
| 1443 | 2 + O(x^16) |
|---|
| 1444 | sage: x = pari([1,2,3,4,5]) |
|---|
| 1445 | sage: x.Ser() |
|---|
| 1446 | 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 + O(x^5) |
|---|
| 1447 | sage: f = x.Ser('v'); print f |
|---|
| 1448 | 1 + 2*v + 3*v^2 + 4*v^3 + 5*v^4 + O(v^5) |
|---|
| 1449 | sage: pari(1)/f |
|---|
| 1450 | 1 - 2*v + v^2 + O(v^5) |
|---|
| 1451 | sage: pari(1).Ser() |
|---|
| 1452 | 1 + O(x^16) |
|---|
| 1453 | """ |
|---|
| 1454 | _sig_on |
|---|
| 1455 | return P.new_gen(gtoser(x.g, P.get_var(v))) |
|---|
| 1456 | |
|---|
| 1457 | |
|---|
| 1458 | def Set(gen x): |
|---|
| 1459 | """ |
|---|
| 1460 | Set(x): convert x into a set, i.e. a row vector of strings in |
|---|
| 1461 | increasing lexicographic order. |
|---|
| 1462 | |
|---|
| 1463 | INPUT: |
|---|
| 1464 | x -- gen |
|---|
| 1465 | OUTPUT: |
|---|
| 1466 | gen -- a vector of strings in increasing lexicographic order. |
|---|
| 1467 | EXAMPLES: |
|---|
| 1468 | sage: pari([1,5,2]).Set() |
|---|
| 1469 | ["1", "2", "5"] |
|---|
| 1470 | sage: pari([]).Set() # the empty set |
|---|
| 1471 | [] |
|---|
| 1472 | sage: pari([1,1,-1,-1,3,3]).Set() |
|---|
| 1473 | ["-1", "1", "3"] |
|---|
| 1474 | sage: pari(1).Set() |
|---|
| 1475 | ["1"] |
|---|
| 1476 | sage: pari('1/(x*y)').Set() |
|---|
| 1477 | ["1/(y*x)"] |
|---|
| 1478 | sage: pari('["bc","ab","bc"]').Set() |
|---|
| 1479 | ["ab", "bc"] |
|---|
| 1480 | """ |
|---|
| 1481 | _sig_on |
|---|
| 1482 | return P.new_gen(gtoset(x.g)) |
|---|
| 1483 | |
|---|
| 1484 | |
|---|
| 1485 | def Str(self): |
|---|
| 1486 | """ |
|---|
| 1487 | Str(self): Return the print representation of self as a PARI |
|---|
| 1488 | object is returned. |
|---|
| 1489 | |
|---|
| 1490 | INPUT: |
|---|
| 1491 | self -- gen |
|---|
| 1492 | OUTPUT: |
|---|
| 1493 | gen -- a PARI gen of type t_STR, i.e., a PARI string |
|---|
| 1494 | EXAMPLES: |
|---|
| 1495 | sage: pari([1,2,['abc',1]]).Str() |
|---|
| 1496 | [1, 2, [abc, 1]] |
|---|
| 1497 | sage: pari('[1,1, 1.54]').Str() |
|---|
| 1498 | [1, 1, 1.540000000000000000000000000] # 32-bit |
|---|
| 1499 | [1, 1, 1.5400000000000000000000000000000000000] # 64-bit |
|---|
| 1500 | sage: pari(1).Str() # 1 is automatically converted to string rep |
|---|
| 1501 | 1 |
|---|
| 1502 | sage: x = pari('x') # PARI variable "x" |
|---|
| 1503 | sage: x.Str() # is converted to string rep. |
|---|
| 1504 | x |
|---|
| 1505 | sage: x.Str().type() |
|---|
| 1506 | 't_STR' |
|---|
| 1507 | """ |
|---|
| 1508 | cdef char* c |
|---|
| 1509 | _sig_on |
|---|
| 1510 | c = GENtostr(self.g) |
|---|
| 1511 | v = self.new_gen(strtoGENstr(c)) |
|---|
| 1512 | free(c) |
|---|
| 1513 | return v |
|---|
| 1514 | |
|---|
| 1515 | |
|---|
| 1516 | def Strchr(gen x): |
|---|
| 1517 | """ |
|---|
| 1518 | Strchr(x): converts x to a string, translating each integer |
|---|
| 1519 | into a character (in ASCII). |
|---|
| 1520 | |
|---|
| 1521 | NOTE: Vecsmall is (essentially) the inverse to Strchr(). |
|---|
| 1522 | |
|---|
| 1523 | INPUT: |
|---|
| 1524 | x -- PARI vector of integers |
|---|
| 1525 | OUTPUT: |
|---|
| 1526 | gen -- a PARI string |
|---|
| 1527 | EXAMPLES: |
|---|
| 1528 | sage: pari([65,66,123]).Strchr() |
|---|
| 1529 | AB{ |
|---|
| 1530 | sage: pari('"SAGE"').Vecsmall() # pari('"SAGE"') --> PARI t_STR |
|---|
| 1531 | Vecsmall([83, 65, 71, 69]) |
|---|
| 1532 | sage: _.Strchr() |
|---|
| 1533 | SAGE |
|---|
| 1534 | sage: pari([83, 65, 71, 69]).Strchr() |
|---|
| 1535 | SAGE |
|---|
| 1536 | """ |
|---|
| 1537 | _sig_on |
|---|
| 1538 | return P.new_gen(Strchr(x.g)) |
|---|
| 1539 | |
|---|
| 1540 | def Strexpand(gen x): |
|---|
| 1541 | """ |
|---|
| 1542 | Strexpand(x): Concatenate the entries of the vector x into a |
|---|
| 1543 | single string, performing tilde expansion. |
|---|
| 1544 | |
|---|
| 1545 | NOTE: I have no clue what the point of this function is. -- William |
|---|
| 1546 | """ |
|---|
| 1547 | if x.type() != 't_VEC': |
|---|
| 1548 | raise TypeError, "x must be of type t_VEC." |
|---|
| 1549 | _sig_on |
|---|
| 1550 | return P.new_gen(Strexpand(x.g)) |
|---|
| 1551 | |
|---|
| 1552 | |
|---|
| 1553 | def Strtex(gen x): |
|---|
| 1554 | r""" |
|---|
| 1555 | Strtex(x): Translates the vector x of PARI gens to TeX format |
|---|
| 1556 | and returns the resulting concatenated strings as a PARI t_STR. |
|---|
| 1557 | |
|---|
| 1558 | INPUT: |
|---|
| 1559 | x -- gen |
|---|
| 1560 | OUTPUT: |
|---|
| 1561 | gen -- PARI t_STR (string) |
|---|
| 1562 | EXAMPLES: |
|---|
| 1563 | sage: v=pari('x^2') |
|---|
| 1564 | sage: v.Strtex() |
|---|
| 1565 | x^2 |
|---|
| 1566 | sage: v=pari(['1/x^2','x']) |
|---|
| 1567 | sage: v.Strtex() |
|---|
| 1568 | \frac{1}{x^2}x |
|---|
| 1569 | sage: v=pari(['1 + 1/x + 1/(y+1)','x-1']) |
|---|
| 1570 | sage: v.Strtex() |
|---|
| 1571 | \frac{ \left(y |
|---|
| 1572 | + 2\right) x |
|---|
| 1573 | + \left(y |
|---|
| 1574 | + 1\right) }{ \left(y |
|---|
| 1575 | + 1\right) x}x |
|---|
| 1576 | - 1 |
|---|
| 1577 | """ |
|---|
| 1578 | if x.type() != 't_VEC': |
|---|
| 1579 | x = P.vector(1, [x]) |
|---|
| 1580 | _sig_on |
|---|
| 1581 | return P.new_gen(Strtex(x.g)) |
|---|
| 1582 | |
|---|
| 1583 | def printtex(gen x): |
|---|
| 1584 | return x.Strtex() |
|---|
| 1585 | |
|---|
| 1586 | def Vec(gen x): |
|---|
| 1587 | """ |
|---|
| 1588 | Vec(x): Transforms the object x into a vector. |
|---|
| 1589 | |
|---|
| 1590 | INPUT: |
|---|
| 1591 | x -- gen |
|---|
| 1592 | OUTPUT: |
|---|
| 1593 | gen -- of PARI type t_VEC |
|---|
| 1594 | EXAMPLES: |
|---|
| 1595 | sage: pari(1).Vec() |
|---|
| 1596 | [1] |
|---|
| 1597 | sage: pari('x^3').Vec() |
|---|
| 1598 | [1, 0, 0, 0] |
|---|
| 1599 | sage: pari('x^3 + 3*x - 2').Vec() |
|---|
| 1600 | [1, 0, 3, -2] |
|---|
| 1601 | sage: pari([1,2,3]).Vec() |
|---|
| 1602 | [1, 2, 3] |
|---|
| 1603 | sage: pari('ab').Vec() |
|---|
| 1604 | [1, 0] |
|---|
| 1605 | """ |
|---|
| 1606 | _sig_on |
|---|
| 1607 | return P.new_gen(gtovec(x.g)) |
|---|
| 1608 | |
|---|
| 1609 | def Vecrev(gen x): |
|---|
| 1610 | """ |
|---|
| 1611 | Vecrev(x): Transforms the object x into a vector. |
|---|
| 1612 | Identical to Vec(x) except when x is |
|---|
| 1613 | -- a polynomial, this is the reverse of Vec. |
|---|
| 1614 | -- a power series, this includes low-order zero coefficients. |
|---|
| 1615 | -- a laurant series, raises an exception |
|---|
| 1616 | |
|---|
| 1617 | INPUT: |
|---|
| 1618 | x -- gen |
|---|
| 1619 | OUTPUT: |
|---|
| 1620 | gen -- of PARI type t_VEC |
|---|
| 1621 | EXAMPLES: |
|---|
| 1622 | sage: pari(1).Vecrev() |
|---|
| 1623 | [1] |
|---|
| 1624 | sage: pari('x^3').Vecrev() |
|---|
| 1625 | [0, 0, 0, 1] |
|---|
| 1626 | sage: pari('x^3 + 3*x - 2').Vecrev() |
|---|
| 1627 | [-2, 3, 0, 1] |
|---|
| 1628 | sage: pari([1, 2, 3]).Vecrev() |
|---|
| 1629 | [1, 2, 3] |
|---|
| 1630 | sage: pari('Col([1, 2, 3])').Vecrev() |
|---|
| 1631 | [1, 2, 3] |
|---|
| 1632 | sage: pari('[1, 2; 3, 4]').Vecrev() |
|---|
| 1633 | [[1, 3]~, [2, 4]~] |
|---|
| 1634 | sage: pari('ab').Vecrev() |
|---|
| 1635 | [0, 1] |
|---|
| 1636 | sage: pari('x^2 + 3*x^3 + O(x^5)').Vecrev() |
|---|
| 1637 | [0, 0, 1, 3, 0] |
|---|
| 1638 | sage: pari('x^-2 + 3*x^3 + O(x^5)').Vecrev() |
|---|
| 1639 | Traceback (most recent call last): |
|---|
| 1640 | ... |
|---|
| 1641 | ValueError: Vecrev() is not defined for Laurent series |
|---|
| 1642 | """ |
|---|
| 1643 | cdef long lx, vx, i |
|---|
| 1644 | cdef GEN y |
|---|
| 1645 | if typ(x.g) == t_POL: |
|---|
| 1646 | lx = lg(x.g) |
|---|
| 1647 | y = cgetg(lx-1, t_VEC) |
|---|
| 1648 | for i from 1 <= i <= lx-2: |
|---|
| 1649 | # no need to copy, since new_gen will deep copy |
|---|
| 1650 | __set_lvalue__(gel(y,i), gel(x.g,i+1)) |
|---|
| 1651 | return P.new_gen(y) |
|---|
| 1652 | elif typ(x.g) == t_SER: |
|---|
| 1653 | lx = lg(x.g) |
|---|
| 1654 | vx = valp(x.g) |
|---|
| 1655 | if vx < 0: |
|---|
| 1656 | raise ValueError, "Vecrev() is not defined for Laurent series" |
|---|
| 1657 | y = cgetg(vx+lx-1, t_VEC) |
|---|
| 1658 | for i from 1 <= i <= vx: |
|---|
| 1659 | __set_lvalue__(gel(y,i), gen_0) |
|---|
| 1660 | for i from 1 <= i <= lx-2: |
|---|
| 1661 | # no need to copy, since new_gen will deep copy |
|---|
| 1662 | __set_lvalue__(gel(y,vx+i), gel(x.g,i+1)) |
|---|
| 1663 | return P.new_gen(y) |
|---|
| 1664 | else: |
|---|
| 1665 | return x.Vec() |
|---|
| 1666 | |
|---|
| 1667 | def Vecsmall(gen x): |
|---|
| 1668 | """ |
|---|
| 1669 | Vecsmall(x): transforms the object x into a t_VECSMALL. |
|---|
| 1670 | |
|---|
| 1671 | INPUT: |
|---|
| 1672 | x -- gen |
|---|
| 1673 | OUTPUT: |
|---|
| 1674 | gen -- PARI t_VECSMALL |
|---|
| 1675 | EXAMPLES: |
|---|
| 1676 | sage: pari([1,2,3]).Vecsmall() |
|---|
| 1677 | Vecsmall([1, 2, 3]) |
|---|
| 1678 | sage: pari('"SAGE"').Vecsmall() |
|---|
| 1679 | Vecsmall([83, 65, 71, 69]) |
|---|
| 1680 | sage: pari(1234).Vecsmall() |
|---|
| 1681 | Vecsmall([1234]) |
|---|
| 1682 | """ |
|---|
| 1683 | _sig_on |
|---|
| 1684 | return P.new_gen(gtovecsmall(x.g)) |
|---|
| 1685 | |
|---|
| 1686 | def binary(gen x): |
|---|
| 1687 | """ |
|---|
| 1688 | binary(x): gives the vector formed by the binary digits of |
|---|
| 1689 | abs(x), where x is of type t_INT. |
|---|
| 1690 | |
|---|
| 1691 | INPUT: |
|---|
| 1692 | x -- gen of type t_INT |
|---|
| 1693 | OUTPUT: |
|---|
| 1694 | gen -- of type t_VEC |
|---|
| 1695 | EXAMPLES: |
|---|
| 1696 | sage: pari(0).binary() |
|---|
| 1697 | [0] |
|---|
| 1698 | sage: pari(-5).binary() |
|---|
| 1699 | [1, 0, 1] |
|---|
| 1700 | sage: pari(5).binary() |
|---|
| 1701 | [1, 0, 1] |
|---|
| 1702 | sage: pari(2005).binary() |
|---|
| 1703 | [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1] |
|---|
| 1704 | |
|---|
| 1705 | sage: pari('"2"').binary() |
|---|
| 1706 | Traceback (most recent call last): |
|---|
| 1707 | ... |
|---|
| 1708 | TypeError: x (=2) must be of type t_INT, but is of type t_STR. |
|---|
| 1709 | """ |
|---|
| 1710 | if typ(x.g) != t_INT: |
|---|
| 1711 | raise TypeError, "x (=%s) must be of type t_INT, but is of type %s."%(x,x.type()) |
|---|
| 1712 | _sig_on |
|---|
| 1713 | return P.new_gen(binaire(x.g)) |
|---|
| 1714 | |
|---|
| 1715 | def bitand(gen x, y): |
|---|
| 1716 | """ |
|---|
| 1717 | bitand(x,y): Bitwise and of two integers x and y. Negative |
|---|
| 1718 | numbers behave as if modulo some large power of 2. |
|---|
| 1719 | |
|---|
| 1720 | INPUT: |
|---|
| 1721 | x -- gen (of type t_INT) |
|---|
| 1722 | y -- coercible to gen (of type t_INT) |
|---|
| 1723 | OUTPUT: |
|---|
| 1724 | gen -- of type type t_INT |
|---|
| 1725 | EXAMPLES: |
|---|
| 1726 | sage: pari(8).bitand(4) |
|---|
| 1727 | 0 |
|---|
| 1728 | sage: pari(8).bitand(8) |
|---|
| 1729 | 8 |
|---|
| 1730 | sage: pari(6).binary() |
|---|
| 1731 | [1, 1, 0] |
|---|
| 1732 | sage: pari(7).binary() |
|---|
| 1733 | [1, 1, 1] |
|---|
| 1734 | sage: pari(6).bitand(7) |
|---|
| 1735 | 6 |
|---|
| 1736 | sage: pari(19).bitand(-1) |
|---|
| 1737 | 19 |
|---|
| 1738 | sage: pari(-1).bitand(-1) |
|---|
| 1739 | -1 |
|---|
| 1740 | """ |
|---|
| 1741 | t0GEN(y) |
|---|
| 1742 | _sig_on |
|---|
| 1743 | return P.new_gen(gbitand(x.g, t0)) |
|---|
| 1744 | |
|---|
| 1745 | |
|---|
| 1746 | def bitneg(gen x, long n=-1): |
|---|
| 1747 | r""" |
|---|
| 1748 | bitneg(x,{n=-1}): Bitwise negation of the integer x truncated |
|---|
| 1749 | to n bits. n=-1 (the default) represents an infinite sequence |
|---|
| 1750 | of the bit 1. Negative numbers behave as if modulo some large |
|---|
| 1751 | power of 2. |
|---|
| 1752 | |
|---|
| 1753 | With n=-1, this function returns -n-1. With n >= 0, it returns |
|---|
| 1754 | a number a such that $a\cong -n-1 \pmod{2^n}$. |
|---|
| 1755 | |
|---|
| 1756 | INPUT: |
|---|
| 1757 | x -- gen (t_INT) |
|---|
| 1758 | n -- long, default = -1 |
|---|
| 1759 | OUTPUT: |
|---|
| 1760 | gen -- t_INT |
|---|
| 1761 | EXAMPLES: |
|---|
| 1762 | sage: pari(10).bitneg() |
|---|
| 1763 | -11 |
|---|
| 1764 | sage: pari(1).bitneg() |
|---|
| 1765 | -2 |
|---|
| 1766 | sage: pari(-2).bitneg() |
|---|
| 1767 | 1 |
|---|
| 1768 | sage: pari(-1).bitneg() |
|---|
| 1769 | 0 |
|---|
| 1770 | sage: pari(569).bitneg() |
|---|
| 1771 | -570 |
|---|
| 1772 | sage: pari(569).bitneg(10) |
|---|
| 1773 | 454 |
|---|
| 1774 | sage: 454 % 2^10 |
|---|
| 1775 | 454 |
|---|
| 1776 | sage: -570 % 2^10 |
|---|
| 1777 | 454 |
|---|
| 1778 | """ |
|---|
| 1779 | _sig_on |
|---|
| 1780 | return P.new_gen(gbitneg(x.g,n)) |
|---|
| 1781 | |
|---|
| 1782 | |
|---|
| 1783 | def bitnegimply(gen x, y): |
|---|
| 1784 | """ |
|---|
| 1785 | bitnegimply(x,y): Bitwise negated imply of two integers x and |
|---|
| 1786 | y, in other words, x BITAND BITNEG(y). Negative numbers behave |
|---|
| 1787 | as if modulo big power of 2. |
|---|
| 1788 | |
|---|
| 1789 | INPUT: |
|---|
| 1790 | x -- gen (of type t_INT) |
|---|
| 1791 | y -- coercible to gen (of type t_INT) |
|---|
| 1792 | OUTPUT: |
|---|
| 1793 | gen -- of type type t_INT |
|---|
| 1794 | EXAMPLES: |
|---|
| 1795 | sage: pari(14).bitnegimply(0) |
|---|
| 1796 | 14 |
|---|
| 1797 | sage: pari(8).bitnegimply(8) |
|---|
| 1798 | 0 |
|---|
| 1799 | sage: pari(8+4).bitnegimply(8) |
|---|
| 1800 | 4 |
|---|
| 1801 | """ |
|---|
| 1802 | t0GEN(y) |
|---|
| 1803 | _sig_on |
|---|
| 1804 | return P.new_gen(gbitnegimply(x.g, t0)) |
|---|
| 1805 | |
|---|
| 1806 | |
|---|
| 1807 | def bitor(gen x, y): |
|---|
| 1808 | """ |
|---|
| 1809 | bitor(x,y): Bitwise or of two integers x and y. Negative |
|---|
| 1810 | numbers behave as if modulo big power of 2. |
|---|
| 1811 | |
|---|
| 1812 | INPUT: |
|---|
| 1813 | x -- gen (of type t_INT) |
|---|
| 1814 | y -- coercible to gen (of type t_INT) |
|---|
| 1815 | OUTPUT: |
|---|
| 1816 | gen -- of type type t_INT |
|---|
| 1817 | EXAMPLES: |
|---|
| 1818 | sage: pari(14).bitor(0) |
|---|
| 1819 | 14 |
|---|
| 1820 | sage: pari(8).bitor(4) |
|---|
| 1821 | 12 |
|---|
| 1822 | sage: pari(12).bitor(1) |
|---|
| 1823 | 13 |
|---|
| 1824 | sage: pari(13).bitor(1) |
|---|
| 1825 | 13 |
|---|
| 1826 | """ |
|---|
| 1827 | t0GEN(y) |
|---|
| 1828 | _sig_on |
|---|
| 1829 | return P.new_gen(gbitor(x.g, t0)) |
|---|
| 1830 | |
|---|
| 1831 | |
|---|
| 1832 | def bittest(gen x, long n): |
|---|
| 1833 | """ |
|---|
| 1834 | bittest(x, long n): Returns bit number n (coefficient of $2^n$ in binary) |
|---|
| 1835 | of the integer x. Negative numbers behave as if modulo a big power of 2. |
|---|
| 1836 | |
|---|
| 1837 | INPUT: |
|---|
| 1838 | x -- gen (pari integer) |
|---|
| 1839 | OUTPUT: |
|---|
| 1840 | bool -- a Python bool |
|---|
| 1841 | EXAMPLES: |
|---|
| 1842 | sage: x = pari(6) |
|---|
| 1843 | sage: x.bittest(0) |
|---|
| 1844 | False |
|---|
| 1845 | sage: x.bittest(1) |
|---|
| 1846 | True |
|---|
| 1847 | sage: x.bittest(2) |
|---|
| 1848 | True |
|---|
| 1849 | sage: x.bittest(3) |
|---|
| 1850 | False |
|---|
| 1851 | sage: pari(-3).bittest(0) |
|---|
| 1852 | True |
|---|
| 1853 | sage: pari(-3).bittest(1) |
|---|
| 1854 | False |
|---|
| 1855 | sage: [pari(-3).bittest(n) for n in range(10)] |
|---|
| 1856 | [True, False, True, True, True, True, True, True, True, True] |
|---|
| 1857 | """ |
|---|
| 1858 | _sig_on |
|---|
| 1859 | b = bool(bittest(x.g, n)) |
|---|
| 1860 | _sig_off |
|---|
| 1861 | return b |
|---|
| 1862 | |
|---|
| 1863 | def bitxor(gen x, y): |
|---|
| 1864 | """ |
|---|
| 1865 | bitxor(x,y): Bitwise exclusive or of two integers x and y. |
|---|
| 1866 | Negative numbers behave as if modulo big power of 2. |
|---|
| 1867 | |
|---|
| 1868 | INPUT: |
|---|
| 1869 | x -- gen (of type t_INT) |
|---|
| 1870 | y -- coercible to gen (of type t_INT) |
|---|
| 1871 | OUTPUT: |
|---|
| 1872 | gen -- of type type t_INT |
|---|
| 1873 | EXAMPLES: |
|---|
| 1874 | sage: pari(6).bitxor(4) |
|---|
| 1875 | 2 |
|---|
| 1876 | sage: pari(0).bitxor(4) |
|---|
| 1877 | 4 |
|---|
| 1878 | sage: pari(6).bitxor(0) |
|---|
| 1879 | 6 |
|---|
| 1880 | """ |
|---|
| 1881 | t0GEN(y) |
|---|
| 1882 | _sig_on |
|---|
| 1883 | return P.new_gen(gbitxor(x.g, t0)) |
|---|
| 1884 | |
|---|
| 1885 | |
|---|
| 1886 | def ceil(gen x): |
|---|
| 1887 | """ |
|---|
| 1888 | Return the smallest integer >= x. |
|---|
| 1889 | |
|---|
| 1890 | INPUT: |
|---|
| 1891 | x -- gen |
|---|
| 1892 | OUTPUT: |
|---|
| 1893 | gen -- integer |
|---|
| 1894 | EXAMPLES: |
|---|
| 1895 | sage: pari(1.4).ceil() |
|---|
| 1896 | 2 |
|---|
| 1897 | sage: pari(-1.4).ceil() |
|---|
| 1898 | -1 |
|---|
| 1899 | sage: pari('x').ceil() |
|---|
| 1900 | x |
|---|
| 1901 | sage: pari('x^2+5*x+2.2').ceil() |
|---|
| 1902 | x^2 + 5*x + 2.200000000000000000000000000 # 32-bit |
|---|
| 1903 | x^2 + 5*x + 2.2000000000000000000000000000000000000 # 64-bit |
|---|
| 1904 | sage: pari('3/4').ceil() |
|---|
| 1905 | 1 |
|---|
| 1906 | """ |
|---|
| 1907 | _sig_on |
|---|
| 1908 | return P.new_gen(gceil(x.g)) |
|---|
| 1909 | |
|---|
| 1910 | def centerlift(gen x, v=-1): |
|---|
| 1911 | """ |
|---|
| 1912 | centerlift(x,{v}): Centered lift of x. This function returns |
|---|
| 1913 | exactly the same thing as lift, except if x is an integer mod. |
|---|
| 1914 | |
|---|
| 1915 | INPUT: |
|---|
| 1916 | x -- gen |
|---|
| 1917 | v -- var (default: x) |
|---|
| 1918 | OUTPUT: |
|---|
| 1919 | gen |
|---|
| 1920 | EXAMPLES: |
|---|
| 1921 | sage: x = pari(-2).Mod(5) |
|---|
| 1922 | sage: x.centerlift() |
|---|
| 1923 | -2 |
|---|
| 1924 | sage: x.lift() |
|---|
| 1925 | 3 |
|---|
| 1926 | sage: f = pari('x-1').Mod('x^2 + 1') |
|---|
| 1927 | sage: f.centerlift() |
|---|
| 1928 | x - 1 |
|---|
| 1929 | sage: f.lift() |
|---|
| 1930 | x - 1 |
|---|
| 1931 | sage: f = pari('x-y').Mod('x^2+1') |
|---|
| 1932 | sage: f |
|---|
| 1933 | Mod(x - y, x^2 + 1) |
|---|
| 1934 | sage: f.centerlift('x') |
|---|
| 1935 | x - y |
|---|
| 1936 | sage: f.centerlift('y') |
|---|
| 1937 | Mod(x - y, x^2 + 1) |
|---|
| 1938 | """ |
|---|
| 1939 | _sig_on |
|---|
| 1940 | return P.new_gen(centerlift0(x.g, P.get_var(v))) |
|---|
| 1941 | |
|---|
| 1942 | |
|---|
| 1943 | def changevar(gen x, y): |
|---|
| 1944 | """ |
|---|
| 1945 | changevar(gen x, y): change variables of x according to the vector y. |
|---|
| 1946 | |
|---|
| 1947 | WARNING: This doesn't seem to work right at all in SAGE (!). |
|---|
| 1948 | Use with caution. *STRANGE* |
|---|
| 1949 | |
|---|
| 1950 | INPUT: |
|---|
| 1951 | x -- gen |
|---|
| 1952 | y -- gen (or coercible to gen) |
|---|
| 1953 | OUTPUT: |
|---|
| 1954 | gen |
|---|
| 1955 | EXAMPLES: |
|---|
| 1956 | sage: pari('x^3+1').changevar(pari(['y'])) |
|---|
| 1957 | y^3 + 1 |
|---|
| 1958 | """ |
|---|
| 1959 | t0GEN(y) |
|---|
| 1960 | _sig_on |
|---|
| 1961 | return P.new_gen(changevar(x.g, t0)) |
|---|
| 1962 | |
|---|
| 1963 | def component(gen x, long n): |
|---|
| 1964 | """ |
|---|
| 1965 | component(x, long n): Return n'th component of the internal |
|---|
| 1966 | representation of x. This this function is 1-based |
|---|
| 1967 | instead of 0-based. |
|---|
| 1968 | |
|---|
| 1969 | NOTE: For vectors or matrices, it is simpler to use x[n-1]. For |
|---|
| 1970 | list objects such as is output by nfinit, it is easier to use |
|---|
| 1971 | member functions. |
|---|
| 1972 | |
|---|
| 1973 | INPUT: |
|---|
| 1974 | x -- gen |
|---|
| 1975 | n -- C long (coercible to) |
|---|
| 1976 | OUTPUT: |
|---|
| 1977 | gen |
|---|
| 1978 | EXAMPLES: |
|---|
| 1979 | sage: pari([0,1,2,3,4]).component(1) |
|---|
| 1980 | 0 |
|---|
| 1981 | sage: pari([0,1,2,3,4]).component(2) |
|---|
| 1982 | 1 |
|---|
| 1983 | sage: pari([0,1,2,3,4]).component(4) |
|---|
| 1984 | 3 |
|---|
| 1985 | sage: pari('x^3 + 2').component(1) |
|---|
| 1986 | 2 |
|---|
| 1987 | sage: pari('x^3 + 2').component(2) |
|---|
| 1988 | 0 |
|---|
| 1989 | sage: pari('x^3 + 2').component(4) |
|---|
| 1990 | 1 |
|---|
| 1991 | |
|---|
| 1992 | sage: pari('x').component(0) |
|---|
| 1993 | Traceback (most recent call last): |
|---|
| 1994 | ... |
|---|
| 1995 | PariError: (8) |
|---|
| 1996 | """ |
|---|
| 1997 | _sig_on |
|---|
| 1998 | return P.new_gen(compo(x.g, n)) |
|---|
| 1999 | |
|---|
| 2000 | def conj(gen x): |
|---|
| 2001 | """ |
|---|
| 2002 | conj(x): Return the algebraic conjugate of x. |
|---|
| 2003 | |
|---|
| 2004 | INPUT: |
|---|
| 2005 | x -- gen |
|---|
| 2006 | OUTPUT: |
|---|
| 2007 | gen |
|---|
| 2008 | EXAMPLES: |
|---|
| 2009 | sage: pari('x+1').conj() |
|---|
| 2010 | x + 1 |
|---|
| 2011 | sage: pari('x+I').conj() |
|---|
| 2012 | x - I |
|---|
| 2013 | sage: pari('1/(2*x+3*I)').conj() |
|---|
| 2014 | 1/(2*x - 3*I) |
|---|
| 2015 | sage: pari([1,2,'2-I','Mod(x,x^2+1)', 'Mod(x,x^2-2)']).conj() |
|---|
| 2016 | [1, 2, 2 + I, Mod(-x, x^2 + 1), Mod(-x, x^2 - 2)] |
|---|
| 2017 | sage: pari('Mod(x,x^2-2)').conj() |
|---|
| 2018 | Mod(-x, x^2 - 2) |
|---|
| 2019 | sage: pari('Mod(x,x^3-3)').conj() |
|---|
| 2020 | Traceback (most recent call last): |
|---|
| 2021 | ... |
|---|
| 2022 | PariError: incorrect type (20) |
|---|
| 2023 | """ |
|---|
| 2024 | _sig_on |
|---|
| 2025 | return P.new_gen(gconj(x.g)) |
|---|
| 2026 | |
|---|
| 2027 | def conjvec(gen x): |
|---|
| 2028 | """ |
|---|
| 2029 | conjvec(x): Returns the vector of all conjugates of the |
|---|
| 2030 | algebraic number x. An algebraic number is a polynomial over |
|---|
| 2031 | Q modulo an irreducible polynomial. |
|---|
| 2032 | |
|---|
| 2033 | INPUT: |
|---|
| 2034 | x -- gen |
|---|
| 2035 | OUTPUT: |
|---|
| 2036 | gen |
|---|
| 2037 | EXAMPLES: |
|---|
| 2038 | sage: pari('Mod(1+x,x^2-2)').conjvec() |
|---|
| 2039 | [-0.4142135623730950488016887242, 2.414213562373095048801688724]~ # 32-bit |
|---|
| 2040 | [-0.41421356237309504880168872420969807857, 2.4142135623730950488016887242096980786]~ # 64-bit |
|---|
| 2041 | sage: pari('Mod(x,x^3-3)').conjvec() |
|---|
| 2042 | [1.442249570307408382321638311, -0.7211247851537041911608191554 + 1.249024766483406479413179544*I, -0.7211247851537041911608191554 - 1.249024766483406479413179544*I]~ # 32-bit |
|---|
| 2043 | [1.4422495703074083823216383107801095884, -0.72112478515370419116081915539005479419 + 1.2490247664834064794131795437632536350*I, -0.72112478515370419116081915539005479419 - 1.2490247664834064794131795437632536350*I]~ # 64-bit |
|---|
| 2044 | """ |
|---|
| 2045 | _sig_on |
|---|
| 2046 | return P.new_gen(conjvec(x.g, prec)) |
|---|
| 2047 | |
|---|
| 2048 | def denominator(gen x): |
|---|
| 2049 | """ |
|---|
| 2050 | denominator(x): Return the denominator of x. When x is a |
|---|
| 2051 | vector, this is the least common multiple of the denominators |
|---|
| 2052 | of the components of x. |
|---|
| 2053 | |
|---|
| 2054 | what about poly? |
|---|
| 2055 | INPUT: |
|---|
| 2056 | x -- gen |
|---|
| 2057 | OUTPUT: |
|---|
| 2058 | gen |
|---|
| 2059 | EXAMPLES: |
|---|
| 2060 | sage: pari('5/9').denominator() |
|---|
| 2061 | 9 |
|---|
| 2062 | sage: pari('(x+1)/(x-2)').denominator() |
|---|
| 2063 | x - 2 |
|---|
| 2064 | sage: pari('2/3 + 5/8*x + 7/3*x^2 + 1/5*y').denominator() |
|---|
| 2065 | 1 |
|---|
| 2066 | sage: pari('2/3*x').denominator() |
|---|
| 2067 | 1 |
|---|
| 2068 | sage: pari('[2/3, 5/8, 7/3, 1/5]').denominator() |
|---|
| 2069 | 120 |
|---|
| 2070 | """ |
|---|
| 2071 | _sig_on |
|---|
| 2072 | return P.new_gen(denom(x.g)) |
|---|
| 2073 | |
|---|
| 2074 | def floor(gen x): |
|---|
| 2075 | """ |
|---|
| 2076 | floor(x): Return the floor of x, which is the largest integer <= x. |
|---|
| 2077 | This function also works component-wise on polynomials, vectors, etc. |
|---|
| 2078 | |
|---|
| 2079 | INPUT: |
|---|
| 2080 | x -- gen |
|---|
| 2081 | OUTPUT: |
|---|
| 2082 | gen |
|---|
| 2083 | EXAMPLES: |
|---|
| 2084 | sage: pari('5/9').floor() |
|---|
| 2085 | 0 |
|---|
| 2086 | sage: pari('11/9').floor() |
|---|
| 2087 | 1 |
|---|
| 2088 | sage: pari('1.17').floor() |
|---|
| 2089 | 1 |
|---|
| 2090 | sage: pari('x').floor() |
|---|
| 2091 | x |
|---|
| 2092 | sage: pari('x+1.5').floor() |
|---|
| 2093 | x + 1.500000000000000000000000000 # 32-bit |
|---|
| 2094 | x + 1.5000000000000000000000000000000000000 # 64-bit |
|---|
| 2095 | sage: pari('[1.5,2.3,4.99]').floor() |
|---|
| 2096 | [1, 2, 4] |
|---|
| 2097 | sage: pari('[[1.1,2.2],[3.3,4.4]]').floor() |
|---|
| 2098 | [[1, 2], [3, 4]] |
|---|
| 2099 | |
|---|
| 2100 | sage: pari('"hello world"').floor() |
|---|
| 2101 | Traceback (most recent call last): |
|---|
| 2102 | ... |
|---|
| 2103 | PariError: incorrect type (20) |
|---|
| 2104 | """ |
|---|
| 2105 | _sig_on |
|---|
| 2106 | return P.new_gen(gfloor(x.g)) |
|---|
| 2107 | |
|---|
| 2108 | def frac(gen x): |
|---|
| 2109 | """ |
|---|
| 2110 | frac(x): Return the fractional part of x, which is x - floor(x). |
|---|
| 2111 | |
|---|
| 2112 | INPUT: |
|---|
| 2113 | x -- gen |
|---|
| 2114 | OUTPUT: |
|---|
| 2115 | gen |
|---|
| 2116 | EXAMPLES: |
|---|
| 2117 | sage: pari('1.7').frac() |
|---|
| 2118 | 0.7000000000000000000000000000 # 32-bit |
|---|
| 2119 | 0.70000000000000000000000000000000000000 # 64-bit |
|---|
| 2120 | sage: pari('sqrt(2)').frac() |
|---|
| 2121 | 0.4142135623730950488016887242 # 32-bit |
|---|
| 2122 | 0.41421356237309504880168872420969807857 # 64-bit |
|---|
| 2123 | sage: pari('sqrt(-2)').frac() |
|---|
| 2124 | Traceback (most recent call last): |
|---|
| 2125 | ... |
|---|
| 2126 | PariError: incorrect type (20) |
|---|
| 2127 | """ |
|---|
| 2128 | _sig_on |
|---|
| 2129 | return P.new_gen(gfrac(x.g)) |
|---|
| 2130 | |
|---|
| 2131 | def imag(gen x): |
|---|
| 2132 | """ |
|---|
| 2133 | imag(x): Return the imaginary part of x. This function also |
|---|
| 2134 | works component-wise. |
|---|
| 2135 | |
|---|
| 2136 | INPUT: |
|---|
| 2137 | x -- gen |
|---|
| 2138 | OUTPUT: |
|---|
| 2139 | gen |
|---|
| 2140 | EXAMPLES: |
|---|
| 2141 | sage: pari('1+2*I').imag() |
|---|
| 2142 | 2 |
|---|
| 2143 | sage: pari('sqrt(-2)').imag() |
|---|
| 2144 | 1.414213562373095048801688724 # 32-bit |
|---|
| 2145 | 1.4142135623730950488016887242096980786 # 64-bit |
|---|
| 2146 | sage: pari('x+I').imag() |
|---|
| 2147 | 1 |
|---|
| 2148 | sage: pari('x+2*I').imag() |
|---|
| 2149 | 2 |
|---|
| 2150 | sage: pari('(1+I)*x^2+2*I').imag() |
|---|
| 2151 | x^2 + 2 |
|---|
| 2152 | sage: pari('[1,2,3] + [4*I,5,6]').imag() |
|---|
| 2153 | [4, 0, 0] |
|---|
| 2154 | """ |
|---|
| 2155 | _sig_on |
|---|
| 2156 | return P.new_gen(gimag(x.g)) |
|---|
| 2157 | |
|---|
| 2158 | def length(gen x): |
|---|
| 2159 | """ |
|---|
| 2160 | length(x): Return the number of non-code words in x. If x |
|---|
| 2161 | is a string, this is the number of characters of x. |
|---|
| 2162 | |
|---|
| 2163 | ?? terminator ?? carriage return ?? |
|---|
| 2164 | """ |
|---|
| 2165 | return glength(x.g) |
|---|
| 2166 | |
|---|
| 2167 | def lift(gen x, v=-1): |
|---|
| 2168 | """ |
|---|
| 2169 | lift(x,{v}): Returns the lift of an element of Z/nZ to Z or |
|---|
| 2170 | R[x]/(P) to R[x] for a type R if v is omitted. If v is given, |
|---|
| 2171 | lift only polymods with main variable v. If v does not occur |
|---|
| 2172 | in x, lift only intmods. |
|---|
| 2173 | |
|---|
| 2174 | INPUT: |
|---|
| 2175 | x -- gen |
|---|
| 2176 | v -- (optional) variable |
|---|
| 2177 | OUTPUT: |
|---|
| 2178 | gen |
|---|
| 2179 | EXAMPLES: |
|---|
| 2180 | sage: x = pari("x") |
|---|
| 2181 | sage: a = x.Mod('x^3 + 17*x + 3') |
|---|
| 2182 | sage: a |
|---|
| 2183 | Mod(x, x^3 + 17*x + 3) |
|---|
| 2184 | sage: b = a^4; b |
|---|
| 2185 | Mod(-17*x^2 - 3*x, x^3 + 17*x + 3) |
|---|
| 2186 | sage: b.lift() |
|---|
| 2187 | -17*x^2 - 3*x |
|---|
| 2188 | |
|---|
| 2189 | ??? more examples |
|---|
| 2190 | """ |
|---|
| 2191 | if v == -1: |
|---|
| 2192 | _sig_on |
|---|
| 2193 | return P.new_gen(lift(x.g)) |
|---|
| 2194 | _sig_on |
|---|
| 2195 | return P.new_gen(lift0(x.g, P.get_var(v))) |
|---|
| 2196 | |
|---|
| 2197 | def numbpart(gen x): |
|---|
| 2198 | """ |
|---|
| 2199 | numbpart(x): returns the number of partitions of x. |
|---|
| 2200 | |
|---|
| 2201 | EXAMPLES: |
|---|
| 2202 | sage: pari(20).numbpart() |
|---|
| 2203 | 627 |
|---|
| 2204 | sage: pari(100).numbpart() |
|---|
| 2205 | 190569292 |
|---|
| 2206 | """ |
|---|
| 2207 | _sig_on |
|---|
| 2208 | return P.new_gen(numbpart(x.g)) |
|---|
| 2209 | |
|---|
| 2210 | def numerator(gen x): |
|---|
| 2211 | """ |
|---|
| 2212 | numerator(x): Returns the numerator of x. |
|---|
| 2213 | |
|---|
| 2214 | INPUT: |
|---|
| 2215 | x -- gen |
|---|
| 2216 | OUTPUT: |
|---|
| 2217 | gen |
|---|
| 2218 | EXAMPLES: |
|---|
| 2219 | |
|---|
| 2220 | """ |
|---|
| 2221 | return P.new_gen(numer(x.g)) |
|---|
| 2222 | |
|---|
| 2223 | |
|---|
| 2224 | def numtoperm(gen k, long n): |
|---|
| 2225 | """ |
|---|
| 2226 | numtoperm(k, n): Return the permutation number k (mod n!) of n |
|---|
| 2227 | letters, where n is an integer. |
|---|
| 2228 | |
|---|
| 2229 | INPUT: |
|---|
| 2230 | k -- gen, integer |
|---|
| 2231 | n -- int |
|---|
| 2232 | OUTPUT: |
|---|
| 2233 | gen -- vector (permutation of {1,...,n}) |
|---|
| 2234 | EXAMPLES: |
|---|
| 2235 | """ |
|---|
| 2236 | _sig_on |
|---|
| 2237 | return P.new_gen(numtoperm(n, k.g)) |
|---|
| 2238 | |
|---|
| 2239 | |
|---|
| 2240 | def padicprec(gen x, p): |
|---|
| 2241 | """ |
|---|
| 2242 | padicprec(x,p): Return the absolute p-adic precision of the object x. |
|---|
| 2243 | |
|---|
| 2244 | INPUT: |
|---|
| 2245 | x -- gen |
|---|
| 2246 | OUTPUT: |
|---|
| 2247 | int |
|---|
| 2248 | EXAMPLES: |
|---|
| 2249 | """ |
|---|
| 2250 | cdef gen _p |
|---|
| 2251 | _p = pari(p) |
|---|
| 2252 | if typ(_p.g) != t_INT: |
|---|
| 2253 | raise TypeError, "p (=%s) must be of type t_INT, but is of type %s."%( |
|---|
| 2254 | _p, _p.type()) |
|---|
| 2255 | return padicprec(x.g, _p.g) |
|---|
| 2256 | |
|---|
| 2257 | def permtonum(gen x): |
|---|
| 2258 | """ |
|---|
| 2259 | permtonum(x): Return the ordinal (between 1 and n!) of permutation vector x. |
|---|
| 2260 | ??? Huh ??? say more. what is a perm vector. 0 to n-1 or 1-n. |
|---|
| 2261 | |
|---|
| 2262 | INPUT: |
|---|
| 2263 | x -- gen (vector of integers) |
|---|
| 2264 | OUTPUT: |
|---|
| 2265 | gen -- integer |
|---|
| 2266 | EXAMPLES: |
|---|
| 2267 | """ |
|---|
| 2268 | if typ(x.g) != t_VEC: |
|---|
| 2269 | raise TypeError, "x (=%s) must be of type t_VEC, but is of type %s."%(x,x.type()) |
|---|
| 2270 | return P.new_gen(permtonum(x.g)) |
|---|
| 2271 | |
|---|
| 2272 | def precision(gen x, long n=-1): |
|---|
| 2273 | """ |
|---|
| 2274 | precision(x,{n}): Change the precision of x to be n, where n |
|---|
| 2275 | is a C-integer). If n is omitted, output the real precision of x. |
|---|
| 2276 | |
|---|
| 2277 | INPUT: |
|---|
| 2278 | x -- gen |
|---|
| 2279 | n -- (optional) int |
|---|
| 2280 | OUTPUT: |
|---|
| 2281 | nothing |
|---|
| 2282 | or |
|---|
| 2283 | gen if n is omitted |
|---|
| 2284 | EXAMPLES: |
|---|
| 2285 | """ |
|---|
| 2286 | if n <= -1: |
|---|
| 2287 | return precision(x.g) |
|---|
| 2288 | return P.new_gen(precision0(x.g, n)) |
|---|
| 2289 | |
|---|
| 2290 | def random(gen N): |
|---|
| 2291 | r""" |
|---|
| 2292 | \code{random(\{N=$2^31$\})}: Return a pseudo-random integer between 0 and $N-1$. |
|---|
| 2293 | |
|---|
| 2294 | INPUT: |
|---|
| 2295 | N -- gen, integer |
|---|
| 2296 | OUTPUT: |
|---|
| 2297 | gen -- integer |
|---|
| 2298 | EXAMPLES: |
|---|
| 2299 | """ |
|---|
| 2300 | if typ(N.g) != t_INT: |
|---|
| 2301 | raise TypeError, "x (=%s) must be of type t_INT, but is of type %s."%(N,N.type()) |
|---|
| 2302 | _sig_on |
|---|
| 2303 | return P.new_gen(genrand(N.g)) |
|---|
| 2304 | |
|---|
| 2305 | def real(gen x): |
|---|
| 2306 | """ |
|---|
| 2307 | real(x): Return the real part of x. |
|---|
| 2308 | |
|---|
| 2309 | INPUT: |
|---|
| 2310 | x -- gen |
|---|
| 2311 | OUTPUT: |
|---|
| 2312 | gen |
|---|
| 2313 | EXAMPLES: |
|---|
| 2314 | """ |
|---|
| 2315 | _sig_on |
|---|
| 2316 | return P.new_gen(greal(x.g)) |
|---|
| 2317 | |
|---|
| 2318 | def round(gen x, estimate=False): |
|---|
| 2319 | """ |
|---|
| 2320 | round(x,estimat=False): If x is a real number, returns x rounded |
|---|
| 2321 | to the nearest integer (rounding up). If the optional argument |
|---|
| 2322 | estimate is True, also returns the binary exponent e of the difference |
|---|
| 2323 | between the original and the rounded value (the "fractional part") |
|---|
| 2324 | (this is the integer ceiling of log_2(error)). |
|---|
| 2325 | |
|---|
| 2326 | When x is a general PARI object, this function returns the result |
|---|
| 2327 | of rounding every coefficient at every level of PARI object. |
|---|
| 2328 | Note that this is different than what the truncate function |
|---|
| 2329 | does (see the example below). |
|---|
| 2330 | |
|---|
| 2331 | One use of round is to get exact results after a long |
|---|
| 2332 | approximate computation, when theory tells you that the |
|---|
| 2333 | coefficients must be integers. |
|---|
| 2334 | |
|---|
| 2335 | INPUT: |
|---|
| 2336 | x -- gen |
|---|
| 2337 | estimate -- (optional) bool, False by default |
|---|
| 2338 | OUTPUT: |
|---|
| 2339 | * if estimate == False, return a single gen. |
|---|
| 2340 | * if estimate == True, return rounded verison of x and |
|---|
| 2341 | error estimate in bits, both as gens. |
|---|
| 2342 | EXAMPLES: |
|---|
| 2343 | sage: pari('1.5').round() |
|---|
| 2344 | 2 |
|---|
| 2345 | sage: pari('1.5').round(True) |
|---|
| 2346 | (2, -1) |
|---|
| 2347 | sage: pari('1.5 + 2.1*I').round() |
|---|
| 2348 | 2 + 2*I |
|---|
| 2349 | sage: pari('1.0001').round(True) |
|---|
| 2350 | (1, -14) |
|---|
| 2351 | sage: pari('(2.4*x^2 - 1.7)/x').round() |
|---|
| 2352 | (2*x^2 - 2)/x |
|---|
| 2353 | sage: pari('(2.4*x^2 - 1.7)/x').truncate() |
|---|
| 2354 | 2.400000000000000000000000000*x # 32-bit |
|---|
| 2355 | 2.4000000000000000000000000000000000000*x # 64-bit |
|---|
| 2356 | """ |
|---|
| 2357 | cdef int n |
|---|
| 2358 | if not estimate: |
|---|
| 2359 | _sig_on |
|---|
| 2360 | return P.new_gen(ground(x.g)) |
|---|
| 2361 | cdef long e |
|---|
| 2362 | cdef gen y |
|---|
| 2363 | _sig_on |
|---|
| 2364 | y = P.new_gen(grndtoi(x.g, &e)) |
|---|
| 2365 | return y, e |
|---|
| 2366 | |
|---|
| 2367 | def simplify(gen x): |
|---|
| 2368 | """ |
|---|
| 2369 | simplify(x): Simplify the object x as much as possible, and return |
|---|
| 2370 | the result. |
|---|
| 2371 | |
|---|
| 2372 | A complex or quadratic number whose imaginary part is an exact 0 |
|---|
| 2373 | (i.e., not an approximate one such as O(3) or 0.E-28) is converted |
|---|
| 2374 | to its real part, and a a polynomial of degree 0 is converted to |
|---|
| 2375 | its constant term. Simplification occurs recursively. |
|---|
| 2376 | |
|---|
| 2377 | This function is useful before using arithmetic functions, which |
|---|
| 2378 | expect integer arguments: |
|---|
| 2379 | |
|---|
| 2380 | EXAMPLES: |
|---|
| 2381 | sage: y = pari('y') |
|---|
| 2382 | sage: x = pari('9') + y - y |
|---|
| 2383 | sage: x |
|---|
| 2384 | 9 |
|---|
| 2385 | sage: x.type() |
|---|
| 2386 | 't_POL' |
|---|
| 2387 | sage: x.factor() |
|---|
| 2388 | matrix(0,2) |
|---|
| 2389 | sage: pari('9').factor() |
|---|
| 2390 | Mat([3, 2]) |
|---|
| 2391 | sage: x.simplify() |
|---|
| 2392 | 9 |
|---|
| 2393 | sage: x.simplify().factor() |
|---|
| 2394 | Mat([3, 2]) |
|---|
| 2395 | sage: x = pari('1.5 + 0*I') |
|---|
| 2396 | sage: x.type() |
|---|
| 2397 | 't_COMPLEX' |
|---|
| 2398 | sage: x.simplify() |
|---|
| 2399 | 1.500000000000000000000000000 # 32-bit |
|---|
| 2400 | 1.5000000000000000000000000000000000000 # 64-bit |
|---|
| 2401 | sage: y = x.simplify() |
|---|
| 2402 | sage: y.type() |
|---|
| 2403 | 't_REAL' |
|---|
| 2404 | """ |
|---|
| 2405 | _sig_on |
|---|
| 2406 | return P.new_gen(simplify(x.g)) |
|---|
| 2407 | |
|---|
| 2408 | def sizebyte(gen x): |
|---|
| 2409 | """ |
|---|
| 2410 | sizebyte(x): Return the total number of bytes occupied by the |
|---|
| 2411 | complete tree of the object x. Note that this number depends |
|---|
| 2412 | on whether the computer is 32-bit or 64-bit (see examples). |
|---|
| 2413 | |
|---|
| 2414 | INPUT: |
|---|
| 2415 | x -- gen |
|---|
| 2416 | OUTPUT: |
|---|
| 2417 | int (a Python int) |
|---|
| 2418 | EXAMPLES: |
|---|
| 2419 | sage: pari('1').sizebyte() |
|---|
| 2420 | 12 # 32-bit |
|---|
| 2421 | 24 # 64-bit |
|---|
| 2422 | sage: pari('10').sizebyte() |
|---|
| 2423 | 12 # 32-bit |
|---|
| 2424 | 24 # 64-bit |
|---|
| 2425 | sage: pari('10000000000000').sizebyte() |
|---|
| 2426 | 16 # 32-bit |
|---|
| 2427 | 24 # 64-bit |
|---|
| 2428 | sage: pari('10^100').sizebyte() |
|---|
| 2429 | 52 # 32-bit |
|---|
| 2430 | 64 # 64-bit |
|---|
| 2431 | sage: pari('x').sizebyte() |
|---|
| 2432 | 36 # 32-bit |
|---|
| 2433 | 72 # 64-bit |
|---|
| 2434 | sage: pari('x^20').sizebyte() |
|---|
| 2435 | 264 # 32-bit |
|---|
| 2436 | 528 # 64-bit |
|---|
| 2437 | sage: pari('[x, 10^100]').sizebyte() |
|---|
| 2438 | 100 # 32-bit |
|---|
| 2439 | 160 # 64-bit |
|---|
| 2440 | """ |
|---|
| 2441 | return taille2(x.g) |
|---|
| 2442 | |
|---|
| 2443 | def sizedigit(gen x): |
|---|
| 2444 | """ |
|---|
| 2445 | |
|---|
| 2446 | sizedigit(x): Return a quick estimate for the maximal number of |
|---|
| 2447 | decimal digits before the decimal point of any component of x. |
|---|
| 2448 | |
|---|
| 2449 | INPUT: |
|---|
| 2450 | x -- gen |
|---|
| 2451 | OUTPUT: |
|---|
| 2452 | int -- Python integer |
|---|
| 2453 | EXAMPLES: |
|---|
| 2454 | sage: x = pari('10^100') |
|---|
| 2455 | sage: x.Str().length() |
|---|
| 2456 | 101 |
|---|
| 2457 | sage: x.sizedigit() |
|---|
| 2458 | 101 |
|---|
| 2459 | |
|---|
| 2460 | Note that digits after the decimal point are ignored. |
|---|
| 2461 | sage: x = pari('1.234') |
|---|
| 2462 | sage: x |
|---|
| 2463 | 1.234000000000000000000000000 # 32-bit |
|---|
| 2464 | 1.2340000000000000000000000000000000000 # 64-bit |
|---|
| 2465 | sage: x.sizedigit() |
|---|
| 2466 | 1 |
|---|
| 2467 | |
|---|
| 2468 | The estimate can be one too big: |
|---|
| 2469 | sage: pari('7234.1').sizedigit() |
|---|
| 2470 | 4 |
|---|
| 2471 | sage: pari('9234.1').sizedigit() |
|---|
| 2472 | 5 |
|---|
| 2473 | """ |
|---|
| 2474 | return sizedigit(x.g) |
|---|
| 2475 | |
|---|
| 2476 | def truncate(gen x, estimate=False): |
|---|
| 2477 | """ |
|---|
| 2478 | truncate(x,estimate=False): Return the truncation of x. |
|---|
| 2479 | If estimate is True, also return the number of error bits. |
|---|
| 2480 | |
|---|
| 2481 | When x is in the real numbers, this means that the part |
|---|
| 2482 | after the decimal point is chopped away, e is the binary |
|---|
| 2483 | exponent of the difference between the original and truncated |
|---|
| 2484 | value (the "fractional part"). If x is a rational |
|---|
| 2485 | function, the result is the integer part (Euclidean |
|---|
| 2486 | quotient of numerator by denominator) and if requested |
|---|
| 2487 | the error estimate is 0. |
|---|
| 2488 | |
|---|
| 2489 | When truncate is applied to a power series (in X), it |
|---|
| 2490 | transforms it into a polynomial or a rational function with |
|---|
| 2491 | denominator a power of X, by chopping away the $O(X^k)$. |
|---|
| 2492 | Similarly, when applied to a p-adic number, it transforms it |
|---|
| 2493 | into an integer or a rational number by chopping away the |
|---|
| 2494 | $O(p^k)$. |
|---|
| 2495 | |
|---|
| 2496 | INPUT: |
|---|
| 2497 | x -- gen |
|---|
| 2498 | estimate -- (optional) bool, which is False by default |
|---|
| 2499 | OUTPUT: |
|---|
| 2500 | * if estimate == False, return a single gen. |
|---|
| 2501 | * if estimate == True, return rounded verison of x and |
|---|
| 2502 | error estimate in bits, both as gens. |
|---|
| 2503 | OUTPUT: |
|---|
| 2504 | EXAMPLES: |
|---|
| 2505 | sage: pari('(x^2+1)/x').round() |
|---|
| 2506 | (x^2 + 1)/x |
|---|
| 2507 | sage: pari('(x^2+1)/x').truncate() |
|---|
| 2508 | x |
|---|
| 2509 | sage: pari('1.043').truncate() |
|---|
| 2510 | 1 |
|---|
| 2511 | sage: pari('1.043').truncate(True) |
|---|
| 2512 | (1, -5) |
|---|
| 2513 | sage: pari('1.6').truncate() |
|---|
| 2514 | 1 |
|---|
| 2515 | sage: pari('1.6').round() |
|---|
| 2516 | 2 |
|---|
| 2517 | sage: pari('1/3 + 2 + 3^2 + O(3^3)').truncate() |
|---|
| 2518 | 34/3 |
|---|
| 2519 | sage: pari('sin(x+O(x^10))').truncate() |
|---|
| 2520 | 1/362880*x^9 - 1/5040*x^7 + 1/120*x^5 - 1/6*x^3 + x |
|---|
| 2521 | sage: pari('sin(x+O(x^10))').round() # each coefficient has abs < 1 |
|---|
| 2522 | x + O(x^10) |
|---|
| 2523 | """ |
|---|
| 2524 | if not estimate: |
|---|
| 2525 | _sig_on |
|---|
| 2526 | return P.new_gen(gtrunc(x.g)) |
|---|
| 2527 | cdef long e |
|---|
| 2528 | cdef gen y |
|---|
| 2529 | _sig_on |
|---|
| 2530 | y = P.new_gen(gcvtoi(x.g, &e)) |
|---|
| 2531 | return y, e |
|---|
| 2532 | |
|---|
| 2533 | def valuation(gen x, p): |
|---|
| 2534 | """ |
|---|
| 2535 | valuation(x,p): Return the valuation of x with respect to p. |
|---|
| 2536 | |
|---|
| 2537 | The valuation is the highest exponent of p dividing x. |
|---|
| 2538 | |
|---|
| 2539 | * If p is an integer, x must be an integer, an intmod whose |
|---|
| 2540 | modulus is divisible by p, a rational number, a p-adic |
|---|
| 2541 | number, or a polynomial or power series in which case the |
|---|
| 2542 | valuation is the minimal of the valuations of the |
|---|
| 2543 | coefficients. |
|---|
| 2544 | |
|---|
| 2545 | * If p is a polynomial, x must be a polynomial or a |
|---|
| 2546 | rational fucntion. If p is a monomial then x may also be |
|---|
| 2547 | a power series. |
|---|
| 2548 | |
|---|
| 2549 | * If x is a vector, complex or quadratic number, then the |
|---|
| 2550 | valuation is the minimum of the component valuations. |
|---|
| 2551 | |
|---|
| 2552 | * If x = 0, the result is $2^31-1$ on 32-bit machines or |
|---|
| 2553 | $2^63-1$ on 64-bit machines if x is an exact object. |
|---|
| 2554 | If x is a p-adic number or power series, the result |
|---|
| 2555 | is the exponent of the zero. |
|---|
| 2556 | |
|---|
| 2557 | INPUT: |
|---|
| 2558 | x -- gen |
|---|
| 2559 | p -- coercible to gen |
|---|
| 2560 | OUTPUT: |
|---|
| 2561 | gen -- integer |
|---|
| 2562 | EXAMPLES: |
|---|
| 2563 | sage: pari(9).valuation(3) |
|---|
| 2564 | 2 |
|---|
| 2565 | sage: pari(9).valuation(9) |
|---|
| 2566 | 1 |
|---|
| 2567 | sage: x = pari(9).Mod(27); x.valuation(3) |
|---|
| 2568 | 2 |
|---|
| 2569 | sage: pari('5/3').valuation(3) |
|---|
| 2570 | -1 |
|---|
| 2571 | sage: pari('9 + 3*x + 15*x^2').valuation(3) |
|---|
| 2572 | 1 |
|---|
| 2573 | sage: pari([9,3,15]).valuation(3) |
|---|
| 2574 | 1 |
|---|
| 2575 | sage: pari('9 + 3*x + 15*x^2 + O(x^5)').valuation(3) |
|---|
| 2576 | 1 |
|---|
| 2577 | |
|---|
| 2578 | sage: pari('x^2*(x+1)^3').valuation(pari('x+1')) |
|---|
| 2579 | 3 |
|---|
| 2580 | sage: pari('x + O(x^5)').valuation('x') |
|---|
| 2581 | 1 |
|---|
| 2582 | sage: pari('2*x^2 + O(x^5)').valuation('x') |
|---|
| 2583 | 2 |
|---|
| 2584 | |
|---|
| 2585 | sage: pari(0).valuation(3) |
|---|
| 2586 | 2147483647 # 32-bit |
|---|
| 2587 | 9223372036854775807 # 64-bit |
|---|
| 2588 | """ |
|---|
| 2589 | t0GEN(p) |
|---|
| 2590 | _sig_on |
|---|
| 2591 | v = ggval(x.g, t0) |
|---|
| 2592 | _sig_off |
|---|
| 2593 | return v |
|---|
| 2594 | |
|---|
| 2595 | def variable(gen x): |
|---|
| 2596 | """ |
|---|
| 2597 | variable(x): Return the main variable of the object x, or p |
|---|
| 2598 | if x is a p-adic number. |
|---|
| 2599 | |
|---|
| 2600 | This function raises a TypeError exception on scalars, i.e., |
|---|
| 2601 | on objects with no variable associated to them. |
|---|
| 2602 | |
|---|
| 2603 | INPUT: |
|---|
| 2604 | x -- gen |
|---|
| 2605 | OUTPUT: |
|---|
| 2606 | gen |
|---|
| 2607 | EXAMPLES: |
|---|
| 2608 | sage: pari('x^2 + x -2').variable() |
|---|
| 2609 | x |
|---|
| 2610 | sage: pari('1+2^3 + O(2^5)').variable() |
|---|
| 2611 | 2 |
|---|
| 2612 | sage: pari('x+y0').variable() |
|---|
| 2613 | x |
|---|
| 2614 | sage: pari('y0+z0').variable() |
|---|
| 2615 | y0 |
|---|
| 2616 | """ |
|---|
| 2617 | _sig_on |
|---|
| 2618 | return P.new_gen(gpolvar(x.g)) |
|---|
| 2619 | |
|---|
| 2620 | |
|---|
| 2621 | ########################################### |
|---|
| 2622 | # 3: TRANSCENDENTAL functions |
|---|
| 2623 | # AUTHORS: Pyrex Code, docs -- Justin Walker (justin@mac.com) |
|---|
| 2624 | # Examples, docs -- William Stein |
|---|
| 2625 | ########################################### |
|---|
| 2626 | |
|---|
| 2627 | def abs(gen self): |
|---|
| 2628 | """ |
|---|
| 2629 | Returns the absolute value of x (its modulus, if x is complex). |
|---|
| 2630 | Rational functions are not allowed. Contrary to most transcendental |
|---|
| 2631 | functions, an exact argument is not converted to a real number before |
|---|
| 2632 | applying abs and an exact result is returned if possible. |
|---|
| 2633 | |
|---|
| 2634 | EXAMPLES: |
|---|
| 2635 | sage: x = pari("-27.1") |
|---|
| 2636 | sage: x.abs() |
|---|
| 2637 | 27.10000000000000000000000000 # 32-bit |
|---|
| 2638 | 27.100000000000000000000000000000000000 # 64-bit |
|---|
| 2639 | |
|---|
| 2640 | If x is a polynomial, returns -x if the leading coefficient is real |
|---|
| 2641 | and negative else returns x. For a power series, the constant |
|---|
| 2642 | coefficient is considered instead. |
|---|
| 2643 | |
|---|
| 2644 | EXAMPLES: |
|---|
| 2645 | sage: pari('x-1.2*x^2').abs() |
|---|
| 2646 | 1.200000000000000000000000000*x^2 - x # 32-bit |
|---|
| 2647 | 1.2000000000000000000000000000000000000*x^2 - x # 64-bit |
|---|
| 2648 | """ |
|---|
| 2649 | _sig_on |
|---|
| 2650 | return P.new_gen(gabs(self.g, prec)) |
|---|
| 2651 | |
|---|
| 2652 | def acos(gen x): |
|---|
| 2653 | r""" |
|---|
| 2654 | The principal branch of $\cos^{-1}(x)$, so that $\Re(\acos(x))$ |
|---|
| 2655 | belongs to $[0,Pi]$. If $x$ is real and $|x| > 1$, |
|---|
| 2656 | then $\acos(x)$ is complex. |
|---|
| 2657 | |
|---|
| 2658 | EXAMPLES: |
|---|
| 2659 | sage: pari('0.5').acos() |
|---|
| 2660 | 1.047197551196597746154214461 # 32-bit |
|---|
| 2661 | 1.0471975511965977461542144610931676281 # 64-bit |
|---|
| 2662 | sage: pari('1.1').acos() |
|---|
| 2663 | -0.4435682543851151891329110664*I # 32-bit |
|---|
| 2664 | -0.44356825438511518913291106635249808665*I # 64-bit |
|---|
| 2665 | sage: pari('1.1+I').acos() |
|---|
| 2666 | 0.8493430542452523259630143655 - 1.097709866825328614547942343*I # 32-bit |
|---|
| 2667 | 0.84934305424525232596301436546298780187 - 1.0977098668253286145479423425784723444*I # 64-bit |
|---|
| 2668 | """ |
|---|
| 2669 | _sig_on |
|---|
| 2670 | return P.new_gen(gacos(x.g, prec)) |
|---|
| 2671 | |
|---|
| 2672 | def acosh(gen x): |
|---|
| 2673 | r""" |
|---|
| 2674 | The principal branch of $\cosh^{-1}(x)$, so that |
|---|
| 2675 | $\Im(\acosh(x))$ belongs to $[0,Pi]$. If $x$ is real and $x < |
|---|
| 2676 | 1$, then $\acosh(x)$ is complex. |
|---|
| 2677 | |
|---|
| 2678 | EXAMPLES: |
|---|
| 2679 | sage: pari(2).acosh() |
|---|
| 2680 | 1.316957896924816708625046347 # 32-bit |
|---|
| 2681 | 1.3169578969248167086250463473079684440 # 64-bit |
|---|
| 2682 | sage: pari(0).acosh() |
|---|
| 2683 | 1.570796326794896619231321692*I # 32-bit |
|---|
| 2684 | 1.5707963267948966192313216916397514421*I # 64-bit |
|---|
| 2685 | sage: pari('I').acosh() |
|---|
| 2686 | 0.8813735870195430252326093250 + 1.570796326794896619231321692*I # 32-bit |
|---|
| 2687 | 0.88137358701954302523260932497979230902 + 1.5707963267948966192313216916397514421*I # 64-bit |
|---|
| 2688 | """ |
|---|
| 2689 | _sig_on |
|---|
| 2690 | return P.new_gen(gach(x.g, prec)) |
|---|
| 2691 | |
|---|
| 2692 | def agm(gen x, y): |
|---|
| 2693 | r""" |
|---|
| 2694 | The arithmetic-geometric mean of x and y. In the case of complex |
|---|
| 2695 | or negative numbers, the principal square root is always chosen. |
|---|
| 2696 | p-adic or power series arguments are also allowed. Note that a p-adic |
|---|
| 2697 | AGM exists only if x/y is congruent to 1 modulo p (modulo 16 for p=2). |
|---|
| 2698 | x and y cannot both be vectors or matrices. |
|---|
| 2699 | |
|---|
| 2700 | EXAMPLES: |
|---|
| 2701 | sage: pari('2').agm(2) |
|---|
| 2702 | 2.000000000000000000000000000 # 32-bit |
|---|
| 2703 | 2.0000000000000000000000000000000000000 # 64-bit |
|---|
| 2704 | sage: pari('0').agm(1) |
|---|
| 2705 | 0 |
|---|
| 2706 | sage: pari('1').agm(2) |
|---|
| 2707 | 1.456791031046906869186432383 # 32-bit |
|---|
| 2708 | 1.4567910310469068691864323832650819750 # 64-bit |
|---|
| 2709 | sage: pari('1+I').agm(-3) |
|---|
| 2710 | -0.9647317222908759112270275374 + 1.157002829526317260939086020*I # 32-bit |
|---|
| 2711 | -0.96473172229087591122702753739366831917 + 1.1570028295263172609390860195427517825*I # 64-bit |
|---|
| 2712 | """ |
|---|
| 2713 | t0GEN(y) |
|---|
| 2714 | _sig_on |
|---|
| 2715 | return P.new_gen(agm(x.g, t0, prec)) |
|---|
| 2716 | |
|---|
| 2717 | def arg(gen x): |
|---|
| 2718 | r""" |
|---|
| 2719 | arg(x): argument of x,such that $-\pi < \arg(x) \leq \pi$. |
|---|
| 2720 | |
|---|
| 2721 | EXAMPLES: |
|---|
| 2722 | sage: pari('2+I').arg() |
|---|
| 2723 | 0.4636476090008061162142562315 # 32-bit |
|---|
| 2724 | 0.46364760900080611621425623146121440203 # 64-bit |
|---|
| 2725 | """ |
|---|
| 2726 | _sig_on |
|---|
| 2727 | return P.new_gen(garg(x.g,prec)) |
|---|
| 2728 | |
|---|
| 2729 | def asin(gen x): |
|---|
| 2730 | r""" |
|---|
| 2731 | The principal branch of $\sin^{-1}(x)$, so that |
|---|
| 2732 | $\Re(\asin(x))$ belongs to $[-\pi/2,\pi/2]$. If $x$ is real |
|---|
| 2733 | and $|x| > 1$ then $\asin(x)$ is complex. |
|---|
| 2734 | |
|---|
| 2735 | EXAMPLES: |
|---|
| 2736 | sage: pari(pari('0.5').sin()).asin() |
|---|
| 2737 | 0.5000000000000000000000000000 # 32-bit |
|---|
| 2738 | 0.50000000000000000000000000000000000000 # 64-bit |
|---|
| 2739 | sage: pari(2).asin() |
|---|
| 2740 | 1.570796326794896619231321692 + 1.316957896924816708625046347*I # 32-bit |
|---|
| 2741 | 1.5707963267948966192313216916397514421 + 1.3169578969248167086250463473079684440*I # 64-bit |
|---|
| 2742 | """ |
|---|
| 2743 | _sig_on |
|---|
| 2744 | return P.new_gen(gasin(x.g, prec)) |
|---|
| 2745 | |
|---|
| 2746 | def asinh(gen x): |
|---|
| 2747 | r""" |
|---|
| 2748 | The principal branch of $\sinh^{-1}(x)$, so that $\Im(\asinh(x))$ belongs |
|---|
| 2749 | to $[-\pi/2,\pi/2]$. |
|---|
| 2750 | |
|---|
| 2751 | EXAMPLES: |
|---|
| 2752 | sage: pari(2).asinh() |
|---|
| 2753 | 1.443635475178810342493276740 # 32-bit |
|---|
| 2754 | 1.4436354751788103424932767402731052694 # 64-bit |
|---|
| 2755 | sage: pari('2+I').asinh() |
|---|
| 2756 | 1.528570919480998161272456185 + 0.4270785863924761254806468833*I # 32-bit |
|---|
| 2757 | 1.5285709194809981612724561847936733933 + 0.42707858639247612548064688331895685930*I # 64-bit |
|---|
| 2758 | """ |
|---|
| 2759 | _sig_on |
|---|
| 2760 | return P.new_gen(gash(x.g, prec)) |
|---|
| 2761 | |
|---|
| 2762 | def atan(gen x): |
|---|
| 2763 | r""" |
|---|
| 2764 | The principal branch of $\tan^{-1}(x)$, so that $\Re(\atan(x))$ belongs |
|---|
| 2765 | to $]-\pi/2, \pi/2[$. |
|---|
| 2766 | |
|---|
| 2767 | EXAMPLES: |
|---|
| 2768 | sage: pari(1).atan() |
|---|
| 2769 | 0.7853981633974483096156608458 # 32-bit |
|---|
| 2770 | 0.78539816339744830961566084581987572104 # 64-bit |
|---|
| 2771 | sage: pari('1.5+I').atan() |
|---|
| 2772 | 1.107148717794090503017065460 + 0.2554128118829953416027570482*I # 32-bit |
|---|
| 2773 | 1.1071487177940905030170654601785370401 + 0.25541281188299534160275704815183096744*I # 64-bit |
|---|
| 2774 | """ |
|---|
| 2775 | _sig_on |
|---|
| 2776 | return P.new_gen(gatan(x.g, prec)) |
|---|
| 2777 | |
|---|
| 2778 | def atanh(gen x): |
|---|
| 2779 | r""" |
|---|
| 2780 | The principal branch of $\tanh^{-1}(x)$, so that |
|---|
| 2781 | $\Im(\atanh(x))$ belongs to $]-\pi/2,\pi/2]$. If $x$ is real |
|---|
| 2782 | and $|x| > 1$ then $\atanh(x)$ is complex. |
|---|
| 2783 | |
|---|
| 2784 | EXAMPLES: |
|---|
| 2785 | sage: pari(0).atanh() |
|---|
| 2786 | 0.E-250 # 32-bit |
|---|
| 2787 | 0.E-693 # 64-bit |
|---|
| 2788 | sage: pari(2).atanh() |
|---|
| 2789 | 0.5493061443340548456976226185 + 1.570796326794896619231321692*I # 32-bit |
|---|
| 2790 | 0.54930614433405484569762261846126285232 + 1.5707963267948966192313216916397514421*I # 64-bit |
|---|
| 2791 | """ |
|---|
| 2792 | _sig_on |
|---|
| 2793 | return P.new_gen(gath(x.g, prec)) |
|---|
| 2794 | |
|---|
| 2795 | def bernfrac(gen x): |
|---|
| 2796 | r""" |
|---|
| 2797 | The Bernoulli number $B_x$, where $B_0 = 1$, $B_1 = -1/2$, |
|---|
| 2798 | $B_2 = 1/6,\ldots,$ expressed as a rational number. The |
|---|
| 2799 | argument $x$ should be of type integer. |
|---|
| 2800 | |
|---|
| 2801 | EXAMPLES: |
|---|
| 2802 | sage: pari(18).bernfrac() |
|---|
| 2803 | 43867/798 |
|---|
| 2804 | sage: [pari(n).bernfrac() for n in range(10)] |
|---|
| 2805 | [1, -1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0] |
|---|
| 2806 | """ |
|---|
| 2807 | _sig_on |
|---|
| 2808 | return P.new_gen(bernfrac(x)) |
|---|
| 2809 | |
|---|
| 2810 | def fibonacci(gen x): |
|---|
| 2811 | r""" |
|---|
| 2812 | Return the fibonacci number of index x. |
|---|
| 2813 | |
|---|
| 2814 | EXAMPLES: |
|---|
| 2815 | sage: pari(18).bernfrac() |
|---|
| 2816 | 43867/798 |
|---|
| 2817 | sage: [pari(n).bernfrac() for n in range(10)] |
|---|
| 2818 | [1, -1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0] |
|---|
| 2819 | """ |
|---|
| 2820 | _sig_on |
|---|
| 2821 | return P.new_gen(fibo(long(x))) |
|---|
| 2822 | |
|---|
| 2823 | def bernreal(gen x): |
|---|
| 2824 | r""" |
|---|
| 2825 | The Bernoulli number $B_x$, as for the function bernfrac, but |
|---|
| 2826 | $B_x$ is returned as a real number (with the current |
|---|
| 2827 | precision). |
|---|
| 2828 | |
|---|
| 2829 | EXAMPLES: |
|---|
| 2830 | sage: pari(18).bernreal() |
|---|
| 2831 | 54.97117794486215538847117794 # 32-bit |
|---|
| 2832 | 54.971177944862155388471177944862155388 # 64-bit |
|---|
| 2833 | """ |
|---|
| 2834 | _sig_on |
|---|
| 2835 | return P.new_gen(bernreal(x, prec)) |
|---|
| 2836 | |
|---|
| 2837 | def bernvec(gen x): |
|---|
| 2838 | r""" |
|---|
| 2839 | Creates a vector containing, as rational numbers, the |
|---|
| 2840 | Bernoulli numbers $B_0, B_2,\ldots, B_{2x}$. This routine is |
|---|
| 2841 | obsolete. Use bernfrac instead each time you need a Bernoulli |
|---|
| 2842 | number in exact form. |
|---|
| 2843 | |
|---|
| 2844 | Note: this routine is implemented using repeated independent |
|---|
| 2845 | calls to bernfrac, which is faster than the standard recursion in |
|---|
| 2846 | exact arithmetic. |
|---|
| 2847 | |
|---|
| 2848 | EXAMPLES: |
|---|
| 2849 | sage: pari(8).bernvec() |
|---|
| 2850 | [1, 1/6, -1/30, 1/42, -1/30, 5/66, -691/2730, 7/6, -3617/510] |
|---|
| 2851 | sage: [pari(2*n).bernfrac() for n in range(9)] |
|---|
| 2852 | [1, 1/6, -1/30, 1/42, -1/30, 5/66, -691/2730, 7/6, -3617/510] |
|---|
| 2853 | """ |
|---|
| 2854 | _sig_on |
|---|
| 2855 | return P.new_gen(bernvec(x)) |
|---|
| 2856 | |
|---|
| 2857 | def besselh1(gen nu, x): |
|---|
| 2858 | r""" |
|---|
| 2859 | The $H^1$-Bessel function of index $\nu$ and argument $x$. |
|---|
| 2860 | |
|---|
| 2861 | EXAMPLES: |
|---|
| 2862 | sage: pari(2).besselh1(3) |
|---|
| 2863 | 0.4860912605858910769078310941 - 0.1604003934849237296757682995*I # 32-bit |
|---|
| 2864 | 0.48609126058589107690783109411498403480 - 0.16040039348492372967576829953798091810*I # 64-bit |
|---|
| 2865 | """ |
|---|
| 2866 | t0GEN(x) |
|---|
| 2867 | _sig_on |
|---|
| 2868 | return P.new_gen(hbessel1(nu.g, t0, prec)) |
|---|
| 2869 | |
|---|
| 2870 | def besselh2(gen nu, x): |
|---|
| 2871 | r""" |
|---|
| 2872 | The $H^2$-Bessel function of index $\nu$ and argument $x$. |
|---|
| 2873 | |
|---|
| 2874 | EXAMPLES: |
|---|
| 2875 | sage: pari(2).besselh2(3) |
|---|
| 2876 | 0.4860912605858910769078310941 + 0.1604003934849237296757682995*I # 32-bit |
|---|
| 2877 | 0.48609126058589107690783109411498403480 + 0.16040039348492372967576829953798091810*I # 64-bit |
|---|
| 2878 | """ |
|---|
| 2879 | t0GEN(x) |
|---|
| 2880 | _sig_on |
|---|
| 2881 | return P.new_gen(hbessel2(nu.g, t0, prec)) |
|---|
| 2882 | |
|---|
| 2883 | def besselj(gen nu, x): |
|---|
| 2884 | r""" |
|---|
| 2885 | Bessel J function (Bessel function of the first kind), with |
|---|
| 2886 | index $\nu$ and argument $x$. If $x$ converts to a power |
|---|
| 2887 | series, the initial factor $(x/2)^{\nu}/\Gamma(\nu+1)$ is |
|---|
| 2888 | omitted (since it cannot be represented in PARI when $\nu$ is not |
|---|
| 2889 | integral). |
|---|
| 2890 | |
|---|
| 2891 | EXAMPLES: |
|---|
| 2892 | sage: pari(2).besselj(3) |
|---|
| 2893 | 0.4860912605858910769078310941 # 32-bit |
|---|
| 2894 | 0.48609126058589107690783109411498403480 # 64-bit |
|---|
| 2895 | """ |
|---|
| 2896 | t0GEN(x) |
|---|
| 2897 | _sig_on |
|---|
| 2898 | return P.new_gen(jbessel(nu.g, t0, prec)) |
|---|
| 2899 | |
|---|
| 2900 | def besseljh(gen nu, x): |
|---|
| 2901 | """ |
|---|
| 2902 | J-Bessel function of half integral index (Speherical Bessel |
|---|
| 2903 | function of the first kind). More precisely, besseljh(n,x) |
|---|
| 2904 | computes $J_{n+1/2}(x)$ where n must an integer, and x is any |
|---|
| 2905 | complex value. In the current implementation (PARI, version |
|---|
| 2906 | 2.2.11), this function is not very accurate when $x$ is small. |
|---|
| 2907 | |
|---|
| 2908 | EXAMPLES: |
|---|
| 2909 | sage: pari(2).besseljh(3) |
|---|
| 2910 | 0.4127100322097159934374967959 # 32-bit |
|---|
| 2911 | 0.41271003220971599343749679594186271499 # 64-bit |
|---|
| 2912 | """ |
|---|
| 2913 | t0GEN(x) |
|---|
| 2914 | _sig_on |
|---|
| 2915 | return P.new_gen(jbesselh(nu.g, t0, prec)) |
|---|
| 2916 | |
|---|
| 2917 | def besseli(gen nu, x): |
|---|
| 2918 | """ |
|---|
| 2919 | Bessel I function (Bessel function of the second kind), with |
|---|
| 2920 | index $\nu$ and argument $x$. If $x$ converts to a power |
|---|
| 2921 | series, the initial factor $(x/2)^{\nu}/\Gamma(\nu+1)$ is |
|---|
| 2922 | omitted (since it cannot be represented in PARI when $\nu$ is not |
|---|
| 2923 | integral). |
|---|
| 2924 | |
|---|
| 2925 | EXAMPLES: |
|---|
| 2926 | sage: pari(2).besseli(3) |
|---|
| 2927 | 2.245212440929951154625478386 # 32-bit |
|---|
| 2928 | 2.2452124409299511546254783856342650577 # 64-bit |
|---|
| 2929 | sage: pari(2).besseli('3+I') |
|---|
| 2930 | 1.125394076139128134398383103 + 2.083138226706609118835787255*I # 32-bit |
|---|
| 2931 | 1.1253940761391281343983831028963896470 + 2.0831382267066091188357872547036161842*I # 64-bit |
|---|
| 2932 | """ |
|---|
| 2933 | t0GEN(x) |
|---|
| 2934 | _sig_on |
|---|
| 2935 | return P.new_gen(ibessel(nu.g, t0, prec)) |
|---|
| 2936 | |
|---|
| 2937 | def besselk(gen nu, x, long flag=0): |
|---|
| 2938 | """ |
|---|
| 2939 | nu.besselk(x, flag=0): K-Bessel function (modified Bessel |
|---|
| 2940 | function of the second kind) of index nu, which can be |
|---|
| 2941 | complex, and argument x. |
|---|
| 2942 | |
|---|
| 2943 | INPUT: |
|---|
| 2944 | nu -- a complex number |
|---|
| 2945 | x -- real number (positive or negative) |
|---|
| 2946 | flag -- default: 0 or 1: use hyperu (hyperu is much slower for |
|---|
| 2947 | small x, and doesn't work for negative x). |
|---|
| 2948 | |
|---|
| 2949 | WARNING/TODO -- with flag = 1 this function is incredibly slow |
|---|
| 2950 | (on 64-bit Linux) as it is implemented using it from the C |
|---|
| 2951 | library, but it shouldn't be (e.g., it's not slow via the GP |
|---|
| 2952 | interface.) Why? |
|---|
| 2953 | |
|---|
| 2954 | EXAMPLES: |
|---|
| 2955 | sage: pari('2+I').besselk(3) |
|---|
| 2956 | 0.04559077184075505871203211094 + 0.02891929465820812820828883526*I # 32-bit |
|---|
| 2957 | 0.045590771840755058712032110938791854704 + 0.028919294658208128208288835257608789842*I # 64-bit |
|---|
| 2958 | |
|---|
| 2959 | sage: pari('2+I').besselk(-3) |
|---|
| 2960 | -4.348708749867516799575863067 - 5.387448826971091267230878827*I # 32-bit |
|---|
| 2961 | -4.3487087498675167995758630674661864255 - 5.3874488269710912672308788273655523057*I # 64-bit |
|---|
| 2962 | |
|---|
| 2963 | sage: pari('2+I').besselk(300, flag=1) # long time |
|---|
| 2964 | 3.742246033197275082909500148 E-132 + 2.490710626415252262644383350 E-134*I # 32-bit |
|---|
| 2965 | 3.7422460331972750829095001475885825717 E-132 + 2.4907106264152522626443833495225745762 E-134*I # 64-bit |
|---|
| 2966 | |
|---|
| 2967 | """ |
|---|
| 2968 | t0GEN(x) |
|---|
| 2969 | _sig_on |
|---|
| 2970 | return P.new_gen(kbessel0(nu.g, t0, flag, prec)) |
|---|
| 2971 | |
|---|
| 2972 | def besseln(gen nu, x): |
|---|
| 2973 | """ |
|---|
| 2974 | nu.besseln(x): Bessel N function (Spherical Bessel function of |
|---|
| 2975 | the second kind) of index nu and argument x. |
|---|
| 2976 | |
|---|
| 2977 | EXAMPLES: |
|---|
| 2978 | sage: pari('2+I').besseln(3) |
|---|
| 2979 | -0.2807755669582439141676487005 - 0.4867085332237257928816949747*I # 32-bit |
|---|
| 2980 | -0.28077556695824391416764870046044688871 - 0.48670853322372579288169497466916637395*I # 64-bit |
|---|
| 2981 | """ |
|---|
| 2982 | t0GEN(x) |
|---|
| 2983 | _sig_on |
|---|
| 2984 | return P.new_gen(nbessel(nu.g, t0, prec)) |
|---|
| 2985 | |
|---|
| 2986 | def cos(gen self): |
|---|
| 2987 | """ |
|---|
| 2988 | The cosine function. |
|---|
| 2989 | |
|---|
| 2990 | EXAMPLES: |
|---|
| 2991 | sage: x = pari('1.5') |
|---|
| 2992 | sage: x.cos() |
|---|
| 2993 | 0.07073720166770291008818985142 # 32-bit |
|---|
| 2994 | 0.070737201667702910088189851434268709084 # 64-bit |
|---|
| 2995 | sage: pari('1+I').cos() |
|---|
| 2996 | 0.8337300251311490488838853943 - 0.9888977057628650963821295409*I # 32-bit |
|---|
| 2997 | 0.83373002513114904888388539433509447980 - 0.98889770576286509638212954089268618864*I # 64-bit |
|---|
| 2998 | sage: pari('x+O(x^8)').cos() |
|---|
| 2999 | 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 + O(x^9) |
|---|
| 3000 | """ |
|---|
| 3001 | _sig_on |
|---|
| 3002 | return P.new_gen(gcos(self.g, prec)) |
|---|
| 3003 | |
|---|
| 3004 | def cosh(gen self): |
|---|
| 3005 | """ |
|---|
| 3006 | The hyperbolic cosine function. |
|---|
| 3007 | |
|---|
| 3008 | EXAMPLES: |
|---|
| 3009 | sage: x = pari('1.5') |
|---|
| 3010 | sage: x.cosh() |
|---|
| 3011 | 2.352409615243247325767667965 # 32-bit |
|---|
| 3012 | 2.3524096152432473257676679654416441702 # 64-bit |
|---|
| 3013 | sage: pari('1+I').cosh() |
|---|
| 3014 | 0.8337300251311490488838853943 + 0.9888977057628650963821295409*I # 32-bit |
|---|
| 3015 | 0.83373002513114904888388539433509447980 + 0.98889770576286509638212954089268618864*I # 64-bit |
|---|
| 3016 | sage: pari('x+O(x^8)').cosh() |
|---|
| 3017 | 1 + 1/2*x^2 + 1/24*x^4 + 1/720*x^6 + O(x^8) |
|---|
| 3018 | """ |
|---|
| 3019 | _sig_on |
|---|
| 3020 | return P.new_gen(gch(self.g, prec)) |
|---|
| 3021 | |
|---|
| 3022 | def cotan(gen x): |
|---|
| 3023 | """ |
|---|
| 3024 | The cotangent of x. |
|---|
| 3025 | |
|---|
| 3026 | EXAMPLES: |
|---|
| 3027 | sage: pari(5).cotan() |
|---|
| 3028 | -0.2958129155327455404277671681 # 32-bit |
|---|
| 3029 | -0.29581291553274554042776716808248528607 # 64-bit |
|---|
| 3030 | |
|---|
| 3031 | On a 32-bit computer computing the cotangent of $\pi$ doesn't |
|---|
| 3032 | raise an error, but instead just returns a very large number. |
|---|
| 3033 | On a 64-bit computer it raises a RuntimeError. |
|---|
| 3034 | |
|---|
| 3035 | sage: pari('Pi').cotan() |
|---|
| 3036 | 1.980704062 E28 # 32-bit |
|---|
| 3037 | Traceback (most recent call last): # 64-bit |
|---|
| 3038 | ... # 64-bit |
|---|
| 3039 | PariError: division by zero (46) # 64-bit |
|---|
| 3040 | """ |
|---|
| 3041 | _sig_on |
|---|
| 3042 | return P.new_gen(gcotan(x.g, prec)) |
|---|
| 3043 | |
|---|
| 3044 | def dilog(gen x): |
|---|
| 3045 | r""" |
|---|
| 3046 | The principal branch of the dilogarithm of $x$, i.e. the analytic |
|---|
| 3047 | continuation of the power series $\log_2(x) = \sum_{n>=1} x^n/n^2$. |
|---|
| 3048 | |
|---|
| 3049 | EXAMPLES: |
|---|
| 3050 | sage: pari(1).dilog() |
|---|
| 3051 | 1.644934066848226436472415167 # 32-bit |
|---|
| 3052 | 1.6449340668482264364724151666460251892 # 64-bit |
|---|
| 3053 | sage: pari('1+I').dilog() |
|---|
| 3054 | 0.6168502750680849136771556875 + 1.460362116753119547679775739*I # 32-bit |
|---|
| 3055 | 0.61685027506808491367715568749225944595 + 1.4603621167531195476797757394917875976*I # 64-bit |
|---|
| 3056 | """ |
|---|
| 3057 | _sig_on |
|---|
| 3058 | return P.new_gen(dilog(x.g, prec)) |
|---|
| 3059 | |
|---|
| 3060 | def eint1(gen x, long n=0): |
|---|
| 3061 | r""" |
|---|
| 3062 | x.eint1({n}): exponential integral E1(x): |
|---|
| 3063 | $$ |
|---|
| 3064 | \int_{x}^{\infty} \frac{e^{-t}}{t} dt |
|---|
| 3065 | $$ |
|---|
| 3066 | If n is present, output the vector |
|---|
| 3067 | [eint1(x), eint1(2*x), ..., eint1(n*x)]. |
|---|
| 3068 | This is faster than repeatedly calling eint1(i*x). |
|---|
| 3069 | |
|---|
| 3070 | REFERENCE: See page 262, Prop 5.6.12, of Cohen's book |
|---|
| 3071 | "A Course in Computational Algebraic Number Theory". |
|---|
| 3072 | |
|---|
| 3073 | EXAMPLES: |
|---|
| 3074 | |
|---|
| 3075 | """ |
|---|
| 3076 | if n <= 0: |
|---|
| 3077 | _sig_on |
|---|
| 3078 | return P.new_gen(eint1(x.g, prec)) |
|---|
| 3079 | else: |
|---|
| 3080 | _sig_on |
|---|
| 3081 | return P.new_gen(veceint1(x.g, stoi(n), prec)) |
|---|
| 3082 | |
|---|
| 3083 | def erfc(gen x): |
|---|
| 3084 | r""" |
|---|
| 3085 | Return the complementary error function: |
|---|
| 3086 | $$(2/\sqrt{\pi}) \int_{x}^{\infty} e^{-t^2} dt.$$ |
|---|
| 3087 | |
|---|
| 3088 | EXAMPLES: |
|---|
| 3089 | sage: pari(1).erfc() |
|---|
| 3090 | 0.1572992070502851306587793649 # 32-bit |
|---|
| 3091 | 0.15729920705028513065877936491739074070 # 64-bit |
|---|
| 3092 | """ |
|---|
| 3093 | _sig_on |
|---|
| 3094 | return P.new_gen(gerfc(x.g, prec)) |
|---|
| 3095 | |
|---|
| 3096 | def eta(gen x, flag=0): |
|---|
| 3097 | r""" |
|---|
| 3098 | x.eta({flag=0}): if flag=0, $\eta$ function without the $q^{1/24}$; |
|---|
| 3099 | otherwise $\eta$ of the complex number $x$ in the upper half plane |
|---|
| 3100 | intelligently computed using $\SL(2,\Z)$ transformations. |
|---|
| 3101 | |
|---|
| 3102 | DETAILS: This functions computes the following. If the input |
|---|
| 3103 | $x$ is a complex number with positive imaginary part, the |
|---|
| 3104 | result is $\prod_{n=1}^{\infty} (q-1^n)$, where $q=e^{2 i \pi |
|---|
| 3105 | x}$. If $x$ is a power series (or can be converted to a power |
|---|
| 3106 | series) with positive valuation, the result it |
|---|
| 3107 | $\prod_{n=1}^{\infty} (1-x^n)$. |
|---|
| 3108 | |
|---|
| 3109 | EXAMPLES: |
|---|
| 3110 | sage: pari('I').eta() |
|---|
| 3111 | 0.9981290699259585132799623222 # 32-bit |
|---|
| 3112 | 0.99812906992595851327996232224527387813 # 64-bit |
|---|
| 3113 | """ |
|---|
| 3114 | if flag == 1: |
|---|
| 3115 | _sig_on |
|---|
| 3116 | return P.new_gen(trueeta(x.g, prec)) |
|---|
| 3117 | _sig_on |
|---|
| 3118 | return P.new_gen(eta(x.g, prec)) |
|---|
| 3119 | |
|---|
| 3120 | def exp(gen self): |
|---|
| 3121 | """ |
|---|
| 3122 | x.exp(): exponential of x. |
|---|
| 3123 | |
|---|
| 3124 | EXAMPLES: |
|---|
| 3125 | sage: pari(0).exp() |
|---|
| 3126 | 1.000000000000000000000000000 # 32-bit |
|---|
| 3127 | 1.0000000000000000000000000000000000000 # 64-bit |
|---|
| 3128 | sage: pari(1).exp() |
|---|
| 3129 | 2.718281828459045235360287471 # 32-bit |
|---|
| 3130 | 2.7182818284590452353602874713526624978 # 64-bit |
|---|
| 3131 | sage: pari('x+O(x^8)').exp() |
|---|
| 3132 | 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + 1/5040*x^7 + O(x^8) |
|---|
| 3133 | """ |
|---|
| 3134 | _sig_on |
|---|
| 3135 | return P.new_gen(gexp(self.g, prec)) |
|---|
| 3136 | |
|---|
| 3137 | def gamma(gen s, precision=0): |
|---|
| 3138 | """ |
|---|
| 3139 | s.gamma({precision}): Gamma function at s. |
|---|
| 3140 | |
|---|
| 3141 | INPUT: |
|---|
| 3142 | s -- gen (real or complex number |
|---|
| 3143 | precision -- optional precisiion |
|---|
| 3144 | |
|---|
| 3145 | OUTPUT: |
|---|
| 3146 | gen -- value of the Gamma function at s. |
|---|
| 3147 | |
|---|
| 3148 | EXAMPLES: |
|---|
| 3149 | sage: pari(2).gamma() |
|---|
| 3150 | 1.000000000000000000000000000 # 32-bit |
|---|
| 3151 | 1.0000000000000000000000000000000000000 # 64-bit |
|---|
| 3152 | sage: pari(5).gamma() |
|---|
| 3153 | 24.00000000000000000000000000 # 32-bit |
|---|
| 3154 | 24.000000000000000000000000000000000000 # 64-bit |
|---|
| 3155 | sage: pari('1+I').gamma() |
|---|
| 3156 | 0.4980156681183560427136911175 - 0.1549498283018106851249551305*I # 32-bit |
|---|
| 3157 | 0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I # 64-bit |
|---|
| 3158 | """ |
|---|
| 3159 | if not precision: precision = prec |
|---|
| 3160 | _sig_on |
|---|
| 3161 | return P.new_gen(ggamma(s.g, precision)) |
|---|
| 3162 | |
|---|
| 3163 | def gammah(gen s): |
|---|
| 3164 | """ |
|---|
| 3165 | x.gammah(): Gamma function evaluated at the argument x+1/2, |
|---|
| 3166 | for x an integer. |
|---|
| 3167 | |
|---|
| 3168 | EXAMPLES: |
|---|
| 3169 | sage: pari(2).gammah() |
|---|
| 3170 | 1.329340388179137020473625613 # 32-bit |
|---|
| 3171 | 1.3293403881791370204736256125058588871 # 64-bit |
|---|
| 3172 | sage: pari(5).gammah() |
|---|
| 3173 | 52.34277778455352018114900849 # 32-bit |
|---|
| 3174 | 52.342777784553520181149008492418193679 # 64-bit |
|---|
| 3175 | sage: pari('1+I').gammah() |
|---|
| 3176 | 0.5753151880634517207185443722 + 0.08821067754409390991246464371*I # 32-bit |
|---|
| 3177 | 0.57531518806345172071854437217501119058 + 0.088210677544093909912464643706507454993*I # 64-bit |
|---|
| 3178 | """ |
|---|
| 3179 | _sig_on |
|---|
| 3180 | return P.new_gen(ggamd(s.g, prec)) |
|---|
| 3181 | |
|---|
| 3182 | def hyperu(gen a, b, x): |
|---|
| 3183 | r""" |
|---|
| 3184 | a.hyperu(b,x): U-confluent hypergeometric function. |
|---|
| 3185 | |
|---|
| 3186 | WARNING/TODO: This function is \emph{extremely slow} as |
|---|
| 3187 | implemented when used from the C library. If you use the GP |
|---|
| 3188 | interpreter inteface it is vastly faster, so clearly this |
|---|
| 3189 | issue could be fixed with a better understanding of GP/PARI. |
|---|
| 3190 | Volunteers? |
|---|
| 3191 | |
|---|
| 3192 | EXAMPLES: |
|---|
| 3193 | sage: pari(1).hyperu(2,3) # long time |
|---|
| 3194 | 0.3333333333333333333333333333 # 32-bit |
|---|
| 3195 | 0.33333333333333333333333333333333333333 # 64-bit |
|---|
| 3196 | """ |
|---|
| 3197 | t0GEN(b) |
|---|
| 3198 | t1GEN(x) |
|---|
| 3199 | _sig_on |
|---|
| 3200 | return P.new_gen(hyperu(a.g, t0, t1, prec)) |
|---|
| 3201 | |
|---|
| 3202 | |
|---|
| 3203 | def incgam(gen s, x, y=None, precision=0): |
|---|
| 3204 | r""" |
|---|
| 3205 | s.incgam(x, {y}, {precision}): incomplete gamma function. y |
|---|
| 3206 | is optional and is the precomputed value of gamma(s). |
|---|
| 3207 | |
|---|
| 3208 | NOTE: This function works for any complex input (unlike in |
|---|
| 3209 | older version of PARI). |
|---|
| 3210 | |
|---|
| 3211 | INPUT: |
|---|
| 3212 | s, x, y -- gens |
|---|
| 3213 | precision -- option precision |
|---|
| 3214 | |
|---|
| 3215 | OUTPUT: |
|---|
| 3216 | gen -- value of the incomplete Gamma function at s. |
|---|
| 3217 | |
|---|
| 3218 | EXAMPLES: |
|---|
| 3219 | sage: pari('1+I').incgam('3-I') # long time |
|---|
| 3220 | -0.04582978599199457259586742326 + 0.04336968187266766812050474478*I # 32-bit |
|---|
| 3221 | -0.045829785991994572595867423261490338705 + 0.043369681872667668120504744775954724733*I # 64-bit |
|---|
| 3222 | """ |
|---|
| 3223 | if not precision: |
|---|
| 3224 | precision = prec |
|---|
| 3225 | t0GEN(x) |
|---|
| 3226 | if y is None: |
|---|
| 3227 | _sig_on |
|---|
| 3228 | return P.new_gen(incgam(s.g, t0, precision)) |
|---|
| 3229 | else: |
|---|
| 3230 | t1GEN(y) |
|---|
| 3231 | _sig_on |
|---|
| 3232 | return P.new_gen(incgam0(s.g, t0, t1, precision)) |
|---|
| 3233 | |
|---|
| 3234 | def incgamc(gen s, x): |
|---|
| 3235 | r""" |
|---|
| 3236 | s.incgamc(x): complementary incomplete gamma function. |
|---|
| 3237 | |
|---|
| 3238 | The arguments $x$ and $s$ are complex numbers such that $s$ is |
|---|
| 3239 | not a pole of $\Gamma$ and $|x|/(|s|+1)$ is not much larger |
|---|
| 3240 | than $1$ (otherwise, the convergence is very slow). The |
|---|
| 3241 | function returns the value of the integral $\int_{0}^{x} |
|---|
| 3242 | e^{-t} t^{s-1} dt.$ |
|---|
| 3243 | |
|---|
| 3244 | EXAMPLES: |
|---|
| 3245 | sage: pari(1).incgamc(2) |
|---|
| 3246 | 0.8646647167633873081060005050 # 32-bit |
|---|
| 3247 | 0.86466471676338730810600050502751559659 # 64-bit |
|---|
| 3248 | """ |
|---|
| 3249 | t0GEN(x) |
|---|
| 3250 | _sig_on |
|---|
| 3251 | return P.new_gen(incgamc(s.g, t0, prec)) |
|---|
| 3252 | |
|---|
| 3253 | |
|---|
| 3254 | def log(gen self): |
|---|
| 3255 | r""" |
|---|
| 3256 | x.log(): natural logarithm of x. |
|---|
| 3257 | |
|---|
| 3258 | This function returns the principal branch of the natural |
|---|
| 3259 | logarithm of $x$, i.e., the branch such that $\Im(\log(x)) \in |
|---|
| 3260 | ]-\pi, \pi].$ The result is complex (with imaginary part equal |
|---|
| 3261 | to $\pi$) if $x\in \R$ and $x<0$. In general, the algorithm |
|---|
| 3262 | uses the formula |
|---|
| 3263 | $$ |
|---|
| 3264 | \log(x) \simeq \frac{\pi}{2{\rm agm}(1,4/s)} - m\log(2), |
|---|
| 3265 | $$ |
|---|
| 3266 | if $s=x 2^m$ is large enough. (The result is exact to $B$ |
|---|
| 3267 | bits provided that $s>2^{B/2}$.) At low accuracies, this |
|---|
| 3268 | function computes $\log$ using the series expansion near $1$. |
|---|
| 3269 | |
|---|
| 3270 | Note that $p$-adic arguments can also be given as input, |
|---|
| 3271 | with the convention that $\log(p)=0$. Hence, in |
|---|
| 3272 | particular, $\exp(\log(x))/x$ is not in general |
|---|
| 3273 | equal to $1$ but instead to a $(p-1)th$ root of |
|---|
| 3274 | unity (or $\pm 1$ if $p=2$) times a power of $p$. |
|---|
| 3275 | |
|---|
| 3276 | EXAMPLES: |
|---|
| 3277 | sage: pari(5).log() |
|---|
| 3278 | 1.609437912434100374600759333 # 32-bit |
|---|
| 3279 | 1.6094379124341003746007593332261876395 # 64-bit |
|---|
| 3280 | sage: pari('I').log() |
|---|
| 3281 | 0.E-250 + 1.570796326794896619231321692*I # 32-bit |
|---|
| 3282 | 0.E-693 + 1.5707963267948966192313216916397514421*I # 64-bit |
|---|
| 3283 | """ |
|---|
| 3284 | _sig_on |
|---|
| 3285 | return P.new_gen(glog(self.g, prec)) |
|---|
| 3286 | |
|---|
| 3287 | def lngamma(gen x): |
|---|
| 3288 | r""" |
|---|
| 3289 | x.lngamma(): logarithm of the gamma function of x. |
|---|
| 3290 | |
|---|
| 3291 | This function returns the principal branch of the logarithm of |
|---|
| 3292 | the gamma function of $x$. The function $\log(\Gamma(x))$ is |
|---|
| 3293 | analytic on the complex plane with non-positive integers |
|---|
| 3294 | removed. This function can have much larger inputs than |
|---|
| 3295 | $\Gamma$ itself. |
|---|
| 3296 | |
|---|
| 3297 | The $p$-adic analogue of this function is unfortunately not |
|---|
| 3298 | implemented. |
|---|
| 3299 | |
|---|
| 3300 | EXAMPLES: |
|---|
| 3301 | sage: pari(100).lngamma() |
|---|
| 3302 | 359.1342053695753987760440105 # 32-bit |
|---|
| 3303 | 359.13420536957539877604401046028690961 # 64-bit |
|---|
| 3304 | """ |
|---|
| 3305 | _sig_on |
|---|
| 3306 | return P.new_gen(glngamma(x.g,prec)) |
|---|
| 3307 | |
|---|
| 3308 | def polylog(gen x, long m, flag=0): |
|---|
| 3309 | """ |
|---|
| 3310 | x.polylog(m,{flag=0}): m-th polylogarithm of x. flag is |
|---|
| 3311 | optional, and can be 0: default, 1: D_m~-modified m-th polylog |
|---|
| 3312 | of x, 2: D_m-modified m-th polylog of x, 3: P_m-modified m-th |
|---|
| 3313 | polylog of x. |
|---|
| 3314 | |
|---|
| 3315 | TODO: Add more explanation, copied from the PARI manual. |
|---|
| 3316 | |
|---|
| 3317 | EXAMPLES: |
|---|
| 3318 | sage: pari(10).polylog(3) |
|---|
| 3319 | 5.641811414751341250600725771 - 8.328202076980270580884185850*I # 32-bit |
|---|
| 3320 | 5.6418114147513412506007257705287671110 - 8.3282020769802705808841858505904310076*I # 64-bit |
|---|
| 3321 | sage: pari(10).polylog(3,0) |
|---|
| 3322 | 5.641811414751341250600725771 - 8.328202076980270580884185850*I # 32-bit |
|---|
| 3323 | 5.6418114147513412506007257705287671110 - 8.3282020769802705808841858505904310076*I # 64-bit |
|---|
| 3324 | sage: pari(10).polylog(3,1) |
|---|
| 3325 | 0.5237784535024110488342571116 # 32-bit |
|---|
| 3326 | 0.52377845350241104883425711161605950842 # 64-bit |
|---|
| 3327 | sage: pari(10).polylog(3,2) |
|---|
| 3328 | -0.4004590561634505605364328952 # 32-bit |
|---|
| 3329 | -0.40045905616345056053643289522452400363 # 64-bit |
|---|
| 3330 | """ |
|---|
| 3331 | _sig_on |
|---|
| 3332 | return P.new_gen(polylog0(m, x.g, flag, prec)) |
|---|
| 3333 | |
|---|
| 3334 | def psi(gen x): |
|---|
| 3335 | r""" |
|---|
| 3336 | x.psi(): psi-function at x. |
|---|
| 3337 | |
|---|
| 3338 | Return the $\psi$-function of $x$, i.e., the logarithmic |
|---|
| 3339 | derivative $\Gamma'(x)/\Gamma(x)$. |
|---|
| 3340 | |
|---|
| 3341 | EXAMPLES: |
|---|
| 3342 | sage: pari(1).psi() |
|---|
| 3343 | -0.5772156649015328606065120901 # 32-bit |
|---|
| 3344 | -0.57721566490153286060651209008240243104 # 64-bit |
|---|
| 3345 | """ |
|---|
| 3346 | _sig_on |
|---|
| 3347 | return P.new_gen(gpsi(x.g, prec)) |
|---|
| 3348 | |
|---|
| 3349 | |
|---|
| 3350 | def sin(gen x): |
|---|
| 3351 | """ |
|---|
| 3352 | x.sin(): The sine of x. |
|---|
| 3353 | |
|---|
| 3354 | EXAMPLES: |
|---|
| 3355 | sage: pari(1).sin() |
|---|
| 3356 | 0.8414709848078965066525023216 # 32-bit |
|---|
| 3357 | 0.84147098480789650665250232163029899962 # 64-bit |
|---|
| 3358 | sage: pari('1+I').sin() |
|---|
| 3359 | 1.298457581415977294826042366 + 0.6349639147847361082550822030*I # 32-bit |
|---|
| 3360 | 1.2984575814159772948260423658078156203 + 0.63496391478473610825508220299150978151*I # 64-bit |
|---|
| 3361 | """ |
|---|
| 3362 | _sig_on |
|---|
| 3363 | return P.new_gen(gsin(x.g, prec)) |
|---|
| 3364 | |
|---|
| 3365 | def sinh(gen self): |
|---|
| 3366 | """ |
|---|
| 3367 | The hyperbolic sine function. |
|---|
| 3368 | |
|---|
| 3369 | EXAMPLES: |
|---|
| 3370 | sage: pari(0).sinh() |
|---|
| 3371 | 0.E-250 # 32-bit |
|---|
| 3372 | 0.E-693 # 64-bit |
|---|
| 3373 | sage: pari('1+I').sinh() |
|---|
| 3374 | 0.6349639147847361082550822030 + 1.298457581415977294826042366*I # 32-bit |
|---|
| 3375 | 0.63496391478473610825508220299150978151 + 1.2984575814159772948260423658078156203*I # 64-bit |
|---|
| 3376 | """ |
|---|
| 3377 | _sig_on |
|---|
| 3378 | return P.new_gen(gsh(self.g, prec)) |
|---|
| 3379 | |
|---|
| 3380 | def sqr(gen x): |
|---|
| 3381 | """ |
|---|
| 3382 | x.sqr(): square of x. NOT identical to x*x. |
|---|
| 3383 | |
|---|
| 3384 | TODO: copy extensive notes about this function |
|---|
| 3385 | from PARI manual. Put examples below. |
|---|
| 3386 | |
|---|
| 3387 | EXAMPLES: |
|---|
| 3388 | sage: pari(2).sqr() |
|---|
| 3389 | 4 |
|---|
| 3390 | """ |
|---|
| 3391 | _sig_on |
|---|
| 3392 | return P.new_gen(gsqr(x.g)) |
|---|
| 3393 | |
|---|
| 3394 | |
|---|
| 3395 | def sqrt(gen x, precision=0): |
|---|
| 3396 | """ |
|---|
| 3397 | x.sqrt({precision}): The square root of x. |
|---|
| 3398 | |
|---|
| 3399 | EXAMPLES: |
|---|
| 3400 | sage: pari(2).sqrt() |
|---|
| 3401 | 1.414213562373095048801688724 # 32-bit |
|---|
| 3402 | 1.4142135623730950488016887242096980786 # 64-bit |
|---|
| 3403 | """ |
|---|
| 3404 | if not precision: precision = prec |
|---|
| 3405 | _sig_on |
|---|
| 3406 | return P.new_gen(gsqrt(x.g, precision)) |
|---|
| 3407 | |
|---|
| 3408 | def sqrtn(gen x, n): |
|---|
| 3409 | r""" |
|---|
| 3410 | x.sqrtn(n): return the principal branch of the n-th root |
|---|
| 3411 | of x, i.e., the one such that |
|---|
| 3412 | $\arg(\sqrt(x)) \in ]-\pi/n, \pi/n]$. |
|---|
| 3413 | Also returns a second argument which is a suitable root |
|---|
| 3414 | of unity allowing one to recover all the other roots. |
|---|
| 3415 | If it was not possible to find such a number, then this |
|---|
| 3416 | second return value is 0. If the argument is present and |
|---|
| 3417 | no square root exists, return 0 instead of raising an error. |
|---|
| 3418 | |
|---|
| 3419 | NOTE: intmods (modulo a prime) and $p$-adic numbers are |
|---|
| 3420 | allowed as arguments. |
|---|
| 3421 | |
|---|
| 3422 | INPUT: |
|---|
| 3423 | x -- gen |
|---|
| 3424 | n -- integer |
|---|
| 3425 | OUTPUT: |
|---|
| 3426 | gen -- principal n-th root of x |
|---|
| 3427 | gen -- z that gives the other roots |
|---|
| 3428 | |
|---|
| 3429 | EXAMPLES: |
|---|
| 3430 | sage: s, z = pari(2).sqrtn(5) |
|---|
| 3431 | sage: z |
|---|
| 3432 | 0.3090169943749474241022934172 + 0.9510565162951535721164393334*I # 32-bit |
|---|
| 3433 | 0.30901699437494742410229341718281905886 + 0.95105651629515357211643933337938214340*I # 64-bit |
|---|
| 3434 | sage: s |
|---|
| 3435 | 1.148698354997035006798626947 # 32-bit |
|---|
| 3436 | 1.1486983549970350067986269467779275894 # 64-bit |
|---|
| 3437 | sage: s^5 |
|---|
| 3438 | 2.000000000000000000000000000 # 32-bit |
|---|
| 3439 | 2.0000000000000000000000000000000000000 # 64-bit |
|---|
| 3440 | sage: (s*z)^5 |
|---|
| 3441 | 2.000000000000000000000000000 - 1.396701498 E-250*I # 32-bit |
|---|
| 3442 | 2.0000000000000000000000000000000000000 - 1.0689317613194482765 E-693*I # 64-bit |
|---|
| 3443 | """ |
|---|
| 3444 | # TODO: ??? lots of good examples in the PARI docs ??? |
|---|
| 3445 | cdef GEN zetan |
|---|
| 3446 | t0GEN(n) |
|---|
| 3447 | _sig_on |
|---|
| 3448 | ans = P.new_gen_noclear(gsqrtn(x.g, t0, &zetan, prec)) |
|---|
| 3449 | return ans, P.new_gen(zetan) |
|---|
| 3450 | |
|---|
| 3451 | def tan(gen x): |
|---|
| 3452 | """ |
|---|
| 3453 | x.tan() -- tangent of x |
|---|
| 3454 | |
|---|
| 3455 | EXAMPLES: |
|---|
| 3456 | sage: pari(2).tan() |
|---|
| 3457 | -2.185039863261518991643306102 # 32-bit |
|---|
| 3458 | -2.1850398632615189916433061023136825434 # 64-bit |
|---|
| 3459 | sage: pari('I').tan() |
|---|
| 3460 | 0.E-250 + 0.7615941559557648881194582826*I # 32-bit |
|---|
| 3461 | 0.E-693 + 0.76159415595576488811945828260479359041*I # 64-bit |
|---|
| 3462 | """ |
|---|
| 3463 | _sig_on |
|---|
| 3464 | return P.new_gen(gtan(x.g, prec)) |
|---|
| 3465 | |
|---|
| 3466 | def tanh(gen x): |
|---|
| 3467 | """ |
|---|
| 3468 | x.tanh() -- hyperbolic tangent of x |
|---|
| 3469 | |
|---|
| 3470 | EXAMPLES: |
|---|
| 3471 | sage: pari(1).tanh() |
|---|
| 3472 | 0.7615941559557648881194582826 # 32-bit |
|---|
| 3473 | 0.76159415595576488811945828260479359041 # 64-bit |
|---|
| 3474 | sage: pari('I').tanh() |
|---|
| 3475 | 0.E-250 + 1.557407724654902230506974807*I # 32-bit |
|---|
| 3476 | -5.344658806597241382 E-694 + 1.5574077246549022305069748074583601731*I # 64-bit |
|---|
| 3477 | """ |
|---|
| 3478 | _sig_on |
|---|
| 3479 | return P.new_gen(gth(x.g, prec)) |
|---|
| 3480 | |
|---|
| 3481 | def teichmuller(gen x): |
|---|
| 3482 | r""" |
|---|
| 3483 | teichmuller(x): teichmuller character of p-adic number x. |
|---|
| 3484 | |
|---|
| 3485 | This is the unique $(p-1)$th root of unity congruent to |
|---|
| 3486 | $x/p^{v_p(x)}$ modulo $p$. |
|---|
| 3487 | |
|---|
| 3488 | EXAMPLES: |
|---|
| 3489 | sage: pari('2+O(7^5)').teichmuller() |
|---|
| 3490 | 2 + 4*7 + 6*7^2 + 3*7^3 + O(7^5) |
|---|
| 3491 | """ |
|---|
| 3492 | _sig_on |
|---|
| 3493 | return P.new_gen(teich(x.g)) |
|---|
| 3494 | |
|---|
| 3495 | def theta(gen q, z): |
|---|
| 3496 | """ |
|---|
| 3497 | q.theta(z): Jacobi sine theta-function. |
|---|
| 3498 | |
|---|
| 3499 | EXAMPLES: |
|---|
| 3500 | sage: pari('0.5').theta(2) |
|---|
| 3501 | 1.632025902952598833772353216 # 32-bit |
|---|
| 3502 | 1.6320259029525988337723532162682089972 # 64-bit |
|---|
| 3503 | """ |
|---|
| 3504 | t0GEN(z) |
|---|
| 3505 | _sig_on |
|---|
| 3506 | return P.new_gen(theta(q.g, t0, prec)) |
|---|
| 3507 | |
|---|
| 3508 | def thetanullk(gen q, long k): |
|---|
| 3509 | """ |
|---|
| 3510 | q.thetanullk(k): return the k-th derivative at z=0 of theta(q,z) |
|---|
| 3511 | EXAMPLES: |
|---|
| 3512 | sage: pari('0.5').thetanullk(1) |
|---|
| 3513 | 0.5489785325603405618549383537 # 32-bit |
|---|
| 3514 | 0.54897853256034056185493835370857284861 # 64-bit |
|---|
| 3515 | """ |
|---|
| 3516 | _sig_on |
|---|
| 3517 | return P.new_gen(thetanullk(q.g, k, prec)) |
|---|
| 3518 | |
|---|
| 3519 | def weber(gen x, flag=0): |
|---|
| 3520 | r""" |
|---|
| 3521 | x.weber({flag=0}): One of Weber's f function of x. |
|---|
| 3522 | flag is optional, and can be |
|---|
| 3523 | 0: default, function f(x)=exp(-i*Pi/24)*eta((x+1)/2)/eta(x) |
|---|
| 3524 | such that $j=(f^{24}-16)^3/f^{24}$, |
|---|
| 3525 | 1: function f1(x)=eta(x/2)/eta(x) such that |
|---|
| 3526 | $j=(f1^24+16)^3/f2^{24}$, |
|---|
| 3527 | 2: function f2(x)=sqrt(2)*eta(2*x)/eta(x) such that |
|---|
| 3528 | $j=(f2^{24}+16)^3/f2^{24}$. |
|---|
| 3529 | |
|---|
| 3530 | TODO: Add further explanation from PARI manual. |
|---|
| 3531 | |
|---|
| 3532 | EXAMPLES: |
|---|
| 3533 | sage: pari('I').weber() |
|---|
| 3534 | 1.189207115002721066717499971 - 6.98350749 E-251*I # 32-bit |
|---|
| 3535 | 1.1892071150027210667174999705604759153 + 0.E-693*I # 64-bit |
|---|
| 3536 | sage: pari('I').weber(1) |
|---|
| 3537 | 1.090507732665257659207010656 # 32-bit |
|---|
| 3538 | 1.0905077326652576592070106557607079790 # 64-bit |
|---|
| 3539 | sage: pari('I').weber(2) |
|---|
| 3540 | 1.090507732665257659207010656 # 32-bit |
|---|
| 3541 | 1.0905077326652576592070106557607079790 # 64-bit |
|---|
| 3542 | """ |
|---|
| 3543 | _sig_on |
|---|
| 3544 | return P.new_gen(weber0(x.g, flag, prec)) |
|---|
| 3545 | |
|---|
| 3546 | |
|---|
| 3547 | def zeta(gen s, precision=0): |
|---|
| 3548 | """ |
|---|
| 3549 | zeta(s): Riemann zeta function at s with s a complex |
|---|
| 3550 | or a p-adic number. |
|---|
| 3551 | |
|---|
| 3552 | TODO: Add extensive explanation from PARI user's manual. |
|---|
| 3553 | |
|---|
| 3554 | INPUT: |
|---|
| 3555 | s -- gen (real or complex number) |
|---|
| 3556 | |
|---|
| 3557 | OUTPUT: |
|---|
| 3558 | gen -- value of zeta at s. |
|---|
| 3559 | |
|---|
| 3560 | EXAMPLES: |
|---|
| 3561 | sage: pari(2).zeta() |
|---|
| 3562 | 1.644934066848226436472415167 # 32-bit |
|---|
| 3563 | 1.6449340668482264364724151666460251892 # 64-bit |
|---|
| 3564 | sage: pari('Pi^2/6') |
|---|
| 3565 | 1.644934066848226436472415167 # 32-bit |
|---|
| 3566 | 1.6449340668482264364724151666460251892 # 64-bit |
|---|
| 3567 | sage: pari(3).zeta() |
|---|
| 3568 | 1.202056903159594285399738162 # 32-bit |
|---|
| 3569 | 1.2020569031595942853997381615114499908 # 64-bit |
|---|
| 3570 | """ |
|---|
| 3571 | if not precision: precision = prec |
|---|
| 3572 | _sig_on |
|---|
| 3573 | return P.new_gen(gzeta(s.g, precision)) |
|---|
| 3574 | |
|---|
| 3575 | ########################################### |
|---|
| 3576 | # 4: NUMBER THEORETICAL functions |
|---|
| 3577 | ########################################### |
|---|
| 3578 | |
|---|
| 3579 | def bezout(gen x, y): |
|---|
| 3580 | cdef gen u, v, g |
|---|
| 3581 | cdef GEN U, V, G |
|---|
| 3582 | t0GEN(y) |
|---|
| 3583 | _sig_on |
|---|
| 3584 | G = gbezout(x.g, t0, &U, &V) |
|---|
| 3585 | _sig_off |
|---|
| 3586 | g = P.new_gen_noclear(G) |
|---|
| 3587 | u = P.new_gen_noclear(U) |
|---|
| 3588 | v = P.new_gen(V) |
|---|
| 3589 | return g, u, v |
|---|
| 3590 | |
|---|
| 3591 | def binomial(gen x, long k): |
|---|
| 3592 | _sig_on |
|---|
| 3593 | return P.new_gen(binome(x.g, k)) |
|---|
| 3594 | |
|---|
| 3595 | def contfrac(gen x, b=0, long lmax=0): |
|---|
| 3596 | """ |
|---|
| 3597 | contfrac(x,{b},{lmax}): continued fraction expansion of x (x |
|---|
| 3598 | rational, real or rational function). b and lmax are both |
|---|
| 3599 | optional, where b is the vector of numerators of the continued |
|---|
| 3600 | fraction, and lmax is a bound for the number of terms in the |
|---|
| 3601 | continued fraction expansion. |
|---|
| 3602 | """ |
|---|
| 3603 | t0GEN(b) |
|---|
| 3604 | _sig_on |
|---|
| 3605 | return P.new_gen(contfrac0(x.g, t0, lmax)) |
|---|
| 3606 | |
|---|
| 3607 | def contfracpnqn(gen x, b=0, long lmax=0): |
|---|
| 3608 | """ |
|---|
| 3609 | contfracpnqn(x): [p_n,p_{n-1}; q_n,q_{n-1}] corresponding to the continued |
|---|
| 3610 | fraction x. |
|---|
| 3611 | """ |
|---|
| 3612 | _sig_on |
|---|
| 3613 | return P.new_gen(pnqn(x.g)) |
|---|
| 3614 | |
|---|
| 3615 | |
|---|
| 3616 | def gcd(gen x, y, long flag=0): |
|---|
| 3617 | """ |
|---|
| 3618 | gcd(x,{y},{flag=0}): greatest common divisor of x and y. flag |
|---|
| 3619 | is optional, and can be 0: default, 1: use the modular gcd |
|---|
| 3620 | algorithm (x and y must be polynomials), 2 use the |
|---|
| 3621 | subresultant algorithm (x and y must be polynomials) |
|---|
| 3622 | """ |
|---|
| 3623 | t0GEN(y) |
|---|
| 3624 | _sig_on |
|---|
| 3625 | return P.new_gen(gcd0(x.g, t0, flag)) |
|---|
| 3626 | |
|---|
| 3627 | def issquare(gen x, find_root=False): |
|---|
| 3628 | """ |
|---|
| 3629 | issquare(x,{&n}): true(1) if x is a square, false(0) if not. |
|---|
| 3630 | If find_root is given, also returns the exact square root if |
|---|
| 3631 | it was computed. |
|---|
| 3632 | """ |
|---|
| 3633 | cdef GEN G, t |
|---|
| 3634 | cdef gen g |
|---|
| 3635 | if find_root: |
|---|
| 3636 | _sig_on |
|---|
| 3637 | t = gcarrecomplet(x.g, &G) |
|---|
| 3638 | _sig_off |
|---|
| 3639 | v = bool(P.new_gen_noclear(t)) |
|---|
| 3640 | if v: |
|---|
| 3641 | return v, P.new_gen(G) |
|---|
| 3642 | else: |
|---|
| 3643 | return v, None |
|---|
| 3644 | else: |
|---|
| 3645 | _sig_on |
|---|
| 3646 | return P.new_gen(gcarreparfait(x.g)) |
|---|
| 3647 | |
|---|
| 3648 | |
|---|
| 3649 | def issquarefree(gen self): |
|---|
| 3650 | """ |
|---|
| 3651 | EXAMPLES: |
|---|
| 3652 | sage: pari(10).issquarefree() |
|---|
| 3653 | True |
|---|
| 3654 | sage: pari(20).issquarefree() |
|---|
| 3655 | False |
|---|
| 3656 | """ |
|---|
| 3657 | _sig_on |
|---|
| 3658 | t = bool(issquarefree(self.g)) |
|---|
| 3659 | _sig_off |
|---|
| 3660 | return t |
|---|
| 3661 | |
|---|
| 3662 | def lcm(gen x, y): |
|---|
| 3663 | """ |
|---|
| 3664 | Return the least common multiple of x and y. |
|---|
| 3665 | EXAMPLES: |
|---|
| 3666 | sage: pari(10).lcm(15) |
|---|
| 3667 | 30 |
|---|
| 3668 | """ |
|---|
| 3669 | t0GEN(y) |
|---|
| 3670 | _sig_on |
|---|
| 3671 | return P.new_gen(glcm(x.g, t0)) |
|---|
| 3672 | |
|---|
| 3673 | def numdiv(gen n): |
|---|
| 3674 | """ |
|---|
| 3675 | Return the number of divisors of the integer n. |
|---|
| 3676 | |
|---|
| 3677 | EXAMPLES: |
|---|
| 3678 | sage: pari(10).numdiv() |
|---|
| 3679 | 4 |
|---|
| 3680 | """ |
|---|
| 3681 | _sig_on |
|---|
| 3682 | return P.new_gen(gnumbdiv(n.g)) |
|---|
| 3683 | |
|---|
| 3684 | def phi(gen n): |
|---|
| 3685 | """ |
|---|
| 3686 | Return the Euler phi function of n. |
|---|
| 3687 | EXAMPLES: |
|---|
| 3688 | sage: pari(10).phi() |
|---|
| 3689 | 4 |
|---|
| 3690 | """ |
|---|
| 3691 | _sig_on |
|---|
| 3692 | return P.new_gen(phi(n.g)) |
|---|
| 3693 | |
|---|
| 3694 | def primepi(gen x): |
|---|
| 3695 | """ |
|---|
| 3696 | Return the number of primes $\leq x$. |
|---|
| 3697 | |
|---|
| 3698 | EXAMPLES: |
|---|
| 3699 | sage: pari(7).primepi() |
|---|
| 3700 | 4 |
|---|
| 3701 | sage: pari(100).primepi() |
|---|
| 3702 | 25 |
|---|
| 3703 | sage: pari(1000).primepi() |
|---|
| 3704 | 168 |
|---|
| 3705 | sage: pari(100000).primepi() |
|---|
| 3706 | 9592 |
|---|
| 3707 | """ |
|---|
| 3708 | _sig_on |
|---|
| 3709 | return P.new_gen(primepi(x.g)) |
|---|
| 3710 | |
|---|
| 3711 | def sumdiv(gen n): |
|---|
| 3712 | """ |
|---|
| 3713 | Return the sum of the divisors of $n$. |
|---|
| 3714 | |
|---|
| 3715 | EXAMPLES: |
|---|
| 3716 | sage: pari(10).sumdiv() |
|---|
| 3717 | 18 |
|---|
| 3718 | """ |
|---|
| 3719 | _sig_on |
|---|
| 3720 | return P.new_gen(sumdiv(n.g)) |
|---|
| 3721 | |
|---|
| 3722 | def sumdivk(gen n, long k): |
|---|
| 3723 | """ |
|---|
| 3724 | Return the sum of the k-th powers of the divisors of n. |
|---|
| 3725 | |
|---|
| 3726 | EXAMPLES: |
|---|
| 3727 | sage: pari(10).sumdivk(2) |
|---|
| 3728 | 130 |
|---|
| 3729 | """ |
|---|
| 3730 | _sig_on |
|---|
| 3731 | return P.new_gen(sumdivk(n.g, k)) |
|---|
| 3732 | |
|---|
| 3733 | def xgcd(gen x, y): |
|---|
| 3734 | """ |
|---|
| 3735 | Returns u,v,d such that d=gcd(x,y) and u*x+v*y=d. |
|---|
| 3736 | |
|---|
| 3737 | EXAMPLES: |
|---|
| 3738 | sage: pari(10).xgcd(15) |
|---|
| 3739 | (5, -1, 1) |
|---|
| 3740 | """ |
|---|
| 3741 | return x.bezout(y) |
|---|
| 3742 | |
|---|
| 3743 | |
|---|
| 3744 | ################################################## |
|---|
| 3745 | # 5: Elliptic curve functions |
|---|
| 3746 | ################################################## |
|---|
| 3747 | |
|---|
| 3748 | def ellinit(self, int flag=0, precision=0): |
|---|
| 3749 | if not precision: |
|---|
| 3750 | precision = prec |
|---|
| 3751 | _sig_on |
|---|
| 3752 | return P.new_gen(ellinit0(self.g, flag, precision)) |
|---|
| 3753 | |
|---|
| 3754 | def ellglobalred(self): |
|---|
| 3755 | _sig_on |
|---|
| 3756 | return self.new_gen(globalreduction(self.g)) |
|---|
| 3757 | |
|---|
| 3758 | def elladd(self, z0, z1): |
|---|
| 3759 | """ |
|---|
| 3760 | elladd(self, z0, z1) |
|---|
| 3761 | |
|---|
| 3762 | Sum of the points z0 and z1 on this elliptic curve. |
|---|
| 3763 | |
|---|
| 3764 | INPUT: |
|---|
| 3765 | self -- elliptic curve E |
|---|
| 3766 | z0 -- point on E |
|---|
| 3767 | z1 -- point on E |
|---|
| 3768 | |
|---|
| 3769 | OUTPUT: |
|---|
| 3770 | point on E |
|---|
| 3771 | |
|---|
| 3772 | EXAMPLES: |
|---|
| 3773 | First we create an elliptic curve: |
|---|
| 3774 | |
|---|
| 3775 | sage: e = pari([0, 1, 1, -2, 0]).ellinit() |
|---|
| 3776 | sage: str(e)[:65] # first part of output |
|---|
| 3777 | '[0, 1, 1, -2, 0, 4, -4, 1, -3, 112, -856, 389, 1404928/389, [0.90' |
|---|
| 3778 | |
|---|
| 3779 | Next we add two points on the elliptic curve. Notice that |
|---|
| 3780 | the Python lists are automatically converted to PARI objects so |
|---|
| 3781 | you don't have to do that explicitly in your code. |
|---|
| 3782 | |
|---|
| 3783 | sage: e.elladd([1,0,1], [-1,1,1]) |
|---|
| 3784 | [-3/4, -15/8] |
|---|
| 3785 | """ |
|---|
| 3786 | t0GEN(z0); t1GEN(z1) |
|---|
| 3787 | _sig_on |
|---|
| 3788 | return self.new_gen(addell(self.g, t0, t1)) |
|---|
| 3789 | |
|---|
| 3790 | def ellak(self, n): |
|---|
| 3791 | r""" |
|---|
| 3792 | e.ellak(n): Returns the coefficient $a_n$ of the $L$-function of |
|---|
| 3793 | the elliptic curve e, i.e. the coefficient of a newform of |
|---|
| 3794 | weight 2 newform. |
|---|
| 3795 | |
|---|
| 3796 | \begin{notice} |
|---|
| 3797 | The curve $e$ \emph{must} be a medium or long vector of the type given |
|---|
| 3798 | by ellinit. For this function to work for every n and not just |
|---|
| 3799 | those prime to the conductor, e must be a minimal Weierstrass |
|---|
| 3800 | equation. If this is not the case, use the function |
|---|
| 3801 | ellminimalmodel first before using ellak (or you will get |
|---|
| 3802 | INCORRECT RESULTS!) |
|---|
| 3803 | \end{notice} |
|---|
| 3804 | |
|---|
| 3805 | INPUT: |
|---|
| 3806 | e -- a PARI elliptic curve. |
|---|
| 3807 | n -- integer .. |
|---|
| 3808 | |
|---|
| 3809 | EXAMPLES: |
|---|
| 3810 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 3811 | sage: e.ellak(6) |
|---|
| 3812 | 2 |
|---|
| 3813 | sage: e.ellak(2005) |
|---|
| 3814 | 2 |
|---|
| 3815 | sage: e.ellak(-1) |
|---|
| 3816 | 0 |
|---|
| 3817 | sage: e.ellak(0) |
|---|
| 3818 | 0 |
|---|
| 3819 | """ |
|---|
| 3820 | t0GEN(n) |
|---|
| 3821 | _sig_on |
|---|
| 3822 | return self.new_gen(akell(self.g, t0)) |
|---|
| 3823 | |
|---|
| 3824 | |
|---|
| 3825 | def ellan(self, long n, python_ints=False): |
|---|
| 3826 | """ |
|---|
| 3827 | Return the Fourier coefficients of the modular form attached |
|---|
| 3828 | to this elliptic curve. |
|---|
| 3829 | |
|---|
| 3830 | INPUT: |
|---|
| 3831 | n -- a long integer |
|---|
| 3832 | python_ints -- bool (default is False); if True, return a |
|---|
| 3833 | list of Python ints instead of a PARI gen |
|---|
| 3834 | wrapper. |
|---|
| 3835 | |
|---|
| 3836 | EXAMPLES: |
|---|
| 3837 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 3838 | sage: e.ellan(3) |
|---|
| 3839 | [1, -2, -1] |
|---|
| 3840 | sage: e.ellan(20) |
|---|
| 3841 | [1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1, -4, -2, 4, 0, 2] |
|---|
| 3842 | sage: e.ellan(-1) |
|---|
| 3843 | [] |
|---|
| 3844 | sage: v = e.ellan(10, python_ints=True); v |
|---|
| 3845 | [1, -2, -1, 2, 1, 2, -2, 0, -2, -2] |
|---|
| 3846 | sage: type(v) |
|---|
| 3847 | <type 'list'> |
|---|
| 3848 | sage: type(v[0]) |
|---|
| 3849 | <type 'int'> |
|---|
| 3850 | """ |
|---|
| 3851 | _sig_on |
|---|
| 3852 | cdef GEN g |
|---|
| 3853 | if python_ints: |
|---|
| 3854 | g = anell(self.g, n) |
|---|
| 3855 | v = [gtolong(<GEN> g[i+1]) for i in range(glength(g))] |
|---|
| 3856 | (<PariInstance>pari).clear_stack() |
|---|
| 3857 | return v |
|---|
| 3858 | else: |
|---|
| 3859 | return self.new_gen(anell(self.g, n)) |
|---|
| 3860 | |
|---|
| 3861 | def ellap(self, p): |
|---|
| 3862 | r""" |
|---|
| 3863 | e.ellap(p): Returns the prime-indexed coefficient $a_p$ of the |
|---|
| 3864 | $L$-function of the elliptic curve $e$, i.e. the coefficient of a |
|---|
| 3865 | newform of weight 2 newform. |
|---|
| 3866 | |
|---|
| 3867 | \begin{notice} |
|---|
| 3868 | If p is not prime, this function will return an {\bf incorrect} |
|---|
| 3869 | answer. |
|---|
| 3870 | |
|---|
| 3871 | The curve e must be a medium or long vector of the type given |
|---|
| 3872 | by ellinit. For this function to work for every n and not just |
|---|
| 3873 | those prime to the conductor, e must be a minimal Weierstrass |
|---|
| 3874 | equation. If this is not the case, use the function |
|---|
| 3875 | ellminimalmodel first before using ellap (or you will get |
|---|
| 3876 | INCORRECT RESULTS!) |
|---|
| 3877 | \end{notice} |
|---|
| 3878 | |
|---|
| 3879 | INPUT: |
|---|
| 3880 | e -- a PARI elliptic curve. |
|---|
| 3881 | p -- prime integer .. |
|---|
| 3882 | |
|---|
| 3883 | EXAMPLES: |
|---|
| 3884 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 3885 | sage: e.ellap(2) |
|---|
| 3886 | -2 |
|---|
| 3887 | sage: e.ellap(2003) |
|---|
| 3888 | 4 |
|---|
| 3889 | sage: e.ellak(-1) |
|---|
| 3890 | 0 |
|---|
| 3891 | """ |
|---|
| 3892 | t0GEN(p) |
|---|
| 3893 | _sig_on |
|---|
| 3894 | return self.new_gen(apell(self.g, t0)) |
|---|
| 3895 | |
|---|
| 3896 | |
|---|
| 3897 | def ellaplist(self, long n, python_ints=False): |
|---|
| 3898 | r""" |
|---|
| 3899 | e.ellaplist(n): Returns a PARI list of all the prime-indexed |
|---|
| 3900 | coefficient $a_p$ of the $L$-function of the elliptic curve |
|---|
| 3901 | $e$, i.e. the coefficient of a newform of weight 2 newform. |
|---|
| 3902 | |
|---|
| 3903 | INPUT: |
|---|
| 3904 | n -- a long integer |
|---|
| 3905 | python_ints -- bool (default is False); if True, return a |
|---|
| 3906 | list of Python ints instead of a PARI gen |
|---|
| 3907 | wrapper. |
|---|
| 3908 | |
|---|
| 3909 | \begin{notice} |
|---|
| 3910 | The curve e must be a medium or long vector of the type given |
|---|
| 3911 | by ellinit. For this function to work for every n and not just |
|---|
| 3912 | those prime to the conductor, e must be a minimal Weierstrass |
|---|
| 3913 | equation. If this is not the case, use the function |
|---|
| 3914 | ellminimalmodel first before using ellanlist (or you will get |
|---|
| 3915 | INCORRECT RESULTS!) |
|---|
| 3916 | \end{notice} |
|---|
| 3917 | |
|---|
| 3918 | INPUT: |
|---|
| 3919 | e -- a PARI elliptic curve. |
|---|
| 3920 | n -- an integer |
|---|
| 3921 | |
|---|
| 3922 | EXAMPLES: |
|---|
| 3923 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 3924 | sage: v = e.ellaplist(10); v |
|---|
| 3925 | [-2, -1, 1, -2] |
|---|
| 3926 | sage: type(v) |
|---|
| 3927 | <type 'sage.libs.pari.gen.gen'> |
|---|
| 3928 | sage: v.type() |
|---|
| 3929 | 't_VEC' |
|---|
| 3930 | sage: e.ellan(10) |
|---|
| 3931 | [1, -2, -1, 2, 1, 2, -2, 0, -2, -2] |
|---|
| 3932 | sage: v = e.ellaplist(10, python_ints=True); v |
|---|
| 3933 | [-2, -1, 1, -2] |
|---|
| 3934 | sage: type(v) |
|---|
| 3935 | <type 'list'> |
|---|
| 3936 | sage: type(v[0]) |
|---|
| 3937 | <type 'int'> |
|---|
| 3938 | """ |
|---|
| 3939 | # 1. make a table of primes up to n. |
|---|
| 3940 | if n < 2: |
|---|
| 3941 | return self.new_gen(zerovec(0)) |
|---|
| 3942 | cdef GEN g |
|---|
| 3943 | pari.init_primes(n+1) |
|---|
| 3944 | t0GEN(n) |
|---|
| 3945 | _sig_on |
|---|
| 3946 | g = primes(gtolong(primepi(t0))) |
|---|
| 3947 | |
|---|
| 3948 | # 2. Replace each prime in the table by apell of it. |
|---|
| 3949 | cdef long i |
|---|
| 3950 | |
|---|
| 3951 | if python_ints: |
|---|
| 3952 | v = [gtolong(apell(self.g, <GEN> g[i+1])) \ |
|---|
| 3953 | for i in range(glength(g))] |
|---|
| 3954 | (<PariInstance>pari).clear_stack() |
|---|
| 3955 | return v |
|---|
| 3956 | else: |
|---|
| 3957 | for i from 0 <= i < glength(g): |
|---|
| 3958 | g[i+1] = <long> apell(self.g, <GEN> g[i+1]) |
|---|
| 3959 | return self.new_gen(g) |
|---|
| 3960 | |
|---|
| 3961 | |
|---|
| 3962 | def ellbil(self, z0, z1): |
|---|
| 3963 | """ |
|---|
| 3964 | EXAMPLES: |
|---|
| 3965 | sage: e = pari([0,1,1,-2,0]).ellinit() |
|---|
| 3966 | sage: e.ellbil([1, 0, 1], [-1, 1, 1]) |
|---|
| 3967 | 0.4181889844988605856298894582 # 32-bit |
|---|
| 3968 | 0.41818898449886058562988945821587638238 # 64-bit |
|---|
| 3969 | """ |
|---|
| 3970 | ## Increasing the precision does not increase the precision |
|---|
| 3971 | ## result, since quantities related to the elliptic curve were |
|---|
| 3972 | ## computed to low precision. |
|---|
| 3973 | ## sage: set_real_precision(10) |
|---|
| 3974 | ## sage: e.ellbil([1, 0, 1], [-1, 1, 1]) |
|---|
| 3975 | ## 0.4181889844988605856298894585 |
|---|
| 3976 | ## However, if we recompute the elliptic curve after increasing |
|---|
| 3977 | ## the precision, then the bilinear pairing will be computed to |
|---|
| 3978 | ## higher precision as well. |
|---|
| 3979 | ## sage: e = pari([0,1,1,-2,0]).ellinit() |
|---|
| 3980 | ## sage: e.ellbil([1, 0, 1], [-1, 1, 1]) |
|---|
| 3981 | ## 0.4181889844988605856298894582 |
|---|
| 3982 | ## sage: set_real_precision(5) |
|---|
| 3983 | t0GEN(z0); t1GEN(z1) |
|---|
| 3984 | _sig_on |
|---|
| 3985 | return self.new_gen(bilhell(self.g, t0, t1, prec)) |
|---|
| 3986 | |
|---|
| 3987 | def ellchangecurve(self, ch): |
|---|
| 3988 | """ |
|---|
| 3989 | EXAMPLES: |
|---|
| 3990 | sage: e = pari([1,2,3,4,5]).ellinit() |
|---|
| 3991 | sage: e.ellglobalred() |
|---|
| 3992 | [10351, [1, -1, 0, -1], 1] |
|---|
| 3993 | sage: f = e.ellchangecurve([1,-1,0,-1]) |
|---|
| 3994 | sage: f[:5] |
|---|
| 3995 | [1, -1, 0, 4, 3] |
|---|
| 3996 | """ |
|---|
| 3997 | t0GEN(ch) |
|---|
| 3998 | _sig_on |
|---|
| 3999 | return self.new_gen(coordch(self.g, t0)) |
|---|
| 4000 | |
|---|
| 4001 | def elleta(self): |
|---|
| 4002 | _sig_on |
|---|
| 4003 | return self.new_gen(elleta(self.g, prec)) |
|---|
| 4004 | |
|---|
| 4005 | def ellheight(self, a, flag=0): |
|---|
| 4006 | t0GEN(a) |
|---|
| 4007 | _sig_on |
|---|
| 4008 | return self.new_gen(ellheight0(self.g, t0, flag, prec)) |
|---|
| 4009 | |
|---|
| 4010 | def ellheightmatrix(self, x): |
|---|
| 4011 | """ |
|---|
| 4012 | ellheightmatrix(e,x) |
|---|
| 4013 | |
|---|
| 4014 | Returns the height matrix for vector of points x on elliptic curve e using |
|---|
| 4015 | theta functions. |
|---|
| 4016 | """ |
|---|
| 4017 | t0GEN(x) |
|---|
| 4018 | _sig_on |
|---|
| 4019 | return self.new_gen(mathell(self.g, t0, prec)) |
|---|
| 4020 | |
|---|
| 4021 | def ellisoncurve(self, x): |
|---|
| 4022 | t0GEN(x) |
|---|
| 4023 | _sig_on |
|---|
| 4024 | t = bool(oncurve(self.g, t0) == 1) |
|---|
| 4025 | _sig_off |
|---|
| 4026 | return t |
|---|
| 4027 | |
|---|
| 4028 | def elllocalred(self, p): |
|---|
| 4029 | t0GEN(p) |
|---|
| 4030 | _sig_on |
|---|
| 4031 | return self.new_gen(elllocalred(self.g, t0)) |
|---|
| 4032 | |
|---|
| 4033 | def elllseries(self, s, A=1): |
|---|
| 4034 | t0GEN(s); t1GEN(A) |
|---|
| 4035 | _sig_on |
|---|
| 4036 | return self.new_gen(lseriesell(self.g, t0, t1, prec)) |
|---|
| 4037 | |
|---|
| 4038 | def ellminimalmodel(self): |
|---|
| 4039 | """ |
|---|
| 4040 | ellminimalmodel(e): return the standard minimal integral model |
|---|
| 4041 | of the rational elliptic curve e and the corresponding change |
|---|
| 4042 | of variables. |
|---|
| 4043 | INPUT: |
|---|
| 4044 | e -- gen (that defines an elliptic curve) |
|---|
| 4045 | OUTPUT: |
|---|
| 4046 | gen -- minimal model |
|---|
| 4047 | gen -- change of coordinates |
|---|
| 4048 | EXAMPLES: |
|---|
| 4049 | sage: e = pari([1,2,3,4,5]).ellinit() |
|---|
| 4050 | sage: F, ch = e.ellminimalmodel() |
|---|
| 4051 | sage: F[:5] |
|---|
| 4052 | [1, -1, 0, 4, 3] |
|---|
| 4053 | sage: ch |
|---|
| 4054 | [1, -1, 0, -1] |
|---|
| 4055 | sage: e.ellchangecurve(ch)[:5] |
|---|
| 4056 | [1, -1, 0, 4, 3] |
|---|
| 4057 | """ |
|---|
| 4058 | cdef GEN x, y |
|---|
| 4059 | cdef gen model, change |
|---|
| 4060 | cdef pari_sp t |
|---|
| 4061 | _sig_on |
|---|
| 4062 | x = ellminimalmodel(self.g, &y) |
|---|
| 4063 | change = self.new_gen_noclear(y) |
|---|
| 4064 | model = self.new_gen(x) |
|---|
| 4065 | return model, change |
|---|
| 4066 | |
|---|
| 4067 | def ellorder(self, x): |
|---|
| 4068 | t0GEN(x) |
|---|
| 4069 | _sig_on |
|---|
| 4070 | return self.new_gen(orderell(self.g, t0)) |
|---|
| 4071 | |
|---|
| 4072 | def ellordinate(self, x): |
|---|
| 4073 | t0GEN(x) |
|---|
| 4074 | _sig_on |
|---|
| 4075 | return self.new_gen(ordell(self.g, t0, prec)) |
|---|
| 4076 | |
|---|
| 4077 | def ellpointtoz(self, P): |
|---|
| 4078 | t0GEN(P) |
|---|
| 4079 | _sig_on |
|---|
| 4080 | return self.new_gen(zell(self.g, t0, prec)) |
|---|
| 4081 | |
|---|
| 4082 | def ellpow(self, z, n): |
|---|
| 4083 | t0GEN(z); t1GEN(n) |
|---|
| 4084 | _sig_on |
|---|
| 4085 | return self.new_gen(powell(self.g, t0, t1)) |
|---|
| 4086 | |
|---|
| 4087 | def ellrootno(self, p=1): |
|---|
| 4088 | t0GEN(p) |
|---|
| 4089 | _sig_on |
|---|
| 4090 | return ellrootno(self.g, t0) |
|---|
| 4091 | |
|---|
| 4092 | def ellsigma(self, z, flag=0): |
|---|
| 4093 | t0GEN(z) |
|---|
| 4094 | _sig_on |
|---|
| 4095 | return self.new_gen(ellsigma(self.g, t0, flag, prec)) |
|---|
| 4096 | |
|---|
| 4097 | def ellsub(self, z1, z2): |
|---|
| 4098 | t0GEN(z1); t1GEN(z2) |
|---|
| 4099 | _sig_on |
|---|
| 4100 | return self.new_gen(subell(self.g, t0, t1)) |
|---|
| 4101 | |
|---|
| 4102 | def elltaniyama(self): |
|---|
| 4103 | _sig_on |
|---|
| 4104 | return self.new_gen(taniyama(self.g)) |
|---|
| 4105 | |
|---|
| 4106 | def elltors(self, flag=0): |
|---|
| 4107 | _sig_on |
|---|
| 4108 | return self.new_gen(elltors0(self.g, flag)) |
|---|
| 4109 | |
|---|
| 4110 | |
|---|
| 4111 | def ellzeta(self, z): |
|---|
| 4112 | t0GEN(z) |
|---|
| 4113 | _sig_on |
|---|
| 4114 | return self.new_gen(ellzeta(self.g, t0, prec)) |
|---|
| 4115 | |
|---|
| 4116 | def ellztopoint(self, z): |
|---|
| 4117 | t0GEN(z) |
|---|
| 4118 | _sig_on |
|---|
| 4119 | return self.new_gen(pointell(self.g, t0, prec)) |
|---|
| 4120 | |
|---|
| 4121 | def omega(self): |
|---|
| 4122 | """ |
|---|
| 4123 | e.omega(): return basis for the period lattice of the elliptic curve e. |
|---|
| 4124 | |
|---|
| 4125 | EXAMPLES: |
|---|
| 4126 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 4127 | sage: e.omega() |
|---|
| 4128 | [1.269209304279553421688794617, 0.6346046521397767108443973084 + 1.458816616938495229330889613*I] # 32-bit |
|---|
| 4129 | [1.2692093042795534216887946167545473052, 0.63460465213977671084439730837727365260 + 1.4588166169384952293308896129036752572*I] # 64-bit |
|---|
| 4130 | """ |
|---|
| 4131 | return self[14:16] |
|---|
| 4132 | |
|---|
| 4133 | def disc(self): |
|---|
| 4134 | """ |
|---|
| 4135 | e.disc(): return the discriminant of the elliptic curve e. |
|---|
| 4136 | |
|---|
| 4137 | EXAMPLES: |
|---|
| 4138 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 4139 | sage: e.disc() |
|---|
| 4140 | -161051 |
|---|
| 4141 | sage: _.factor() |
|---|
| 4142 | [-1, 1; 11, 5] |
|---|
| 4143 | """ |
|---|
| 4144 | return self[11] |
|---|
| 4145 | |
|---|
| 4146 | def j(self): |
|---|
| 4147 | """ |
|---|
| 4148 | e.j(): return the j-invariant of the elliptic curve e. |
|---|
| 4149 | |
|---|
| 4150 | EXAMPLES: |
|---|
| 4151 | sage: e = pari([0, -1, 1, -10, -20]).ellinit() |
|---|
| 4152 | sage: e.j() |
|---|
| 4153 | -122023936/161051 |
|---|
| 4154 | sage: _.factor() |
|---|
| 4155 | [-1, 1; 2, 12; 11, -5; 31, 3] |
|---|
| 4156 | """ |
|---|
| 4157 | return self[12] |
|---|
| 4158 | |
|---|
| 4159 | |
|---|
| 4160 | |
|---|
| 4161 | |
|---|
| 4162 | def ellj(self): |
|---|
| 4163 | _sig_on |
|---|
| 4164 | return P.new_gen(jell(self.g, prec)) |
|---|
| 4165 | |
|---|
| 4166 | |
|---|
| 4167 | ########################################### |
|---|
| 4168 | # 6: Functions related to general NUMBER FIELDS |
|---|
| 4169 | ########################################### |
|---|
| 4170 | def bnfcertify(self): |
|---|
| 4171 | r""" |
|---|
| 4172 | \code{bnf} being as output by \code{bnfinit}, checks whether |
|---|
| 4173 | the result is correct, i.e. whether the calculation of the |
|---|
| 4174 | contents of self are correct without assuming the Generalized |
|---|
| 4175 | Riemann Hypothesis. If it is correct, the answer is 1. If not, |
|---|
| 4176 | the program may output some error message, but more probably |
|---|
| 4177 | will loop indefinitely. In \emph{no} occasion can the program |
|---|
| 4178 | give a wrong answer (barring bugs of course): if the program |
|---|
| 4179 | answers 1, the answer is certified. |
|---|
| 4180 | |
|---|
| 4181 | \note{WARNING! By default, most of the bnf routines depend on |
|---|
| 4182 | the correctness of a heuristic assumption which is stronger |
|---|
| 4183 | than GRH. In order to obtain a provably-correct result you |
|---|
| 4184 | \emph{must} specify $c=c_2=12$ for the technical optional |
|---|
| 4185 | parameters to the function. There are known counterexamples |
|---|
| 4186 | for smaller $c$ (which is the default).} |
|---|
| 4187 | |
|---|
| 4188 | """ |
|---|
| 4189 | cdef long n |
|---|
| 4190 | _sig_on |
|---|
| 4191 | n = certifybuchall(self.g) |
|---|
| 4192 | _sig_off |
|---|
| 4193 | return n |
|---|
| 4194 | |
|---|
| 4195 | def bnfinit(self, long flag=0, tech=None): |
|---|
| 4196 | if tech is None: |
|---|
| 4197 | _sig_on |
|---|
| 4198 | return P.new_gen(bnfinit0(self.g, flag, <GEN>0, prec)) |
|---|
| 4199 | else: |
|---|
| 4200 | t0GEN(tech) |
|---|
| 4201 | _sig_on |
|---|
| 4202 | return P.new_gen(bnfinit0(self.g, flag, t0, prec)) |
|---|
| 4203 | |
|---|
| 4204 | def bnfisintnorm(self, x): |
|---|
| 4205 | t0GEN(x) |
|---|
| 4206 | _sig_on |
|---|
| 4207 | return self.new_gen(bnfisintnorm(self.g, t0)) |
|---|
| 4208 | |
|---|
| 4209 | def bnfisprincipal(self, x, long flag=1): |
|---|
| 4210 | t0GEN(x) |
|---|
| 4211 | _sig_on |
|---|
| 4212 | return self.new_gen(isprincipalall(self.g, t0, flag)) |
|---|
| 4213 | |
|---|
| 4214 | def bnfnarrow(self): |
|---|
| 4215 | _sig_on |
|---|
| 4216 | return self.new_gen(buchnarrow(self.g)) |
|---|
| 4217 | |
|---|
| 4218 | def bnfunit(self): |
|---|
| 4219 | _sig_on |
|---|
| 4220 | return self.new_gen(buchfu(self.g)) |
|---|
| 4221 | |
|---|
| 4222 | def dirzetak(self, n): |
|---|
| 4223 | t0GEN(n) |
|---|
| 4224 | _sig_on |
|---|
| 4225 | return self.new_gen(dirzetak(self.g, t0)) |
|---|
| 4226 | |
|---|
| 4227 | def idealred(self, I, vdir=0): |
|---|
| 4228 | t0GEN(I); t1GEN(vdir) |
|---|
| 4229 | _sig_on |
|---|
| 4230 | return self.new_gen(ideallllred(self.g, t0, t1, prec)) |
|---|
| 4231 | |
|---|
| 4232 | def idealadd(self, x, y): |
|---|
| 4233 | t0GEN(x); t1GEN(y) |
|---|
| 4234 | _sig_on |
|---|
| 4235 | return self.new_gen(idealadd(self.g, t0, t1)) |
|---|
| 4236 | |
|---|
| 4237 | def idealappr(self, x, long flag=0): |
|---|
| 4238 | t0GEN(x) |
|---|
| 4239 | _sig_on |
|---|
| 4240 | return self.new_gen(idealappr(self.g, t0)) |
|---|
| 4241 | |
|---|
| 4242 | def idealdiv(self, x, y, long flag=0): |
|---|
| 4243 | t0GEN(x); t1GEN(y) |
|---|
| 4244 | _sig_on |
|---|
| 4245 | return self.new_gen(idealdiv0(self.g, t0, t1, flag)) |
|---|
| 4246 | |
|---|
| 4247 | def idealfactor(self, x): |
|---|
| 4248 | t0GEN(x) |
|---|
| 4249 | _sig_on |
|---|
| 4250 | return self.new_gen(idealfactor(self.g, t0)) |
|---|
| 4251 | |
|---|
| 4252 | def idealhnf(self, a, b=None): |
|---|
| 4253 | t0GEN(a) |
|---|
| 4254 | _sig_on |
|---|
| 4255 | if b is None: |
|---|
| 4256 | return self.new_gen(idealhermite(self.g, t0)) |
|---|
| 4257 | else: |
|---|
| 4258 | t1GEN(b) |
|---|
| 4259 | return self.new_gen(idealhnf0(self.g, t0, t1)) |
|---|
| 4260 | |
|---|
| 4261 | def idealmul(self, x, y, long flag=0): |
|---|
| 4262 | t0GEN(x); t1GEN(y) |
|---|
| 4263 | _sig_on |
|---|
| 4264 | if flag == 0: |
|---|
| 4265 | return self.new_gen(idealmul(self.g, t0, t1)) |
|---|
| 4266 | else: |
|---|
| 4267 | return self.new_gen(idealmulred(self.g, t0, t1, prec)) |
|---|
| 4268 | |
|---|
| 4269 | def idealnorm(self, x): |
|---|
| 4270 | t0GEN(x) |
|---|
| 4271 | _sig_on |
|---|
| 4272 | return self.new_gen(idealnorm(self.g, t0)) |
|---|
| 4273 | |
|---|
| 4274 | def idealtwoelt(self, x, a=None): |
|---|
| 4275 | t0GEN(x) |
|---|
| 4276 | _sig_on |
|---|
| 4277 | if a is None: |
|---|
| 4278 | return self.new_gen(ideal_two_elt0(self.g, t0, NULL)) |
|---|
| 4279 | else: |
|---|
| 4280 | t1GEN(a) |
|---|
| 4281 | return self.new_gen(ideal_two_elt0(self.g, t0, t1)) |
|---|
| 4282 | |
|---|
| 4283 | def idealval(self, x, p): |
|---|
| 4284 | t0GEN(x); t1GEN(p) |
|---|
| 4285 | _sig_on |
|---|
| 4286 | return idealval(self.g, t0, t1) |
|---|
| 4287 | |
|---|
| 4288 | def elementval(self, x, p): |
|---|
| 4289 | t0GEN(x); t1GEN(p) |
|---|
| 4290 | _sig_on |
|---|
| 4291 | return element_val(self.g, t0, t1) |
|---|
| 4292 | |
|---|
| 4293 | def modreverse(self): |
|---|
| 4294 | """ |
|---|
| 4295 | modreverse(x): reverse polymod of the polymod x, if it exists. |
|---|
| 4296 | |
|---|
| 4297 | EXAMPLES: |
|---|
| 4298 | """ |
|---|
| 4299 | _sig_on |
|---|
| 4300 | return self.new_gen(polymodrecip(self.g)) |
|---|
| 4301 | |
|---|
| 4302 | def nfbasis(self, long flag=0, p=0): |
|---|
| 4303 | cdef gen _p |
|---|
| 4304 | cdef GEN g |
|---|
| 4305 | if p != 0: |
|---|
| 4306 | _p = self.pari(p) |
|---|
| 4307 | g = _p.g |
|---|
| 4308 | else: |
|---|
| 4309 | g = <GEN>NULL |
|---|
| 4310 | _sig_on |
|---|
| 4311 | return self.new_gen(nfbasis0(self.g, flag, g)) |
|---|
| 4312 | |
|---|
| 4313 | def nfbasis_d(self, long flag=0, p=0): |
|---|
| 4314 | """ |
|---|
| 4315 | nfbasis_d(x): Return a basis of the number field defined over |
|---|
| 4316 | QQ by x and its discriminant. |
|---|
| 4317 | |
|---|
| 4318 | EXAMPLES: |
|---|
| 4319 | sage: F = NumberField(x^3-2,'alpha') |
|---|
| 4320 | sage: F._pari_()[0].nfbasis_d() |
|---|
| 4321 | ([1, x, x^2], -108) |
|---|
| 4322 | |
|---|
| 4323 | sage: G = NumberField(x^5-11,'beta') |
|---|
| 4324 | sage: G._pari_()[0].nfbasis_d() |
|---|
| 4325 | ([1, x, x^2, x^3, x^4], 45753125) |
|---|
| 4326 | |
|---|
| 4327 | sage: pari([-2,0,0,1]).Polrev().nfbasis_d() |
|---|
| 4328 | ([1, x, x^2], -108) |
|---|
| 4329 | """ |
|---|
| 4330 | cdef gen _p, d |
|---|
| 4331 | cdef GEN g |
|---|
| 4332 | if p != 0: |
|---|
| 4333 | _p = self.pari(p) |
|---|
| 4334 | g = _p.g |
|---|
| 4335 | else: |
|---|
| 4336 | g = <GEN>NULL |
|---|
| 4337 | d = self.pari(0) |
|---|
| 4338 | _sig_on |
|---|
| 4339 | nfb = self.new_gen(nfbasis(self.g, &d.g, flag, g)) |
|---|
| 4340 | _sig_off |
|---|
| 4341 | return nfb, d.__int__() |
|---|
| 4342 | |
|---|
| 4343 | def nfdisc(self, long flag=0, p=0): |
|---|
| 4344 | """ |
|---|
| 4345 | nfdisc(x): Return the discriminant of the number field |
|---|
| 4346 | defined over QQ by x. |
|---|
| 4347 | |
|---|
| 4348 | EXAMPLES: |
|---|
| 4349 | sage: F = NumberField(x^3-2,'alpha') |
|---|
| 4350 | sage: F._pari_()[0].nfdisc() |
|---|
| 4351 | -108 |
|---|
| 4352 | |
|---|
| 4353 | sage: G = NumberField(x^5-11,'beta') |
|---|
| 4354 | sage: G._pari_()[0].nfdisc() |
|---|
| 4355 | 45753125 |
|---|
| 4356 | |
|---|
| 4357 | sage: f = x^3-2 |
|---|
| 4358 | sage: f._pari_() |
|---|
| 4359 | x^3 - 2 |
|---|
| 4360 | sage: f._pari_().nfdisc() |
|---|
| 4361 | -108 |
|---|
| 4362 | """ |
|---|
| 4363 | cdef gen _p |
|---|
| 4364 | cdef GEN g |
|---|
| 4365 | if p != 0: |
|---|
| 4366 | _p = self.pari(p) |
|---|
| 4367 | g = _p.g |
|---|
| 4368 | else: |
|---|
| 4369 | g = <GEN>NULL |
|---|
| 4370 | _sig_on |
|---|
| 4371 | return self.new_gen(nfdiscf0(self.g, flag, g)) |
|---|
| 4372 | |
|---|
| 4373 | def nffactor(self, x): |
|---|
| 4374 | t0GEN(x) |
|---|
| 4375 | _sig_on |
|---|
| 4376 | return self.new_gen(nffactor(self.g, t0)) |
|---|
| 4377 | |
|---|
| 4378 | def nfgenerator(self): |
|---|
| 4379 | f = self[0] |
|---|
| 4380 | x = f.variable() |
|---|
| 4381 | return x.Mod(f) |
|---|
| 4382 | |
|---|
| 4383 | def nfinit(self, long flag=0): |
|---|
| 4384 | _sig_on |
|---|
| 4385 | return P.new_gen(nfinit0(self.g, flag, prec)) |
|---|
| 4386 | |
|---|
| 4387 | def nfisisom(self, gen other): |
|---|
| 4388 | """ |
|---|
| 4389 | nfisisom(x, y): Determine if the number fields defined by |
|---|
| 4390 | x and y are isomorphic. According to the PARI documentation, |
|---|
| 4391 | this is much faster if at least one of x or y is a |
|---|
| 4392 | number field. If they are isomorphic, it returns an |
|---|
| 4393 | embedding for the generators. If not, returns 0. |
|---|
| 4394 | |
|---|
| 4395 | EXAMPLES: |
|---|
| 4396 | sage: F = NumberField(x^3-2,'alpha') |
|---|
| 4397 | sage: G = NumberField(x^3-2,'beta') |
|---|
| 4398 | sage: F._pari_().nfisisom(G._pari_()) |
|---|
| 4399 | [x] |
|---|
| 4400 | |
|---|
| 4401 | sage: GG = NumberField(x^3-4,'gamma') |
|---|
| 4402 | sage: F._pari_().nfisisom(GG._pari_()) |
|---|
| 4403 | [1/2*x^2] |
|---|
| 4404 | |
|---|
| 4405 | sage: F._pari_().nfisisom(GG.pari_nf()) |
|---|
| 4406 | [1/2*x^2] |
|---|
| 4407 | |
|---|
| 4408 | sage: F.pari_nf().nfisisom(GG._pari_()[0]) |
|---|
| 4409 | [x^2] |
|---|
| 4410 | |
|---|
| 4411 | sage: H = NumberField(x^2-2,'alpha') |
|---|
| 4412 | sage: F._pari_().nfisisom(H._pari_()) |
|---|
| 4413 | 0 |
|---|
| 4414 | """ |
|---|
| 4415 | _sig_on |
|---|
| 4416 | return P.new_gen(nfisisom(self.g, other.g)) |
|---|
| 4417 | |
|---|
| 4418 | def nfrootsof1(self): |
|---|
| 4419 | """ |
|---|
| 4420 | nf.nfrootsof1() |
|---|
| 4421 | |
|---|
| 4422 | number of roots of unity and primitive root of unity in the |
|---|
| 4423 | number field nf. |
|---|
| 4424 | |
|---|
| 4425 | EXAMPLES: |
|---|
| 4426 | sage: nf = pari('x^2 + 1').nfinit() |
|---|
| 4427 | sage: nf.nfrootsof1() |
|---|
| 4428 | [4, [0, 1]~] |
|---|
| 4429 | """ |
|---|
| 4430 | _sig_on |
|---|
| 4431 | return P.new_gen(rootsof1(self.g)) |
|---|
| 4432 | |
|---|
| 4433 | def nfsubfields(self, d=0): |
|---|
| 4434 | """ |
|---|
| 4435 | Find all subfields of degree d of number field nf (all |
|---|
| 4436 | subfields if d is null or omitted). Result is a vector of |
|---|
| 4437 | subfields, each being given by [g,h], where g is an absolute |
|---|
| 4438 | equation and h expresses one of the roots of g in terms of the |
|---|
| 4439 | root x of the polynomial defining nf. |
|---|
| 4440 | |
|---|
| 4441 | INPUT: |
|---|
| 4442 | self -- nf number field |
|---|
| 4443 | d -- integer |
|---|
| 4444 | """ |
|---|
| 4445 | if d == 0: |
|---|
| 4446 | _sig_on |
|---|
| 4447 | return self.new_gen(subfields0(self.g, <GEN>0)) |
|---|
| 4448 | t0GEN(d) |
|---|
| 4449 | _sig_on |
|---|
| 4450 | return self.new_gen(subfields0(self.g, t0)) |
|---|
| 4451 | |
|---|
| 4452 | def rnfcharpoly(self, T, a, v='x'): |
|---|
| 4453 | t0GEN(T); t1GEN(a); t2GEN(v) |
|---|
| 4454 | _sig_on |
|---|
| 4455 | return self.new_gen(rnfcharpoly(self.g, t0, t1, gvar(t2))) |
|---|
| 4456 | |
|---|
| 4457 | def rnfdisc(self, x): |
|---|
| 4458 | t0GEN(x) |
|---|
| 4459 | _sig_on |
|---|
| 4460 | return self.new_gen(rnfdiscf(self.g, t0)) |
|---|
| 4461 | |
|---|
| 4462 | def rnfeltabstorel(self, x): |
|---|
| 4463 | t0GEN(x) |
|---|
| 4464 | _sig_on |
|---|
| 4465 | polymodmod = self.new_gen(rnfelementabstorel(self.g, t0)) |
|---|
| 4466 | return polymodmod.centerlift().centerlift() |
|---|
| 4467 | |
|---|
| 4468 | def rnfeltreltoabs(self, x): |
|---|
| 4469 | t0GEN(x) |
|---|
| 4470 | _sig_on |
|---|
| 4471 | return self.new_gen(rnfelementreltoabs(self.g, t0)) |
|---|
| 4472 | |
|---|
| 4473 | def rnfequation(self, poly, long flag=0): |
|---|
| 4474 | t0GEN(poly) |
|---|
| 4475 | _sig_on |
|---|
| 4476 | return self.new_gen(rnfequation0(self.g, t0, flag)) |
|---|
| 4477 | |
|---|
| 4478 | def rnfidealabstorel(self, x): |
|---|
| 4479 | t0GEN(x) |
|---|
| 4480 | _sig_on |
|---|
| 4481 | return self.new_gen(rnfidealabstorel(self.g, t0)) |
|---|
| 4482 | |
|---|
| 4483 | def rnfidealhnf(self, x): |
|---|
| 4484 | t0GEN(x) |
|---|
| 4485 | _sig_on |
|---|
| 4486 | return self.new_gen(rnfidealhermite(self.g, t0)) |
|---|
| 4487 | |
|---|
| 4488 | def rnfidealnormrel(self, x): |
|---|
| 4489 | t0GEN(x) |
|---|
| 4490 | _sig_on |
|---|
| 4491 | return self.new_gen(rnfidealnormrel(self.g, t0)) |
|---|
| 4492 | |
|---|
| 4493 | def rnfidealreltoabs(self, x): |
|---|
| 4494 | t0GEN(x) |
|---|
| 4495 | _sig_on |
|---|
| 4496 | return self.new_gen(rnfidealreltoabs(self.g, t0)) |
|---|
| 4497 | |
|---|
| 4498 | def rnfidealtwoelt(self, x): |
|---|
| 4499 | t0GEN(x) |
|---|
| 4500 | _sig_on |
|---|
| 4501 | return self.new_gen(rnfidealtwoelement(self.g, t0)) |
|---|
| 4502 | |
|---|
| 4503 | def rnfinit(self, poly): |
|---|
| 4504 | """ |
|---|
| 4505 | EXAMPLES: |
|---|
| 4506 | We construct a relative number field. |
|---|
| 4507 | sage: f = pari('y^3+y+1') |
|---|
| 4508 | sage: K = f.nfinit() |
|---|
| 4509 | sage: x = pari('x'); y = pari('y') |
|---|
| 4510 | sage: g = x^5 - x^2 + y |
|---|
| 4511 | sage: L = K.rnfinit(g) |
|---|
| 4512 | """ |
|---|
| 4513 | t0GEN(poly) |
|---|
| 4514 | _sig_on |
|---|
| 4515 | return P.new_gen(rnfinitalg(self.g, t0, prec)) |
|---|
| 4516 | |
|---|
| 4517 | def rnfisfree(self, poly): |
|---|
| 4518 | t0GEN(poly) |
|---|
| 4519 | _sig_on |
|---|
| 4520 | return rnfisfree(self.g, t0) |
|---|
| 4521 | |
|---|
| 4522 | |
|---|
| 4523 | |
|---|
| 4524 | |
|---|
| 4525 | |
|---|
| 4526 | ################################################## |
|---|
| 4527 | # 7: POLYNOMIALS and power series |
|---|
| 4528 | ################################################## |
|---|
| 4529 | def reverse(self): |
|---|
| 4530 | """ |
|---|
| 4531 | Return the polynomial obtained by reversing the coefficients |
|---|
| 4532 | of this polynomial. |
|---|
| 4533 | """ |
|---|
| 4534 | return self.Vec().Polrev() |
|---|
| 4535 | |
|---|
| 4536 | def deriv(self, v=-1): |
|---|
| 4537 | _sig_on |
|---|
| 4538 | return self.new_gen(deriv(self.g, self.get_var(v))) |
|---|
| 4539 | |
|---|
| 4540 | def eval(self, x): |
|---|
| 4541 | t0GEN(x) |
|---|
| 4542 | _sig_on |
|---|
| 4543 | return self.new_gen(poleval(self.g, t0)) |
|---|
| 4544 | |
|---|
| 4545 | def __call__(self, x): |
|---|
| 4546 | return self.eval(x) |
|---|
| 4547 | |
|---|
| 4548 | def factorpadic(self, p, long r=20, long flag=0): |
|---|
| 4549 | """ |
|---|
| 4550 | self.factorpadic(p,{r=20},{flag=0}): p-adic factorization of the |
|---|
| 4551 | polynomial x to precision r. flag is optional and may be set |
|---|
| 4552 | to 0 (use round 4) or 1 (use Buchmann-Lenstra) |
|---|
| 4553 | """ |
|---|
| 4554 | t0GEN(p) |
|---|
| 4555 | _sig_on |
|---|
| 4556 | return self.new_gen(factorpadic0(self.g, t0, r, flag)) |
|---|
| 4557 | |
|---|
| 4558 | def factormod(self, p, long flag=0): |
|---|
| 4559 | """ |
|---|
| 4560 | x.factormod(p,{flag=0}): factorization mod p of the polynomial |
|---|
| 4561 | x using Berlekamp. flag is optional, and can be 0: default or |
|---|
| 4562 | 1: simple factormod, same except that only the degrees of the |
|---|
| 4563 | irreducible factors are given. |
|---|
| 4564 | """ |
|---|
| 4565 | t0GEN(p) |
|---|
| 4566 | _sig_on |
|---|
| 4567 | return self.new_gen(factormod0(self.g, t0, flag)) |
|---|
| 4568 | |
|---|
| 4569 | def intformal(self, y=-1): |
|---|
| 4570 | """ |
|---|
| 4571 | x.intformal({y}): formal integration of x with respect to the main |
|---|
| 4572 | variable of y, or to the main variable of x if y is omitted |
|---|
| 4573 | """ |
|---|
| 4574 | _sig_on |
|---|
| 4575 | return self.new_gen(integ(self.g, self.get_var(y))) |
|---|
| 4576 | |
|---|
| 4577 | def padicappr(self, a): |
|---|
| 4578 | """ |
|---|
| 4579 | x.padicappr(a): p-adic roots of the polynomial x congruent to a mod p |
|---|
| 4580 | """ |
|---|
| 4581 | t0GEN(a) |
|---|
| 4582 | _sig_on |
|---|
| 4583 | return self.new_gen(padicappr(self.g, t0)) |
|---|
| 4584 | |
|---|
| 4585 | def newtonpoly(self, p): |
|---|
| 4586 | """ |
|---|
| 4587 | self.newtonpoly(p): Newton polygon of polynomial x with respect |
|---|
| 4588 | to the prime p. |
|---|
| 4589 | """ |
|---|
| 4590 | t0GEN(p) |
|---|
| 4591 | _sig_on |
|---|
| 4592 | return self.new_gen(newtonpoly(self.g, t0)) |
|---|
| 4593 | |
|---|
| 4594 | def polcoeff(self, long n, var=-1): |
|---|
| 4595 | """ |
|---|
| 4596 | EXAMPLES: |
|---|
| 4597 | sage: f = pari("x^2 + y^3 + x*y") |
|---|
| 4598 | sage: f |
|---|
| 4599 | x^2 + y*x + y^3 |
|---|
| 4600 | sage: f.polcoeff(1) |
|---|
| 4601 | y |
|---|
| 4602 | sage: f.polcoeff(3) |
|---|
| 4603 | 0 |
|---|
| 4604 | sage: f.polcoeff(3, "y") |
|---|
| 4605 | 1 |
|---|
| 4606 | sage: f.polcoeff(1, "y") |
|---|
| 4607 | x |
|---|
| 4608 | """ |
|---|
| 4609 | _sig_on |
|---|
| 4610 | return self.new_gen(polcoeff0(self.g, n, self.get_var(var))) |
|---|
| 4611 | |
|---|
| 4612 | def polcompositum(self, pol2, long flag=0): |
|---|
| 4613 | t0GEN(pol2) |
|---|
| 4614 | _sig_on |
|---|
| 4615 | return self.new_gen(polcompositum0(self.g, t0, flag)) |
|---|
| 4616 | |
|---|
| 4617 | def poldegree(self, var=-1): |
|---|
| 4618 | """ |
|---|
| 4619 | f.poldegree(var={x}): Return the degree of this polynomial. |
|---|
| 4620 | """ |
|---|
| 4621 | _sig_on |
|---|
| 4622 | n = poldegree(self.g, self.get_var(var)) |
|---|
| 4623 | _sig_off |
|---|
| 4624 | return n |
|---|
| 4625 | |
|---|
| 4626 | def poldisc(self, var=-1): |
|---|
| 4627 | """ |
|---|
| 4628 | f.poldist(var={x}): Return the discriminant of this polynomial. |
|---|
| 4629 | """ |
|---|
| 4630 | _sig_on |
|---|
| 4631 | return self.new_gen(poldisc0(self.g, self.get_var(var))) |
|---|
| 4632 | |
|---|
| 4633 | def poldiscreduced(self): |
|---|
| 4634 | _sig_on |
|---|
| 4635 | return self.new_gen(reduceddiscsmith(self.g)) |
|---|
| 4636 | |
|---|
| 4637 | def polgalois(self): |
|---|
| 4638 | """ |
|---|
| 4639 | f.polgalois(): Galois group of the polynomial f |
|---|
| 4640 | """ |
|---|
| 4641 | _sig_on |
|---|
| 4642 | return self.new_gen(galois(self.g, prec)) |
|---|
| 4643 | |
|---|
| 4644 | def polhensellift(self, y, p, long e): |
|---|
| 4645 | """ |
|---|
| 4646 | self.polhensellift(y, p, e): lift the factorization y of |
|---|
| 4647 | self modulo p to a factorization modulo $p^e$ using Hensel |
|---|
| 4648 | lift. The factors in y must be pairwise relatively prime |
|---|
| 4649 | modulo p. |
|---|
| 4650 | """ |
|---|
| 4651 | t0GEN(y) |
|---|
| 4652 | t1GEN(p) |
|---|
| 4653 | _sig_on |
|---|
| 4654 | return self.new_gen(polhensellift(self.g, t0, t1, e)) |
|---|
| 4655 | |
|---|
| 4656 | def polisirreducible(self): |
|---|
| 4657 | """ |
|---|
| 4658 | f.polisirreducible(): Returns True if f is an irreducible |
|---|
| 4659 | non-constant polynomial, or False if f is reducible or |
|---|
| 4660 | constant. |
|---|
| 4661 | """ |
|---|
| 4662 | _sig_on |
|---|
| 4663 | return bool(self.new_gen(gisirreducible(self.g))) |
|---|
| 4664 | |
|---|
| 4665 | |
|---|
| 4666 | def pollead(self, v=-1): |
|---|
| 4667 | """ |
|---|
| 4668 | self.pollead({v}): leading coefficient of polynomial or series |
|---|
| 4669 | self, or self itself if self is a scalar. Error |
|---|
| 4670 | otherwise. With respect to the main variable of self if v is |
|---|
| 4671 | omitted, with respect to the variable v otherwise |
|---|
| 4672 | """ |
|---|
| 4673 | _sig_on |
|---|
| 4674 | return self.new_gen(pollead(self.g, self.get_var(v))) |
|---|
| 4675 | |
|---|
| 4676 | def polrecip(self): |
|---|
| 4677 | _sig_on |
|---|
| 4678 | return self.new_gen(polrecip(self.g)) |
|---|
| 4679 | |
|---|
| 4680 | def polred(self, flag=0, fa=None): |
|---|
| 4681 | _sig_on |
|---|
| 4682 | if fa is None: |
|---|
| 4683 | return self.new_gen(polred0(self.g, flag, NULL)) |
|---|
| 4684 | else: |
|---|
| 4685 | t0GEN(fa) |
|---|
| 4686 | return self.new_gen(polred0(self.g, flag, t0)) |
|---|
| 4687 | |
|---|
| 4688 | def polredabs(self, flag=0): |
|---|
| 4689 | _sig_on |
|---|
| 4690 | return self.new_gen(polredabs0(self.g, flag)) |
|---|
| 4691 | |
|---|
| 4692 | def polresultant(self, y, var=-1, flag=0): |
|---|
| 4693 | t0GEN(y) |
|---|
| 4694 | _sig_on |
|---|
| 4695 | return self.new_gen(polresultant0(self.g, t0, self.get_var(var), flag)) |
|---|
| 4696 | |
|---|
| 4697 | def polroots(self, flag=0): |
|---|
| 4698 | """ |
|---|
| 4699 | polroots(x,{flag=0}): complex roots of the polynomial x. flag |
|---|
| 4700 | is optional, and can be 0: default, uses Schonhage's method modified |
|---|
| 4701 | by Gourdon, or 1: uses a modified Newton method. |
|---|
| 4702 | """ |
|---|
| 4703 | _sig_on |
|---|
| 4704 | return self.new_gen(roots0(self.g, flag, prec)) |
|---|
| 4705 | |
|---|
| 4706 | def polrootsmod(self, p, flag=0): |
|---|
| 4707 | t0GEN(p) |
|---|
| 4708 | _sig_on |
|---|
| 4709 | return self.new_gen(rootmod0(self.g, t0, flag)) |
|---|
| 4710 | |
|---|
| 4711 | def polrootspadic(self, p, r=20): |
|---|
| 4712 | t0GEN(p) |
|---|
| 4713 | _sig_on |
|---|
| 4714 | return self.new_gen(rootpadic(self.g, t0, r)) |
|---|
| 4715 | |
|---|
| 4716 | def polrootspadicfast(self, p, r=20): |
|---|
| 4717 | t0GEN(p) |
|---|
| 4718 | _sig_on |
|---|
| 4719 | return self.new_gen(rootpadicfast(self.g, t0, r)) |
|---|
| 4720 | |
|---|
| 4721 | def polsturm(self, a, b): |
|---|
| 4722 | t0GEN(a) |
|---|
| 4723 | t1GEN(b) |
|---|
| 4724 | _sig_on |
|---|
| 4725 | n = sturmpart(self.g, t0, t1) |
|---|
| 4726 | _sig_off |
|---|
| 4727 | return n |
|---|
| 4728 | |
|---|
| 4729 | def polsylvestermatrix(self, g): |
|---|
| 4730 | t0GEN(g) |
|---|
| 4731 | _sig_on |
|---|
| 4732 | return self.new_gen(sylvestermatrix(self.g, t0)) |
|---|
| 4733 | |
|---|
| 4734 | def polsym(self, long n): |
|---|
| 4735 | _sig_on |
|---|
| 4736 | return self.new_gen(polsym(self.g, n)) |
|---|
| 4737 | |
|---|
| 4738 | def serconvol(self, g): |
|---|
| 4739 | t0GEN(g) |
|---|
| 4740 | _sig_on |
|---|
| 4741 | return self.new_gen(convol(self.g, t0)) |
|---|
| 4742 | |
|---|
| 4743 | def serlaplace(self): |
|---|
| 4744 | _sig_on |
|---|
| 4745 | return self.new_gen(laplace(self.g)) |
|---|
| 4746 | |
|---|
| 4747 | def serreverse(self): |
|---|
| 4748 | """ |
|---|
| 4749 | serreverse(f): reversion of the power series f. |
|---|
| 4750 | |
|---|
| 4751 | If f(t) is a series in t with valuation 1, find the |
|---|
| 4752 | series g(t) such that g(f(t)) = t. |
|---|
| 4753 | |
|---|
| 4754 | EXAMPLES: |
|---|
| 4755 | sage: f = pari('x+x^2+x^3+O(x^4)'); f |
|---|
| 4756 | x + x^2 + x^3 + O(x^4) |
|---|
| 4757 | sage: g = f.serreverse(); g |
|---|
| 4758 | x - x^2 + x^3 + O(x^4) |
|---|
| 4759 | sage: f.subst('x',g) |
|---|
| 4760 | x + O(x^4) |
|---|
| 4761 | sage: g.subst('x',f) |
|---|
| 4762 | x + O(x^4) |
|---|
| 4763 | """ |
|---|
| 4764 | _sig_on |
|---|
| 4765 | return self.new_gen(recip(self.g)) |
|---|
| 4766 | |
|---|
| 4767 | def thueinit(self, flag=0): |
|---|
| 4768 | _sig_on |
|---|
| 4769 | return self.new_gen(thueinit(self.g, flag, prec)) |
|---|
| 4770 | |
|---|
| 4771 | |
|---|
| 4772 | |
|---|
| 4773 | |
|---|
| 4774 | |
|---|
| 4775 | ########################################### |
|---|
| 4776 | # 8: Vectors, matrices, LINEAR ALGEBRA and sets |
|---|
| 4777 | ########################################### |
|---|
| 4778 | |
|---|
| 4779 | def vecextract(self, y, z=None): |
|---|
| 4780 | r""" |
|---|
| 4781 | self.vecextract(y,{z}): extraction of the components of the |
|---|
| 4782 | matrix or vector x according to y and z. If z is omitted, y |
|---|
| 4783 | designates columns, otherwise y corresponds to rows and z to |
|---|
| 4784 | columns. y and z can be vectors (of indices), strings |
|---|
| 4785 | (indicating ranges as in"1..10") or masks |
|---|
| 4786 | (integers whose binary representation indicates the indices |
|---|
| 4787 | to extract, from left to right 1, 2, 4, 8, etc.) |
|---|
| 4788 | |
|---|
| 4789 | \note{This function uses the PARI row and column indexing, |
|---|
| 4790 | so the first row or column is indexed by 1 instead of 0.} |
|---|
| 4791 | """ |
|---|
| 4792 | t0GEN(y) |
|---|
| 4793 | if z is None: |
|---|
| 4794 | _sig_on |
|---|
| 4795 | return P.new_gen(extract(self.g, t0)) |
|---|
| 4796 | else: |
|---|
| 4797 | t1GEN(z) |
|---|
| 4798 | _sig_on |
|---|
| 4799 | return P.new_gen(extract0(self.g, t0, t1)) |
|---|
| 4800 | |
|---|
| 4801 | def ncols(self): |
|---|
| 4802 | """ |
|---|
| 4803 | Return the number of rows of self. |
|---|
| 4804 | |
|---|
| 4805 | EXAMPLES: |
|---|
| 4806 | sage: pari('matrix(19,8)').ncols() |
|---|
| 4807 | 8 |
|---|
| 4808 | """ |
|---|
| 4809 | cdef long n |
|---|
| 4810 | _sig_on |
|---|
| 4811 | n = glength(self.g) |
|---|
| 4812 | _sig_off |
|---|
| 4813 | return n |
|---|
| 4814 | |
|---|
| 4815 | def nrows(self): |
|---|
| 4816 | """ |
|---|
| 4817 | Return the number of rows of self. |
|---|
| 4818 | |
|---|
| 4819 | EXAMPLES: |
|---|
| 4820 | sage: pari('matrix(19,8)').nrows() |
|---|
| 4821 | 19 |
|---|
| 4822 | """ |
|---|
| 4823 | cdef long n |
|---|
| 4824 | _sig_on |
|---|
| 4825 | n = glength(<GEN>(self.g[1])) |
|---|
| 4826 | _sig_off |
|---|
| 4827 | return n |
|---|
| 4828 | |
|---|
| 4829 | def mattranspose(self): |
|---|
| 4830 | """ |
|---|
| 4831 | Transpose of the matrix self. |
|---|
| 4832 | |
|---|
| 4833 | EXAMPLES: |
|---|
| 4834 | sage: pari('[1,2,3; 4,5,6; 7,8,9]').mattranspose() |
|---|
| 4835 | [1, 4, 7; 2, 5, 8; 3, 6, 9] |
|---|
| 4836 | """ |
|---|
| 4837 | _sig_on |
|---|
| 4838 | return self.new_gen(gtrans(self.g)).Mat() |
|---|
| 4839 | |
|---|
| 4840 | def matadjoint(self): |
|---|
| 4841 | """ |
|---|
| 4842 | matadjoint(x): adjoint matrix of x. |
|---|
| 4843 | |
|---|
| 4844 | EXAMPLES: |
|---|
| 4845 | sage: pari('[1,2,3; 4,5,6; 7,8,9]').matadjoint() |
|---|
| 4846 | [-3, 6, -3; 6, -12, 6; -3, 6, -3] |
|---|
| 4847 | sage: pari('[a,b,c; d,e,f; g,h,i]').matadjoint() |
|---|
| 4848 | [(i*e - h*f), (-i*b + h*c), (f*b - e*c); (-i*d + g*f), i*a - g*c, -f*a + d*c; (h*d - g*e), -h*a + g*b, e*a - d*b] |
|---|
| 4849 | """ |
|---|
| 4850 | _sig_on |
|---|
| 4851 | return self.new_gen(adj(self.g)).Mat() |
|---|
| 4852 | |
|---|
| 4853 | def qflll(self, long flag=0): |
|---|
| 4854 | """ |
|---|
| 4855 | qflll(x,{flag=0}): LLL reduction of the vectors forming the |
|---|
| 4856 | matrix x (gives the unimodular transformation matrix). The |
|---|
| 4857 | columns of x must be linearly independent, unless specified |
|---|
| 4858 | otherwise below. flag is optional, and can be 0: default, 1: |
|---|
| 4859 | assumes x is integral, columns may be dependent, 2: assumes x |
|---|
| 4860 | is integral, returns a partially reduced basis, 4: assumes x |
|---|
| 4861 | is integral, returns [K,I] where K is the integer kernel of x |
|---|
| 4862 | and I the LLL reduced image, 5: same as 4 but x may have |
|---|
| 4863 | polynomial coefficients, 8: same as 0 but x may have |
|---|
| 4864 | polynomial coefficients. |
|---|
| 4865 | """ |
|---|
| 4866 | _sig_on |
|---|
| 4867 | return self.new_gen(qflll0(self.g,flag,prec)).Mat() |
|---|
| 4868 | |
|---|
| 4869 | def qflllgram(self, long flag=0): |
|---|
| 4870 | """ |
|---|
| 4871 | qflllgram(x,{flag=0}): LLL reduction of the lattice whose gram |
|---|
| 4872 | matrix is x (gives the unimodular transformation matrix). flag |
|---|
| 4873 | is optional and can be 0: default,1: lllgramint algorithm for |
|---|
| 4874 | integer matrices, 4: lllgramkerim giving the kernel and the |
|---|
| 4875 | LLL reduced image, 5: lllgramkerimgen same when the matrix has |
|---|
| 4876 | polynomial coefficients, 8: lllgramgen, same as qflllgram when |
|---|
| 4877 | the coefficients are polynomials. |
|---|
| 4878 | """ |
|---|
| 4879 | _sig_on |
|---|
| 4880 | return self.new_gen(qflllgram0(self.g,flag,prec)).Mat() |
|---|
| 4881 | |
|---|
| 4882 | def lllgram(self): |
|---|
| 4883 | return self.qflllgram(0) |
|---|
| 4884 | |
|---|
| 4885 | def lllgramint(self): |
|---|
| 4886 | return self.qflllgram(1) |
|---|
| 4887 | |
|---|
| 4888 | def qfminim(self, B, max, long flag=0): |
|---|
| 4889 | """ |
|---|
| 4890 | qfminim(x,{bound},{maxnum},{flag=0}): number of vectors of |
|---|
| 4891 | square norm <= bound, maximum norm and list of vectors for the |
|---|
| 4892 | integral and definite quadratic form x; minimal non-zero |
|---|
| 4893 | vectors if bound=0. flag is optional, and can be 0: default; |
|---|
| 4894 | 1: returns the first minimal vector found (ignore maxnum); 2: |
|---|
| 4895 | as 0 but uses a more robust, slower implementation, valid for |
|---|
| 4896 | non integral quadratic forms. |
|---|
| 4897 | """ |
|---|
| 4898 | _sig_on |
|---|
| 4899 | t0GEN(B) |
|---|
| 4900 | t1GEN(max) |
|---|
| 4901 | return self.new_gen(qfminim0(self.g,t0,t1,flag,precdl)) |
|---|
| 4902 | |
|---|
| 4903 | def qfrep(self, B, long flag=0): |
|---|
| 4904 | """ |
|---|
| 4905 | qfrep(x,B,{flag=0}): vector of (half) the number of vectors of |
|---|
| 4906 | norms from 1 to B for the integral and definite quadratic form |
|---|
| 4907 | x. Binary digits of flag mean 1: count vectors of even norm |
|---|
| 4908 | from 1 to 2B, 2: return a t_VECSMALL instead of a t_VEC. |
|---|
| 4909 | """ |
|---|
| 4910 | _sig_on |
|---|
| 4911 | t0GEN(B) |
|---|
| 4912 | return self.new_gen(qfrep0(self.g,t0,flag)) |
|---|
| 4913 | |
|---|
| 4914 | def matsolve(self, B): |
|---|
| 4915 | """ |
|---|
| 4916 | matsolve(B): Solve the linear system Mx=B for an invertible matrix M |
|---|
| 4917 | |
|---|
| 4918 | matsolve(B) uses gaussian elimination to solve Mx=B, where M is |
|---|
| 4919 | invertible and B is a column vector. |
|---|
| 4920 | |
|---|
| 4921 | The corresponding pari library routine is gauss. The gp-interface |
|---|
| 4922 | name matsolve has been given preference here. |
|---|
| 4923 | |
|---|
| 4924 | INPUT: |
|---|
| 4925 | B -- a column vector of the same dimension as the square matrix self |
|---|
| 4926 | |
|---|
| 4927 | EXAMPLES: |
|---|
| 4928 | sage: pari('[1,1;1,-1]').matsolve(pari('[1;0]')) |
|---|
| 4929 | [1/2; 1/2] |
|---|
| 4930 | """ |
|---|
| 4931 | _sig_on |
|---|
| 4932 | t0GEN(B) |
|---|
| 4933 | return self.new_gen(gauss(self.g,t0)) |
|---|
| 4934 | |
|---|
| 4935 | def matker(self, long flag=0): |
|---|
| 4936 | """ |
|---|
| 4937 | Return a basis of the kernel of this matrix. |
|---|
| 4938 | |
|---|
| 4939 | INPUT: |
|---|
| 4940 | flag -- optional; may be set to |
|---|
| 4941 | 0: default; |
|---|
| 4942 | non-zero: x is known to have integral entries. |
|---|
| 4943 | |
|---|
| 4944 | EXAMPLES: |
|---|
| 4945 | sage: pari('[1,2,3;4,5,6;7,8,9]').matker() |
|---|
| 4946 | [1; -2; 1] |
|---|
| 4947 | |
|---|
| 4948 | With algorithm 1, even if the matrix has integer entries the |
|---|
| 4949 | kernel need nto be saturated (which is weird): |
|---|
| 4950 | sage: pari('[1,2,3;4,5,6;7,8,9]').matker(1) |
|---|
| 4951 | [3; -6; 3] |
|---|
| 4952 | sage: pari('matrix(3,3,i,j,i)').matker() |
|---|
| 4953 | [-1, -1; 1, 0; 0, 1] |
|---|
| 4954 | sage: pari('[1,2,3;4,5,6;7,8,9]*Mod(1,2)').matker() |
|---|
| 4955 | [Mod(1, 2); Mod(0, 2); 1] |
|---|
| 4956 | """ |
|---|
| 4957 | _sig_on |
|---|
| 4958 | return self.new_gen(matker0(self.g, flag)) |
|---|
| 4959 | |
|---|
| 4960 | def matkerint(self, long flag=0): |
|---|
| 4961 | """ |
|---|
| 4962 | Return the integer kernel of a matrix. |
|---|
| 4963 | |
|---|
| 4964 | This is the LLL-reduced Z-basis of the kernel of the matrix x |
|---|
| 4965 | with integral entries. |
|---|
| 4966 | |
|---|
| 4967 | INPUT: |
|---|
| 4968 | flag -- optional, and may be set to |
|---|
| 4969 | 0: default, uses a modified LLL, |
|---|
| 4970 | 1: uses matrixqz. |
|---|
| 4971 | |
|---|
| 4972 | EXAMPLES: |
|---|
| 4973 | sage: pari('[2,1;2,1]').matker() |
|---|
| 4974 | [-1/2; 1] |
|---|
| 4975 | sage: pari('[2,1;2,1]').matkerint() |
|---|
| 4976 | [-1; 2] |
|---|
| 4977 | |
|---|
| 4978 | This is worrisome (so be careful!): |
|---|
| 4979 | sage: pari('[2,1;2,1]').matkerint(1) |
|---|
| 4980 | Mat(1) |
|---|
| 4981 | """ |
|---|
| 4982 | _sig_on |
|---|
| 4983 | return self.new_gen(matkerint0(self.g, flag)) |
|---|
| 4984 | |
|---|
| 4985 | def matdet(self, long flag=0): |
|---|
| 4986 | """ |
|---|
| 4987 | Return the determinant of this matrix. |
|---|
| 4988 | |
|---|
| 4989 | INPUT: |
|---|
| 4990 | flag -- (optional) flag |
|---|
| 4991 | 0: using Gauss-Bareiss. |
|---|
| 4992 | 1: use classical gaussian elimination (slightly better for integer entries) |
|---|
| 4993 | |
|---|
| 4994 | EXAMPLES: |
|---|
| 4995 | sage: pari('[1,2; 3,4]').matdet(0) |
|---|
| 4996 | -2 |
|---|
| 4997 | sage: pari('[1,2; 3,4]').matdet(1) |
|---|
| 4998 | -2 |
|---|
| 4999 | """ |
|---|
| 5000 | _sig_on |
|---|
| 5001 | return self.new_gen(det0(self.g, flag)) |
|---|
| 5002 | |
|---|
| 5003 | def trace(self): |
|---|
| 5004 | """ |
|---|
| 5005 | Return the trace of this PARI object. |
|---|
| 5006 | |
|---|
| 5007 | EXAMPLES: |
|---|
| 5008 | sage: pari('[1,2; 3,4]').trace() |
|---|
| 5009 | 5 |
|---|
| 5010 | """ |
|---|
| 5011 | _sig_on |
|---|
| 5012 | return self.new_gen(gtrace(self.g)) |
|---|
| 5013 | |
|---|
| 5014 | def mathnf(self, flag=0): |
|---|
| 5015 | """ |
|---|
| 5016 | A.mathnf({flag=0}): (upper triangular) Hermite normal form of |
|---|
| 5017 | A, basis for the lattice formed by the columns of A. |
|---|
| 5018 | |
|---|
| 5019 | INPUT: |
|---|
| 5020 | flag -- optional, value range from 0 to 4 (0 if |
|---|
| 5021 | omitted), meaning : |
|---|
| 5022 | 0: naive algorithm |
|---|
| 5023 | 1: Use Batut's algorithm -- output 2-component vector |
|---|
| 5024 | [H,U] such that H is the HNF of A, and U is a |
|---|
| 5025 | unimodular matrix such that xU=H. |
|---|
| 5026 | 3: Use Batut's algorithm. Output [H,U,P] where P is |
|---|
| 5027 | a permutation matrix such that P A U = H. |
|---|
| 5028 | 4: As 1, using a heuristic variant of LLL reduction |
|---|
| 5029 | along the way. |
|---|
| 5030 | |
|---|
| 5031 | EXAMPLES: |
|---|
| 5032 | sage: pari('[1,2,3; 4,5,6; 7,8,9]').mathnf() |
|---|
| 5033 | [6, 1; 3, 1; 0, 1] |
|---|
| 5034 | """ |
|---|
| 5035 | _sig_on |
|---|
| 5036 | return self.new_gen(mathnf0(self.g, flag)) |
|---|
| 5037 | |
|---|
| 5038 | def mathnfmod(self, d): |
|---|
| 5039 | """ |
|---|
| 5040 | Returns the Hermite normal form if d is a multiple of the determinant |
|---|
| 5041 | |
|---|
| 5042 | Beware that PARI's concept of a hermite normal form is an upper |
|---|
| 5043 | triangular matrix with the same column space as the input matrix. |
|---|
| 5044 | |
|---|
| 5045 | INPUT: |
|---|
| 5046 | d -- multiple of the determinant of self |
|---|
| 5047 | |
|---|
| 5048 | EXAMPLES: |
|---|
| 5049 | sage: M=matrix([[1,2,3],[4,5,6],[7,8,11]]) |
|---|
| 5050 | sage: d=M.det() |
|---|
| 5051 | sage: pari(M).mathnfmod(d) |
|---|
| 5052 | [6, 4, 3; 0, 1, 0; 0, 0, 1] |
|---|
| 5053 | |
|---|
| 5054 | Note that d really needs to be a multiple of the discriminant, not |
|---|
| 5055 | just of the exponent of the cokernel: |
|---|
| 5056 | |
|---|
| 5057 | sage: M=matrix([[1,0,0],[0,2,0],[0,0,6]]) |
|---|
| 5058 | sage: pari(M).mathnfmod(6) |
|---|
| 5059 | [1, 0, 0; 0, 1, 0; 0, 0, 6] |
|---|
| 5060 | sage: pari(M).mathnfmod(12) |
|---|
| 5061 | [1, 0, 0; 0, 2, 0; 0, 0, 6] |
|---|
| 5062 | |
|---|
| 5063 | """ |
|---|
| 5064 | _sig_on |
|---|
| 5065 | t0GEN(d) |
|---|
| 5066 | return self.new_gen(hnfmod(self.g, t0)) |
|---|
| 5067 | |
|---|
| 5068 | def mathnfmodid(self, d): |
|---|
| 5069 | """ |
|---|
| 5070 | Returns the Hermite Normal Form of M concatenated with d*Identity |
|---|
| 5071 | |
|---|
| 5072 | Beware that PARI's concept of a Hermite normal form is a maximal rank |
|---|
| 5073 | upper triangular matrix with the same column space as the input matrix. |
|---|
| 5074 | |
|---|
| 5075 | INPUT: |
|---|
| 5076 | d -- Determines |
|---|
| 5077 | |
|---|
| 5078 | EXAMPLES: |
|---|
| 5079 | sage: M=matrix([[1,0,0],[0,2,0],[0,0,6]]) |
|---|
| 5080 | sage: pari(M).mathnfmodid(6) |
|---|
| 5081 | [1, 0, 0; 0, 2, 0; 0, 0, 6] |
|---|
| 5082 | |
|---|
| 5083 | This routine is not completely equivalent to mathnfmod: |
|---|
| 5084 | |
|---|
| 5085 | sage: pari(M).mathnfmod(6) |
|---|
| 5086 | [1, 0, 0; 0, 1, 0; 0, 0, 6] |
|---|
| 5087 | """ |
|---|
| 5088 | _sig_on |
|---|
| 5089 | t0GEN(d) |
|---|
| 5090 | return self.new_gen(hnfmodid(self.g, t0)) |
|---|
| 5091 | |
|---|
| 5092 | def matsnf(self, flag=0): |
|---|
| 5093 | """ |
|---|
| 5094 | x.matsnf({flag=0}): Smith normal form (i.e. elementary |
|---|
| 5095 | divisors) of the matrix x, expressed as a vector d. Binary |
|---|
| 5096 | digits of flag mean 1: returns [u,v,d] where d=u*x*v, |
|---|
| 5097 | otherwise only the diagonal d is returned, 2: allow polynomial |
|---|
| 5098 | entries, otherwise assume x is integral, 4: removes all |
|---|
| 5099 | information corresponding to entries equal to 1 in d. |
|---|
| 5100 | |
|---|
| 5101 | EXAMPLES: |
|---|
| 5102 | sage: pari('[1,2,3; 4,5,6; 7,8,9]').matsnf() |
|---|
| 5103 | [0, 3, 1] |
|---|
| 5104 | """ |
|---|
| 5105 | _sig_on |
|---|
| 5106 | return self.new_gen(matsnf0(self.g, flag)) |
|---|
| 5107 | |
|---|
| 5108 | def matfrobenius(self, flag=0): |
|---|
| 5109 | r""" |
|---|
| 5110 | M.matfrobenius({flag=0}): Return the Frobenius form of the |
|---|
| 5111 | square matrix M. If flag is 1, return only the elementary |
|---|
| 5112 | divisors (a list of polynomials). If flag is 2, return a |
|---|
| 5113 | two-components vector [F,B] where F is the Frobenius form and |
|---|
| 5114 | B is the basis change so that $M=B^{-1} F B$. |
|---|
| 5115 | |
|---|
| 5116 | EXAMPLES: |
|---|
| 5117 | sage: a = pari('[1,2;3,4]') |
|---|
| 5118 | sage: a.matfrobenius() |
|---|
| 5119 | [0, 2; 1, 5] |
|---|
| 5120 | sage: a.matfrobenius(flag=1) |
|---|
| 5121 | [x^2 - 5*x - 2] |
|---|
| 5122 | sage: a.matfrobenius(2) |
|---|
| 5123 | [[0, 2; 1, 5], [1, -1/3; 0, 1/3]] |
|---|
| 5124 | sage: v = a.matfrobenius(2) |
|---|
| 5125 | sage: v[0] |
|---|
| 5126 | [0, 2; 1, 5] |
|---|
| 5127 | sage: v[1]^(-1)*v[0]*v[1] |
|---|
| 5128 | [1, 2; 3, 4] |
|---|
| 5129 | |
|---|
| 5130 | We let t be the matrix of $T_2$ acting on modular symbols of level 43, |
|---|
| 5131 | which was computed using \code{ModularSymbols(43,sign=1).T(2).matrix()}: |
|---|
| 5132 | |
|---|
| 5133 | sage: t = pari('[3, -2, 0, 0; 0, -2, 0, 1; 0, -1, -2, 2; 0, -2, 0, 2]') |
|---|
| 5134 | sage: t.matfrobenius() |
|---|
| 5135 | [0, 0, 0, -12; 1, 0, 0, -2; 0, 1, 0, 8; 0, 0, 1, 1] |
|---|
| 5136 | sage: t.charpoly('x') |
|---|
| 5137 | x^4 - x^3 - 8*x^2 + 2*x + 12 |
|---|
| 5138 | sage: t.matfrobenius(1) |
|---|
| 5139 | [x^4 - x^3 - 8*x^2 + 2*x + 12] |
|---|
| 5140 | |
|---|
| 5141 | AUTHOR: |
|---|
| 5142 | -- 2006-04-02: Martin Albrecht |
|---|
| 5143 | """ |
|---|
| 5144 | _sig_on |
|---|
| 5145 | return self.new_gen(matfrobenius(self.g, flag, 0)) |
|---|
| 5146 | |
|---|
| 5147 | |
|---|
| 5148 | ########################################### |
|---|
| 5149 | # 9: SUMS, products, integrals and similar functions |
|---|
| 5150 | ########################################### |
|---|
| 5151 | |
|---|
| 5152 | |
|---|
| 5153 | ########################################### |
|---|
| 5154 | # polarit2.c |
|---|
| 5155 | ########################################### |
|---|
| 5156 | def factor(gen self, limit=-1, bint proof=1): |
|---|
| 5157 | """ |
|---|
| 5158 | Return the factorization of x. |
|---|
| 5159 | |
|---|
| 5160 | INPUT: |
|---|
| 5161 | limit -- (default: -1) is optional and can be set whenever |
|---|
| 5162 | x is of (possibly recursive) rational type. If limit |
|---|
| 5163 | is set return partial factorization, using primes |
|---|
| 5164 | up to limit (up to primelimit if limit=0). |
|---|
| 5165 | |
|---|
| 5166 | proof -- (default: True) optional. If False (not the default), |
|---|
| 5167 | returned factors $<10^{15}$ may only be pseudoprimes. |
|---|
| 5168 | |
|---|
| 5169 | NOTE: In the standard PARI/GP interpreter and C-library the |
|---|
| 5170 | factor command *always* has proof=False, so beware! |
|---|
| 5171 | |
|---|
| 5172 | EXAMPLES: |
|---|
| 5173 | sage: pari('x^10-1').factor() |
|---|
| 5174 | [x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1] |
|---|
| 5175 | sage: pari(2^100-1).factor() |
|---|
| 5176 | [3, 1; 5, 3; 11, 1; 31, 1; 41, 1; 101, 1; 251, 1; 601, 1; 1801, 1; 4051, 1; 8101, 1; 268501, 1] |
|---|
| 5177 | sage: pari(2^100-1).factor(proof=False) |
|---|
| 5178 | [3, 1; 5, 3; 11, 1; 31, 1; 41, 1; 101, 1; 251, 1; 601, 1; 1801, 1; 4051, 1; 8101, 1; 268501, 1] |
|---|
| 5179 | |
|---|
| 5180 | We illustrate setting a limit: |
|---|
| 5181 | sage: pari(next_prime(10^50)*next_prime(10^60)*next_prime(10^4)).factor(10^5) |
|---|
| 5182 | [10007, 1; 100000000000000000000000000000000000000000000000151000000000700000000000000000000000000000000000000000000001057, 1] |
|---|
| 5183 | |
|---|
| 5184 | |
|---|
| 5185 | PARI doesn't have an algorithm for factoring multivariate polynomials: |
|---|
| 5186 | |
|---|
| 5187 | sage: pari('x^3 - y^3').factor() |
|---|
| 5188 | Traceback (most recent call last): |
|---|
| 5189 | ... |
|---|
| 5190 | PariError: sorry, (15) |
|---|
| 5191 | """ |
|---|
| 5192 | cdef int r |
|---|
| 5193 | if limit == -1 and typ(self.g) == t_INT and proof: |
|---|
| 5194 | _sig_on |
|---|
| 5195 | r = factorint_withproof_sage(&t0, self.g, ten_to_15) |
|---|
| 5196 | _sig_off |
|---|
| 5197 | z = P.new_gen(t0) |
|---|
| 5198 | if not r: |
|---|
| 5199 | return z |
|---|
| 5200 | else: |
|---|
| 5201 | return _factor_int_when_pari_factor_failed(self, z) |
|---|
| 5202 | _sig_on |
|---|
| 5203 | return P.new_gen(factor0(self.g, limit)) |
|---|
| 5204 | |
|---|
| 5205 | |
|---|
| 5206 | ########################################### |
|---|
| 5207 | # misc (classify when I know where they go) |
|---|
| 5208 | ########################################### |
|---|
| 5209 | |
|---|
| 5210 | def hilbert(x, y, p): |
|---|
| 5211 | t0GEN(y) |
|---|
| 5212 | t1GEN(p) |
|---|
| 5213 | _sig_on |
|---|
| 5214 | return hil0(x.g, t0, t1) |
|---|
| 5215 | |
|---|
| 5216 | def chinese(self, y): |
|---|
| 5217 | t0GEN(y) |
|---|
| 5218 | _sig_on |
|---|
| 5219 | return P.new_gen(chinese(self.g, t0)) |
|---|
| 5220 | |
|---|
| 5221 | def order(self): |
|---|
| 5222 | _sig_on |
|---|
| 5223 | return P.new_gen(order(self.g)) |
|---|
| 5224 | |
|---|
| 5225 | def znprimroot(self): |
|---|
| 5226 | _sig_on |
|---|
| 5227 | return P.new_gen(ggener(self.g)) |
|---|
| 5228 | |
|---|
| 5229 | def __abs__(self): |
|---|
| 5230 | return self.abs() |
|---|
| 5231 | |
|---|
| 5232 | def norm(gen self): |
|---|
| 5233 | _sig_on |
|---|
| 5234 | return P.new_gen(gnorm(self.g)) |
|---|
| 5235 | |
|---|
| 5236 | def nextprime(gen self): |
|---|
| 5237 | """ |
|---|
| 5238 | nextprime(x): smallest pseudoprime >= x |
|---|
| 5239 | """ |
|---|
| 5240 | #NOTE: This is much faster than MAGMA's NextPrime with Proof := False. |
|---|
| 5241 | _sig_on |
|---|
| 5242 | return P.new_gen(gnextprime(self.g)) |
|---|
| 5243 | |
|---|
| 5244 | def subst(self, var, y): |
|---|
| 5245 | """ |
|---|
| 5246 | EXAMPLES: |
|---|
| 5247 | sage: x = pari("x"); y = pari("y") |
|---|
| 5248 | sage: f = pari('x^3 + 17*x + 3') |
|---|
| 5249 | sage: f.subst(x, y) |
|---|
| 5250 | y^3 + 17*y + 3 |
|---|
| 5251 | sage: f.subst(x, "z") |
|---|
| 5252 | z^3 + 17*z + 3 |
|---|
| 5253 | sage: f.subst(x, "z")^2 |
|---|
| 5254 | z^6 + 34*z^4 + 6*z^3 + 289*z^2 + 102*z + 9 |
|---|
| 5255 | sage: f.subst(x, "x+1") |
|---|
| 5256 | x^3 + 3*x^2 + 20*x + 21 |
|---|
| 5257 | sage: f.subst(x, "xyz") |
|---|
| 5258 | xyz^3 + 17*xyz + 3 |
|---|
| 5259 | sage: f.subst(x, "xyz")^2 |
|---|
| 5260 | xyz^6 + 34*xyz^4 + 6*xyz^3 + 289*xyz^2 + 102*xyz + 9 |
|---|
| 5261 | """ |
|---|
| 5262 | cdef long n |
|---|
| 5263 | n = P.get_var(var) |
|---|
| 5264 | t0GEN(y) |
|---|
| 5265 | _sig_on |
|---|
| 5266 | return P.new_gen(gsubst(self.g, n, t0)) |
|---|
| 5267 | |
|---|
| 5268 | def substpol(self, y, z): |
|---|
| 5269 | t0GEN(y) |
|---|
| 5270 | t1GEN(z) |
|---|
| 5271 | _sig_on |
|---|
| 5272 | return self.new_gen(gsubstpol(self.g, t0, t1)) |
|---|
| 5273 | |
|---|
| 5274 | def taylor(self, v=-1): |
|---|
| 5275 | _sig_on |
|---|
| 5276 | return self.new_gen(tayl(self.g, self.get_var(v), precdl)) |
|---|
| 5277 | |
|---|
| 5278 | def thue(self, rhs, ne): |
|---|
| 5279 | t0GEN(rhs) |
|---|
| 5280 | t1GEN(ne) |
|---|
| 5281 | _sig_on |
|---|
| 5282 | return self.new_gen(thue(self.g, t0, t1)) |
|---|
| 5283 | |
|---|
| 5284 | def charpoly(self, var=-1, flag=0): |
|---|
| 5285 | """ |
|---|
| 5286 | charpoly(A,{v=x},{flag=0}): det(v*Id-A) = characteristic |
|---|
| 5287 | polynomial of A using the comatrix. flag is optional and may |
|---|
| 5288 | be set to 1 (use Lagrange interpolation) or 2 (use Hessenberg |
|---|
| 5289 | form), 0 being the default. |
|---|
| 5290 | """ |
|---|
| 5291 | _sig_on |
|---|
| 5292 | return P.new_gen(charpoly0(self.g, P.get_var(var), flag)) |
|---|
| 5293 | |
|---|
| 5294 | |
|---|
| 5295 | def kronecker(gen self, y): |
|---|
| 5296 | t0GEN(y) |
|---|
| 5297 | _sig_on |
|---|
| 5298 | return P.new_gen(gkronecker(self.g, t0)) |
|---|
| 5299 | |
|---|
| 5300 | |
|---|
| 5301 | def type(gen self): |
|---|
| 5302 | return str(type_name(typ(self.g))) |
|---|
| 5303 | |
|---|
| 5304 | |
|---|
| 5305 | def polinterpolate(self, ya, x): |
|---|
| 5306 | """ |
|---|
| 5307 | self.polinterpolate({ya},{x},{&e}): polynomial interpolation |
|---|
| 5308 | at x according to data vectors self, ya (i.e. return P such |
|---|
| 5309 | that P(self[i]) = ya[i] for all i). Also return an error |
|---|
| 5310 | estimate on the returned value. |
|---|
| 5311 | """ |
|---|
| 5312 | t0GEN(ya) |
|---|
| 5313 | t1GEN(x) |
|---|
| 5314 | cdef GEN dy, g |
|---|
| 5315 | _sig_on |
|---|
| 5316 | g = polint(self.g, t0, t1, &dy) |
|---|
| 5317 | _sig_off |
|---|
| 5318 | dif = self.new_gen_noclear(dy) |
|---|
| 5319 | return self.new_gen(g), dif |
|---|
| 5320 | |
|---|
| 5321 | def algdep(self, long n, bit=0): |
|---|
| 5322 | """ |
|---|
| 5323 | EXAMPLES: |
|---|
| 5324 | sage: n = pari.set_real_precision (200) |
|---|
| 5325 | sage: w1 = pari('z1=2-sqrt(26); (z1+I)/(z1-I)') |
|---|
| 5326 | sage: f = w1.algdep(12); f |
|---|
| 5327 | 545*x^11 - 297*x^10 - 281*x^9 + 48*x^8 - 168*x^7 + 690*x^6 - 168*x^5 + 48*x^4 - 281*x^3 - 297*x^2 + 545*x |
|---|
| 5328 | sage: f(w1) |
|---|
| 5329 | 7.75513996 E-200 + 5.70672991 E-200*I # 32-bit |
|---|
| 5330 | 3.780069700150794274 E-209 - 9.362977321012524836 E-211*I # 64-bit |
|---|
| 5331 | sage: f.factor() |
|---|
| 5332 | [x, 1; x + 1, 2; x^2 + 1, 1; x^2 + x + 1, 1; 545*x^4 - 1932*x^3 + 2790*x^2 - 1932*x + 545, 1] |
|---|
| 5333 | sage: pari.set_real_precision(n) |
|---|
| 5334 | 200 |
|---|
| 5335 | """ |
|---|
| 5336 | cdef long b |
|---|
| 5337 | b = bit |
|---|
| 5338 | _sig_on |
|---|
| 5339 | return self.new_gen(algdep0(self.g, n, b, prec)) |
|---|
| 5340 | |
|---|
| 5341 | def concat(self, y): |
|---|
| 5342 | t0GEN(y) |
|---|
| 5343 | _sig_on |
|---|
| 5344 | return self.new_gen(concat(self.g, t0)) |
|---|
| 5345 | |
|---|
| 5346 | def lindep(self, flag=0): |
|---|
| 5347 | _sig_on |
|---|
| 5348 | return self.new_gen(lindep0(self.g, flag, prec)) |
|---|
| 5349 | |
|---|
| 5350 | def listinsert(self, obj, long n): |
|---|
| 5351 | t0GEN(obj) |
|---|
| 5352 | _sig_on |
|---|
| 5353 | return self.new_gen(listinsert(self.g, t0, n)) |
|---|
| 5354 | |
|---|
| 5355 | def listput(self, obj, long n): |
|---|
| 5356 | t0GEN(obj) |
|---|
| 5357 | _sig_on |
|---|
| 5358 | return self.new_gen(listput(self.g, t0, n)) |
|---|
| 5359 | |
|---|
| 5360 | |
|---|
| 5361 | |
|---|
| 5362 | def elleisnum(self, long k, int flag=0): |
|---|
| 5363 | """ |
|---|
| 5364 | om.elleisnum(k, {flag=0}, {prec}): om=[om1,om2] being a |
|---|
| 5365 | 2-component vector giving a basis of a lattice L and k an |
|---|
| 5366 | even positive integer, computes the numerical value of the |
|---|
| 5367 | Eisenstein series of weight k. When flag is non-zero and |
|---|
| 5368 | k=4 or 6, this gives g2 or g3 with the correct |
|---|
| 5369 | normalization. |
|---|
| 5370 | |
|---|
| 5371 | INPUT: |
|---|
| 5372 | om -- gen, 2-component vector giving a basis of a lattice L |
|---|
| 5373 | k -- int (even positive) |
|---|
| 5374 | flag -- int (default 0) |
|---|
| 5375 | pref -- precision |
|---|
| 5376 | |
|---|
| 5377 | OUTPUT: |
|---|
| 5378 | gen -- numerical value of E_k |
|---|
| 5379 | |
|---|
| 5380 | EXAMPLES: |
|---|
| 5381 | sage: e = pari([0,1,1,-2,0]).ellinit() |
|---|
| 5382 | sage: om = e.omega() |
|---|
| 5383 | sage: om |
|---|
| 5384 | [2.490212560855055075321357792, 1.971737701551648204422407698*I] # 32-bit |
|---|
| 5385 | [2.4902125608550550753213577919423024602, 1.9717377015516482044224076981513423349*I] # 64-bit |
|---|
| 5386 | sage: om.elleisnum(2) |
|---|
| 5387 | -5.288649339654257621791534695 # 32-bit |
|---|
| 5388 | -5.2886493396542576217915346952045657616 # 64-bit |
|---|
| 5389 | sage: om.elleisnum(4) |
|---|
| 5390 | 112.0000000000000000000000000 # 32-bit |
|---|
| 5391 | 112.00000000000000000000000000000000000 # 64-bit |
|---|
| 5392 | sage: om.elleisnum(100) |
|---|
| 5393 | 2.153142485760776361127070349 E50 # 32-bit |
|---|
| 5394 | 2.1531424857607763611270703492586704424 E50 # 64-bit |
|---|
| 5395 | """ |
|---|
| 5396 | _sig_on |
|---|
| 5397 | return self.new_gen(elleisnum(self.g, k, flag, prec)) |
|---|
| 5398 | |
|---|
| 5399 | def ellwp(self, z='z', long n=20, long flag=0): |
|---|
| 5400 | """ |
|---|
| 5401 | ellwp(E, z,{flag=0}): Return the complex value of the Weierstrass |
|---|
| 5402 | P-function at z on the lattice defined by e. |
|---|
| 5403 | |
|---|
| 5404 | INPUT: |
|---|
| 5405 | E -- list OR elliptic curve |
|---|
| 5406 | list -- [om1, om2], which are Z-generators for a lattice |
|---|
| 5407 | elliptic curve -- created using ellinit |
|---|
| 5408 | |
|---|
| 5409 | z -- (optional) complex number OR string (default = "z") |
|---|
| 5410 | complex number -- any number in the complex plane |
|---|
| 5411 | string (or PARI variable) -- name of a variable. |
|---|
| 5412 | |
|---|
| 5413 | n -- int (optional: default 20) if z is a variable, compute up to at least o(z^n). |
|---|
| 5414 | |
|---|
| 5415 | flag -- int: 0 (default): compute only P(z) |
|---|
| 5416 | 1 compute [P(z),P'(z)] |
|---|
| 5417 | 2 consider om or E as an elliptic curve and use P-function to |
|---|
| 5418 | compute the point on E (with the Weierstrass equation for E) |
|---|
| 5419 | P(z) |
|---|
| 5420 | for that curve (identical to ellztopoint in this case). |
|---|
| 5421 | |
|---|
| 5422 | OUTPUT: |
|---|
| 5423 | gen -- complex number or list of two complex numbers |
|---|
| 5424 | |
|---|
| 5425 | EXAMPLES: |
|---|
| 5426 | |
|---|
| 5427 | We first define the elliptic curve X_0(11): |
|---|
| 5428 | sage: E = pari([0,-1,1,-10,-20]).ellinit() |
|---|
| 5429 | |
|---|
| 5430 | Compute P(1). |
|---|
| 5431 | sage: E.ellwp(1) |
|---|
| 5432 | 13.96586952574849779469497770 + 1.465441833 E-249*I # 32-bit |
|---|
| 5433 | 13.965869525748497794694977695009324221 + 5.607702583566084181 E-693*I # 64-bit |
|---|
| 5434 | |
|---|
| 5435 | Compute P(1+I), where I = sqrt(-1). |
|---|
| 5436 | sage: E.ellwp(pari("1+I")) |
|---|
| 5437 | -1.115106825655550879209066492 + 2.334190523074698836184798794*I # 32-bit |
|---|
| 5438 | -1.1151068256555508792090664916218413986 + 2.3341905230746988361847987936140321964*I # 64-bit |
|---|
| 5439 | sage: E.ellwp("1+I") |
|---|
| 5440 | -1.115106825655550879209066492 + 2.334190523074698836184798794*I # 32-bit |
|---|
| 5441 | -1.1151068256555508792090664916218413986 + 2.3341905230746988361847987936140321964*I # 64-bit |
|---|
| 5442 | |
|---|
| 5443 | The series expansion, to the default 20 precision: |
|---|
| 5444 | sage: E.ellwp() |
|---|
| 5445 | z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20) |
|---|
| 5446 | |
|---|
| 5447 | Compute the series for wp to lower precision: |
|---|
| 5448 | sage: E.ellwp(n=4) |
|---|
| 5449 | z^-2 + 31/15*z^2 + O(z^4) |
|---|
| 5450 | |
|---|
| 5451 | Next we use the version where the input is generators for a lattice: |
|---|
| 5452 | sage: pari(['1.2692', '0.63 + 1.45*I']).ellwp(1) |
|---|
| 5453 | 13.96561469366894364802003736 + 0.0006448292728105361474541633318*I # 32-bit |
|---|
| 5454 | 13.965614693668943648020037358850990554 + 0.00064482927281053614745416280316868200698*I # 64-bit |
|---|
| 5455 | |
|---|
| 5456 | With flag 1 compute the pair P(z) and P'(z): |
|---|
| 5457 | sage: E.ellwp(1, flag=1) |
|---|
| 5458 | [13.96586952574849779469497770 + 1.465441833 E-249*I, 50.56193008800727525558465690 + 4.46944479 E-249*I] # 32-bit |
|---|
| 5459 | [13.965869525748497794694977695009324221 + 5.607702583566084181 E-693*I, 50.561930088007275255584656898892400699 + 1.7102908181111172423 E-692*I] # 64-bit |
|---|
| 5460 | |
|---|
| 5461 | With flag=2, the computed pair is (x,y) on the curve instead of [P(z),P'(z)]: |
|---|
| 5462 | sage: E.ellwp(1, flag=2) |
|---|
| 5463 | [14.29920285908183112802831103 + 1.465441833 E-249*I, 50.06193008800727525558465690 + 4.46944479 E-249*I] # 32-bit |
|---|
| 5464 | [14.299202859081831128028311028342657555 + 5.607702583566084181 E-693*I, 50.061930088007275255584656898892400699 + 1.7102908181111172423 E-692*I] # 64-bit |
|---|
| 5465 | """ |
|---|
| 5466 | t0GEN(z) |
|---|
| 5467 | if n < 0: |
|---|
| 5468 | n = 0 |
|---|
| 5469 | if n%2 == 1: |
|---|
| 5470 | n = n + 1 |
|---|
| 5471 | _sig_on |
|---|
| 5472 | return self.new_gen(ellwp0(self.g, t0, flag, prec, (n+2)/2)) |
|---|
| 5473 | |
|---|
| 5474 | def ellchangepoint(self, y): |
|---|
| 5475 | """ |
|---|
| 5476 | self.ellchangepoint(y): change data on point or vector of points self |
|---|
| 5477 | on an elliptic curve according to y=[u,r,s,t] |
|---|
| 5478 | |
|---|
| 5479 | EXAMPLES: |
|---|
| 5480 | sage: e = pari([0,1,1,-2,0]).ellinit() |
|---|
| 5481 | sage: x = pari([1,0,1]) |
|---|
| 5482 | sage: e.ellisoncurve([1,4,4]) |
|---|
| 5483 | False |
|---|
| 5484 | sage: e.ellisoncurve(x) |
|---|
| 5485 | True |
|---|
| 5486 | sage: f = e.ellchangecurve([1,2,3,-1]) |
|---|
| 5487 | sage: f[:5] # show only first five entries |
|---|
| 5488 | [6, -2, -1, 17, 8] |
|---|
| 5489 | sage: x.ellchangepoint([1,2,3,-1]) |
|---|
| 5490 | [-1, 4] |
|---|
| 5491 | sage: f.ellisoncurve([-1,4]) |
|---|
| 5492 | True |
|---|
| 5493 | """ |
|---|
| 5494 | t0GEN(y) |
|---|
| 5495 | _sig_on |
|---|
| 5496 | return self.new_gen(pointch(self.g, t0)) |
|---|
| 5497 | |
|---|
| 5498 | ################################################## |
|---|
| 5499 | # Technical functions that can be used by other |
|---|
| 5500 | # classes that derive from gen. |
|---|
| 5501 | ################################################## |
|---|
| 5502 | cdef gen pari(self, object x): |
|---|
| 5503 | return pari(x) |
|---|
| 5504 | |
|---|
| 5505 | cdef gen new_gen(self, GEN x): |
|---|
| 5506 | return P.new_gen(x) |
|---|
| 5507 | |
|---|
| 5508 | cdef gen new_gen_noclear(self, GEN x): |
|---|
| 5509 | return P.new_gen_noclear(x) |
|---|
| 5510 | |
|---|
| 5511 | cdef GEN _deepcopy_to_python_heap(self, GEN x, pari_sp* address): |
|---|
| 5512 | return P.deepcopy_to_python_heap(x, address) |
|---|
| 5513 | |
|---|
| 5514 | cdef int get_var(self, v): |
|---|
| 5515 | return P.get_var(v) |
|---|
| 5516 | |
|---|
| 5517 | |
|---|
| 5518 | |
|---|
| 5519 | cdef unsigned long num_primes |
|---|
| 5520 | |
|---|
| 5521 | cdef class PariInstance(sage.structure.parent_base.ParentWithBase): |
|---|
| 5522 | def __init__(self, long size=16000000, unsigned long maxprime=500000): |
|---|
| 5523 | """ |
|---|
| 5524 | Initialize the PARI system. |
|---|
| 5525 | |
|---|
| 5526 | INPUT: |
|---|
| 5527 | size -- long, the number of bytes for the initial PARI stack |
|---|
| 5528 | (see note below) |
|---|
| 5529 | maxprime -- unsigned long, upper limit on a precomputed prime |
|---|
| 5530 | number table (default: 500000) |
|---|
| 5531 | |
|---|
| 5532 | NOTES: |
|---|
| 5533 | |
|---|
| 5534 | * In py_pari, the PARI stack is different than in gp or the |
|---|
| 5535 | PARI C library. In Python, instead of the PARI stack |
|---|
| 5536 | holding the results of all computations, it *only* holds the |
|---|
| 5537 | results of an individual computation. Each time a new |
|---|
| 5538 | Python/PARI object is computed, it it copied to its own |
|---|
| 5539 | space in the Python heap, and the memory it occupied on the |
|---|
| 5540 | PARI stack is freed. Thus it is not necessary to make the |
|---|
| 5541 | stack very large. Also, unlike in PARI, if the stack does |
|---|
| 5542 | overflow, in most cases the PARI stack is automatically |
|---|
| 5543 | increased and the relevant step of the computation rerun. |
|---|
| 5544 | |
|---|
| 5545 | This design obviously involves some performance penalties |
|---|
| 5546 | over the way PARI works, but it scales much better and is |
|---|
| 5547 | far more robus for large projects. |
|---|
| 5548 | |
|---|
| 5549 | * If you do not want prime numbers, put maxprime=2, but be |
|---|
| 5550 | careful because many PARI functions require this table. If |
|---|
| 5551 | you get the error message "not enough precomputed primes", |
|---|
| 5552 | increase this parameter. |
|---|
| 5553 | |
|---|
| 5554 | """ |
|---|
| 5555 | if bot: |
|---|
| 5556 | return # pari already initialized. |
|---|
| 5557 | |
|---|
| 5558 | global initialized, num_primes, ZERO, ONE, TWO, avma, top, bot, \ |
|---|
| 5559 | initial_bot, initial_top |
|---|
| 5560 | |
|---|
| 5561 | |
|---|
| 5562 | #print "Initializing PARI (size=%s, maxprime=%s)"%(size,maxprime) |
|---|
| 5563 | pari_init(1024, maxprime) |
|---|
| 5564 | initial_bot = bot |
|---|
| 5565 | initial_top = top |
|---|
| 5566 | bot = 0 |
|---|
| 5567 | |
|---|
| 5568 | _sig_on |
|---|
| 5569 | init_stack(size) |
|---|
| 5570 | _sig_off |
|---|
| 5571 | |
|---|
| 5572 | GP_DATA.fmt.prettyp = 0 |
|---|
| 5573 | |
|---|
| 5574 | # Take control of SIGSEGV back from PARI. |
|---|
| 5575 | import signal |
|---|
| 5576 | signal.signal(signal.SIGSEGV, signal.SIG_DFL) |
|---|
| 5577 | |
|---|
| 5578 | # We do the following, since otherwise the IPython pager |
|---|
| 5579 | # causes sage to crash when it is exited early. This is |
|---|
| 5580 | # because when PARI was initialized it set a trap for this |
|---|
| 5581 | # signal. |
|---|
| 5582 | import signal |
|---|
| 5583 | signal.signal(signal.SIGPIPE, _my_sigpipe) |
|---|
| 5584 | initialized = 1 |
|---|
| 5585 | stack_avma = avma |
|---|
| 5586 | num_primes = maxprime |
|---|
| 5587 | self.ZERO = self.new_gen(gen_0) |
|---|
| 5588 | self.ONE = self.new_gen(gen_1) |
|---|
| 5589 | self.TWO = self.new_gen(gen_2) |
|---|
| 5590 | |
|---|
| 5591 | #def __dealloc__(self): |
|---|
| 5592 | |
|---|
| 5593 | def _unsafe_deallocate_pari_stack(self): |
|---|
| 5594 | if bot: |
|---|
| 5595 | sage_free(<void*>bot) |
|---|
| 5596 | global top, bot |
|---|
| 5597 | top = initial_top |
|---|
| 5598 | bot = initial_bot |
|---|
| 5599 | pari_close() |
|---|
| 5600 | |
|---|
| 5601 | def __repr__(self): |
|---|
| 5602 | return "Interface to the PARI C library" |
|---|
| 5603 | |
|---|
| 5604 | def __hash__(self): |
|---|
| 5605 | return 907629390 # hash('pari') |
|---|
| 5606 | |
|---|
| 5607 | cdef has_coerce_map_from_c_impl(self, x): |
|---|
| 5608 | return True |
|---|
| 5609 | |
|---|
| 5610 | def __richcmp__(left, right, int op): |
|---|
| 5611 | """ |
|---|
| 5612 | EXAMPLES: |
|---|
| 5613 | sage: pari == pari |
|---|
| 5614 | True |
|---|
| 5615 | sage: pari == gp |
|---|
| 5616 | False |
|---|
| 5617 | sage: pari == 5 |
|---|
| 5618 | False |
|---|
| 5619 | """ |
|---|
| 5620 | return (<Parent>left)._richcmp(right, op) |
|---|
| 5621 | |
|---|
| 5622 | def default(self, variable, value=None): |
|---|
| 5623 | if not value is None: |
|---|
| 5624 | return self('default(%s, %s)'%(variable, value)) |
|---|
| 5625 | return self('default(%s)'%variable) |
|---|
| 5626 | |
|---|
| 5627 | def set_debug_level(self, level): |
|---|
| 5628 | """ |
|---|
| 5629 | Set the debug PARI C library variable. |
|---|
| 5630 | """ |
|---|
| 5631 | self.default('debug', int(level)) |
|---|
| 5632 | |
|---|
| 5633 | def get_debug_level(self): |
|---|
| 5634 | """ |
|---|
| 5635 | Set the debug PARI C library variable. |
|---|
| 5636 | """ |
|---|
| 5637 | return int(self.default('debug')) |
|---|
| 5638 | |
|---|
| 5639 | cdef GEN toGEN(self, x, int i) except NULL: |
|---|
| 5640 | cdef gen _x |
|---|
| 5641 | if PY_TYPE_CHECK(x, gen): |
|---|
| 5642 | _x = x |
|---|
| 5643 | return _x.g |
|---|
| 5644 | |
|---|
| 5645 | t0heap[i] = self(x) |
|---|
| 5646 | _x = t0heap[i] |
|---|
| 5647 | return _x.g |
|---|
| 5648 | |
|---|
| 5649 | # TODO: Refactor code out of __call__ so it... |
|---|
| 5650 | |
|---|
| 5651 | s = str(x) |
|---|
| 5652 | cdef GEN g |
|---|
| 5653 | _sig_on |
|---|
| 5654 | g = flisseq(s) |
|---|
| 5655 | _sig_off |
|---|
| 5656 | return g |
|---|
| 5657 | |
|---|
| 5658 | |
|---|
| 5659 | def set_real_precision(self, long n): |
|---|
| 5660 | """ |
|---|
| 5661 | Sets the PARI default real precision, both for creation of |
|---|
| 5662 | new objects and for printing. This is the number of digits |
|---|
| 5663 | *IN DECIMAL* that real numbers are printed or computed to |
|---|
| 5664 | by default. |
|---|
| 5665 | |
|---|
| 5666 | Returns the previous PARI real precision. |
|---|
| 5667 | """ |
|---|
| 5668 | cdef unsigned long k |
|---|
| 5669 | global prec |
|---|
| 5670 | |
|---|
| 5671 | k = GP_DATA.fmt.sigd |
|---|
| 5672 | s = str(n) |
|---|
| 5673 | _sig_on |
|---|
| 5674 | sd_realprecision(s, 2) |
|---|
| 5675 | prec = GP_DATA.fmt.sigd |
|---|
| 5676 | _sig_off |
|---|
| 5677 | return int(k) # Python int |
|---|
| 5678 | |
|---|
| 5679 | def get_real_precision(self): |
|---|
| 5680 | return GP_DATA.fmt.sigd |
|---|
| 5681 | |
|---|
| 5682 | def set_series_precision(self, long n): |
|---|
| 5683 | global precdl |
|---|
| 5684 | precdl = n |
|---|
| 5685 | |
|---|
| 5686 | def get_series_precision(self): |
|---|
| 5687 | return precdl |
|---|
| 5688 | |
|---|
| 5689 | |
|---|
| 5690 | ########################################### |
|---|
| 5691 | # Create a gen from a GEN object. |
|---|
| 5692 | # This *steals* a reference to the GEN, as it |
|---|
| 5693 | # frees the memory the GEN occupied. |
|---|
| 5694 | ########################################### |
|---|
| 5695 | |
|---|
| 5696 | cdef gen new_gen(self, GEN x): |
|---|
| 5697 | """ |
|---|
| 5698 | Create a new gen, then free the *entire* stack and call _sig_off. |
|---|
| 5699 | """ |
|---|
| 5700 | cdef gen g |
|---|
| 5701 | g = _new_gen(x) |
|---|
| 5702 | |
|---|
| 5703 | global mytop, avma |
|---|
| 5704 | avma = mytop |
|---|
| 5705 | _sig_off |
|---|
| 5706 | return g |
|---|
| 5707 | |
|---|
| 5708 | cdef void clear_stack(self): |
|---|
| 5709 | """ |
|---|
| 5710 | Clear the entire PARI stack and turn off call _sig_off. |
|---|
| 5711 | """ |
|---|
| 5712 | global mytop, avma |
|---|
| 5713 | avma = mytop |
|---|
| 5714 | _sig_off |
|---|
| 5715 | |
|---|
| 5716 | cdef gen new_gen_noclear(self, GEN x): |
|---|
| 5717 | """ |
|---|
| 5718 | Create a new gen, but don't free any memory on the stack and |
|---|
| 5719 | don't call _sig_off. |
|---|
| 5720 | """ |
|---|
| 5721 | z = _new_gen(x) |
|---|
| 5722 | return z |
|---|
| 5723 | |
|---|
| 5724 | cdef gen new_gen_from_mpz_t(self, mpz_t value): |
|---|
| 5725 | cdef GEN z |
|---|
| 5726 | cdef long limbs = 0 |
|---|
| 5727 | |
|---|
| 5728 | limbs = mpz_size(value) |
|---|
| 5729 | |
|---|
| 5730 | if (limbs > 500): |
|---|
| 5731 | _sig_on |
|---|
| 5732 | z = cgetg( limbs+2, t_INT ) |
|---|
| 5733 | setlgefint( z, limbs+2 ) |
|---|
| 5734 | setsigne( z, mpz_sgn(value) ) |
|---|
| 5735 | mpz_export( int_LSW(z), NULL, -1, sizeof(long), 0, 0, value ) |
|---|
| 5736 | return self.new_gen(z) |
|---|
| 5737 | |
|---|
| 5738 | cdef gen new_gen_from_int(self, int value): |
|---|
| 5739 | cdef GEN z |
|---|
| 5740 | cdef long sign = 0 |
|---|
| 5741 | |
|---|
| 5742 | z = cgetg( 3, t_INT ) |
|---|
| 5743 | setlgefint( z, 3 ) |
|---|
| 5744 | if (value > 0): |
|---|
| 5745 | sign = 1 |
|---|
| 5746 | z[2] = value |
|---|
| 5747 | elif (value < 0): |
|---|
| 5748 | sign = -1 |
|---|
| 5749 | z[2] = -value |
|---|
| 5750 | setsigne( z, sign ) |
|---|
| 5751 | return _new_gen(z) |
|---|
| 5752 | |
|---|
| 5753 | def double_to_gen(self, x): |
|---|
| 5754 | cdef double dx |
|---|
| 5755 | dx = float(x) |
|---|
| 5756 | return self.double_to_gen_c(dx) |
|---|
| 5757 | |
|---|
| 5758 | cdef gen double_to_gen_c(self, double x): |
|---|
| 5759 | """ |
|---|
| 5760 | Create a new gen with the value of the double x, using Pari's |
|---|
| 5761 | dbltor. |
|---|
| 5762 | |
|---|
| 5763 | EXAMPLES: |
|---|
| 5764 | sage: pari.double_to_gen(1) |
|---|
| 5765 | 1.0000000000000000000 |
|---|
| 5766 | sage: pari.double_to_gen(1e30) |
|---|
| 5767 | 1.0000000000000000199 E30 |
|---|
| 5768 | sage: pari.double_to_gen(0) |
|---|
| 5769 | 0.E-15 |
|---|
| 5770 | sage: pari.double_to_gen(-sqrt(RDF(2))) |
|---|
| 5771 | -1.4142135623730951455 |
|---|
| 5772 | """ |
|---|
| 5773 | # Pari has an odd concept where it attempts to track the accuracy |
|---|
| 5774 | # of floating-point 0; a floating-point zero might be 0.0e-20 |
|---|
| 5775 | # (meaning roughly that it might represent any number in the |
|---|
| 5776 | # range -1e-20 <= x <= 1e20). |
|---|
| 5777 | |
|---|
| 5778 | # Pari's dbltor converts a floating-point 0 into the Pari real |
|---|
| 5779 | # 0.0e-307; Pari treats this as an extremely precise 0. This |
|---|
| 5780 | # can cause problems; for instance, the Pari incgam() function can |
|---|
| 5781 | # be very slow if the first argument is very precise. |
|---|
| 5782 | |
|---|
| 5783 | # So we translate 0 into a floating-point 0 with 53 bits |
|---|
| 5784 | # of precision (that's the number of mantissa bits in an IEEE |
|---|
| 5785 | # double). |
|---|
| 5786 | |
|---|
| 5787 | if x == 0: |
|---|
| 5788 | return self.new_gen(real_0_bit(-53)) |
|---|
| 5789 | else: |
|---|
| 5790 | return self.new_gen(dbltor(x)) |
|---|
| 5791 | |
|---|
| 5792 | cdef GEN double_to_GEN(self, double x): |
|---|
| 5793 | if x == 0: |
|---|
| 5794 | return real_0_bit(-53) |
|---|
| 5795 | else: |
|---|
| 5796 | return dbltor(x) |
|---|
| 5797 | |
|---|
| 5798 | def complex(self, re, im): |
|---|
| 5799 | """ |
|---|
| 5800 | Create a new complex number, initialized from re and im. |
|---|
| 5801 | """ |
|---|
| 5802 | t0GEN(re) |
|---|
| 5803 | t1GEN(im) |
|---|
| 5804 | cdef GEN cp |
|---|
| 5805 | cp = cgetg(3, t_COMPLEX) |
|---|
| 5806 | __set_lvalue__(gel(cp, 1), t0) |
|---|
| 5807 | __set_lvalue__(gel(cp, 2), t1) |
|---|
| 5808 | return self.new_gen(cp) |
|---|
| 5809 | |
|---|
| 5810 | cdef GEN deepcopy_to_python_heap(self, GEN x, pari_sp* address): |
|---|
| 5811 | return deepcopy_to_python_heap(x, address) |
|---|
| 5812 | |
|---|
| 5813 | cdef gen new_ref(self, GEN x, g): |
|---|
| 5814 | cdef gen p |
|---|
| 5815 | p = gen() |
|---|
| 5816 | p.init(x, 0) |
|---|
| 5817 | try: |
|---|
| 5818 | p.refers_to[-1] = g # so underlying memory won't get deleted |
|---|
| 5819 | # out from under us. |
|---|
| 5820 | except TypeError: |
|---|
| 5821 | p.refers_to = {-1:g} |
|---|
| 5822 | return p |
|---|
| 5823 | |
|---|
| 5824 | cdef gen adapt(self, s): |
|---|
| 5825 | if isinstance(s, gen): |
|---|
| 5826 | return s |
|---|
| 5827 | return pari(s) |
|---|
| 5828 | |
|---|
| 5829 | def __call__(self, s): |
|---|
| 5830 | """ |
|---|
| 5831 | Create the PARI object obtained by evaluating s using PARI. |
|---|
| 5832 | """ |
|---|
| 5833 | |
|---|
| 5834 | late_import() |
|---|
| 5835 | |
|---|
| 5836 | if isinstance(s, gen): |
|---|
| 5837 | return s |
|---|
| 5838 | elif PY_TYPE_CHECK(s, Integer): |
|---|
| 5839 | return self.new_gen_from_mpz_t(<mpz_t>(<void *>s + mpz_t_offset)) |
|---|
| 5840 | |
|---|
| 5841 | try: |
|---|
| 5842 | return s._pari_() |
|---|
| 5843 | except AttributeError: |
|---|
| 5844 | pass |
|---|
| 5845 | if isinstance(s, (types.ListType, types.XRangeType, |
|---|
| 5846 | types.TupleType, types.GeneratorType)): |
|---|
| 5847 | v = self.vector(len(s)) |
|---|
| 5848 | for i, x in enumerate(s): |
|---|
| 5849 | v[i] = self(x) |
|---|
| 5850 | return v |
|---|
| 5851 | elif isinstance(s, bool): |
|---|
| 5852 | if s: |
|---|
| 5853 | return self.ONE |
|---|
| 5854 | return self.ZERO |
|---|
| 5855 | |
|---|
| 5856 | cdef GEN g |
|---|
| 5857 | t = str(s) |
|---|
| 5858 | _sig_str('evaluating PARI string') |
|---|
| 5859 | g = gp_read_str(t) |
|---|
| 5860 | return self.new_gen(g) |
|---|
| 5861 | |
|---|
| 5862 | cdef _coerce_c_impl(self, x): |
|---|
| 5863 | """ |
|---|
| 5864 | Implicit canonical coercion into a PARI object. |
|---|
| 5865 | """ |
|---|
| 5866 | try: |
|---|
| 5867 | return self(x) |
|---|
| 5868 | except (TypeError, AttributeError): |
|---|
| 5869 | raise TypeError, "no canonical coercion of %s into PARI"%x |
|---|
| 5870 | if isinstance(x, gen): |
|---|
| 5871 | return x |
|---|
| 5872 | raise TypeError, "x must be a PARI object" |
|---|
| 5873 | |
|---|
| 5874 | cdef _an_element_c_impl(self): # override this in SageX |
|---|
| 5875 | return self.ZERO |
|---|
| 5876 | |
|---|
| 5877 | def new_with_prec(self, s, long precision=0): |
|---|
| 5878 | r""" |
|---|
| 5879 | pari.new_with_bits_prec(self, s, precision) creates s as a PARI gen |
|---|
| 5880 | with at least \code{precision} decimal \emph{digits} of precision. |
|---|
| 5881 | """ |
|---|
| 5882 | global prec |
|---|
| 5883 | cdef unsigned long old_prec |
|---|
| 5884 | old_prec = prec |
|---|
| 5885 | if not precision: |
|---|
| 5886 | precision = prec |
|---|
| 5887 | self.set_real_precision(precision) |
|---|
| 5888 | x = self(s) |
|---|
| 5889 | self.set_real_precision(old_prec) |
|---|
| 5890 | return x |
|---|
| 5891 | |
|---|
| 5892 | def new_with_bits_prec(self, s, long precision=0): |
|---|
| 5893 | r""" |
|---|
| 5894 | pari.new_with_bits_prec(self, s, precision) creates s as a PARI gen |
|---|
| 5895 | with (at most) precision \emph{bits} of precision. |
|---|
| 5896 | """ |
|---|
| 5897 | global prec |
|---|
| 5898 | |
|---|
| 5899 | cdef unsigned long old_prec |
|---|
| 5900 | old_prec = prec |
|---|
| 5901 | precision = long(precision / 3.4)+1 # be safe, since log_2(10) = 3.3219280948873626 |
|---|
| 5902 | if not precision: |
|---|
| 5903 | precision = prec |
|---|
| 5904 | self.set_real_precision(precision) |
|---|
| 5905 | x = self(s) |
|---|
| 5906 | self.set_real_precision(old_prec) |
|---|
| 5907 | return x |
|---|
| 5908 | |
|---|
| 5909 | |
|---|
| 5910 | |
|---|
| 5911 | cdef int get_var(self, v): |
|---|
| 5912 | """ |
|---|
| 5913 | Converts a Python string into a PARI variable reference number. |
|---|
| 5914 | Or if v = -1, returns -1. |
|---|
| 5915 | """ |
|---|
| 5916 | if v != -1: |
|---|
| 5917 | s = str(v) |
|---|
| 5918 | return fetch_user_var(s) |
|---|
| 5919 | return -1 |
|---|
| 5920 | |
|---|
| 5921 | |
|---|
| 5922 | ############################################################ |
|---|
| 5923 | # conversion between GEN and string types |
|---|
| 5924 | # Note that string --> GEN evaluates the string in PARI, |
|---|
| 5925 | # where GEN_to_str returns a Python string. |
|---|
| 5926 | ############################################################ |
|---|
| 5927 | cdef object GEN_to_str(self, GEN g): |
|---|
| 5928 | cdef char* c |
|---|
| 5929 | cdef int n |
|---|
| 5930 | _sig_off |
|---|
| 5931 | _sig_on |
|---|
| 5932 | c = GENtostr(g) |
|---|
| 5933 | _sig_off |
|---|
| 5934 | s = str(c) |
|---|
| 5935 | free(c) |
|---|
| 5936 | return s |
|---|
| 5937 | |
|---|
| 5938 | |
|---|
| 5939 | ############################################################ |
|---|
| 5940 | # Initialization |
|---|
| 5941 | ############################################################ |
|---|
| 5942 | |
|---|
| 5943 | def allocatemem(self, s=0, silent=False): |
|---|
| 5944 | r""" |
|---|
| 5945 | Double the \emph{PARI} stack. |
|---|
| 5946 | """ |
|---|
| 5947 | if s == 0 and not silent: |
|---|
| 5948 | print "Doubling the PARI stack." |
|---|
| 5949 | s = int(s) |
|---|
| 5950 | cdef size_t a = s |
|---|
| 5951 | if int(a) != s: |
|---|
| 5952 | raise ValueError, "s must be nonnegative and not too big." |
|---|
| 5953 | init_stack(s) |
|---|
| 5954 | |
|---|
| 5955 | def pari_version(self): |
|---|
| 5956 | return str(PARIVERSION) |
|---|
| 5957 | |
|---|
| 5958 | def init_primes(self, _M): |
|---|
| 5959 | """ |
|---|
| 5960 | Recompute the primes table including at least all primes up to |
|---|
| 5961 | M (but possibly more). |
|---|
| 5962 | |
|---|
| 5963 | EXAMPLES: |
|---|
| 5964 | sage: pari.init_primes(200000) |
|---|
| 5965 | """ |
|---|
| 5966 | cdef unsigned long M |
|---|
| 5967 | M = _M |
|---|
| 5968 | global diffptr, num_primes |
|---|
| 5969 | if M <= num_primes: |
|---|
| 5970 | return |
|---|
| 5971 | #if not silent: |
|---|
| 5972 | # print "Extending PARI prime table up to %s"%M |
|---|
| 5973 | free(<void*> diffptr) |
|---|
| 5974 | num_primes = M |
|---|
| 5975 | diffptr = initprimes(M) |
|---|
| 5976 | |
|---|
| 5977 | |
|---|
| 5978 | ############################################## |
|---|
| 5979 | ## Support for GP Scripts |
|---|
| 5980 | ############################################## |
|---|
| 5981 | |
|---|
| 5982 | |
|---|
| 5983 | def read(self, filename): |
|---|
| 5984 | r""" |
|---|
| 5985 | Read a script from the named filename into the interpreter, where |
|---|
| 5986 | s is a string. The functions defined in the script are then |
|---|
| 5987 | available for use from SAGE/PARI. |
|---|
| 5988 | |
|---|
| 5989 | EXAMPLE: |
|---|
| 5990 | |
|---|
| 5991 | If foo.gp is a script that contains |
|---|
| 5992 | \begin{verbatim} |
|---|
| 5993 | {foo(n) = |
|---|
| 5994 | n^2 |
|---|
| 5995 | } |
|---|
| 5996 | \end{verbatim} |
|---|
| 5997 | and you type \code{read("foo.gp")}, then the command |
|---|
| 5998 | \code{pari("foo(12)")} will create the Python/PARI gen which |
|---|
| 5999 | is the integer 144. |
|---|
| 6000 | |
|---|
| 6001 | CONSTRAINTS: |
|---|
| 6002 | The PARI script must *not* contain the following function calls: |
|---|
| 6003 | |
|---|
| 6004 | print, default, ??? (please report any others that cause trouble) |
|---|
| 6005 | """ |
|---|
| 6006 | F = open(filename).read() |
|---|
| 6007 | while True: |
|---|
| 6008 | i = F.find("}") |
|---|
| 6009 | if i == -1: |
|---|
| 6010 | _read_script(F) |
|---|
| 6011 | break |
|---|
| 6012 | s = F[:i+1] |
|---|
| 6013 | _read_script(s) |
|---|
| 6014 | F = F[i+1:] |
|---|
| 6015 | return |
|---|
| 6016 | |
|---|
| 6017 | ############################################## |
|---|
| 6018 | |
|---|
| 6019 | def prime_list(self, long n): |
|---|
| 6020 | """ |
|---|
| 6021 | prime_list(n): returns list of the first n primes |
|---|
| 6022 | |
|---|
| 6023 | To extend the table of primes use pari.init_primes(M). |
|---|
| 6024 | |
|---|
| 6025 | INPUT: |
|---|
| 6026 | n -- C long |
|---|
| 6027 | OUTPUT: |
|---|
| 6028 | gen -- PARI list of first n primes |
|---|
| 6029 | |
|---|
| 6030 | EXAMPLES: |
|---|
| 6031 | sage: pari.prime_list(0) |
|---|
| 6032 | [] |
|---|
| 6033 | sage: pari.prime_list(-1) |
|---|
| 6034 | [] |
|---|
| 6035 | sage: pari.prime_list(3) |
|---|
| 6036 | [2, 3, 5] |
|---|
| 6037 | sage: pari.prime_list(10) |
|---|
| 6038 | [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] |
|---|
| 6039 | sage: pari.prime_list(20) |
|---|
| 6040 | [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] |
|---|
| 6041 | sage: len(pari.prime_list(1000)) |
|---|
| 6042 | 1000 |
|---|
| 6043 | """ |
|---|
| 6044 | if n >= 2: |
|---|
| 6045 | self.nth_prime(n) |
|---|
| 6046 | _sig_on |
|---|
| 6047 | return self.new_gen(primes(n)) |
|---|
| 6048 | |
|---|
| 6049 | def primes_up_to_n(self, long n): |
|---|
| 6050 | """ |
|---|
| 6051 | Return the primes <= n as a pari list. |
|---|
| 6052 | """ |
|---|
| 6053 | if n <= 1: |
|---|
| 6054 | return pari([]) |
|---|
| 6055 | self.init_primes(n+1) |
|---|
| 6056 | return self.prime_list(pari(n).primepi()) |
|---|
| 6057 | |
|---|
| 6058 | ## cdef long k |
|---|
| 6059 | ## k = (n+10)/math.log(n) |
|---|
| 6060 | ## p = 2 |
|---|
| 6061 | ## while p <= n: |
|---|
| 6062 | ## p = self.nth_prime(k) |
|---|
| 6063 | ## k = 2 |
|---|
| 6064 | ## v = self.prime_list(k) |
|---|
| 6065 | ## return v[:pari(n).primepi()] |
|---|
| 6066 | |
|---|
| 6067 | def __nth_prime(self, long n): |
|---|
| 6068 | """ |
|---|
| 6069 | nth_prime(n): returns the n-th prime, where n is a C-int |
|---|
| 6070 | """ |
|---|
| 6071 | global num_primes |
|---|
| 6072 | |
|---|
| 6073 | if n <= 0: |
|---|
| 6074 | raise ArithmeticError, "nth prime meaningless for negative n (=%s)"%n |
|---|
| 6075 | cdef GEN g |
|---|
| 6076 | _sig_on |
|---|
| 6077 | g = prime(n) |
|---|
| 6078 | return self.new_gen(g) |
|---|
| 6079 | |
|---|
| 6080 | |
|---|
| 6081 | def nth_prime(self, long n): |
|---|
| 6082 | try: |
|---|
| 6083 | return self.__nth_prime(n) |
|---|
| 6084 | except PariError: |
|---|
| 6085 | self.init_primes(max(2*num_primes,20*n)) |
|---|
| 6086 | return self.nth_prime(n) |
|---|
| 6087 | |
|---|
| 6088 | def euler(self): |
|---|
| 6089 | """ |
|---|
| 6090 | Return Euler's constant to the current real precision. |
|---|
| 6091 | |
|---|
| 6092 | EXAMPLES: |
|---|
| 6093 | sage: pari.euler() |
|---|
| 6094 | 0.5772156649015328606065120901 # 32-bit |
|---|
| 6095 | 0.57721566490153286060651209008240243104 # 64-bit |
|---|
| 6096 | sage: orig = pari.get_real_precision(); orig |
|---|
| 6097 | 28 # 32-bit |
|---|
| 6098 | 38 # 64-bit |
|---|
| 6099 | sage: _ = pari.set_real_precision(50) |
|---|
| 6100 | sage: pari.euler() |
|---|
| 6101 | 0.57721566490153286060651209008240243104215933593992 |
|---|
| 6102 | |
|---|
| 6103 | We restore precision to the default. |
|---|
| 6104 | sage: pari.set_real_precision(orig) |
|---|
| 6105 | 50 |
|---|
| 6106 | |
|---|
| 6107 | Euler is returned to the original precision: |
|---|
| 6108 | sage: pari.euler() |
|---|
| 6109 | 0.5772156649015328606065120901 # 32-bit |
|---|
| 6110 | 0.57721566490153286060651209008240243104 # 64-bit |
|---|
| 6111 | """ |
|---|
| 6112 | if not precision: |
|---|
| 6113 | precision = prec |
|---|
| 6114 | _sig_on |
|---|
| 6115 | consteuler(precision) |
|---|
| 6116 | return self.new_gen(geuler) |
|---|
| 6117 | |
|---|
| 6118 | def pi(self): |
|---|
| 6119 | """ |
|---|
| 6120 | Return the value of the constant pi = 3.1415 to the current |
|---|
| 6121 | real precision. |
|---|
| 6122 | |
|---|
| 6123 | EXAMPLES: |
|---|
| 6124 | sage: pari.pi() |
|---|
| 6125 | 3.141592653589793238462643383 # 32-bit |
|---|
| 6126 | 3.1415926535897932384626433832795028842 # 64-bit |
|---|
| 6127 | sage: orig_prec = pari.set_real_precision(5) |
|---|
| 6128 | sage: pari.pi() |
|---|
| 6129 | 3.1416 |
|---|
| 6130 | |
|---|
| 6131 | sage: pari.get_real_precision() |
|---|
| 6132 | 5 |
|---|
| 6133 | sage: _ = pari.set_real_precision(40) |
|---|
| 6134 | sage: pari.pi() |
|---|
| 6135 | 3.141592653589793238462643383279502884197 |
|---|
| 6136 | |
|---|
| 6137 | |
|---|
| 6138 | We restore precision to the default. |
|---|
| 6139 | sage: _ = pari.set_real_precision(orig_prec) |
|---|
| 6140 | |
|---|
| 6141 | Note that pi is now computed to the original precision: |
|---|
| 6142 | |
|---|
| 6143 | sage: pari.pi() |
|---|
| 6144 | 3.141592653589793238462643383 # 32-bit |
|---|
| 6145 | 3.1415926535897932384626433832795028842 # 64-bit |
|---|
| 6146 | """ |
|---|
| 6147 | if not precision: |
|---|
| 6148 | precision = prec |
|---|
| 6149 | _sig_on |
|---|
| 6150 | constpi(precision) |
|---|
| 6151 | return self.new_gen(gpi) |
|---|
| 6152 | |
|---|
| 6153 | def pollegendre(self, long n, v=-1): |
|---|
| 6154 | """ |
|---|
| 6155 | pollegendre(n,{v=x}): legendre polynomial of degree n (n |
|---|
| 6156 | C-integer), in variable v |
|---|
| 6157 | """ |
|---|
| 6158 | _sig_on |
|---|
| 6159 | return self.new_gen(legendre(n, self.get_var(v))) |
|---|
| 6160 | |
|---|
| 6161 | def poltchebi(self, long n, v=-1): |
|---|
| 6162 | _sig_on |
|---|
| 6163 | return self.new_gen(tchebi(n, self.get_var(v))) |
|---|
| 6164 | |
|---|
| 6165 | def factorial(self, long n): |
|---|
| 6166 | """ |
|---|
| 6167 | Return the factorial of the integer n as a PARI gen. |
|---|
| 6168 | """ |
|---|
| 6169 | _sig_on |
|---|
| 6170 | return self.new_gen(mpfact(n)) |
|---|
| 6171 | |
|---|
| 6172 | def polcyclo(self, long n, v=-1): |
|---|
| 6173 | _sig_on |
|---|
| 6174 | return self.new_gen(cyclo(n, self.get_var(v))) |
|---|
| 6175 | |
|---|
| 6176 | def polsubcyclo(self, long n, long d, v=-1): |
|---|
| 6177 | _sig_on |
|---|
| 6178 | return self.new_gen(polsubcyclo(n, d, self.get_var(v))) |
|---|
| 6179 | |
|---|
| 6180 | def polzagier(self, long n, long m): |
|---|
| 6181 | _sig_on |
|---|
| 6182 | return self.new_gen(polzag(n, m)) |
|---|
| 6183 | |
|---|
| 6184 | def listcreate(self, long n): |
|---|
| 6185 | _sig_on |
|---|
| 6186 | return self.new_gen(listcreate(n)) |
|---|
| 6187 | |
|---|
| 6188 | def vector(self, long n, entries=None): |
|---|
| 6189 | """ |
|---|
| 6190 | vector(long n, entries=None): |
|---|
| 6191 | Create and return the length n PARI vector with given list of entries. |
|---|
| 6192 | """ |
|---|
| 6193 | cdef gen v |
|---|
| 6194 | _sig_on |
|---|
| 6195 | v = self.new_gen(zerovec(n)) |
|---|
| 6196 | if entries is not None: |
|---|
| 6197 | if len(entries) != n: |
|---|
| 6198 | raise IndexError, "length of entries (=%s) must equal n (=%s)"%\ |
|---|
| 6199 | (len(entries), n) |
|---|
| 6200 | for i, x in enumerate(entries): |
|---|
| 6201 | v[i] = x |
|---|
| 6202 | return v |
|---|
| 6203 | |
|---|
| 6204 | def matrix(self, long m, long n, entries=None): |
|---|
| 6205 | """ |
|---|
| 6206 | matrix(long m, long n, entries=None): |
|---|
| 6207 | Create and return the m x n PARI matrix with given list of entries. |
|---|
| 6208 | """ |
|---|
| 6209 | cdef int i, j, k |
|---|
| 6210 | cdef gen A |
|---|
| 6211 | _sig_on |
|---|
| 6212 | A = self.new_gen(zeromat(m,n)).Mat() |
|---|
| 6213 | if entries != None: |
|---|
| 6214 | if len(entries) != m*n: |
|---|
| 6215 | raise IndexError, "len of entries (=%s) must be %s*%s=%s"%(len(entries),m,n,m*n) |
|---|
| 6216 | k = 0 |
|---|
| 6217 | for i from 0 <= i < m: |
|---|
| 6218 | for j from 0 <= j < n: |
|---|
| 6219 | A[i,j] = entries[k] |
|---|
| 6220 | k = k + 1 |
|---|
| 6221 | return A |
|---|
| 6222 | |
|---|
| 6223 | def finitefield_init(self, p, long n, var=-1): |
|---|
| 6224 | """ |
|---|
| 6225 | finitefield_init(p, long n, var="x"): Return a polynomial f(x) so |
|---|
| 6226 | that the extension of F_p of degree n is k = F_p[x]/(f). Moreover, |
|---|
| 6227 | the element x (mod f) of k is a generator for the multiplicative |
|---|
| 6228 | group of k. |
|---|
| 6229 | |
|---|
| 6230 | INPUT: |
|---|
| 6231 | p -- int, a prime number |
|---|
| 6232 | n -- int, positive integer |
|---|
| 6233 | var -- str, default to "x", but could be any pari variable. |
|---|
| 6234 | OUTPUT: |
|---|
| 6235 | pari polynomial mod p -- defines field |
|---|
| 6236 | EXAMPLES: |
|---|
| 6237 | sage: pari.finitefield_init(97,1) |
|---|
| 6238 | Mod(1, 97)*x + Mod(92, 97) |
|---|
| 6239 | |
|---|
| 6240 | The last entry in each of the following two lines is |
|---|
| 6241 | determined by a random algorithm. |
|---|
| 6242 | sage: pari.finitefield_init(7,2) # random |
|---|
| 6243 | Mod(1, 7)*x^2 + Mod(6, 7)*x + Mod(3, 7) |
|---|
| 6244 | sage: pari.finitefield_init(2,3) # random |
|---|
| 6245 | Mod(1, 2)*x^3 + Mod(1, 2)*x^2 + Mod(1, 2) |
|---|
| 6246 | """ |
|---|
| 6247 | cdef gen _p, _f2, s |
|---|
| 6248 | cdef int err |
|---|
| 6249 | cdef long x |
|---|
| 6250 | cdef GEN v, g |
|---|
| 6251 | _p = self(int(p)) |
|---|
| 6252 | if n < 1: |
|---|
| 6253 | raise ArithmeticError, "Degree n (=%s) must be at least 1."%n |
|---|
| 6254 | if _p < 2 or not _p.isprime(): |
|---|
| 6255 | raise ArithmeticError, "Prime p (=%s) must be prime."%_p |
|---|
| 6256 | x = self.get_var(var) |
|---|
| 6257 | if n == 1: |
|---|
| 6258 | _sig_on |
|---|
| 6259 | return self.new_gen(ffinit(_p.g, n, x)) - _p.znprimroot() |
|---|
| 6260 | _sig_on |
|---|
| 6261 | f = self.new_gen(ffinit(_p.g, n, x)) |
|---|
| 6262 | _f2 = f.lift() |
|---|
| 6263 | _sig_on |
|---|
| 6264 | g = FpXQ_gener(_f2.g, _p.g) |
|---|
| 6265 | s = self.new_gen(g)*self.ONE.Mod(p) |
|---|
| 6266 | return s.Mod(f).charpoly(var) |
|---|
| 6267 | |
|---|
| 6268 | ############################################## |
|---|
| 6269 | # Used in integer factorization -- must be done |
|---|
| 6270 | # after the pari_instance creation above: |
|---|
| 6271 | |
|---|
| 6272 | cdef gen _tmp = P.new_gen(gp_read_str('1000000000000000')) |
|---|
| 6273 | cdef GEN ten_to_15 = _tmp.g |
|---|
| 6274 | |
|---|
| 6275 | ############################################## |
|---|
| 6276 | |
|---|
| 6277 | |
|---|
| 6278 | |
|---|
| 6279 | cdef int init_stack(size_t size) except -1: |
|---|
| 6280 | cdef size_t s |
|---|
| 6281 | cdef pari_sp cur_stack_size |
|---|
| 6282 | |
|---|
| 6283 | global top, bot, avma, stack_avma, mytop |
|---|
| 6284 | |
|---|
| 6285 | |
|---|
| 6286 | err = False # whether or not a memory allocation error occured. |
|---|
| 6287 | |
|---|
| 6288 | |
|---|
| 6289 | # delete this if get core dumps and change the 2* to a 1* below. |
|---|
| 6290 | if bot: |
|---|
| 6291 | sage_free(<void*>bot) |
|---|
| 6292 | |
|---|
| 6293 | prev_stack_size = top - bot |
|---|
| 6294 | if size == 0: |
|---|
| 6295 | size = 2*(top-bot) |
|---|
| 6296 | |
|---|
| 6297 | # Decide on size |
|---|
| 6298 | s = fix_size(size) |
|---|
| 6299 | |
|---|
| 6300 | # Alocate memory for new stack using Python's memory allocator. |
|---|
| 6301 | # As explained in the python/C api reference, using this instead |
|---|
| 6302 | # of malloc is much better (and more platform independent, etc.) |
|---|
| 6303 | bot = <pari_sp> sage_malloc(s) |
|---|
| 6304 | |
|---|
| 6305 | while not bot: |
|---|
| 6306 | err = True |
|---|
| 6307 | s = fix_size(prev_stack_size) |
|---|
| 6308 | bot = <pari_sp> sage_malloc(s) |
|---|
| 6309 | if not bot: |
|---|
| 6310 | prev_stack_size /= 2 |
|---|
| 6311 | |
|---|
| 6312 | #endif |
|---|
| 6313 | top = bot + s |
|---|
| 6314 | mytop = top |
|---|
| 6315 | avma = top |
|---|
| 6316 | stack_avma = avma |
|---|
| 6317 | |
|---|
| 6318 | if err: |
|---|
| 6319 | raise MemoryError, "Unable to allocate %s bytes memory for PARI."%size |
|---|
| 6320 | |
|---|
| 6321 | |
|---|
| 6322 | def _my_sigpipe(signum, frame): |
|---|
| 6323 | # If I do anything, it messes up Ipython's pager. |
|---|
| 6324 | pass |
|---|
| 6325 | |
|---|
| 6326 | cdef size_t fix_size(size_t a): |
|---|
| 6327 | cdef size_t b |
|---|
| 6328 | b = a - (a & (BYTES_IN_LONG-1)) # sizeof(long) | b <= a |
|---|
| 6329 | if b < 1024: |
|---|
| 6330 | b = 1024 |
|---|
| 6331 | return b |
|---|
| 6332 | |
|---|
| 6333 | cdef GEN deepcopy_to_python_heap(GEN x, pari_sp* address): |
|---|
| 6334 | cdef size_t s |
|---|
| 6335 | cdef pari_sp tmp_bot, tmp_top, tmp_avma |
|---|
| 6336 | global avma, bot, top, mytop |
|---|
| 6337 | cdef GEN h |
|---|
| 6338 | |
|---|
| 6339 | tmp_top = top |
|---|
| 6340 | tmp_bot = bot |
|---|
| 6341 | tmp_avma = avma |
|---|
| 6342 | |
|---|
| 6343 | h = forcecopy(x) |
|---|
| 6344 | s = <size_t> (tmp_avma - avma) |
|---|
| 6345 | |
|---|
| 6346 | #print "Allocating %s bytes for PARI/Python object"%(<long> s) |
|---|
| 6347 | bot = <pari_sp> sage_malloc(s) |
|---|
| 6348 | top = bot + s |
|---|
| 6349 | avma = top |
|---|
| 6350 | h = forcecopy(x) |
|---|
| 6351 | address[0] = bot |
|---|
| 6352 | |
|---|
| 6353 | # Restore the stack to how it was before x was created. |
|---|
| 6354 | top = tmp_top |
|---|
| 6355 | bot = tmp_bot |
|---|
| 6356 | avma = tmp_avma |
|---|
| 6357 | return h |
|---|
| 6358 | |
|---|
| 6359 | # The first one makes a separate copy on the heap, so the stack |
|---|
| 6360 | # won't overflow -- but this costs more time... |
|---|
| 6361 | cdef gen _new_gen (GEN x): |
|---|
| 6362 | cdef GEN h |
|---|
| 6363 | cdef pari_sp address |
|---|
| 6364 | cdef gen y |
|---|
| 6365 | h = deepcopy_to_python_heap(x, &address) |
|---|
| 6366 | y = PY_NEW(gen) |
|---|
| 6367 | y.init(h, address) |
|---|
| 6368 | return y |
|---|
| 6369 | |
|---|
| 6370 | cdef gen xxx_new_gen(GEN x): |
|---|
| 6371 | cdef gen y |
|---|
| 6372 | y = PY_NEW(gen) |
|---|
| 6373 | y.init(x, 0) |
|---|
| 6374 | _sig_off |
|---|
| 6375 | return y |
|---|
| 6376 | |
|---|
| 6377 | def min(x,y): |
|---|
| 6378 | """ |
|---|
| 6379 | min(x,y): Return the minimum of x and y. |
|---|
| 6380 | """ |
|---|
| 6381 | if x <= y: |
|---|
| 6382 | return x |
|---|
| 6383 | return y |
|---|
| 6384 | |
|---|
| 6385 | def max(x,y): |
|---|
| 6386 | """ |
|---|
| 6387 | max(x,y): Return the maximum of x and y. |
|---|
| 6388 | """ |
|---|
| 6389 | if x >= y: |
|---|
| 6390 | return x |
|---|
| 6391 | return y |
|---|
| 6392 | |
|---|
| 6393 | cdef int _read_script(char* s) except -1: |
|---|
| 6394 | _sig_on |
|---|
| 6395 | gp_read_str(s) |
|---|
| 6396 | _sig_off |
|---|
| 6397 | |
|---|
| 6398 | # We set top to avma, so the script's affects won't be undone |
|---|
| 6399 | # when we call new_gen again. |
|---|
| 6400 | global mytop, top, avma |
|---|
| 6401 | mytop = avma |
|---|
| 6402 | return 0 |
|---|
| 6403 | |
|---|
| 6404 | |
|---|
| 6405 | ####################### |
|---|
| 6406 | # Base gen class |
|---|
| 6407 | ####################### |
|---|
| 6408 | |
|---|
| 6409 | |
|---|
| 6410 | cdef extern from "pari/pari.h": |
|---|
| 6411 | char *errmessage[] |
|---|
| 6412 | int user |
|---|
| 6413 | int errpile |
|---|
| 6414 | int noer |
|---|
| 6415 | |
|---|
| 6416 | cdef extern from "misc.h": |
|---|
| 6417 | int factorint_withproof_sage(GEN* ans, GEN x, GEN cutoff) |
|---|
| 6418 | int gcmp_sage(GEN x, GEN y) |
|---|
| 6419 | |
|---|
| 6420 | def __errmessage(d): |
|---|
| 6421 | if d <= 0 or d > noer: |
|---|
| 6422 | return "unknown" |
|---|
| 6423 | return errmessage[d] |
|---|
| 6424 | |
|---|
| 6425 | # FIXME: we derive PariError from RuntimeError, for backward |
|---|
| 6426 | # compatibility with code that catches the latter. Once this is |
|---|
| 6427 | # in production, we should change the base class to StandardError. |
|---|
| 6428 | from exceptions import RuntimeError |
|---|
| 6429 | |
|---|
| 6430 | # can we have "cdef class" ? |
|---|
| 6431 | # because of the inheritance, need to somehow "import" the builtin |
|---|
| 6432 | # exception class... |
|---|
| 6433 | class PariError (RuntimeError): |
|---|
| 6434 | |
|---|
| 6435 | errmessage = staticmethod(__errmessage) |
|---|
| 6436 | |
|---|
| 6437 | def __repr__(self): |
|---|
| 6438 | return "PariError(%d)"%self.args[0] |
|---|
| 6439 | |
|---|
| 6440 | def __str__(self): |
|---|
| 6441 | return "%s (%d)"%(self.errmessage(self.args[0]),self.args[0]) |
|---|
| 6442 | |
|---|
| 6443 | # We expose a trap function to C. |
|---|
| 6444 | # If this function returns without raising an exception, |
|---|
| 6445 | # the code is retried. |
|---|
| 6446 | # This is a proof-of-concept example. |
|---|
| 6447 | # THE TRY CODE IS NOT REENTRANT -- NO CALLS TO PARI FROM HERE !!! |
|---|
| 6448 | # - Gonzalo Tornario |
|---|
| 6449 | |
|---|
| 6450 | cdef void _pari_trap "_pari_trap" (long errno, long retries) except *: |
|---|
| 6451 | """ |
|---|
| 6452 | TESTS: |
|---|
| 6453 | sage: v = pari.listcreate(2^62 if is_64_bit else 2^30) |
|---|
| 6454 | Traceback (most recent call last): |
|---|
| 6455 | ... |
|---|
| 6456 | MemoryError: Unable to allocate ... bytes memory for PARI. |
|---|
| 6457 | """ |
|---|
| 6458 | _sig_off |
|---|
| 6459 | if retries > 100: |
|---|
| 6460 | raise RuntimeError, "_pari_trap recursion too deep" |
|---|
| 6461 | if errno == errpile: |
|---|
| 6462 | P.allocatemem(silent=True) |
|---|
| 6463 | |
|---|
| 6464 | #raise RuntimeError, "The PARI stack overflowed. It has automatically been doubled using pari.allocatemem(). Please retry your computation, possibly after you manually call pari.allocatemem() a few times." |
|---|
| 6465 | #print "Stack overflow! (%d retries so far)"%retries |
|---|
| 6466 | #print " enlarge the stack." |
|---|
| 6467 | |
|---|
| 6468 | elif errno == user: |
|---|
| 6469 | |
|---|
| 6470 | raise Exception, "PARI user exception" |
|---|
| 6471 | |
|---|
| 6472 | else: |
|---|
| 6473 | |
|---|
| 6474 | raise PariError, errno |
|---|
| 6475 | |
|---|
| 6476 | |
|---|
| 6477 | |
|---|
| 6478 | def vecsmall_to_intlist(gen v): |
|---|
| 6479 | """ |
|---|
| 6480 | INPUT: |
|---|
| 6481 | v -- a gen of type Vecsmall |
|---|
| 6482 | OUTPUT: |
|---|
| 6483 | a Python list of Python ints |
|---|
| 6484 | """ |
|---|
| 6485 | if typ(v.g) != t_VECSMALL: |
|---|
| 6486 | raise TypeError, "input v must be of type vecsmall (use v.Vecsmall())" |
|---|
| 6487 | return [v.g[k+1] for k in range(glength(v.g))] |
|---|
| 6488 | |
|---|
| 6489 | |
|---|
| 6490 | |
|---|
| 6491 | cdef _factor_int_when_pari_factor_failed(x, failed_factorization): |
|---|
| 6492 | """ |
|---|
| 6493 | This is called by factor when PARI's factor tried to factor, got |
|---|
| 6494 | the failed_factorization, and it turns out that one of the factors |
|---|
| 6495 | in there is not proved prime. At this point, we don't care too |
|---|
| 6496 | much about speed (so don't write everything below using the PARI C |
|---|
| 6497 | library), since the probability this function ever gets called is |
|---|
| 6498 | infinitesimal. (That said, we of course did test this function by |
|---|
| 6499 | forcing a fake failure in the code in misc.h.) |
|---|
| 6500 | """ |
|---|
| 6501 | P = failed_factorization[0] # 'primes' |
|---|
| 6502 | E = failed_factorization[1] # exponents |
|---|
| 6503 | if len(P) == 1 and E[0] == 1: |
|---|
| 6504 | # Major problem -- factor can't split the integer at all, but it's composite. We're stuffed. |
|---|
| 6505 | print "BIG WARNING: The number %s wasn't split at all by PARI, but it's definitely composite."%(P[0]) |
|---|
| 6506 | print "This is probably an infinite loop..." |
|---|
| 6507 | w = [] |
|---|
| 6508 | for i in range(len(P)): |
|---|
| 6509 | p = P[i] |
|---|
| 6510 | e = E[i] |
|---|
| 6511 | if not p.isprime(): |
|---|
| 6512 | # Try to factor further -- assume this works. |
|---|
| 6513 | F = p.factor(proof=True) |
|---|
| 6514 | for j in range(len(F[0])): |
|---|
| 6515 | w.append((F[0][j], F[1][j])) |
|---|
| 6516 | else: |
|---|
| 6517 | w.append((p, e)) |
|---|
| 6518 | m = pari.matrix(len(w), 2) |
|---|
| 6519 | for i in range(len(w)): |
|---|
| 6520 | m[i,0] = w[i][0] |
|---|
| 6521 | m[i,1] = w[i][1] |
|---|
| 6522 | return m |
|---|
| 6523 | |
|---|