-
# HG changeset patch
# User Simon King <simon.king@uni-jena.de>
# Date 1305801904 -7200
# Node ID d39a4e5e0267dc00fa94b2df86be784b40e1904e
# Parent 216c066ba7528d60ef6439664addd703d9670480
#9944: Clean up coercion of polynomial rings (dense versus sparse etc).
Improve performance of _new_constant_poly by using specialised implementations.
Additional minor fixes.
diff -r 216c066ba752 sage/categories/category.py
a
|
b
|
|
989 | 989 | Category of hom sets in Category of sets |
990 | 990 | |
991 | 991 | """ |
992 | | if hasattr(self, "HomCategory"): |
| 992 | try: #if hasattr(self, "HomCategory"): |
993 | 993 | return self.HomCategory(self) |
994 | | else: |
| 994 | except AttributeError: |
995 | 995 | return Category.join((category.hom_category() for category in self.super_categories())) |
996 | 996 | |
997 | 997 | def abstract_category(self): |
-
diff -r 216c066ba752 sage/categories/pushout.py
a
|
b
|
|
565 | 565 | """ |
566 | 566 | Construction functor for univariate polynomial rings. |
567 | 567 | |
568 | | EXAMPLE: |
| 568 | EXAMPLE:: |
569 | 569 | |
570 | 570 | sage: P = ZZ['t'].construction()[0] |
571 | 571 | sage: P(GF(3)) |
… |
… |
|
577 | 577 | sage: P(f)((x+y)*P(R).0) |
578 | 578 | (-x + y)*t |
579 | 579 | |
| 580 | By trac ticket #9944, the construction functor distinguishes sparse and |
| 581 | dense polynomial rings. Before, the following example failed:: |
| 582 | |
| 583 | sage: R.<x> = PolynomialRing(GF(5), sparse=True) |
| 584 | sage: F,B = R.construction() |
| 585 | sage: F(B) is R |
| 586 | True |
| 587 | sage: S.<x> = PolynomialRing(ZZ) |
| 588 | sage: R.has_coerce_map_from(S) |
| 589 | False |
| 590 | sage: S.has_coerce_map_from(R) |
| 591 | False |
| 592 | sage: S.0 + R.0 |
| 593 | 2*x |
| 594 | sage: (S.0 + R.0).parent() |
| 595 | Univariate Polynomial Ring in x over Finite Field of size 5 |
| 596 | sage: (S.0 + R.0).parent().is_sparse() |
| 597 | False |
| 598 | |
580 | 599 | """ |
581 | 600 | rank = 9 |
582 | 601 | |
583 | | def __init__(self, var, multi_variate=False): |
| 602 | def __init__(self, var, multi_variate=False, sparse=False): |
584 | 603 | """ |
585 | 604 | TESTS:: |
586 | 605 | |
… |
… |
|
603 | 622 | Functor.__init__(self, Rings(), Rings()) |
604 | 623 | self.var = var |
605 | 624 | self.multi_variate = multi_variate |
| 625 | self.sparse = sparse |
606 | 626 | |
607 | 627 | def _apply_functor(self, R): |
608 | 628 | """ |
… |
… |
|
616 | 636 | |
617 | 637 | """ |
618 | 638 | from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing |
619 | | return PolynomialRing(R, self.var) |
| 639 | return PolynomialRing(R, self.var, sparse=self.sparse) |
620 | 640 | |
621 | 641 | def __cmp__(self, other): |
622 | 642 | """ |
… |
… |
|
667 | 687 | if isinstance(other, MultiPolynomialFunctor): |
668 | 688 | return other.merge(self) |
669 | 689 | elif self == other: |
670 | | return self |
| 690 | # i.e., they only differ in sparsity |
| 691 | if not self.sparse: |
| 692 | return self |
| 693 | return other |
671 | 694 | else: |
672 | 695 | return None |
673 | 696 | |
… |
… |
|
2244 | 2267 | Q = R.quo(I,names=self.names) |
2245 | 2268 | except IndexError: # That may happen! |
2246 | 2269 | raise CoercionException, "Can not apply this quotient functor to %s"%R |
2247 | | if self.as_field and hasattr(Q, 'field'): |
2248 | | Q = Q.field() |
| 2270 | if self.as_field:# and hasattr(Q, 'field'): |
| 2271 | try: |
| 2272 | Q = Q.field() |
| 2273 | except AttributeError: |
| 2274 | pass |
2249 | 2275 | return Q |
2250 | 2276 | |
2251 | 2277 | def __cmp__(self, other): |
… |
… |
|
2676 | 2702 | sage: F(QQ) # indirect doctest |
2677 | 2703 | Algebraic Field |
2678 | 2704 | """ |
2679 | | if hasattr(R,'construction'): |
| 2705 | try: |
2680 | 2706 | c = R.construction() |
2681 | 2707 | if c is not None and c[0]==self: |
2682 | 2708 | return R |
| 2709 | except AttributeError: |
| 2710 | pass |
2683 | 2711 | return R.algebraic_closure() |
2684 | 2712 | |
2685 | 2713 | def merge(self, other): |
-
diff -r 216c066ba752 sage/modular/cusps.py
a
|
b
|
|
33 | 33 | from sage.structure.element import Element, is_InfinityElement |
34 | 34 | from sage.modular.modsym.p1list import lift_to_sl2z_llong |
35 | 35 | from sage.matrix.all import is_Matrix |
| 36 | from sage.misc.cachefunc import cached_method |
36 | 37 | |
37 | 38 | class Cusps_class(ParentWithBase): |
38 | 39 | """ |
… |
… |
|
148 | 149 | else: |
149 | 150 | return self._coerce_try(x, QQ) |
150 | 151 | |
| 152 | @cached_method |
| 153 | def zero_element(self): |
| 154 | """ |
| 155 | Return the zero cusp. |
| 156 | |
| 157 | NOTE: |
| 158 | |
| 159 | The existence of this method is assumed by some |
| 160 | parts of Sage's coercion model. |
| 161 | |
| 162 | EXAMPLE:: |
| 163 | |
| 164 | sage: Cusps.zero_element() |
| 165 | 0 |
| 166 | |
| 167 | """ |
| 168 | return Cusp(0, parent=self) |
| 169 | |
151 | 170 | Cusps = Cusps_class() |
152 | 171 | |
153 | 172 | |
-
diff -r 216c066ba752 sage/modular/cusps_nf.py
a
|
b
|
|
87 | 87 | from sage.rings.integer_ring import IntegerRing |
88 | 88 | from sage.structure.parent_base import ParentWithBase |
89 | 89 | from sage.structure.element import Element, is_InfinityElement |
| 90 | from sage.misc.cachefunc import cached_method |
90 | 91 | |
91 | 92 | _nfcusps_cache = {} |
92 | 93 | |
… |
… |
|
331 | 332 | |
332 | 333 | def __call__(self, x): |
333 | 334 | """ |
334 | | Coerce x into the set of cusps of a number field. |
| 335 | Convert x into the set of cusps of a number field. |
335 | 336 | |
336 | 337 | EXAMPLES:: |
337 | 338 | |
… |
… |
|
353 | 354 | """ |
354 | 355 | return NFCusp(self.number_field(), x, parent=self) |
355 | 356 | |
| 357 | @cached_method |
| 358 | def zero_element(self): |
| 359 | """ |
| 360 | Return the zero cusp. |
| 361 | |
| 362 | NOTE: |
| 363 | |
| 364 | This method just exists to make some general algorithms work. |
| 365 | It is not intended that the returned cusp is an additive |
| 366 | neutral element. |
| 367 | |
| 368 | EXAMPLE:: |
| 369 | |
| 370 | sage: k.<a> = NumberField(x^2 + 5) |
| 371 | sage: kCusps = NFCusps(k) |
| 372 | sage: kCusps.zero_element() |
| 373 | Cusp [0: 1] of Number Field in a with defining polynomial x^2 + 5 |
| 374 | |
| 375 | """ |
| 376 | return self(0) |
| 377 | |
356 | 378 | def number_field(self): |
357 | 379 | """ |
358 | 380 | Return the number field that this set of cusps is attached to. |
-
diff -r 216c066ba752 sage/modular/overconvergent/genus0.py
a
|
b
|
|
176 | 176 | |
177 | 177 | from sage.matrix.all import matrix, MatrixSpace, diagonal_matrix |
178 | 178 | from sage.misc.misc import verbose |
| 179 | from sage.misc.cachefunc import cached_method |
179 | 180 | from sage.modular.all import (DirichletGroup, trivial_character, EtaProduct, |
180 | 181 | j_invariant_qexp, hecke_operator_on_qexp) |
181 | 182 | from sage.modular.arithgroup.all import (Gamma1, is_Gamma0, is_Gamma1) |
… |
… |
|
621 | 622 | |
622 | 623 | ##################################### |
623 | 624 | # Element construction and coercion # |
| 625 | # (unfortunately not using # |
| 626 | # the new coercion model) # |
624 | 627 | ##################################### |
625 | 628 | |
626 | 629 | def __call__(self, input): |
… |
… |
|
721 | 724 | |
722 | 725 | else: |
723 | 726 | raise TypeError, "Don't know how to create an overconvergent modular form from %s" % input |
724 | | |
| 727 | |
| 728 | @cached_method |
| 729 | def zero_element(self): |
| 730 | """ |
| 731 | Return the zero of this space. |
| 732 | |
| 733 | EXAMPLE:: |
| 734 | |
| 735 | sage: K.<w> = Qp(13).extension(x^2-13); M = OverconvergentModularForms(13, 20, radius=1/2, base_ring=K) |
| 736 | sage: K.zero_element() |
| 737 | 0 |
| 738 | """ |
| 739 | return self(0) |
| 740 | |
725 | 741 | def _coerce_from_ocmf(self, f): |
726 | 742 | r""" |
727 | 743 | Try to convert the overconvergent modular form `f` into an element of self. An error will be raised if this is |
-
diff -r 216c066ba752 sage/modular/overconvergent/weightspace.py
a
|
b
|
|
69 | 69 | from sage.misc.misc import sxrange |
70 | 70 | from sage.rings.padics.padic_generic_element import pAdicGenericElement |
71 | 71 | from sage.misc.misc import verbose |
| 72 | from sage.misc.cachefunc import cached_method |
72 | 73 | import weakref |
73 | 74 | |
74 | 75 | _wscache = {} |
… |
… |
|
198 | 199 | else: |
199 | 200 | return ArbitraryWeight(self, arg1, arg2) |
200 | 201 | |
| 202 | @cached_method |
| 203 | def zero_element(self): |
| 204 | """ |
| 205 | Return the zero of this weight space. |
| 206 | |
| 207 | EXAMPLES:: |
| 208 | |
| 209 | sage: W = pAdicWeightSpace(17) |
| 210 | sage: W.zero_element() |
| 211 | 0 |
| 212 | """ |
| 213 | return self(0) |
| 214 | |
201 | 215 | def prime(self): |
202 | 216 | r""" |
203 | 217 | Return the prime `p` such that this is a `p`-adic weight space. |
-
diff -r 216c066ba752 sage/modules/free_module_homspace.py
a
|
b
|
|
74 | 74 | import sage.modules.free_module_morphism |
75 | 75 | import sage.matrix.all as matrix |
76 | 76 | import free_module_morphism |
| 77 | from inspect import isfunction |
77 | 78 | |
78 | 79 | from matrix_morphism import MatrixMorphism |
79 | 80 | |
… |
… |
|
95 | 96 | def __call__(self, A, check=True): |
96 | 97 | """ |
97 | 98 | INPUT: |
98 | | A -- either a matrix or a list/tuple of images of generators |
99 | | check -- bool (default: True) |
| 99 | |
| 100 | - A -- either a matrix or a list/tuple of images of generators, |
| 101 | or a function returning elements of the codomain for elements |
| 102 | of the domain. |
| 103 | - check -- bool (default: True) |
100 | 104 | |
101 | 105 | If A is a matrix, then it is the matrix of this linear |
102 | 106 | transformation, with respect to the basis for the domain and |
… |
… |
|
104 | 108 | identity morphism. |
105 | 109 | |
106 | 110 | EXAMPLES:: |
| 111 | |
107 | 112 | sage: V = (QQ^3).span_of_basis([[1,1,0],[1,0,2]]) |
108 | 113 | sage: H = V.Hom(V); H |
109 | 114 | Set of Morphisms from ... |
… |
… |
|
119 | 124 | True |
120 | 125 | sage: phi(V.0) == V.1 |
121 | 126 | True |
| 127 | |
| 128 | The following tests against a bug that was fixed in trac |
| 129 | ticket #9944. The method ``zero()`` calls this hom space with |
| 130 | a function, not with a matrix, and that case had previously |
| 131 | not been taken care of:: |
| 132 | |
| 133 | sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ) |
| 134 | sage: V.Hom(V).zero() # indirect doctest |
| 135 | Free module morphism defined by the matrix |
| 136 | [0 0 0] |
| 137 | [0 0 0] |
| 138 | [0 0 0] |
| 139 | Domain: Free module of degree 3 and rank 3 over Integer Ring |
| 140 | Echelon ... |
| 141 | Codomain: Free module of degree 3 and rank 3 over Integer Ring |
| 142 | Echelon ... |
| 143 | |
122 | 144 | """ |
123 | 145 | if not matrix.is_Matrix(A): |
124 | 146 | # Compute the matrix of the morphism that sends the |
125 | 147 | # generators of the domain to the elements of A. |
126 | 148 | C = self.codomain() |
127 | | try: |
128 | | v = [C(a) for a in A] |
129 | | A = matrix.matrix([C.coordinates(a) for a in v]) |
130 | | except TypeError: |
131 | | pass |
| 149 | if isfunction(A): |
| 150 | try: |
| 151 | v = [C(A(g)) for g in self.domain().gens()] |
| 152 | A = matrix.matrix([C.coordinates(a) for a in v]) |
| 153 | except TypeError, msg: |
| 154 | # Let us hope that FreeModuleMorphism knows to handle that case |
| 155 | pass |
| 156 | else: |
| 157 | try: |
| 158 | v = [C(a) for a in A] |
| 159 | A = matrix.matrix([C.coordinates(a) for a in v]) |
| 160 | except TypeError, msg: |
| 161 | # Let us hope that FreeModuleMorphism knows to handle that case |
| 162 | pass |
132 | 163 | return free_module_morphism.FreeModuleMorphism(self, A) |
133 | 164 | |
134 | 165 | def _matrix_space(self): |
… |
… |
|
137 | 168 | the homomorphisms in this free module homspace. |
138 | 169 | |
139 | 170 | OUTPUT: |
140 | | - matrix space |
| 171 | |
| 172 | - matrix space |
141 | 173 | |
142 | 174 | EXAMPLES:: |
143 | 175 | |
… |
… |
|
158 | 190 | Return a basis for this space of free module homomorphisms. |
159 | 191 | |
160 | 192 | OUTPUT: |
161 | | - tuple |
| 193 | |
| 194 | - tuple |
162 | 195 | |
163 | 196 | EXAMPLES:: |
164 | 197 | |
-
diff -r 216c066ba752 sage/rings/finite_rings/element_givaro.pyx
a
|
b
|
|
4 | 4 | Sage includes the Givaro finite field library, for highly optimized |
5 | 5 | arithmetic in finite fields. |
6 | 6 | |
7 | | NOTES: The arithmetic is performed by the Givaro C++ library which |
8 | | uses Zech logs internally to represent finite field elements. This |
| 7 | NOTES: |
| 8 | |
| 9 | The arithmetic is performed by the Givaro C++ library which uses Zech |
| 10 | logs internally to represent finite field elements. This |
9 | 11 | implementation is the default finite extension field implementation in |
10 | 12 | Sage for the cardinality $< 2^{16}$, as it is vastly faster than the |
11 | 13 | PARI implementation which uses polynomials to represent finite field |
12 | 14 | elements. Some functionality in this class however is implemented |
13 | 15 | using the PARI implementation. |
14 | 16 | |
15 | | EXAMPLES: |
| 17 | EXAMPLES:: |
| 18 | |
16 | 19 | sage: k = GF(5); type(k) |
17 | 20 | <class 'sage.rings.finite_rings.finite_field_prime_modn.FiniteField_prime_modn_with_category'> |
18 | 21 | sage: k = GF(5^2,'c'); type(k) |
… |
… |
|
31 | 34 | <class 'sage.rings.finite_rings.finite_field_givaro.FiniteField_givaro_with_category'> |
32 | 35 | |
33 | 36 | AUTHORS: |
34 | | -- Martin Albrecht <malb@informatik.uni-bremen.de> (2006-06-05) |
35 | | -- William Stein (2006-12-07): editing, lots of docs, etc. |
36 | | -- Robert Bradshaw (2007-05-23): is_square/sqrt, pow. |
| 37 | |
| 38 | - Martin Albrecht <malb@informatik.uni-bremen.de> (2006-06-05) |
| 39 | - William Stein (2006-12-07): editing, lots of docs, etc. |
| 40 | - Robert Bradshaw (2007-05-23): is_square/sqrt, pow. |
| 41 | |
37 | 42 | """ |
38 | 43 | |
39 | 44 | |
… |
… |
|
410 | 415 | e = e % self.characteristic() |
411 | 416 | res = self.objectptr.initi(res,int(e)) |
412 | 417 | |
| 418 | elif e is None: |
| 419 | e_int = 0 |
| 420 | res = self.objectptr.initi(res,e_int) |
| 421 | |
413 | 422 | elif PY_TYPE_CHECK(e, float): |
414 | 423 | res = self.objectptr.initd(res,e) |
415 | 424 | |
-
diff -r 216c066ba752 sage/rings/finite_rings/finite_field_givaro.py
a
|
b
|
|
203 | 203 | Coerces several data types to self. |
204 | 204 | |
205 | 205 | INPUT: |
206 | | e -- data to coerce |
| 206 | |
| 207 | e -- data to coerce |
207 | 208 | |
208 | 209 | EXAMPLES: |
209 | 210 | |
210 | | FiniteField_givaroElement are accepted where the parent |
211 | | is either self, equals self or is the prime subfield |
| 211 | FiniteField_givaroElement are accepted where the parent |
| 212 | is either self, equals self or is the prime subfield:: |
212 | 213 | |
213 | 214 | sage: k = GF(2**8, 'a') |
214 | 215 | sage: k.gen() == k(k.gen()) |
215 | 216 | True |
216 | 217 | |
217 | | |
218 | | Floats, ints, longs, Integer are interpreted modulo characteristic |
| 218 | Floats, ints, longs, Integer are interpreted modulo characteristic:: |
219 | 219 | |
220 | 220 | sage: k(2) |
221 | 221 | 0 |
… |
… |
|
224 | 224 | sage: k(float(2.0)) |
225 | 225 | 0 |
226 | 226 | |
227 | | Rational are interpreted as |
228 | | self(numerator)/self(denominator). |
229 | | Both may not be >= self.characteristic(). |
| 227 | Rational are interpreted as self(numerator)/self(denominator). |
| 228 | Both may not be >= self.characteristic(). |
| 229 | :: |
230 | 230 | |
231 | 231 | sage: k = GF(3**8, 'a') |
232 | 232 | sage: k(1/2) == k(1)/k(2) |
233 | 233 | True |
234 | 234 | |
235 | | Free module elements over self.prime_subfield() are interpreted 'little endian' |
| 235 | Free module elements over self.prime_subfield() are interpreted 'little endian':: |
236 | 236 | |
237 | 237 | sage: k = GF(2**8, 'a') |
238 | 238 | sage: e = k.vector_space().gen(1); e |
… |
… |
|
240 | 240 | sage: k(e) |
241 | 241 | a |
242 | 242 | |
243 | | Strings are evaluated as polynomial representation of elements in self |
| 243 | 'None' yields zero:: |
| 244 | |
| 245 | sage: k(None) |
| 246 | 0 |
| 247 | |
| 248 | Strings are evaluated as polynomial representation of elements in self:: |
244 | 249 | |
245 | 250 | sage: k('a^2+1') |
246 | 251 | a^2 + 1 |
247 | 252 | |
248 | 253 | Univariate polynomials coerce into finite fields by evaluating |
249 | | the polynomial at the field's generator: |
| 254 | the polynomial at the field's generator:: |
| 255 | |
250 | 256 | sage: from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro |
251 | 257 | sage: R.<x> = QQ[] |
252 | 258 | sage: k, a = FiniteField_givaro(5^2, 'a').objgen() |
… |
… |
|
269 | 275 | q^2 + 2*q + 4 |
270 | 276 | |
271 | 277 | |
272 | | Multivariate polynomials only coerce if constant: |
| 278 | Multivariate polynomials only coerce if constant:: |
| 279 | |
273 | 280 | sage: R = k['x,y,z']; R |
274 | 281 | Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 5^2 |
275 | 282 | sage: k(R(2)) |
… |
… |
|
281 | 288 | ZeroDivisionError: division by zero in finite field. |
282 | 289 | |
283 | 290 | |
284 | | PARI elements are interpreted as finite field elements; this PARI flexibility |
285 | | is (absurdly!) liberal: |
| 291 | PARI elements are interpreted as finite field elements; this PARI flexibility |
| 292 | is (absurdly!) liberal:: |
286 | 293 | |
287 | 294 | sage: k = GF(2**8, 'a') |
288 | 295 | sage: k(pari('Mod(1,2)')) |
… |
… |
|
292 | 299 | sage: k(pari('Mod(1,3)*a^20')) |
293 | 300 | a^7 + a^5 + a^4 + a^2 |
294 | 301 | |
295 | | GAP elements need to be finite field elements: |
| 302 | GAP elements need to be finite field elements:: |
296 | 303 | |
297 | 304 | sage: from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro |
298 | 305 | sage: x = gap('Z(13)') |
-
diff -r 216c066ba752 sage/rings/polynomial/infinite_polynomial_element.py
a
|
b
|
|
565 | 565 | Infinite polynomial ring in x over Rational Field |
566 | 566 | |
567 | 567 | """ |
568 | | if x._p not in self.base_ring(): |
| 568 | # if x._p not in self.base_ring(): |
| 569 | try: |
| 570 | p = self.base_ring()(x._p) |
| 571 | except TypeError: |
569 | 572 | raise NotImplementedError, "Fraction Fields of Infinite Polynomial Rings are not implemented" |
570 | | divisor = self.base_ring().one_element()/x._p # use induction... |
| 573 | divisor = self.base_ring().one_element()/p # use induction... |
571 | 574 | OUTP = self.parent().tensor_with_ring(divisor.base_ring()) |
572 | 575 | return OUTP(self)*OUTP(divisor) |
573 | 576 | |
-
diff -r 216c066ba752 sage/rings/polynomial/laurent_polynomial_ring.py
a
|
b
|
|
273 | 273 | # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'): |
274 | 274 | names = arg1 |
275 | 275 | n = len(names) |
276 | | R = _multi_variate(base_ring, names, n, sparse, order) |
| 276 | R = _multi_variate(base_ring, names, n, sparse, order) |
277 | 277 | |
278 | 278 | if arg1 is None and arg2 is None: |
279 | 279 | raise TypeError, "you *must* specify the indeterminates (as not None)." |
… |
… |
|
347 | 347 | prepend_string += 'k' |
348 | 348 | else: |
349 | 349 | break |
350 | | R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex') |
| 350 | R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex', None) |
351 | 351 | P = LaurentPolynomialRing_mpair(R, prepend_string, names) |
352 | 352 | _save_in_cache(key, P) |
353 | 353 | return P |
… |
… |
|
386 | 386 | break |
387 | 387 | else: |
388 | 388 | break |
389 | | R = _multi_variate_poly(base_ring, names, n, sparse, order) |
| 389 | R = _multi_variate_poly(base_ring, names, n, sparse, order, None) |
390 | 390 | P = LaurentPolynomialRing_mpair(R, prepend_string, names) |
391 | 391 | _save_in_cache(key, P) |
392 | 392 | return P |
… |
… |
|
542 | 542 | Composite map: |
543 | 543 | From: Rational Field |
544 | 544 | To: Multivariate Laurent Polynomial Ring in x, y over Rational Field |
545 | | Defn: Call morphism: |
| 545 | Defn: Polynomial base injection morphism: |
546 | 546 | From: Rational Field |
547 | 547 | To: Multivariate Polynomial Ring in x, y over Rational Field |
548 | 548 | then |
-
diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_element.py
a
|
b
|
|
335 | 335 | x = polydict.PolyDict(x, parent.base_ring()(0), remove_zero=True) |
336 | 336 | MPolynomial_element.__init__(self, parent, x) |
337 | 337 | |
| 338 | def _new_constant_poly(self, x, P): |
| 339 | """ |
| 340 | Quickly create a new constant polynomial with value x in parent P. |
| 341 | |
| 342 | ASSUMPTION: |
| 343 | |
| 344 | x must be an element of the base ring of P. That assumption is |
| 345 | not verified. |
| 346 | |
| 347 | EXAMPLE:: |
| 348 | |
| 349 | sage: R.<x,y> = QQ['t'][] |
| 350 | sage: x._new_constant_poly(R.base_ring()(2),R) |
| 351 | 2 |
| 352 | |
| 353 | """ |
| 354 | return MPolynomial_polydict(P, {P._zero_tuple:x}) |
| 355 | |
338 | 356 | def __neg__(self): |
339 | 357 | """ |
340 | 358 | EXAMPLES:: |
-
diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_libsingular.pxd
a
|
b
|
|
4 | 4 | from sage.rings.polynomial.multi_polynomial_ring_generic cimport MPolynomialRing_generic |
5 | 5 | from sage.structure.parent cimport Parent |
6 | 6 | |
| 7 | cdef class MPolynomialRing_libsingular |
| 8 | |
7 | 9 | cdef class MPolynomial_libsingular(MPolynomial): |
8 | 10 | cdef poly *_poly |
9 | 11 | cpdef _repr_short_(self) |
10 | 12 | cpdef is_constant(self) |
11 | 13 | cpdef _homogenize(self, int var) |
| 14 | cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P) |
12 | 15 | |
13 | 16 | cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): |
14 | 17 | cdef object __singular |
15 | 18 | cdef object __macaulay2 |
16 | 19 | cdef object __m2_set_ring_cache |
17 | 20 | cdef object __minpoly |
| 21 | cdef poly *_one_element_poly |
18 | 22 | cdef ring *_ring |
19 | 23 | cdef int _cmp_c_impl(left, Parent right) except -2 |
20 | 24 | |
-
diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_libsingular.pyx
a
|
b
|
|
299 | 299 | |
300 | 300 | TEST: |
301 | 301 | |
302 | | Make sure that a faster conversion map from the base ring is used; |
| 302 | Make sure that a faster coercion map from the base ring is used; |
303 | 303 | see trac ticket #9944:: |
304 | 304 | |
305 | 305 | sage: R.<x,y> = PolynomialRing(ZZ) |
306 | | sage: R.convert_map_from(R.base_ring()) |
| 306 | sage: R.coerce_map_from(R.base_ring()) |
307 | 307 | Polynomial base injection morphism: |
308 | 308 | From: Integer Ring |
309 | 309 | To: Multivariate Polynomial Ring in x, y over Integer Ring |
… |
… |
|
315 | 315 | self.__ngens = n |
316 | 316 | self._ring = singular_ring_new(base_ring, n, self._names, order) |
317 | 317 | self._one_element = <MPolynomial_libsingular>new_MP(self,p_ISet(1, self._ring)) |
| 318 | self._one_element_poly = (<MPolynomial_libsingular>self._one_element)._poly |
318 | 319 | self._zero_element = <MPolynomial_libsingular>new_MP(self,NULL) |
319 | 320 | # This polynomial ring should belong to Algebras(base_ring). |
320 | 321 | # Algebras(...).parent_class, which was called from MPolynomialRing_generic.__init__, |
… |
… |
|
324 | 325 | # wipe the memory and construct the conversion from scratch. |
325 | 326 | from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection |
326 | 327 | base_inject = PolynomialBaseringInjection(base_ring, self) |
327 | | self.register_conversion(base_inject) |
| 328 | self.register_coercion(base_inject) |
328 | 329 | |
329 | 330 | def __dealloc__(self): |
330 | 331 | r""" |
… |
… |
|
773 | 774 | |
774 | 775 | return new_MP(self, _p) |
775 | 776 | |
776 | | if hasattr(element,'_polynomial_'): |
| 777 | try: #if hasattr(element,'_polynomial_'): |
777 | 778 | # SymbolicVariable |
778 | 779 | return element._polynomial_(self) |
| 780 | except AttributeError: |
| 781 | pass |
779 | 782 | |
780 | 783 | if is_Macaulay2Element(element): |
781 | 784 | return self(element.external_string()) |
… |
… |
|
1720 | 1723 | if self._parent is not <ParentWithBase>None and (<MPolynomialRing_libsingular>self._parent)._ring != NULL and self._poly != NULL: |
1721 | 1724 | p_Delete(&self._poly, (<MPolynomialRing_libsingular>self._parent)._ring) |
1722 | 1725 | |
| 1726 | cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P): |
| 1727 | r""" |
| 1728 | Quickly create a new constant polynomial with value x in the parent P. |
| 1729 | |
| 1730 | ASSUMPTION: |
| 1731 | |
| 1732 | The value x must be an element of the base ring. That assumption is |
| 1733 | not verified. |
| 1734 | |
| 1735 | EXAMPLE:: |
| 1736 | |
| 1737 | sage: R.<x,y> = QQ[] |
| 1738 | sage: x._new_constant_poly(2/1,R) |
| 1739 | 2 |
| 1740 | |
| 1741 | """ |
| 1742 | if not x: |
| 1743 | return <MPolynomial_libsingular>new_MP(P, NULL) |
| 1744 | cdef ring *_ring = P._ring |
| 1745 | cdef poly *_p |
| 1746 | singular_polynomial_rmul(&_p, P._one_element_poly, x, _ring) |
| 1747 | return new_MP(P,_p) |
| 1748 | |
1723 | 1749 | def __call__(self, *x, **kwds): |
1724 | 1750 | """ |
1725 | 1751 | Evaluate this multi-variate polynomial at ``x``, where ``x`` |
-
diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_ring.py
a
|
b
|
|
159 | 159 | if n: |
160 | 160 | from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection |
161 | 161 | base_inject = PolynomialBaseringInjection(base_ring, self) |
162 | | self.register_conversion(base_inject) |
| 162 | self.register_coercion(base_inject) |
163 | 163 | |
164 | 164 | def _monomial_order_function(self): |
165 | 165 | return self.__monomial_order_function |
-
diff -r 216c066ba752 sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py
a
|
b
|
|
37 | 37 | (1 + O(13^7))*t + (2 + O(13^7)) |
38 | 38 | """ |
39 | 39 | Polynomial.__init__(self, parent, is_gen=is_gen) |
| 40 | parentbr = parent.base_ring() |
40 | 41 | from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing |
41 | 42 | if construct: |
42 | 43 | (self._poly, self._valbase, self._relprecs, self._normalized, self._valaddeds, self._list) = x #the last two of these may be None |
… |
… |
|
45 | 46 | self._poly = PolynomialRing(ZZ, parent.variable_name()).gen() |
46 | 47 | self._valbase = 0 |
47 | 48 | self._valaddeds = [infinity, 0] |
48 | | self._relprecs = [infinity, parent.base_ring().precision_cap()] |
| 49 | self._relprecs = [infinity, parentbr.precision_cap()] |
49 | 50 | self._normalized = True |
50 | 51 | self._list = None |
51 | 52 | return |
… |
… |
|
75 | 76 | elif x.base_ring() is ZZ: |
76 | 77 | self._poly = x |
77 | 78 | self._valbase = Integer(0) |
78 | | p = parent.base_ring().prime() |
79 | | self._relprecs = [c.valuation(p) + parent.base_ring().precision_cap() for c in x.list()] |
| 79 | p = parentbr.prime() |
| 80 | self._relprecs = [c.valuation(p) + parentbr.precision_cap() for c in x.list()] |
80 | 81 | self._comp_valaddeds() |
81 | 82 | self._normalized = len(self._valaddeds) == 0 or (min(self._valaddeds) == 0) |
82 | 83 | self._list = None |
… |
… |
|
84 | 85 | self._adjust_prec_info(absprec, relprec) |
85 | 86 | return |
86 | 87 | else: |
87 | | x = [parent.base_ring()(a) for a in x.list()] |
| 88 | x = [parentbr(a) for a in x.list()] |
88 | 89 | check = False |
89 | 90 | elif isinstance(x, dict): |
90 | | zero = parent.base_ring()(0) |
| 91 | zero = parentbr.zero_element() |
91 | 92 | n = max(x.keys()) |
92 | 93 | v = [zero for _ in xrange(n + 1)] |
93 | 94 | for i, z in x.iteritems(): |
94 | 95 | v[i] = z |
95 | 96 | x = v |
96 | 97 | elif isinstance(x, pari_gen): |
97 | | x = [parent.base_ring()(w) for w in x.Vecrev()] |
| 98 | x = [parentbr(w) for w in x.Vecrev()] |
98 | 99 | check = False |
99 | 100 | #The default behavior if we haven't already figured out what the type is is to assume it coerces into the base_ring as a constant polynomial |
100 | 101 | elif not isinstance(x, list): |
101 | 102 | x = [x] # constant polynomial |
102 | | |
| 103 | |
| 104 | # In contrast to other polynomials, the zero element is not distinguished |
| 105 | # by having its list empty. Instead, it has list [0] |
| 106 | if not x: |
| 107 | x = [parentbr.zero_element()] |
103 | 108 | if check: |
104 | | x = [parent.base_ring()(z) for z in x] |
| 109 | x = [parentbr(z) for z in x] |
105 | 110 | |
106 | 111 | # Remove this -- for p-adics this is terrible, since it kills any non exact zero. |
107 | 112 | #if len(x) == 1 and not x[0]: |
… |
… |
|
125 | 130 | if not absprec is infinity or not relprec is infinity: |
126 | 131 | self._adjust_prec_info(absprec, relprec) |
127 | 132 | |
| 133 | def _new_constant_poly(self, a, P): |
| 134 | """ |
| 135 | Create a new constant polynomial in parent P with value a. |
| 136 | |
| 137 | ASSUMPTION: |
| 138 | |
| 139 | The value a must be an element of the base ring of P. That |
| 140 | assumption is not verified. |
| 141 | |
| 142 | EXAMPLE:: |
| 143 | |
| 144 | sage: R.<t> = Zp(5)[] |
| 145 | sage: t._new_constant_poly(O(5),R) |
| 146 | (O(5)) |
| 147 | |
| 148 | """ |
| 149 | return self.__class__(P,[a], check=False) |
| 150 | |
128 | 151 | def _normalize(self): |
129 | 152 | # Currently slow: need to optimize |
130 | 153 | if not self._normalized: |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_compiled.pyx
a
|
b
|
|
114 | 114 | def __repr__(self): |
115 | 115 | return "CompiledPolynomialFunction(%s)"%(self._dag) |
116 | 116 | |
| 117 | def __call__(self, x): |
| 118 | return self.eval(x) |
| 119 | |
117 | 120 | cdef object eval(CompiledPolynomialFunction self, object x): |
118 | 121 | cdef object temp |
119 | 122 | try: |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_element.pxd
a
|
b
|
|
5 | 5 | |
6 | 6 | from sage.structure.element import Element, CommutativeAlgebraElement |
7 | 7 | from sage.structure.element cimport Element, CommutativeAlgebraElement, ModuleElement |
| 8 | from sage.structure.parent cimport Parent |
8 | 9 | from polynomial_compiled import CompiledPolynomialFunction |
9 | 10 | from polynomial_compiled cimport CompiledPolynomialFunction |
10 | 11 | |
… |
… |
|
15 | 16 | cpdef Polynomial truncate(self, long n) |
16 | 17 | cdef long _hash_c(self) |
17 | 18 | cpdef constant_coefficient(self) |
18 | | cpdef Polynomial _new_constant_poly(self, a) |
| 19 | cpdef Polynomial _new_constant_poly(self, a, Parent P) |
19 | 20 | |
20 | 21 | # UNSAFE, only call from an inplace operator |
21 | 22 | # may return a new element if not possible to modify inplace |
22 | 23 | cdef _inplace_truncate(self, long n) |
23 | 24 | |
24 | 25 | cdef class Polynomial_generic_dense(Polynomial): |
25 | | cdef Polynomial_generic_dense _new_c(self, list coeffs) |
| 26 | cdef Polynomial_generic_dense _new_c(self, list coeffs, Parent P) |
26 | 27 | cdef list __coeffs |
27 | 28 | cdef void __normalize(self) |
28 | 29 | # cdef _dict_to_list(self, x, zero) |
29 | | |
| 30 | |
| 31 | cpdef Polynomial_generic_dense _new_constant_dense_poly(list coeffs, Parent P, sample) |
| 32 | |
30 | 33 | #cdef class Polynomial_generic_sparse(Polynomial): |
31 | 34 | # cdef object __coeffs # a python dict (for now) |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_element.pyx
a
|
b
|
|
85 | 85 | |
86 | 86 | from sage.rings.integer cimport Integer |
87 | 87 | from sage.rings.ideal import is_Ideal |
| 88 | from sage.rings.polynomial.polynomial_ring import is_PolynomialRing |
88 | 89 | |
89 | 90 | from sage.categories.map cimport Map |
90 | 91 | from sage.categories.morphism cimport Morphism |
… |
… |
|
159 | 160 | import sage.rings.complex_interval_field |
160 | 161 | is_ComplexIntervalField = sage.rings.complex_interval_field.is_ComplexIntervalField |
161 | 162 | |
| 163 | |
162 | 164 | cdef class Polynomial(CommutativeAlgebraElement): |
163 | 165 | """ |
164 | 166 | A polynomial. |
… |
… |
|
300 | 302 | # that could be in derived class. |
301 | 303 | # Note that we are guaranteed that right is in the base ring, so this could be fast. |
302 | 304 | if left == 0: |
303 | | return self.parent()(0) |
| 305 | return self.parent().zero_element() |
304 | 306 | return self.parent()(left) * self |
305 | 307 | |
306 | 308 | cpdef ModuleElement _rmul_(self, RingElement right): |
… |
… |
|
320 | 322 | # that could be in derived class. |
321 | 323 | # Note that we are guaranteed that right is in the base ring, so this could be fast. |
322 | 324 | if right == 0: |
323 | | return self.parent()(0) |
| 325 | return self.parent().zero_element() |
324 | 326 | return self * self.parent()(right) |
325 | 327 | |
326 | 328 | def subs(self, *x, **kwds): |
… |
… |
|
546 | 548 | """ |
547 | 549 | cdef long i, d = self.degree() |
548 | 550 | |
549 | | if len(kwds) >= 1: |
| 551 | if kwds: |
550 | 552 | P = self.parent() |
551 | 553 | name = P.variable_name() |
552 | 554 | if kwds.has_key(name): |
… |
… |
|
587 | 589 | result = self[d] |
588 | 590 | if len(x) > 1: |
589 | 591 | other_args = x[1:] |
590 | | if hasattr(result, '__call__'): |
| 592 | try: #if hasattr(result, '__call__'): |
591 | 593 | result = result(other_args) |
592 | | else: |
| 594 | except TypeError: #else: |
593 | 595 | raise TypeError, "Wrong number of arguments" |
594 | 596 | |
595 | 597 | if d == -1: |
596 | 598 | try: |
| 599 | return a.parent().zero_element() |
| 600 | except AttributeError: |
| 601 | pass |
| 602 | try: # for things like the interface to the PARI C library |
597 | 603 | return a.parent()(0) |
598 | 604 | except AttributeError: |
599 | 605 | return result |
600 | 606 | |
601 | 607 | if d == 0: |
602 | 608 | try: |
| 609 | return a.parent().one_element() * result |
| 610 | except AttributeError: |
| 611 | pass |
| 612 | try: # for things like the interface to the PARI C library |
603 | 613 | return a.parent()(1) * result |
604 | 614 | except AttributeError: |
605 | 615 | return result |
… |
… |
|
961 | 971 | sage: ~f |
962 | 972 | 1/(x - 90283) |
963 | 973 | """ |
964 | | return self.parent()(1)/self |
| 974 | return self.parent().one_element()/self |
965 | 975 | |
966 | 976 | def inverse_of_unit(self): |
967 | 977 | """ |
… |
… |
|
1076 | 1086 | for i in range(n+1): |
1077 | 1087 | for j in range(n-1): |
1078 | 1088 | M[i+j, j+n] = m[i] |
1079 | | v = vector(R, [R(1)] + [R(0)]*(2*n-2)) # the constant polynomial 1 |
| 1089 | v = vector(R, [R.one_element()] + [R.zero_element()]*(2*n-2)) # the constant polynomial 1 |
1080 | 1090 | if M.is_invertible(): |
1081 | 1091 | x = M.solve_right(v) # there has to be a better way to solve |
1082 | 1092 | return a.parent()(list(x)[0:n]) |
… |
… |
|
1122 | 1132 | (t^4 + O(t^5))*s^4 + (2*t^3 + O(t^4))*s^3 + (3*t^2 + O(t^3))*s^2 + (2*t + O(t^2))*s + 1 |
1123 | 1133 | """ |
1124 | 1134 | if right == 0 or self == 0: |
1125 | | return self._parent(0) |
| 1135 | return self._parent.zero_element() |
1126 | 1136 | |
1127 | 1137 | if self._parent.is_exact(): |
1128 | 1138 | return self._mul_karatsuba(right) |
… |
… |
|
1411 | 1421 | P = self.parent() |
1412 | 1422 | R = P.base_ring() |
1413 | 1423 | if P.is_sparse(): |
1414 | | v = {right:R(1)} |
| 1424 | v = {right:R.one_element()} |
1415 | 1425 | else: |
1416 | | v = [R(0)]*right + [R(1)] |
| 1426 | v = [R.zero_element()]*right + [R.one_element()] |
1417 | 1427 | r = self.parent()(v, check=False) |
1418 | 1428 | else: |
1419 | 1429 | r = generic_power(self, right) |
… |
… |
|
1733 | 1743 | x = self.list() |
1734 | 1744 | cdef Py_ssize_t i, j |
1735 | 1745 | cdef Py_ssize_t d = len(x)-1 |
1736 | | zero = self._parent.base_ring()(0) |
| 1746 | zero = self._parent.base_ring().zero_element() |
1737 | 1747 | two = self._parent.base_ring()(2) |
1738 | 1748 | coeffs = [zero] * (2 * d + 1) |
1739 | 1749 | for i from 0 <= i <= d: |
… |
… |
|
2326 | 2336 | return self |
2327 | 2337 | cdef Py_ssize_t n, degree = self.degree() |
2328 | 2338 | if degree == 0: |
2329 | | return self.parent()(0) |
| 2339 | return self.parent().zero_element() |
2330 | 2340 | coeffs = self.list() |
2331 | 2341 | return self._parent([n*coeffs[n] for n from 1 <= n <= degree]) |
2332 | 2342 | |
… |
… |
|
2366 | 2376 | """ |
2367 | 2377 | cdef Py_ssize_t n, degree = self.degree() |
2368 | 2378 | if degree < 0: |
2369 | | return self.parent()(0) |
| 2379 | return self.parent().zero_element() |
2370 | 2380 | |
2371 | 2381 | coeffs = self.list() |
2372 | 2382 | v = [0, coeffs[0]] + [coeffs[n]/(n+1) for n from 1 <= n <= degree] |
… |
… |
|
2956 | 2966 | else: |
2957 | 2967 | # Otherwise we have to adjust for |
2958 | 2968 | # the content ignored by PARI. |
2959 | | content_fix = R.base_ring()(1) |
| 2969 | content_fix = R.base_ring().one_element() |
2960 | 2970 | for f, e in F: |
2961 | 2971 | if not f.is_monic(): |
2962 | 2972 | content_fix *= f.leading_coefficient()**e |
2963 | 2973 | unit //= content_fix |
2964 | 2974 | if not unit.is_unit(): |
2965 | 2975 | F.append((R(unit), ZZ(1))) |
2966 | | unit = R.base_ring()(1) |
| 2976 | unit = R.base_ring().one_element() |
2967 | 2977 | |
2968 | 2978 | if not n is None: |
2969 | 2979 | pari.set_real_precision(n) # restore precision |
… |
… |
|
3436 | 3446 | """ |
3437 | 3447 | return self[0] |
3438 | 3448 | |
3439 | | cpdef Polynomial _new_constant_poly(self, a): |
3440 | | """ |
3441 | | Create a new constant polynomial from a, which MUST be an element of the base ring. |
3442 | | """ |
3443 | | return self._parent._element_constructor(a) |
| 3449 | cpdef Polynomial _new_constant_poly(self, a, Parent P): |
| 3450 | """ |
| 3451 | Create a new constant polynomial from a in P, which MUST be an |
| 3452 | element of the base ring of P (this is not checked). |
| 3453 | |
| 3454 | EXAMPLE:: |
| 3455 | |
| 3456 | sage: R.<w> = PolynomialRing(GF(9,'a'), sparse=True) |
| 3457 | sage: a = w._new_constant_poly(0, R); a |
| 3458 | 0 |
| 3459 | sage: a.coeffs() |
| 3460 | [] |
| 3461 | |
| 3462 | """ |
| 3463 | if a: |
| 3464 | return self.__class__(P,[a], check=False) #P._element_constructor(a, check=False) |
| 3465 | return self.__class__(P,[], check=False) |
3444 | 3466 | |
3445 | 3467 | def is_monic(self): |
3446 | 3468 | """ |
… |
… |
|
3744 | 3766 | if n < 0: |
3745 | 3767 | raise ValueError, "n must be at least 0" |
3746 | 3768 | if len(v) < n: |
3747 | | z = self._parent.base_ring()(0) |
| 3769 | z = self._parent.base_ring().zero_element() |
3748 | 3770 | return v + [z]*(n - len(v)) |
3749 | 3771 | else: |
3750 | 3772 | return v[:int(n)] |
… |
… |
|
5173 | 5195 | """ |
5174 | 5196 | if other.is_zero(): |
5175 | 5197 | R = self.parent() |
5176 | | return self, R(1), R(0) |
| 5198 | return self, R.one_element(), R.zero_element() |
5177 | 5199 | # Algorithm 3.2.2 of Cohen, GTM 138 |
5178 | 5200 | R = self.parent() |
5179 | 5201 | A = self |
5180 | 5202 | B = other |
5181 | | U = R(1) |
| 5203 | U = R.one_element() |
5182 | 5204 | G = A |
5183 | | V1 = R(0) |
| 5205 | V1 = R.zero_element() |
5184 | 5206 | V3 = B |
5185 | 5207 | while not V3.is_zero(): |
5186 | 5208 | Q, R = G.quo_rem(V3) |
… |
… |
|
5305 | 5327 | if n == 0 or self.degree() < 0: |
5306 | 5328 | return self # safe because immutable. |
5307 | 5329 | if n > 0: |
5308 | | output = [self.base_ring()(0)] * n |
| 5330 | output = [self.base_ring().zero_element()] * n |
5309 | 5331 | output.extend(self.coeffs()) |
5310 | 5332 | return self._parent(output, check=False) |
5311 | 5333 | if n < 0: |
… |
… |
|
5327 | 5349 | |
5328 | 5350 | EXAMPLES:: |
5329 | 5351 | |
5330 | | sage: R.<x> = ZZ[]; S.<y> = R[] |
| 5352 | sage: R.<x> = ZZ[]; S.<y> = PolynomialRing(R, sparse=True) |
5331 | 5353 | sage: f = y^3 + x*y -3*x; f |
5332 | 5354 | y^3 + x*y - 3*x |
5333 | 5355 | sage: f.truncate(2) |
… |
… |
|
5337 | 5359 | sage: f.truncate(0) |
5338 | 5360 | 0 |
5339 | 5361 | """ |
5340 | | return <Polynomial>self._parent(self[:n], check=False) |
| 5362 | # We must not have check=False, since 0 must not have __coeffs = [0]. |
| 5363 | return <Polynomial>self._parent(self[:n])#, check=False) |
5341 | 5364 | |
5342 | 5365 | cdef _inplace_truncate(self, long prec): |
5343 | 5366 | return self.truncate(prec) |
… |
… |
|
5545 | 5568 | t0 = bd |
5546 | 5569 | return _karatsuba_sum(t0,_karatsuba_sum(t1,t2)) |
5547 | 5570 | |
| 5571 | cpdef Polynomial_generic_dense _new_constant_dense_poly(list coeffs, Parent P, sample): |
| 5572 | cdef Polynomial_generic_dense f = <Polynomial_generic_dense>PY_NEW_SAME_TYPE(sample) |
| 5573 | f._parent = P |
| 5574 | f.__coeffs = coeffs |
| 5575 | return f |
| 5576 | |
| 5577 | |
5548 | 5578 | cdef class Polynomial_generic_dense(Polynomial): |
5549 | 5579 | """ |
5550 | 5580 | A generic dense polynomial. |
… |
… |
|
5560 | 5590 | """ |
5561 | 5591 | def __init__(self, parent, x=None, int check=1, is_gen=False, int construct=0, **kwds): |
5562 | 5592 | Polynomial.__init__(self, parent, is_gen=is_gen) |
5563 | | |
5564 | 5593 | if x is None: |
5565 | 5594 | self.__coeffs = [] |
5566 | 5595 | return |
| 5596 | |
5567 | 5597 | R = parent.base_ring() |
5568 | | |
| 5598 | if PY_TYPE_CHECK(x, list): |
| 5599 | if check: |
| 5600 | self.__coeffs = [R(t) for t in x] |
| 5601 | self.__normalize() |
| 5602 | else: |
| 5603 | self.__coeffs = x |
| 5604 | return |
| 5605 | |
5569 | 5606 | if sage.rings.fraction_field_element.is_FractionFieldElement(x): |
5570 | 5607 | if x.denominator() != 1: |
5571 | 5608 | raise TypeError, "denominator must be 1" |
… |
… |
|
5575 | 5612 | if PY_TYPE_CHECK(x, Polynomial): |
5576 | 5613 | if (<Element>x)._parent is self._parent: |
5577 | 5614 | x = list(x.list()) |
5578 | | elif (<Element>x)._parent is R or (<Element>x)._parent == R: |
| 5615 | elif R.has_coerce_map_from((<Element>x)._parent):# is R or (<Element>x)._parent == R: |
| 5616 | try: |
| 5617 | if x.is_zero(): |
| 5618 | self.__coeffs = [] |
| 5619 | return |
| 5620 | except (AttributeError, TypeError): |
| 5621 | pass |
5579 | 5622 | x = [x] |
5580 | 5623 | else: |
5581 | | x = [R(a, **kwds) for a in x.list()] |
5582 | | check = 0 |
5583 | | |
5584 | | elif PY_TYPE_CHECK(x, list): |
5585 | | pass |
5586 | | |
| 5624 | self.__coeffs = [R(a, **kwds) for a in x.list()] |
| 5625 | if check: |
| 5626 | self.__normalize() |
| 5627 | return |
| 5628 | |
5587 | 5629 | elif PY_TYPE_CHECK(x, int) and x == 0: |
5588 | 5630 | self.__coeffs = [] |
5589 | 5631 | return |
5590 | | |
| 5632 | |
5591 | 5633 | elif isinstance(x, dict): |
5592 | | x = self._dict_to_list(x, R(0)) |
| 5634 | x = self._dict_to_list(x, R.zero_element()) |
5593 | 5635 | |
5594 | 5636 | elif isinstance(x, pari_gen): |
5595 | 5637 | x = [R(w, **kwds) for w in x.Vecrev()] |
5596 | | check = 1 |
| 5638 | check = 0 |
5597 | 5639 | elif not isinstance(x, list): |
| 5640 | # We trust that the element constructors do not send x=0 |
| 5641 | # if x: |
5598 | 5642 | x = [x] # constant polynomials |
| 5643 | # else: |
| 5644 | # x = [] # zero polynomial |
5599 | 5645 | if check: |
5600 | 5646 | self.__coeffs = [R(z, **kwds) for z in x] |
| 5647 | self.__normalize() |
5601 | 5648 | else: |
5602 | 5649 | self.__coeffs = x |
5603 | | if check: |
5604 | | self.__normalize() |
5605 | | |
5606 | | cdef Polynomial_generic_dense _new_c(self, list coeffs): |
| 5650 | |
| 5651 | cdef Polynomial_generic_dense _new_c(self, list coeffs, Parent P): |
5607 | 5652 | cdef Polynomial_generic_dense f = <Polynomial_generic_dense>PY_NEW_SAME_TYPE(self) |
5608 | | f._parent = self._parent |
| 5653 | f._parent = P |
5609 | 5654 | f.__coeffs = coeffs |
5610 | 5655 | return f |
5611 | 5656 | |
5612 | | cpdef Polynomial _new_constant_poly(self, a): |
5613 | | """ |
5614 | | Create a new constant polynomial from a, which MUST be an element of the base ring. |
5615 | | |
5616 | | EXAMPLES: |
| 5657 | cpdef Polynomial _new_constant_poly(self, a, Parent P): |
| 5658 | """ |
| 5659 | Create a new constant polynomial in P with value a. |
| 5660 | |
| 5661 | ASSUMPTION: |
| 5662 | |
| 5663 | The given value **must** be an element of the base ring. That |
| 5664 | assumption is not verified. |
| 5665 | |
| 5666 | EXAMPLES:: |
| 5667 | |
5617 | 5668 | sage: S.<y> = QQ[] |
5618 | 5669 | sage: R.<x> = S[] |
5619 | | sage: x._new_constant_poly(y+1) |
| 5670 | sage: x._new_constant_poly(y+1, R) |
5620 | 5671 | y + 1 |
5621 | | sage: parent(x._new_constant_poly(y+1)) |
| 5672 | sage: parent(x._new_constant_poly(y+1, R)) |
5622 | 5673 | Univariate Polynomial Ring in x over Univariate Polynomial Ring in y over Rational Field |
5623 | 5674 | """ |
5624 | 5675 | if a: |
5625 | | return self._new_c([a]) |
| 5676 | return self._new_c([a],P) |
5626 | 5677 | else: |
5627 | | return self._new_c([]) |
| 5678 | return self._new_c([],P) |
5628 | 5679 | |
5629 | 5680 | def __reduce__(self): |
5630 | 5681 | """ |
… |
… |
|
5677 | 5728 | 0 |
5678 | 5729 | """ |
5679 | 5730 | if n < 0 or n >= len(self.__coeffs): |
5680 | | return self.base_ring()(0) |
| 5731 | return self.base_ring().zero_element() |
5681 | 5732 | return self.__coeffs[n] |
5682 | 5733 | |
5683 | 5734 | def __getslice__(self, Py_ssize_t i, j): |
… |
… |
|
5698 | 5749 | i = 0 |
5699 | 5750 | zeros = [] |
5700 | 5751 | elif i > 0: |
5701 | | zeros = [self._parent.base_ring()(0)] * i |
| 5752 | zeros = [self._parent.base_ring().zero_element()] * i |
5702 | 5753 | return self._parent(zeros + self.__coeffs[i:j]) |
5703 | 5754 | |
5704 | 5755 | def _unsafe_mutate(self, n, value): |
… |
… |
|
5729 | 5780 | elif n < 0: |
5730 | 5781 | raise IndexError, "polynomial coefficient index must be nonnegative" |
5731 | 5782 | elif value != 0: |
5732 | | zero = self.base_ring()(0) |
| 5783 | zero = self.base_ring().zero_element() |
5733 | 5784 | for _ in xrange(len(self.__coeffs), n): |
5734 | 5785 | self.__coeffs.append(zero) |
5735 | 5786 | self.__coeffs.append(value) |
… |
… |
|
5750 | 5801 | sage: f.quo_rem(1+2*x) |
5751 | 5802 | (4*x^2 + 4*x + 5/2, -3/2) |
5752 | 5803 | """ |
5753 | | if right.parent() == self.parent(): |
| 5804 | P = (<Element>self)._parent |
| 5805 | if right.parent() == P: |
5754 | 5806 | return Polynomial.__floordiv__(self, right) |
5755 | | d = self.parent().base_ring()(right) |
5756 | | cdef Polynomial_generic_dense res = self._new_c([c // d for c in self.__coeffs]) |
| 5807 | d = P.base_ring()(right) |
| 5808 | cdef Polynomial_generic_dense res = self._new_c([c // d for c in self.__coeffs], P) |
5757 | 5809 | res.__normalize() |
5758 | 5810 | return res |
5759 | 5811 | |
… |
… |
|
5772 | 5824 | min = len(x) |
5773 | 5825 | cdef list low = [x[i] + y[i] for i from 0 <= i < min] |
5774 | 5826 | if len(x) == len(y): |
5775 | | res = self._new_c(low) |
| 5827 | res = self._new_c(low, self._parent) |
5776 | 5828 | res.__normalize() |
5777 | 5829 | return res |
5778 | 5830 | else: |
5779 | | return self._new_c(low + high) |
| 5831 | return self._new_c(low + high, self._parent) |
5780 | 5832 | |
5781 | 5833 | cpdef ModuleElement _iadd_(self, ModuleElement right): |
5782 | 5834 | cdef Py_ssize_t check=0, i, min |
… |
… |
|
5808 | 5860 | min = len(x) |
5809 | 5861 | low = [x[i] - y[i] for i from 0 <= i < min] |
5810 | 5862 | if len(x) == len(y): |
5811 | | res = self._new_c(low) |
| 5863 | res = self._new_c(low, self._parent) |
5812 | 5864 | res.__normalize() |
5813 | 5865 | return res |
5814 | 5866 | else: |
5815 | | return self._new_c(low + high) |
| 5867 | return self._new_c(low + high, self._parent) |
5816 | 5868 | |
5817 | 5869 | cpdef ModuleElement _isub_(self, ModuleElement right): |
5818 | 5870 | cdef Py_ssize_t check=0, i, min |
… |
… |
|
5835 | 5887 | if c._parent is not (<Element>self.__coeffs[0])._parent: |
5836 | 5888 | c = (<Element>self.__coeffs[0])._parent._coerce_c(c) |
5837 | 5889 | v = [c * a for a in self.__coeffs] |
5838 | | cdef Polynomial_generic_dense res = self._new_c(v) |
5839 | | if not v[len(v)-1]: |
5840 | | res.__normalize() |
| 5890 | cdef Polynomial_generic_dense res = self._new_c(v, self._parent) |
| 5891 | #if not v[len(v)-1]: |
| 5892 | # "normalize" checks this anyway... |
| 5893 | res.__normalize() |
5841 | 5894 | return res |
5842 | 5895 | |
5843 | 5896 | cpdef ModuleElement _lmul_(self, RingElement c): |
… |
… |
|
5846 | 5899 | if c._parent is not (<Element>self.__coeffs[0])._parent: |
5847 | 5900 | c = (<Element>self.__coeffs[0])._parent._coerce_c(c) |
5848 | 5901 | v = [a * c for a in self.__coeffs] |
5849 | | cdef Polynomial_generic_dense res = self._new_c(v) |
5850 | | if not v[len(v)-1]: |
5851 | | res.__normalize() |
| 5902 | cdef Polynomial_generic_dense res = self._new_c(v, self._parent) |
| 5903 | #if not v[len(v)-1]: |
| 5904 | # "normalize" checks this anyway... |
| 5905 | res.__normalize() |
5852 | 5906 | return res |
5853 | 5907 | |
5854 | 5908 | cpdef ModuleElement _ilmul_(self, RingElement c): |
… |
… |
|
5878 | 5932 | t |
5879 | 5933 | """ |
5880 | 5934 | if len(self.__coeffs) == 0: |
5881 | | return self.base_ring()(0) |
| 5935 | return self.base_ring().zero_element() |
5882 | 5936 | else: |
5883 | 5937 | return self.__coeffs[0] |
5884 | 5938 | |
… |
… |
|
5944 | 5998 | if n == 0 or self.degree() < 0: |
5945 | 5999 | return self |
5946 | 6000 | if n > 0: |
5947 | | output = [self.base_ring()(0)] * n |
| 6001 | output = [self.base_ring().zero_element()] * n |
5948 | 6002 | output.extend(self.__coeffs) |
5949 | | return self._new_c(output) |
| 6003 | return self._new_c(output, self._parent) |
5950 | 6004 | if n < 0: |
5951 | 6005 | if n > len(self.__coeffs) - 1: |
5952 | 6006 | return self._parent([]) |
5953 | 6007 | else: |
5954 | | return self._new_c(self.__coeffs[-int(n):]) |
| 6008 | return self._new_c(self.__coeffs[-int(n):], self._parent) |
5955 | 6009 | |
5956 | 6010 | cpdef Polynomial truncate(self, long n): |
5957 | 6011 | r""" |
… |
… |
|
5980 | 6034 | sage: type(f) |
5981 | 6035 | <type 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense'> |
5982 | 6036 | """ |
5983 | | if n < len(self.__coeffs): |
5984 | | while n > 0 and not self.__coeffs[n-1]: |
5985 | | n -= 1 |
5986 | | return self._new_c(self.__coeffs[:n]) |
| 6037 | l = len(self.__coeffs) |
| 6038 | if n > l: |
| 6039 | n = l |
| 6040 | while n > 0 and not self.__coeffs[n-1]: |
| 6041 | n -= 1 |
| 6042 | return self._new_c(self.__coeffs[:n], self._parent) |
5987 | 6043 | |
5988 | 6044 | cdef _inplace_truncate(self, long n): |
5989 | 6045 | if n < len(self.__coeffs): |
… |
… |
|
6001 | 6057 | """ |
6002 | 6058 | This class is used for conversion from a polynomial ring to its base ring. |
6003 | 6059 | |
6004 | | It calls the constant_coefficient method, which can be optimized for |
6005 | | a particular polynomial type. |
| 6060 | Since trac ticket #9944, it calls the constant_coefficient method, |
| 6061 | which can be optimized for a particular polynomial type. |
| 6062 | |
| 6063 | EXAMPLES:: |
| 6064 | |
| 6065 | sage: P0.<y_1> = GF(3)[] |
| 6066 | sage: P1.<y_2,y_1,y_0> = GF(3)[] |
| 6067 | sage: P0(-y_1) # indirect doctest |
| 6068 | 2*y_1 |
| 6069 | sage: phi = GF(3).convert_map_from(P0); phi |
| 6070 | Generic map: |
| 6071 | From: Univariate Polynomial Ring in y_1 over Finite Field of size 3 |
| 6072 | To: Finite Field of size 3 |
| 6073 | sage: type(phi) |
| 6074 | <type 'sage.rings.polynomial.polynomial_element.ConstantPolynomialSection'> |
| 6075 | sage: phi(P0.one_element()) |
| 6076 | 1 |
| 6077 | sage: phi(y_1) |
| 6078 | Traceback (most recent call last): |
| 6079 | ... |
| 6080 | TypeError: not a constant polynomial |
| 6081 | |
6006 | 6082 | """ |
6007 | 6083 | cpdef Element _call_(self, x): |
6008 | 6084 | """ |
… |
… |
|
6023 | 6099 | TypeError: not a constant polynomial |
6024 | 6100 | """ |
6025 | 6101 | if x.degree() <= 0: |
6026 | | return <Element>((<Polynomial>x).constant_coefficient()) |
| 6102 | try: |
| 6103 | return <Element>(x.constant_coefficient()) |
| 6104 | except AttributeError: |
| 6105 | return <Element>((<Polynomial>x).constant_coefficient()) |
6027 | 6106 | else: |
6028 | 6107 | raise TypeError, "not a constant polynomial" |
6029 | 6108 | |
… |
… |
|
6032 | 6111 | This class is used for conversion from a ring to a polynomial |
6033 | 6112 | over that ring. |
6034 | 6113 | |
6035 | | If the polynomial ring has a One and if the elements provide an |
6036 | | ``_rmul_`` method, and ``_rmul_`` does *not* return None (which is |
6037 | | the case for `p`-adics) then conversion is obtained by multiplying |
6038 | | the base ring element with the One by means of `_rmul_`. |
6039 | | |
6040 | | Otherwise It calls the _new_constant_poly method on the generator, |
6041 | | which should be optimized for a particular polynomial type, but |
6042 | | often isn't. |
| 6114 | It calls the _new_constant_poly method on the generator, |
| 6115 | which should be optimized for a particular polynomial type. |
6043 | 6116 | |
6044 | 6117 | Technically, it should be a method of the polynomial ring, but |
6045 | | few polynomial rings are cython classes. |
6046 | | |
6047 | | NOTE: |
6048 | | |
6049 | | We use `_rmul_` and not `_lmul_` since for many polynomial rings |
6050 | | `_lmul_` simply calls `_rmul_`. |
| 6118 | few polynomial rings are cython classes, and so, as a method |
| 6119 | of a cython polynomial class, it is faster. |
6051 | 6120 | |
6052 | 6121 | EXAMPLES: |
6053 | 6122 | |
6054 | | We demonstrate that different polynomial ring classes use |
6055 | | polynomial base injection maps:: |
| 6123 | We demonstrate that most polynomial ring classes use |
| 6124 | polynomial base injection maps for coercion. They are |
| 6125 | supposed to be the fastest maps for that purpose. See |
| 6126 | trac ticket #9944:: |
6056 | 6127 | |
6057 | 6128 | sage: R.<x> = Qp(3)[] |
6058 | | sage: R.convert_map_from(R.base_ring()) |
| 6129 | sage: R.coerce_map_from(R.base_ring()) |
6059 | 6130 | Polynomial base injection morphism: |
6060 | 6131 | From: 3-adic Field with capped relative precision 20 |
6061 | 6132 | To: Univariate Polynomial Ring in x over 3-adic Field with capped relative precision 20 |
6062 | 6133 | sage: R.<x,y> = Qp(3)[] |
6063 | | sage: R.convert_map_from(R.base_ring()) |
| 6134 | sage: R.coerce_map_from(R.base_ring()) |
6064 | 6135 | Polynomial base injection morphism: |
6065 | 6136 | From: 3-adic Field with capped relative precision 20 |
6066 | 6137 | To: Multivariate Polynomial Ring in x, y over 3-adic Field with capped relative precision 20 |
6067 | 6138 | sage: R.<x,y> = QQ[] |
6068 | | sage: R.convert_map_from(R.base_ring()) |
| 6139 | sage: R.coerce_map_from(R.base_ring()) |
6069 | 6140 | Polynomial base injection morphism: |
6070 | 6141 | From: Rational Field |
6071 | 6142 | To: Multivariate Polynomial Ring in x, y over Rational Field |
6072 | 6143 | sage: R.<x> = QQ[] |
6073 | | sage: R.convert_map_from(R.base_ring()) |
| 6144 | sage: R.coerce_map_from(R.base_ring()) |
6074 | 6145 | Polynomial base injection morphism: |
6075 | 6146 | From: Rational Field |
6076 | 6147 | To: Univariate Polynomial Ring in x over Rational Field |
6077 | 6148 | |
6078 | 6149 | By trac ticket #9944, there are now only very few exceptions:: |
6079 | 6150 | |
6080 | | sage: PolynomialRing(QQ,names=[]).convert_map_from(QQ) |
| 6151 | sage: PolynomialRing(QQ,names=[]).coerce_map_from(QQ) |
6081 | 6152 | Call morphism: |
6082 | 6153 | From: Rational Field |
6083 | 6154 | To: Multivariate Polynomial Ring in no variables over Rational Field |
… |
… |
|
6085 | 6156 | """ |
6086 | 6157 | |
6087 | 6158 | cdef RingElement _an_element |
6088 | | cdef object _one_rmul_ |
| 6159 | cdef object _new_constant_poly_ |
6089 | 6160 | |
6090 | 6161 | def __init__(self, domain, codomain): |
6091 | 6162 | """ |
… |
… |
|
6111 | 6182 | (1 + 2 + O(2^20))*t |
6112 | 6183 | |
6113 | 6184 | """ |
6114 | | assert domain is codomain.base_ring(), "domain must be basering" |
| 6185 | assert codomain.base_ring() is domain, "domain must be basering" |
6115 | 6186 | Morphism.__init__(self, domain, codomain) |
6116 | 6187 | self._an_element = codomain.gen() |
6117 | 6188 | self._repr_type_str = "Polynomial base injection" |
6118 | | if domain is codomain: # some rings are base rings of themselves! |
6119 | | return |
6120 | | try: |
6121 | | one = codomain._element_constructor_(domain.one_element()) |
6122 | | except (AttributeError, NotImplementedError, TypeError): |
6123 | | # perhaps it uses the old model? |
6124 | | try: |
6125 | | one = codomain._coerce_c(domain.one_element()) |
6126 | | except (AttributeError, NotImplementedError, TypeError): |
6127 | | return |
6128 | | try: |
6129 | | one_rmul_ = one._rmul_ |
6130 | | except AttributeError: |
6131 | | return |
6132 | | # For the p-adic fields, _lmul_ and _rmul_ return None!!! |
6133 | | # To work around, we need to test its sanity before we try |
6134 | | # to use it. |
6135 | | try: |
6136 | | if one_rmul_(domain.one_element()) is None: |
6137 | | return |
6138 | | self._one_rmul_ = one_rmul_ |
6139 | | except TypeError: |
6140 | | pass |
6141 | | |
| 6189 | self._new_constant_poly_ = self._an_element._new_constant_poly |
| 6190 | |
6142 | 6191 | cpdef Element _call_(self, x): |
6143 | 6192 | """ |
6144 | 6193 | TESTS: |
… |
… |
|
6152 | 6201 | sage: parent(m(2)) |
6153 | 6202 | Univariate Polynomial Ring in x over Integer Ring |
6154 | 6203 | """ |
6155 | | if self._one_rmul_ is not None: |
6156 | | return self._one_rmul_(x) |
6157 | | return self._an_element._new_constant_poly(<Element>x) |
| 6204 | return self._new_constant_poly_(x, self._codomain) |
6158 | 6205 | |
6159 | 6206 | cpdef Element _call_with_args(self, x, args=(), kwds={}): |
6160 | 6207 | """ |
… |
… |
|
6164 | 6211 | sage: m(1 + O(5^11), absprec = 5) # indirect doctest |
6165 | 6212 | (1 + O(5^11)) |
6166 | 6213 | """ |
6167 | | return self._codomain._element_constructor(x, *args, **kwds) |
| 6214 | try: |
| 6215 | return self._codomain._element_constructor_(x, *args, **kwds) |
| 6216 | except AttributeError: |
| 6217 | # if there is no element constructor, |
| 6218 | # there is a custom call method. |
| 6219 | return self._codomain(x, *args, **kwds) |
6168 | 6220 | |
6169 | 6221 | def section(self): |
6170 | 6222 | """ |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_element_generic.py
a
|
b
|
|
88 | 88 | w = {} |
89 | 89 | for n, c in x.dict().iteritems(): |
90 | 90 | w[n] = R(c) |
91 | | #raise TypeError, "Cannot coerce %s into %s."%(x, parent) |
| 91 | # The following line has been added in trac ticket #9944. |
| 92 | # Apparently, the "else" case has never occured before. |
| 93 | x = w |
92 | 94 | elif isinstance(x, list): |
93 | 95 | y = {} |
94 | 96 | for i in xrange(len(x)): |
… |
… |
|
418 | 420 | x^100000 + 4*x^75000 + 3*x |
419 | 421 | |
420 | 422 | AUTHOR: |
| 423 | |
421 | 424 | - David Harvey (2006-08-05) |
422 | 425 | """ |
423 | 426 | output = dict(self.__coeffs) |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_integer_dense_flint.pxd
a
|
b
|
|
6 | 6 | |
7 | 7 | from sage.rings.polynomial.polynomial_element cimport Polynomial |
8 | 8 | from sage.rings.integer cimport Integer |
| 9 | from sage.structure.parent cimport Parent |
9 | 10 | |
10 | 11 | cdef class Polynomial_integer_dense_flint(Polynomial): |
11 | 12 | cdef fmpz_poly_t __poly |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_integer_dense_flint.pyx
a
|
b
|
|
80 | 80 | x._is_gen = 0 |
81 | 81 | return x |
82 | 82 | |
| 83 | cpdef Polynomial _new_constant_poly(self, a, Parent P): |
| 84 | r""" |
| 85 | Quickly creates a new constant polynomial with value a in parent P |
| 86 | |
| 87 | ASSUMPTION: |
| 88 | |
| 89 | The given value has to be in the base ring of P. This assumption is not |
| 90 | verified. |
| 91 | |
| 92 | EXAMPLE:: |
| 93 | |
| 94 | sage: R.<x> = ZZ[] |
| 95 | sage: x._new_constant_poly(2,R) |
| 96 | 2 |
| 97 | |
| 98 | """ |
| 99 | cdef Polynomial_integer_dense_flint x = PY_NEW(Polynomial_integer_dense_flint) |
| 100 | x._parent = P |
| 101 | x._is_gen = 0 |
| 102 | if not PY_TYPE_CHECK(a, Integer): |
| 103 | a = ZZ(a) |
| 104 | fmpz_poly_set_coeff_mpz(x.__poly, 0, (<Integer>a).value) |
| 105 | return x |
83 | 106 | |
84 | 107 | def __init__(self, parent, x=None, check=True, is_gen=False, |
85 | 108 | construct=False): |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_rational_flint.pxd
a
|
b
|
|
12 | 12 | include "../../libs/flint/fmpq_poly.pxd" |
13 | 13 | |
14 | 14 | from sage.rings.polynomial.polynomial_element cimport Polynomial |
| 15 | from sage.structure.parent cimport Parent |
15 | 16 | |
16 | 17 | cdef class Polynomial_rational_flint(Polynomial): |
17 | 18 | cdef fmpq_poly_t __poly |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_rational_flint.pyx
a
|
b
|
|
101 | 101 | res._is_gen = 0 |
102 | 102 | return res |
103 | 103 | |
| 104 | cpdef Polynomial _new_constant_poly(self, x, Parent P): |
| 105 | r""" |
| 106 | Quickly creates a new constant polynomial with value x in parent P |
| 107 | |
| 108 | ASSUMPTION: |
| 109 | |
| 110 | x must be a rational or convertible to an int. |
| 111 | |
| 112 | EXAMPLE:: |
| 113 | |
| 114 | sage: R.<x> = QQ[] |
| 115 | sage: x._new_constant_poly(2/1,R) |
| 116 | 2 |
| 117 | sage: x._new_constant_poly(2,R) |
| 118 | 2 |
| 119 | sage: x._new_constant_poly("2",R) |
| 120 | 2 |
| 121 | sage: x._new_constant_poly("2.1",R) |
| 122 | Traceback (most recent call last): |
| 123 | ... |
| 124 | ValueError: invalid literal for int() with base 10: '2.1' |
| 125 | |
| 126 | """ |
| 127 | cdef Polynomial_rational_flint res = PY_NEW(Polynomial_rational_flint) |
| 128 | res._parent = P |
| 129 | res._is_gen = <char>0 |
| 130 | if PY_TYPE_CHECK(x, int): |
| 131 | fmpq_poly_set_si(res.__poly, <int> x) |
| 132 | |
| 133 | elif PY_TYPE_CHECK(x, Integer): |
| 134 | fmpq_poly_set_mpz(res.__poly, (<Integer> x).value) |
| 135 | |
| 136 | elif PY_TYPE_CHECK(x, Rational): |
| 137 | fmpq_poly_set_mpq(res.__poly, (<Rational> x).value) |
| 138 | |
| 139 | else: |
| 140 | fmpq_poly_set_si(res.__poly, int(x)) |
| 141 | return res |
| 142 | |
| 143 | |
104 | 144 | def __cinit__(self): |
105 | 145 | """ |
106 | 146 | Initialises the underlying data structure. |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_real_mpfr_dense.pyx
a
|
b
|
|
42 | 42 | sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense |
43 | 43 | sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) |
44 | 44 | 3.14159265358979*x^4 + 4.00000000000000*x^3 + 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 |
| 45 | sage: PolynomialRealDense(RR['x'], None) |
| 46 | 0 |
| 47 | |
45 | 48 | """ |
46 | 49 | Polynomial.__init__(self, parent, is_gen=is_gen) |
47 | 50 | self._base_ring = parent._base |
48 | 51 | cdef Py_ssize_t i, degree |
49 | 52 | cdef int prec = self._base_ring.__prec |
50 | 53 | cdef mp_rnd_t rnd = self._base_ring.rnd |
| 54 | if x is None: |
| 55 | self._coeffs = <mpfr_t*>sage_malloc(sizeof(mpfr_t)) # degree zero |
| 56 | mpfr_init2(self._coeffs[0], prec) |
| 57 | mpfr_set_si(self._coeffs[0], PyInt_AS_LONG(int(0)), rnd) |
| 58 | self._normalize() |
| 59 | return |
51 | 60 | if is_gen: |
52 | 61 | x = [0, 1] |
53 | 62 | elif isinstance(x, (int, float, Integer, Rational, RealNumber)): |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_ring.py
a
|
b
|
|
14 | 14 | |
15 | 15 | - Martin Albrecht (2006-08-25): removed it again as it isn't needed anymore |
16 | 16 | |
| 17 | - Simon King (2011-05): Dense and sparse polynomial rings must not be equal. |
| 18 | |
17 | 19 | EXAMPLES: |
| 20 | |
18 | 21 | Creating a polynomial ring injects the variable into the interpreter namespace:: |
19 | 22 | |
20 | 23 | sage: z = QQ['z'].0 |
… |
… |
|
32 | 35 | sage: k = PolynomialRing(ZZ,'y', sparse=True); loads(dumps(k)) |
33 | 36 | Sparse Univariate Polynomial Ring in y over Integer Ring |
34 | 37 | |
35 | | The rings of sparse and dense polynomials in the same variable are |
36 | | canonically isomorphic:: |
37 | | |
38 | | sage: PolynomialRing(ZZ,'y', sparse=True) == PolynomialRing(ZZ,'y') |
39 | | True |
| 38 | Rings with different variable names are not equal:: |
40 | 39 | |
41 | 40 | sage: QQ['y'] < QQ['x'] |
42 | 41 | False |
… |
… |
|
58 | 57 | sage: g * f |
59 | 58 | w^2 + (i + j)*w - k |
60 | 59 | |
| 60 | Trac ticket #9944 introduced some changes related with |
| 61 | coercion. Previously, a dense and a sparse polynomial ring with the |
| 62 | same variable name over the same base ring evaluated equal, but of |
| 63 | course they were not identical.Coercion maps are cached - but if a |
| 64 | coercion to a dense ring is requested and a coercion to a sparse ring |
| 65 | is returned instead (since the cache keys are equal!), all hell breaks |
| 66 | loose. |
| 67 | |
| 68 | Therefore, the coercion between rings of sparse and dense polynomials |
| 69 | works as follows:: |
| 70 | |
| 71 | sage: R.<x> = PolynomialRing(QQ, sparse=True) |
| 72 | sage: S.<x> = QQ[] |
| 73 | sage: S == R |
| 74 | False |
| 75 | sage: S.has_coerce_map_from(R) |
| 76 | True |
| 77 | sage: R.has_coerce_map_from(S) |
| 78 | False |
| 79 | sage: (R.0+S.0).parent() |
| 80 | Univariate Polynomial Ring in x over Rational Field |
| 81 | sage: (S.0+R.0).parent() |
| 82 | Univariate Polynomial Ring in x over Rational Field |
| 83 | |
| 84 | It may be that one has rings of dense or sparse polynomials over |
| 85 | different base rings. In that situation, coercion works by means of |
| 86 | the :func:`~sage.categories.pushout.pushout` formalism:: |
| 87 | |
| 88 | sage: R.<x> = PolynomialRing(GF(5), sparse=True) |
| 89 | sage: S.<x> = PolynomialRing(ZZ) |
| 90 | sage: R.has_coerce_map_from(S) |
| 91 | False |
| 92 | sage: S.has_coerce_map_from(R) |
| 93 | False |
| 94 | sage: S.0 + R.0 |
| 95 | 2*x |
| 96 | sage: (S.0 + R.0).parent() |
| 97 | Univariate Polynomial Ring in x over Finite Field of size 5 |
| 98 | sage: (S.0 + R.0).parent().is_sparse() |
| 99 | False |
| 100 | |
| 101 | Similarly, there is a coercion from the (non-default) NTL |
| 102 | implementation for univariate polynomials over the integers |
| 103 | to the default FLINT implementation, but not vice versa:: |
| 104 | |
| 105 | sage: R.<x> = PolynomialRing(ZZ, implementation = 'NTL') |
| 106 | sage: S.<x> = PolynomialRing(ZZ, implementation = 'FLINT') |
| 107 | sage: (S.0+R.0).parent() is S |
| 108 | True |
| 109 | sage: (R.0+S.0).parent() is S |
| 110 | True |
| 111 | |
61 | 112 | TESTS:: |
62 | 113 | |
63 | 114 | sage: K.<x>=FractionField(QQ['x']) |
… |
… |
|
108 | 159 | from sage.rings.integer_ring import is_IntegerRing, IntegerRing |
109 | 160 | from sage.rings.integer import Integer |
110 | 161 | from sage.libs.pari.all import pari_gen |
| 162 | |
111 | 163 | import sage.misc.defaults |
112 | 164 | import sage.misc.latex as latex |
113 | 165 | from sage.misc.prandom import randint |
| 166 | from sage.misc.cachefunc import cached_method |
| 167 | |
114 | 168 | from sage.rings.real_mpfr import is_RealField |
115 | 169 | from polynomial_real_mpfr_dense import PolynomialRealDense |
116 | 170 | from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr |
… |
… |
|
233 | 287 | |
234 | 288 | def _element_constructor_(self, x=None, check=True, is_gen = False, construct=False, **kwds): |
235 | 289 | r""" |
236 | | Coerce ``x`` into this univariate polynomial ring, |
| 290 | Convert ``x`` into this univariate polynomial ring, |
237 | 291 | possibly non-canonically. |
238 | 292 | |
239 | 293 | Stacked polynomial rings coerce into constants if possible. First, |
… |
… |
|
287 | 341 | -y |
288 | 342 | |
289 | 343 | TESTS: |
| 344 | |
290 | 345 | This shows that the issue at trac #4106 is fixed:: |
291 | 346 | |
292 | 347 | sage: x = var('x') |
… |
… |
|
296 | 351 | x |
297 | 352 | """ |
298 | 353 | C = self._polynomial_class |
| 354 | if isinstance(x, list): |
| 355 | return C(self, x, check=check, is_gen=False,construct=construct) |
299 | 356 | if isinstance(x, Element): |
300 | 357 | P = x.parent() |
301 | 358 | if P is self: |
302 | 359 | return x |
| 360 | elif P is self.base_ring(): |
| 361 | # It *is* the base ring, hence, we should not need to check. |
| 362 | # Moreover, if x is equal to zero then we usually need to |
| 363 | # provide [] to the polynomial class, not [x], if we don't want |
| 364 | # to check (normally, polynomials like to strip trailing zeroes). |
| 365 | # However, in the padic case, we WANT that trailing |
| 366 | # zeroes are not stripped, because O(5)==0, but still it must |
| 367 | # not be forgotten. It should be the job of the __init__ method |
| 368 | # to decide whether to strip or not to strip. |
| 369 | return C(self, [x], check=False, is_gen=False, |
| 370 | construct=construct) |
303 | 371 | elif P == self.base_ring(): |
304 | 372 | return C(self, [x], check=True, is_gen=False, |
305 | | construct=construct) |
| 373 | construct=construct) |
| 374 | |
306 | 375 | elif self.base_ring().has_coerce_map_from(P): |
307 | 376 | return C(self, [x], check=True, is_gen=False, |
308 | 377 | construct=construct) |
309 | | if hasattr(x, '_polynomial_'): |
310 | | return x._polynomial_(self) |
| 378 | try: #if hasattr(x, '_polynomial_'): |
| 379 | return x._polynomial_(self) |
| 380 | except AttributeError: |
| 381 | pass |
311 | 382 | if isinstance(x, SingularElement) and self._has_singular: |
312 | 383 | self._singular_().set_ring() |
313 | 384 | try: |
… |
… |
|
333 | 404 | raise TypeError, "denominator must be a unit" |
334 | 405 | if x.type() != 't_POL': |
335 | 406 | x = x.Polrev() |
336 | | |
337 | 407 | return C(self, x, check, is_gen, construct=construct, **kwds) |
338 | 408 | |
339 | 409 | def is_integral_domain(self, proof = True): |
… |
… |
|
352 | 422 | |
353 | 423 | def construction(self): |
354 | 424 | from sage.categories.pushout import PolynomialFunctor |
355 | | return PolynomialFunctor(self.variable_name()), self.base_ring() |
| 425 | return PolynomialFunctor(self.variable_name(), sparse=self.__is_sparse), self.base_ring() |
356 | 426 | |
357 | 427 | def completion(self, p, prec=20, extras=None): |
358 | 428 | """ |
… |
… |
|
393 | 463 | - any ring that canonically coerces to the base ring of this ring. |
394 | 464 | |
395 | 465 | - polynomial rings in the same variable over any base ring that |
396 | | canonically coerces to the base ring of this ring |
| 466 | canonically coerces to the base ring of this ring. |
| 467 | |
| 468 | Caveat: There is no coercion from a dense into a sparse |
| 469 | polynomial ring. So, when adding a dense and a sparse |
| 470 | polynomial, the result will be dense. See trac ticket #9944. |
397 | 471 | |
398 | 472 | EXAMPLES:: |
399 | 473 | |
… |
… |
|
420 | 494 | Polynomial base injection morphism: |
421 | 495 | From: Rational Field |
422 | 496 | To: Univariate Polynomial Ring in x over Rational Field |
| 497 | |
| 498 | Here we test against the change in the coercions introduced |
| 499 | in trac ticket #9944:: |
| 500 | |
| 501 | sage: R.<x> = PolynomialRing(QQ, sparse=True) |
| 502 | sage: S.<x> = QQ[] |
| 503 | sage: (R.0+S.0).parent() |
| 504 | Univariate Polynomial Ring in x over Rational Field |
| 505 | sage: (S.0+R.0).parent() |
| 506 | Univariate Polynomial Ring in x over Rational Field |
| 507 | |
423 | 508 | """ |
424 | 509 | # handle constants that canonically coerce into self.base_ring() |
425 | 510 | # first, if possible |
… |
… |
|
434 | 519 | # coerces into self.base_ring() |
435 | 520 | try: |
436 | 521 | if is_PolynomialRing(P): |
| 522 | if self.__is_sparse and not P.is_sparse(): |
| 523 | return False |
437 | 524 | if P.variable_name() == self.variable_name(): |
438 | 525 | if P.base_ring() is self.base_ring() and \ |
439 | 526 | self.base_ring() is ZZ_sage: |
… |
… |
|
566 | 653 | # of the polynomial ring canonically coerce into codomain. |
567 | 654 | # Since poly rings are free, any image of the gen |
568 | 655 | # determines a homomorphism |
569 | | codomain.coerce(self.base_ring()(1)) |
| 656 | codomain.coerce(self.base_ring().one_element()) |
570 | 657 | except TypeError: |
571 | 658 | return False |
572 | 659 | return True |
573 | 660 | |
574 | | def __cmp__(left, right): |
575 | | c = cmp(type(left),type(right)) |
576 | | if c: return c |
577 | | return cmp((left.base_ring(), left.variable_name()), (right.base_ring(), right.variable_name())) |
| 661 | # Polynomial rings should be unique parents. Hence, |
| 662 | # no need for __cmp__. Or actually, having a __cmp__ |
| 663 | # method that identifies a dense with a sparse ring |
| 664 | # is a bad bad idea! |
| 665 | # def __cmp__(left, right): |
| 666 | # c = cmp(type(left),type(right)) |
| 667 | # if c: return c |
| 668 | # return cmp((left.base_ring(), left.variable_name()), (right.base_ring(), right.variable_name())) |
| 669 | |
| 670 | def __hash__(self): |
| 671 | # should be faster than just relying on the string representation |
| 672 | try: |
| 673 | return self._cached_hash |
| 674 | except AttributeError: |
| 675 | pass |
| 676 | h = self._cached_hash = hash((self.base_ring(),self.variable_name())) |
| 677 | return h |
578 | 678 | |
579 | 679 | def _repr_(self): |
| 680 | try: |
| 681 | return self._cached_repr |
| 682 | except AttributeError: |
| 683 | pass |
580 | 684 | s = "Univariate Polynomial Ring in %s over %s"%( |
581 | 685 | self.variable_name(), self.base_ring()) |
582 | 686 | if self.is_sparse(): |
583 | 687 | s = "Sparse " + s |
| 688 | self._cached_repr = s |
584 | 689 | return s |
585 | 690 | |
586 | 691 | def _latex_(self): |
… |
… |
|
969 | 1074 | Refer to monics() for full documentation. |
970 | 1075 | """ |
971 | 1076 | base = self.base_ring() |
972 | | for coeffs in sage.misc.mrange.xmrange_iter([[base(1)]]+[base]*of_degree): |
| 1077 | for coeffs in sage.misc.mrange.xmrange_iter([[base.one_element()]]+[base]*of_degree): |
973 | 1078 | # Each iteration returns a *new* list! |
974 | 1079 | # safe to mutate the return |
975 | 1080 | coeffs.reverse() |
… |
… |
|
988 | 1093 | Refer to polynomials() for full documentation. |
989 | 1094 | """ |
990 | 1095 | base = self.base_ring() |
| 1096 | base0 = base.zero_element() |
991 | 1097 | for leading_coeff in base: |
992 | | if leading_coeff != base(0): |
| 1098 | if leading_coeff != base0: |
993 | 1099 | for lt1 in sage.misc.mrange.xmrange_iter([base]*(of_degree)): |
994 | 1100 | # Each iteration returns a *new* list! |
995 | 1101 | # safe to mutate the return |
… |
… |
|
1208 | 1314 | element_class = Polynomial_integer_dense_flint |
1209 | 1315 | self._implementation_names = (None, 'FLINT') |
1210 | 1316 | else: |
1211 | | raise ValueError, "Unknown implementation %s for ZZ[x]" |
| 1317 | raise ValueError, "Unknown implementation %s for ZZ[x]"%implementation |
1212 | 1318 | PolynomialRing_commutative.__init__(self, base_ring, name=name, |
1213 | 1319 | sparse=sparse, element_class=element_class) |
1214 | 1320 | |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_ring_constructor.py
a
|
b
|
|
4 | 4 | This module provides the function :func:`PolynomialRing`, which constructs |
5 | 5 | rings of univariate and multivariate polynomials, and implements caching to |
6 | 6 | prevent the same ring being created in memory multiple times (which is |
7 | | wasteful). |
| 7 | wasteful and breaks the general assumption in Sage that parents are unique). |
8 | 8 | |
9 | 9 | There is also a function :func:`BooleanPolynomialRing_constructor`, used for |
10 | 10 | constructing Boolean polynomial rings, which are not technically polynomial |
… |
… |
|
81 | 81 | - ``implementation`` -- string or None; selects an implementation in cases |
82 | 82 | where Sage includes multiple choices (currently `\ZZ[x]` can be |
83 | 83 | implemented with 'NTL' or 'FLINT'; default is 'FLINT') |
| 84 | |
| 85 | NOTE: |
| 86 | |
| 87 | The following rules were introduced in trac ticket #9944, in order |
| 88 | to preserve the "unique parent assumption" in Sage (i.e., if two |
| 89 | parents evaluate equal then they should actually be identical). |
| 90 | |
| 91 | - In the multivariate case, a dense representation is not supported. Hence, |
| 92 | the argument ``sparse=False`` is silently ignored in that case. |
| 93 | - If the given implementation does not exist for rings with the given number |
| 94 | of generators and the given sparsity, then an error results. |
84 | 95 | |
85 | 96 | OUTPUT: |
86 | 97 | |
… |
… |
|
106 | 117 | |
107 | 118 | You can't just globally change the names of those variables. |
108 | 119 | This is because objects all over Sage could have pointers to |
109 | | that polynomial ring. :: |
| 120 | that polynomial ring. |
| 121 | :: |
110 | 122 | |
111 | 123 | sage: R._assign_names(['z','w']) |
112 | 124 | Traceback (most recent call last): |
… |
… |
|
120 | 132 | ... |
121 | 133 | z^2 - 2*w^2 |
122 | 134 | |
123 | | After the ``with`` block the names revert to what they were before. :: |
| 135 | After the ``with`` block the names revert to what they were before. |
| 136 | :: |
124 | 137 | |
125 | 138 | sage: print f |
126 | 139 | x^2 - 2*y^2 |
… |
… |
|
189 | 202 | integers, one based on NTL and one based on FLINT. The default |
190 | 203 | is FLINT. Note that FLINT uses a "more dense" representation for |
191 | 204 | its polynomials than NTL, so in particular, creating a polynomial |
192 | | like 2^1000000 * x^1000000 in FLINT may be unwise. :: |
| 205 | like 2^1000000 * x^1000000 in FLINT may be unwise. |
| 206 | :: |
193 | 207 | |
194 | 208 | sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL |
195 | 209 | Univariate Polynomial Ring in x over Integer Ring (using NTL) |
… |
… |
|
206 | 220 | sage: xFLINT.parent() |
207 | 221 | Univariate Polynomial Ring in x over Integer Ring |
208 | 222 | |
209 | | There is a coercion between the two rings, so the values can be |
210 | | mixed in a single expression. :: |
| 223 | There is a coercion from the non-default to the default |
| 224 | implementation, so the values can be mixed in a single |
| 225 | expression:: |
211 | 226 | |
212 | 227 | sage: (xNTL + xFLINT^2) |
213 | 228 | x^2 + x |
214 | 229 | |
215 | | Unfortunately, it is unpredictable whether the result of such an |
216 | | expression will use the NTL or FLINT implementation. :: |
| 230 | The result of such an expression will use the default, i.e., |
| 231 | the FLINT implementation:: |
217 | 232 | |
218 | | sage: (xNTL + xFLINT^2).parent() # random output |
| 233 | sage: (xNTL + xFLINT^2).parent() |
219 | 234 | Univariate Polynomial Ring in x over Integer Ring |
220 | 235 | |
221 | 236 | 2. ``PolynomialRing(base_ring, names, order='degrevlex')`` |
… |
… |
|
299 | 314 | Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 |
300 | 315 | sage: (x2 + x41 + x71)^2 |
301 | 316 | x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2 |
| 317 | |
| 318 | TESTS: |
| 319 | |
| 320 | We test here some changes introduced in #9944. |
| 321 | |
| 322 | If there is no dense implementation for the given number of |
| 323 | variables, then requesting a dense ring results yields the |
| 324 | corresponding sparse ring:: |
| 325 | |
| 326 | sage: R.<x,y> = QQ[] |
| 327 | sage: S.<x,y> = PolynomialRing(QQ, sparse=False) |
| 328 | sage: R is S |
| 329 | True |
| 330 | |
| 331 | If the requested implementation is not known or not supported for |
| 332 | the given number of variables and the given sparsity, then an |
| 333 | error results:: |
| 334 | |
| 335 | sage: R.<x> = PolynomialRing(ZZ, implementation='Foo') |
| 336 | Traceback (most recent call last): |
| 337 | ... |
| 338 | ValueError: Unknown implementation Foo for ZZ[x] |
| 339 | sage: R.<x,y> = PolynomialRing(ZZ, implementation='FLINT') |
| 340 | Traceback (most recent call last): |
| 341 | ... |
| 342 | ValueError: The FLINT implementation is not known for multivariate polynomial rings |
| 343 | |
| 344 | The following corner case used to result in a warning message from |
| 345 | ``libSingular``, and the generators of the resulting polynomial |
| 346 | ring were not zero:: |
| 347 | |
| 348 | sage: R = Integers(1)['x','y'] |
| 349 | sage: R.0 == 0 |
| 350 | True |
| 351 | |
302 | 352 | """ |
303 | 353 | import sage.rings.polynomial.polynomial_ring as m |
304 | 354 | |
… |
… |
|
332 | 382 | raise TypeError, "You *must* specify the names of the variables." |
333 | 383 | n = int(arg2) |
334 | 384 | names = arg1 |
335 | | R = _multi_variate(base_ring, names, n, sparse, order) |
| 385 | R = _multi_variate(base_ring, names, n, sparse, order, implementation) |
336 | 386 | |
337 | 387 | elif isinstance(arg1, str) or (isinstance(arg1, (list,tuple)) and len(arg1) == 1): |
338 | 388 | if not ',' in arg1: |
… |
… |
|
347 | 397 | raise TypeError, "invalid input to PolynomialRing function; please see the docstring for that function" |
348 | 398 | names = arg1.split(',') |
349 | 399 | n = len(names) |
350 | | R = _multi_variate(base_ring, names, n, sparse, order) |
| 400 | R = _multi_variate(base_ring, names, n, sparse, order, implementation) |
351 | 401 | elif isinstance(arg1, (list, tuple)): |
352 | 402 | # PolynomialRing(base_ring, names (list or tuple), order='degrevlex'): |
353 | 403 | names = arg1 |
354 | 404 | n = len(names) |
355 | | R = _multi_variate(base_ring, names, n, sparse, order) |
| 405 | R = _multi_variate(base_ring, names, n, sparse, order, implementation) |
356 | 406 | |
357 | 407 | if arg1 is None and arg2 is None: |
358 | 408 | raise TypeError, "you *must* specify the indeterminates (as not None)." |
… |
… |
|
376 | 426 | |
377 | 427 | def _get_from_cache(key): |
378 | 428 | try: |
379 | | if _cache.has_key(key): |
380 | | return _cache[key] #() |
| 429 | return _cache[key] #() |
381 | 430 | except TypeError, msg: |
382 | | raise TypeError, 'key = %s\n%s'%(key,msg) |
383 | | return None |
| 431 | raise TypeError, 'key = %s\n%s'%(key,msg) |
| 432 | except KeyError: |
| 433 | return None |
384 | 434 | |
385 | 435 | def _save_in_cache(key, R): |
386 | 436 | try: |
… |
… |
|
393 | 443 | def _single_variate(base_ring, name, sparse, implementation): |
394 | 444 | import sage.rings.polynomial.polynomial_ring as m |
395 | 445 | name = normalize_names(1, name) |
396 | | key = (base_ring, name, sparse, implementation) |
| 446 | key = (base_ring, name, sparse, implementation if not sparse else None) |
397 | 447 | R = _get_from_cache(key) |
398 | 448 | if not R is None: return R |
399 | 449 | |
… |
… |
|
437 | 487 | _save_in_cache(key, R) |
438 | 488 | return R |
439 | 489 | |
440 | | def _multi_variate(base_ring, names, n, sparse, order): |
| 490 | def _multi_variate(base_ring, names, n, sparse, order, implementation): |
| 491 | # if not sparse: |
| 492 | # raise ValueError, "A dense representation of multivariate polynomials is not supported" |
| 493 | sparse = False |
| 494 | # "True" would be correct, since there is no dense implementation of |
| 495 | # multivariate polynomials. However, traditionally, "False" is used in the key, |
| 496 | # even though it is meaningless. |
| 497 | |
| 498 | if implementation is not None: |
| 499 | raise ValueError, "The %s implementation is not known for multivariate polynomial rings"%implementation |
| 500 | |
441 | 501 | names = normalize_names(n, names) |
442 | 502 | |
443 | 503 | import sage.rings.polynomial.multi_polynomial_ring as m |
… |
… |
|
460 | 520 | except ( TypeError, NotImplementedError ): |
461 | 521 | R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order) |
462 | 522 | else: |
463 | | try: |
464 | | R = MPolynomialRing_libsingular(base_ring, n, names, order) |
465 | | except ( TypeError, NotImplementedError ): |
| 523 | if not base_ring.is_zero(): |
| 524 | try: |
| 525 | R = MPolynomialRing_libsingular(base_ring, n, names, order) |
| 526 | except ( TypeError, NotImplementedError ): |
| 527 | R = m.MPolynomialRing_polydict(base_ring, n, names, order) |
| 528 | else: |
466 | 529 | R = m.MPolynomialRing_polydict(base_ring, n, names, order) |
467 | | |
468 | 530 | _save_in_cache(key, R) |
469 | 531 | return R |
470 | 532 | |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_template.pxi
a
|
b
|
|
147 | 147 | _parent = get_cparent(parent) |
148 | 148 | |
149 | 149 | celement_construct(&self.x, get_cparent(parent)) |
150 | | |
151 | 150 | gen = celement_new(_parent) |
152 | 151 | monomial = celement_new(_parent) |
153 | 152 | |
… |
… |
|
156 | 155 | |
157 | 156 | for deg, coef in x.iteritems(): |
158 | 157 | celement_pow(monomial, gen, deg, NULL, _parent) |
159 | | celement_mul(monomial, &(<Polynomial_template>parent(coef)).x, monomial, _parent) |
| 158 | celement_mul(monomial, &(<Polynomial_template>self.__class__(parent, coef)).x, monomial, _parent) |
160 | 159 | celement_add(&self.x, &self.x, monomial, _parent) |
161 | 160 | |
162 | 161 | celement_delete(gen, _parent) |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_zmod_flint.pxd
a
|
b
|
|
3 | 3 | pass |
4 | 4 | |
5 | 5 | from sage.libs.flint.zmod_poly cimport zmod_poly_t, zmod_poly_struct |
| 6 | from sage.structure.parent cimport Parent |
6 | 7 | |
7 | 8 | ctypedef zmod_poly_struct celement |
8 | 9 | |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_zmod_flint.pyx
a
|
b
|
|
112 | 112 | e._parent = self._parent |
113 | 113 | return e |
114 | 114 | |
| 115 | cpdef Polynomial _new_constant_poly(self, x, Parent P): |
| 116 | r""" |
| 117 | Quickly creates a new constant polynomial with value x in parent P. |
| 118 | |
| 119 | ASSUMPTION: |
| 120 | |
| 121 | x must convertible to an int. |
| 122 | |
| 123 | The modulus of P must coincide with the modulus of this element. |
| 124 | That assumption is not verified! |
| 125 | |
| 126 | EXAMPLE:: |
| 127 | |
| 128 | sage: R.<x> = GF(3)[] |
| 129 | sage: x._new_constant_poly(4,R) |
| 130 | 1 |
| 131 | sage: x._new_constant_poly('4',R) |
| 132 | 1 |
| 133 | sage: x._new_constant_poly('4.1',R) |
| 134 | Traceback (most recent call last): |
| 135 | ... |
| 136 | ValueError: invalid literal for int() with base 10: '4.1' |
| 137 | |
| 138 | """ |
| 139 | cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) |
| 140 | r._parent = P |
| 141 | zmod_poly_init(&r.x, zmod_poly_modulus(&self.x)) |
| 142 | celement_set_si(&r.x, int(x), get_cparent(P)) |
| 143 | return r |
115 | 144 | |
116 | 145 | cdef _set_list(self, x): |
117 | 146 | """ |
-
diff -r 216c066ba752 sage/rings/polynomial/polynomial_zz_pex.pyx
a
|
b
|
|
77 | 77 | sage: R.<x> = PolynomialRing(K,implementation='NTL') |
78 | 78 | sage: x^2+a |
79 | 79 | x^2 + a |
| 80 | |
| 81 | TEST: |
| 82 | |
| 83 | The following tests against a bug that was fixed in trac ticket #9944. |
| 84 | With the ring definition above, we now have:: |
| 85 | |
| 86 | sage: R([3,'1234']) |
| 87 | 1234*x + 3 |
| 88 | sage: R([3,'12e34']) |
| 89 | Traceback (most recent call last): |
| 90 | ... |
| 91 | TypeError: unable to convert '12e34' into the base ring |
| 92 | sage: R([3,x]) |
| 93 | Traceback (most recent call last): |
| 94 | ... |
| 95 | TypeError: unable to convert x into the base ring |
| 96 | |
80 | 97 | """ |
81 | 98 | cdef cparent _parent |
82 | 99 | cdef ntl_ZZ_pE d |
… |
… |
|
97 | 114 | celement_construct(&self.x, _parent) |
98 | 115 | K = parent.base_ring() |
99 | 116 | for i,e in enumerate(x): |
100 | | if not hasattr(e,'polynomial'): |
| 117 | try: |
| 118 | e_polynomial = e.polynomial() |
| 119 | except (AttributeError, TypeError): |
| 120 | # A type error may occur, since sometimes |
| 121 | # e.polynomial expects an additional argument |
101 | 122 | try: |
102 | | e = K.coerce(e) |
103 | | except: |
104 | | TypeError("unable to coerce this value to the base ring") |
105 | | d = parent._modulus.ZZ_pE(list(e.polynomial())) |
| 123 | # self(x) is supposed to be a conversion, |
| 124 | # not necessarily a coercion. So, we must |
| 125 | # not do K.coerce(e) but K(e). |
| 126 | e = K(e) # K.coerce(e) |
| 127 | e_polynomial = e.polynomial() |
| 128 | except TypeError: |
| 129 | raise TypeError, "unable to convert %s into the base ring"%repr(e) |
| 130 | d = parent._modulus.ZZ_pE(list(e_polynomial)) |
106 | 131 | ZZ_pEX_SetCoeff(self.x, i, d.x) |
107 | 132 | return |
108 | 133 | |
-
diff -r 216c066ba752 sage/rings/power_series_poly.pyx
a
|
b
|
|
46 | 46 | prec = (<PowerSeries_poly>f)._prec |
47 | 47 | f = R((<PowerSeries_poly>f).__f) |
48 | 48 | else: |
| 49 | if f: |
| 50 | f = R(f, check=check) |
| 51 | else: |
| 52 | f = R(None) |
| 53 | else: |
| 54 | if f: |
49 | 55 | f = R(f, check=check) |
50 | | else: |
51 | | f = R(f, check=check) |
| 56 | else: # None is supposed to yield zero |
| 57 | f = R(None) |
52 | 58 | |
53 | 59 | self.__f = f |
54 | 60 | if check and not (prec is infinity): |
… |
… |
|
79 | 85 | |
80 | 86 | sage: A.<z> = RR[[]] |
81 | 87 | sage: f = z - z^3 + O(z^10) |
82 | | sage: f == loads(dumps(f)) # uses __reduce__ |
| 88 | sage: f == loads(dumps(f)) # indirect doctest |
83 | 89 | True |
84 | 90 | """ |
85 | 91 | # do *not* delete old versions. |
-
diff -r 216c066ba752 sage/rings/power_series_ring_element.pyx
a
|
b
|
|
1864 | 1864 | |
1865 | 1865 | g = _solve_linear_de(R, N, L2, a, b, f0) |
1866 | 1866 | |
1867 | | term1 = R(g, check=False) |
1868 | | term2 = R(a[:L], check=False) |
| 1867 | term1 = R(g) # we must not have check=False, since otherwise [..., 0, 0] is not stripped |
| 1868 | term2 = R(a[:L]) #, check=False) |
1869 | 1869 | product = (term1 * term2).list() |
1870 | 1870 | |
1871 | 1871 | # todo: perhaps next loop could be made more efficient |
-
diff -r 216c066ba752 sage/rings/qqbar.py
a
|
b
|
|
375 | 375 | R.<x> = QQbar[] |
376 | 376 | v1 = AA(2) |
377 | 377 | v2 = QQbar(sqrt(v1)) |
378 | | v3 = sqrt(QQbar(3)) |
379 | | v4 = v2*v3 |
380 | | v5 = (1 - v2)*(1 - v3) - 1 - v4 |
381 | | v6 = QQbar(sqrt(v1)) |
382 | | si1 = v6*v3 |
383 | | cp = AA.common_polynomial(x^2 + ((1 - v6)*(1 + v3) - 1 + si1)*x - si1) |
384 | | v7 = QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) |
385 | | v8 = 1 - v7 |
386 | | v9 = v5 + (v8 - 1) |
387 | | v10 = -1 - v3 - QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) |
388 | | v11 = 1 + v10 |
389 | | v12 = v8*(v5 + v4) - (v5 - v4*v7) |
390 | | si2 = v4*v7 |
391 | | AA.polynomial_root(AA.common_polynomial(x^4 + (v9 + (v11 - 1))*x^3 + (v12 + (v11*v9 - v9))*x^2 + (v11*(v12 - si2) - (v12 - si2*v10))*x - si2*v10), RIF(RR(0.99999999999999989), RR(1.0000000000000002))) |
| 378 | v3 = QQbar(3) |
| 379 | v4 = sqrt(v3) |
| 380 | v5 = v2*v4 |
| 381 | v6 = (1 - v2)*(1 - v4) - 1 - v5 |
| 382 | v7 = QQbar(sqrt(v1)) |
| 383 | v8 = sqrt(v3) |
| 384 | si1 = v7*v8 |
| 385 | cp = AA.common_polynomial(x^2 + ((1 - v7)*(1 + v8) - 1 + si1)*x - si1) |
| 386 | v9 = QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) |
| 387 | v10 = 1 - v9 |
| 388 | v11 = v6 + (v10 - 1) |
| 389 | v12 = -1 - v4 - QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) |
| 390 | v13 = 1 + v12 |
| 391 | v14 = v10*(v6 + v5) - (v6 - v5*v9) |
| 392 | si2 = v5*v9 |
| 393 | AA.polynomial_root(AA.common_polynomial(x^4 + (v11 + (v13 - 1))*x^3 + (v14 + (v13*v11 - v11))*x^2 + (v13*(v14 - si2) - (v14 - si2*v12))*x - si2*v12), RIF(RR(0.99999999999999989), RR(1.0000000000000002))) |
392 | 394 | sage: one |
393 | 395 | 1 |
394 | 396 | |
-
diff -r 216c066ba752 sage/rings/ring.pyx
a
|
b
|
|
361 | 361 | break |
362 | 362 | |
363 | 363 | if len(gens) == 0: |
364 | | gens = [self(0)] |
| 364 | gens = [self.zero_element()] |
365 | 365 | |
366 | 366 | if coerce: |
367 | 367 | #print [type(g) for g in gens] |
… |
… |
|
492 | 492 | True |
493 | 493 | """ |
494 | 494 | if self._zero_ideal is None: |
495 | | I = Ring.ideal(self, [self(0)], coerce=False) |
| 495 | I = Ring.ideal(self, [self.zero_element()], coerce=False) |
496 | 496 | self._zero_ideal = I |
497 | 497 | return I |
498 | 498 | return self._zero_ideal |
-
diff -r 216c066ba752 sage/schemes/elliptic_curves/monsky_washnitzer.py
a
|
b
|
|
1387 | 1387 | answer mod `p^{\mathrm{prec}}` at the end. |
1388 | 1388 | |
1389 | 1389 | |
1390 | | OUTPUT: 2x2 matrix of frobenius on Monsky-Washnitzer cohomology, |
| 1390 | OUTPUT: |
| 1391 | |
| 1392 | 2x2 matrix of frobenius on Monsky-Washnitzer cohomology, |
1391 | 1393 | with entries in the coefficient ring of Q. |
1392 | 1394 | |
1393 | | EXAMPLES: A simple example:: |
| 1395 | EXAMPLES: |
| 1396 | |
| 1397 | A simple example:: |
1394 | 1398 | |
1395 | 1399 | sage: p = 5 |
1396 | 1400 | sage: prec = 3 |
-
diff -r 216c066ba752 sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py
a
|
b
|
|
35 | 35 | |
36 | 36 | |
37 | 37 | INPUT: |
38 | | - P and Q points on self in the same residue disc |
| 38 | |
| 39 | - P and Q points on self in the same residue disc |
39 | 40 | |
40 | 41 | OUTPUT: |
41 | | Returns a point $X(t) = ( x(t) : y(t) : z(t) )$ such that |
| 42 | |
| 43 | Returns a point $X(t) = ( x(t) : y(t) : z(t) )$ such that |
| 44 | |
42 | 45 | (1) $X(0) = P$ and $X(1) = Q$ if $P, Q$ are not in the infinite disc |
43 | 46 | (2) $X(P[0]^g}/P[1]) = P$ and $X(Q[0]^g/Q[1]) = Q$ if $P, Q$ are in the infinite disc |
44 | 47 | |
45 | | EXAMPLES: |
| 48 | EXAMPLES:: |
| 49 | |
46 | 50 | sage: R.<x> = QQ['x'] |
47 | 51 | sage: H = HyperellipticCurve(x^3-10*x+9) |
48 | 52 | sage: K = Qp(5,8) |
49 | 53 | sage: HK = H.change_ring(K) |
50 | 54 | |
51 | | A non-Weierstrass disc: |
| 55 | A non-Weierstrass disc:: |
| 56 | |
52 | 57 | sage: P = HK(0,3) |
53 | 58 | sage: Q = HK(5, 3 + 3*5^2 + 2*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)) |
54 | 59 | sage: x,y,z, = HK.local_analytic_interpolation(P,Q) |
55 | 60 | sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1] |
56 | 61 | (True, True, True, True) |
57 | 62 | |
58 | | A finite Weierstrass disc |
| 63 | A finite Weierstrass disc:: |
| 64 | |
59 | 65 | sage: P = HK.lift_x(1 + 2*5^2) |
60 | 66 | sage: Q = HK.lift_x(1 + 3*5^2) |
61 | 67 | sage: x,y,z = HK.local_analytic_interpolation(P,Q) |
62 | 68 | sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1] |
63 | 69 | (True, True, True, True) |
64 | 70 | |
65 | | The infinite disc |
| 71 | The infinite disc:: |
| 72 | |
66 | 73 | sage: P = HK.lift_x(5^-2) |
67 | 74 | sage: Q = HK.lift_x(4*5^-2) |
68 | 75 | sage: x,y,z = HK.local_analytic_interpolation(P,Q) |
… |
… |
|
77 | 84 | sage: y(Q[0]/Q[1]) == Q[1] |
78 | 85 | True |
79 | 86 | |
80 | | An error if points are not in the same disc: |
| 87 | An error if points are not in the same disc:: |
| 88 | |
81 | 89 | sage: x,y,z = HK.local_analytic_interpolation(P,HK(1,0)) |
82 | 90 | Traceback (most recent call last): |
83 | 91 | ... |
84 | 92 | ValueError: (5^-2 + O(5^6) : 5^-3 + 4*5^2 + 5^3 + 3*5^4 + O(5^5) : 1 + O(5^8)) and (1 + O(5^8) : 0 : 1 + O(5^8)) are not in the same residue disc |
85 | 93 | |
86 | 94 | AUTHORS: |
87 | | - Robert Bradshaw (2007-03) |
88 | | - Jennifer Balakrishnan (2010-02) |
| 95 | |
| 96 | - Robert Bradshaw (2007-03) |
| 97 | - Jennifer Balakrishnan (2010-02) |
89 | 98 | """ |
90 | 99 | prec = self.base_ring().precision_cap() |
91 | 100 | if self.is_same_disc(P,Q) == False: |
… |
… |
|
118 | 127 | that is, the point at infinity and those points in the suport |
119 | 128 | of the divisor of $y$ |
120 | 129 | |
121 | | EXAMPLES: |
| 130 | EXAMPLES:: |
| 131 | |
122 | 132 | sage: K = pAdicField(11, 5) |
123 | 133 | sage: x = polygen(K) |
124 | 134 | sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) |
… |
… |
|
134 | 144 | """ |
135 | 145 | Checks if $P$ is in a Weierstrass disc |
136 | 146 | |
137 | | EXAMPLES: |
| 147 | EXAMPLES:: |
| 148 | |
138 | 149 | sage: R.<x> = QQ['x'] |
139 | 150 | sage: H = HyperellipticCurve(x^3-10*x+9) |
140 | 151 | sage: K = Qp(5,8) |
… |
… |
|
154 | 165 | True |
155 | 166 | |
156 | 167 | AUTHOR: |
157 | | - Jennifer Balakrishnan (2010-02) |
| 168 | |
| 169 | - Jennifer Balakrishnan (2010-02) |
158 | 170 | """ |
159 | 171 | if (P[1].valuation() == 0 and P != self(0,1,0)): |
160 | 172 | return False |
… |
… |
|
165 | 177 | """ |
166 | 178 | Checks if $P$ is a Weierstrass point (i.e., fixed by the hyperelliptic involution) |
167 | 179 | |
168 | | EXAMPLES: |
| 180 | EXAMPLES:: |
| 181 | |
169 | 182 | sage: R.<x> = QQ['x'] |
170 | 183 | sage: H = HyperellipticCurve(x^3-10*x+9) |
171 | 184 | sage: K = Qp(5,8) |
… |
… |
|
185 | 198 | False |
186 | 199 | |
187 | 200 | AUTHOR: |
188 | | - Jennifer Balakrishnan (2010-02) |
| 201 | |
| 202 | - Jennifer Balakrishnan (2010-02) |
189 | 203 | |
190 | 204 | """ |
191 | 205 | if (P[1] == 0 or P[2] ==0): |
… |
… |
|
198 | 212 | Given $Q$ a point on self in a Weierstrass disc, finds the |
199 | 213 | center of the Weierstrass disc (if defined over self.base_ring()) |
200 | 214 | |
201 | | EXAMPLES: |
| 215 | EXAMPLES:: |
| 216 | |
202 | 217 | sage: R.<x> = QQ['x'] |
203 | 218 | sage: H = HyperellipticCurve(x^3-10*x+9) |
204 | 219 | sage: K = Qp(5,8) |
… |
… |
|
217 | 232 | (0 : 1 + O(5^8) : 0) |
218 | 233 | |
219 | 234 | AUTHOR: |
220 | | - Jennifer Balakrishnan |
| 235 | |
| 236 | - Jennifer Balakrishnan |
221 | 237 | """ |
222 | 238 | if self.is_in_weierstrass_disc(Q) == False: |
223 | 239 | raise ValueError, "%s is not in a Weierstrass disc"%Q |
… |
… |
|
230 | 246 | """ |
231 | 247 | Gives the residue disc of $P$ |
232 | 248 | |
233 | | EXAMPLES: |
| 249 | EXAMPLES:: |
| 250 | |
234 | 251 | sage: R.<x> = QQ['x'] |
235 | 252 | sage: H = HyperellipticCurve(x^3-10*x+9) |
236 | 253 | sage: K = Qp(5,8) |
… |
… |
|
249 | 266 | (0 : 1 : 0) |
250 | 267 | |
251 | 268 | AUTHOR: |
252 | | - Jennifer Balakrishnan |
| 269 | |
| 270 | - Jennifer Balakrishnan |
253 | 271 | """ |
254 | 272 | xPv = P[0].valuation() |
255 | 273 | yPv = P[1].valuation() |
… |
… |
|
274 | 292 | """ |
275 | 293 | Checks if $P,Q$ are in same residue disc |
276 | 294 | |
277 | | EXAMPLES: |
| 295 | EXAMPLES:: |
| 296 | |
278 | 297 | sage: R.<x> = QQ['x'] |
279 | 298 | sage: H = HyperellipticCurve(x^3-10*x+9) |
280 | 299 | sage: K = Qp(5,8) |
… |
… |
|
295 | 314 | return False |
296 | 315 | |
297 | 316 | def tiny_integrals(self, F, P, Q): |
298 | | """ |
| 317 | r""" |
299 | 318 | Evaluate the integrals of $f_i dx/2y$ from $P$ to $Q$ for each $f_i$ in $F$ |
300 | 319 | by formally integrating a power series in a local parameter $t$ |
301 | 320 | |
302 | 321 | $P$ and $Q$ MUST be in the same residue disk for this result to make sense. |
303 | 322 | |
304 | 323 | INPUT: |
305 | | - F a list of functions $f_i$ |
306 | | - P a point on self |
307 | | - Q a point on self (in the same residue disc as P) |
| 324 | |
| 325 | - F a list of functions $f_i$ |
| 326 | - P a point on self |
| 327 | - Q a point on self (in the same residue disc as P) |
308 | 328 | |
309 | 329 | OUTPUT: |
310 | | The integrals $\int_P^Q f_i dx/2y$ |
311 | 330 | |
312 | | EXAMPLES: |
| 331 | The integrals $\int_P^Q f_i dx/2y$ |
| 332 | |
| 333 | EXAMPLES:: |
| 334 | |
313 | 335 | sage: K = pAdicField(17, 5) |
314 | 336 | sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a |
315 | 337 | sage: P = E(K(14/3), K(11/2)) |
… |
… |
|
318 | 340 | sage: E.tiny_integrals([1,x],P, TP) == E.tiny_integrals_on_basis(P,TP) |
319 | 341 | True |
320 | 342 | |
| 343 | :: |
| 344 | |
321 | 345 | sage: K = pAdicField(11, 5) |
322 | 346 | sage: x = polygen(K) |
323 | 347 | sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) |
… |
… |
|
326 | 350 | sage: C.tiny_integrals([1],P,Q) |
327 | 351 | (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8)) |
328 | 352 | |
329 | | Note that this fails if the points are not in the same residue disc: |
| 353 | Note that this fails if the points are not in the same residue disc:: |
| 354 | |
330 | 355 | sage: S = C(0,1/4) |
331 | 356 | sage: C.tiny_integrals([1,x,x^2,x^3],P,S) |
332 | 357 | Traceback (most recent call last): |
… |
… |
|
354 | 379 | return vector(integrals) |
355 | 380 | |
356 | 381 | def tiny_integrals_on_basis(self, P, Q): |
357 | | """ |
| 382 | r""" |
358 | 383 | Evaluate the integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
359 | 384 | by formally integrating a power series in a local parameter $t$. |
360 | 385 | $P$ and $Q$ MUST be in the same residue disc for this result to make sense. |
361 | 386 | |
362 | 387 | INPUT: |
363 | | - P a point on self |
364 | | - Q a point on self (in the same residue disc as P) |
| 388 | |
| 389 | - P a point on self |
| 390 | - Q a point on self (in the same residue disc as P) |
365 | 391 | |
366 | 392 | OUTPUT: |
367 | | The integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
368 | 393 | |
369 | | EXAMPLES: |
| 394 | The integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
| 395 | |
| 396 | EXAMPLES:: |
| 397 | |
370 | 398 | sage: K = pAdicField(17, 5) |
371 | 399 | sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a |
372 | 400 | sage: P = E(K(14/3), K(11/2)) |
373 | 401 | sage: TP = E.teichmuller(P); |
374 | 402 | sage: E.tiny_integrals_on_basis(P, TP) |
375 | 403 | (17 + 14*17^2 + 17^3 + 8*17^4 + O(17^5), 16*17 + 5*17^2 + 8*17^3 + 14*17^4 + O(17^5)) |
| 404 | |
| 405 | :: |
376 | 406 | |
377 | 407 | sage: K = pAdicField(11, 5) |
378 | 408 | sage: x = polygen(K) |
… |
… |
|
383 | 413 | (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2)) |
384 | 414 | |
385 | 415 | |
386 | | Note that this fails if the points are not in the same residue disc: |
| 416 | Note that this fails if the points are not in the same residue disc:: |
| 417 | |
387 | 418 | sage: S = C(0,1/4) |
388 | 419 | sage: C.tiny_integrals_on_basis(P,S) |
389 | 420 | Traceback (most recent call last): |
… |
… |
|
400 | 431 | |
401 | 432 | |
402 | 433 | def teichmuller(self, P): |
403 | | """ |
| 434 | r""" |
404 | 435 | Find a Teichm\:uller point in the same residue class of $P$. |
405 | 436 | |
406 | 437 | Because this lift of frobenius acts as $x \mapsto x^p$, |
407 | 438 | take the Teichmuller lift of $x$ and then find a matching $y$ |
408 | 439 | from that. |
409 | 440 | |
410 | | EXAMPLES: |
| 441 | EXAMPLES:: |
| 442 | |
411 | 443 | sage: K = pAdicField(7, 5) |
412 | 444 | sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a |
413 | 445 | sage: P = E(K(14/3), K(11/2)) |
… |
… |
|
431 | 463 | |
432 | 464 | |
433 | 465 | def coleman_integrals_on_basis(self, P, Q, algorithm=None): |
434 | | """ |
| 466 | r""" |
435 | 467 | Computes the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
436 | 468 | |
437 | 469 | INPUT: |
438 | | - P point on self |
439 | | - Q point on self |
440 | | - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) |
| 470 | |
| 471 | - P point on self |
| 472 | - Q point on self |
| 473 | - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) |
441 | 474 | |
442 | 475 | OUTPUT: |
443 | | the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
| 476 | |
| 477 | the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
444 | 478 | |
445 | | EXAMPLES: |
| 479 | EXAMPLES:: |
| 480 | |
446 | 481 | sage: K = pAdicField(11, 5) |
447 | 482 | sage: x = polygen(K) |
448 | 483 | sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) |
… |
… |
|
453 | 488 | sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller') |
454 | 489 | (10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5)) |
455 | 490 | |
| 491 | :: |
| 492 | |
456 | 493 | sage: K = pAdicField(11,5) |
457 | 494 | sage: x = polygen(K) |
458 | 495 | sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) |
… |
… |
|
460 | 497 | sage: Q = C.lift_x(3*11^(-2)) |
461 | 498 | sage: C.coleman_integrals_on_basis(P, Q) |
462 | 499 | (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2)) |
463 | | |
| 500 | |
| 501 | :: |
| 502 | |
464 | 503 | sage: R = C(0,1/4) |
465 | 504 | sage: a = C.coleman_integrals_on_basis(P,R) # long time (7s on sage.math, 2011) |
466 | 505 | sage: b = C.coleman_integrals_on_basis(R,Q) # long time (9s on sage.math, 2011) |
… |
… |
|
468 | 507 | sage: a+b == c # long time |
469 | 508 | True |
470 | 509 | |
| 510 | :: |
| 511 | |
471 | 512 | sage: R.<x> = QQ['x'] |
472 | 513 | sage: H = HyperellipticCurve(x^3-10*x+9) |
473 | 514 | sage: K = Qp(5,8) |
… |
… |
|
495 | 536 | (0, 0) |
496 | 537 | |
497 | 538 | AUTHORS: |
498 | | - Robert Bradshaw (2007-03): non-Weierstrass points |
499 | | - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points |
| 539 | |
| 540 | - Robert Bradshaw (2007-03): non-Weierstrass points |
| 541 | - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points |
500 | 542 | """ |
501 | 543 | import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer |
502 | 544 | from sage.misc.profiler import Profiler |
… |
… |
|
623 | 665 | """ |
624 | 666 | Returns the invariant differential $dx/2y$ on self |
625 | 667 | |
626 | | EXAMPLES: |
| 668 | EXAMPLES:: |
| 669 | |
627 | 670 | sage: R.<x> = QQ['x'] |
628 | 671 | sage: H = HyperellipticCurve(x^3+1) |
629 | 672 | sage: K = Qp(5,8) |
… |
… |
|
631 | 674 | sage: w = HK.invariant_differential(); w |
632 | 675 | (((1+O(5^8)))*1) dx/2y |
633 | 676 | |
| 677 | :: |
| 678 | |
634 | 679 | sage: K = pAdicField(11, 6) |
635 | 680 | sage: x = polygen(K) |
636 | 681 | sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) |
… |
… |
|
644 | 689 | return MW.invariant_differential() |
645 | 690 | |
646 | 691 | def coleman_integral(self, w, P, Q, algorithm = 'None'): |
647 | | """ |
| 692 | r""" |
648 | 693 | Returns the Coleman integral $\int_P^Q w$ |
649 | 694 | |
650 | 695 | INPUT: |
651 | | - w differential (if one of P,Q is Weierstrass, w must be odd) |
652 | | - P point on self |
653 | | - Q point on self |
654 | | - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) |
| 696 | |
| 697 | - w differential (if one of P,Q is Weierstrass, w must be odd) |
| 698 | - P point on self |
| 699 | - Q point on self |
| 700 | - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) |
655 | 701 | |
656 | 702 | OUTPUT: |
657 | | the Coleman integral $\int_P^Q w$ |
| 703 | |
| 704 | the Coleman integral $\int_P^Q w$ |
658 | 705 | |
659 | 706 | EXAMPLES: |
| 707 | |
660 | 708 | Example of Leprevost from Kiran Kedlaya |
661 | 709 | The first two should be zero as $(P-Q) = 30(P-Q)$ in the Jacobian |
662 | | and $dx/2y$ and $x dx/2y$ are holomorphic. |
| 710 | and $dx/2y$ and $x dx/2y$ are holomorphic. |
| 711 | :: |
663 | 712 | |
664 | 713 | sage: K = pAdicField(11, 6) |
665 | 714 | sage: x = polygen(K) |
… |
… |
|
674 | 723 | O(11^6) |
675 | 724 | sage: C.coleman_integral(x^2*w, P, Q) |
676 | 725 | 7*11 + 6*11^2 + 3*11^3 + 11^4 + 5*11^5 + O(11^6) |
677 | | |
| 726 | |
| 727 | :: |
| 728 | |
678 | 729 | sage: p = 71; m = 4 |
679 | 730 | sage: K = pAdicField(p, m) |
680 | 731 | sage: x = polygen(K) |
… |
… |
|
690 | 741 | 21*71 + 67*71^2 + 27*71^3 + O(71^4) |
691 | 742 | sage: w.integrate(P, R) + w.integrate(P1, R1) |
692 | 743 | O(71^4) |
693 | | |
694 | | A simple example, integrating dx: |
695 | | |
| 744 | |
| 745 | A simple example, integrating dx:: |
| 746 | |
696 | 747 | sage: R.<x> = QQ['x'] |
697 | 748 | sage: E= HyperellipticCurve(x^3-4*x+4) |
698 | 749 | sage: K = Qp(5,10) |
… |
… |
|
704 | 755 | 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) |
705 | 756 | sage: Q[0] - P[0] |
706 | 757 | 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) |
707 | | |
708 | | Yet another example: |
| 758 | |
| 759 | Yet another example:: |
709 | 760 | |
710 | 761 | sage: R.<x> = QQ['x'] |
711 | 762 | sage: H = HyperellipticCurve(x*(x-1)*(x+9)) |
… |
… |
|
723 | 774 | sage: HK.coleman_integral(b,P,Q) |
724 | 775 | 7 + 7^2 + 4*7^3 + 5*7^4 + 3*7^5 + 7^6 + 5*7^7 + 3*7^8 + 4*7^9 + 4*7^10 + O(7^11) |
725 | 776 | |
| 777 | :: |
| 778 | |
726 | 779 | sage: R.<x> = QQ['x'] |
727 | 780 | sage: H = HyperellipticCurve(x^3+1) |
728 | 781 | sage: K = Qp(5,8) |
… |
… |
|
739 | 792 | 3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9) |
740 | 793 | sage: HK.coleman_integral(w,P,Q) |
741 | 794 | 3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9) |
742 | | |
743 | | Integrals involving Weierstrass points: |
| 795 | |
| 796 | Integrals involving Weierstrass points:: |
744 | 797 | |
745 | 798 | sage: R.<x> = QQ['x'] |
746 | 799 | sage: H = HyperellipticCurve(x^3-10*x+9) |
… |
… |
|
770 | 823 | 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9) |
771 | 824 | |
772 | 825 | AUTHORS: |
773 | | - Robert Bradshaw (2007-03) |
774 | | - Kiran Kedlaya (2008-05) |
775 | | - Jennifer Balakrishnan (2010-02) |
| 826 | |
| 827 | - Robert Bradshaw (2007-03) |
| 828 | - Kiran Kedlaya (2008-05) |
| 829 | - Jennifer Balakrishnan (2010-02) |
776 | 830 | |
777 | 831 | """ |
778 | 832 | # TODO: implement Jacobians and show the relationship directly |
… |
… |
|
810 | 864 | """ |
811 | 865 | Returns the $p$-th power lift of Frobenius of $P$ |
812 | 866 | |
813 | | EXAMPLES: |
| 867 | EXAMPLES:: |
| 868 | |
814 | 869 | sage: K = Qp(11, 5) |
815 | 870 | sage: R.<x> = K[] |
816 | 871 | sage: E = HyperellipticCurve(x^5 - 21*x - 20) |
817 | 872 | sage: P = E.lift_x(2) |
818 | 873 | sage: E.frobenius(P) |
819 | 874 | (2 + 10*11 + 5*11^2 + 11^3 + O(11^5) : 5 + 9*11 + 2*11^2 + 2*11^3 + O(11^5) : 1 + O(11^5)) |
820 | | |
821 | 875 | sage: Q = E.teichmuller(P); Q |
822 | 876 | (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5)) |
823 | 877 | sage: E.frobenius(Q) |
824 | 878 | (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5)) |
825 | 879 | |
| 880 | :: |
| 881 | |
826 | 882 | sage: R.<x> = QQ[] |
827 | 883 | sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) |
828 | 884 | sage: Q = H(0,0) |
… |
… |
|
845 | 901 | 1 + O(a^100)) |
846 | 902 | |
847 | 903 | AUTHORS: |
848 | | - Robert Bradshaw and Jennifer Balakrishnan (2010-02) |
| 904 | |
| 905 | - Robert Bradshaw and Jennifer Balakrishnan (2010-02) |
849 | 906 | """ |
850 | 907 | try: |
851 | 908 | _frob = self._frob |
… |
… |
|
895 | 952 | return _frob(P) |
896 | 953 | |
897 | 954 | def newton_sqrt(self,f,x0, prec): |
898 | | """ |
899 | | NOTE: this function should eventually be moved to $p$-adic power series ring |
| 955 | r""" |
| 956 | Takes the square root of the power series $f$ by Newton's method |
| 957 | |
| 958 | NOTE: |
| 959 | |
| 960 | this function should eventually be moved to $p$-adic power series ring |
900 | 961 | |
901 | | takes the square root of the power series $f$ by Newton's method |
902 | 962 | |
903 | 963 | INPUT: |
904 | | - f power series wtih coefficients in $\Q_p$ or an extension |
905 | | - x0 seeds the Newton iteration |
906 | | - prec precision |
| 964 | |
| 965 | - f power series wtih coefficients in $\Q_p$ or an extension |
| 966 | - x0 seeds the Newton iteration |
| 967 | - prec precision |
907 | 968 | |
908 | 969 | OUTPUT: |
909 | | the square root of $f$ |
910 | 970 | |
911 | | EXAMPLES: |
| 971 | the square root of $f$ |
| 972 | |
| 973 | EXAMPLES:: |
| 974 | |
912 | 975 | sage: R.<x> = QQ['x'] |
913 | 976 | sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) |
914 | 977 | sage: Q = H(0,0) |
… |
… |
|
924 | 987 | O(a^122) |
925 | 988 | |
926 | 989 | AUTHOR: |
927 | | - Jennifer Balakrishnan |
| 990 | |
| 991 | - Jennifer Balakrishnan |
928 | 992 | |
929 | 993 | """ |
930 | 994 | z = x0 |
… |
… |
|
945 | 1009 | return z |
946 | 1010 | |
947 | 1011 | def curve_over_ram_extn(self,deg): |
948 | | """ |
| 1012 | r""" |
949 | 1013 | Returns self over $\Q_p(p^(1/deg))$ |
950 | 1014 | |
951 | 1015 | INPUT: |
952 | | - deg: the degree of the ramified extension |
| 1016 | |
| 1017 | - deg: the degree of the ramified extension |
953 | 1018 | |
954 | 1019 | OUTPUT: |
955 | | self over $\Q_p(p^(1/deg))$ |
956 | 1020 | |
957 | | EXAMPLES: |
| 1021 | self over $\Q_p(p^(1/deg))$ |
| 1022 | |
| 1023 | EXAMPLES:: |
| 1024 | |
958 | 1025 | sage: R.<x> = QQ['x'] |
959 | 1026 | sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) |
960 | 1027 | sage: K = Qp(11,5) |
… |
… |
|
964 | 1031 | Hyperelliptic Curve over Eisenstein Extension of 11-adic Field with capped relative precision 5 in a defined by (1 + O(11^5))*x^2 + (O(11^6))*x + (10*11 + 10*11^2 + 10*11^3 + 10*11^4 + 10*11^5 + O(11^6)) defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x |
965 | 1032 | |
966 | 1033 | AUTHOR: |
967 | | - Jennifer Balakrishnan |
| 1034 | |
| 1035 | - Jennifer Balakrishnan |
968 | 1036 | |
969 | 1037 | """ |
970 | 1038 | from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve |
… |
… |
|
985 | 1053 | Given self over an extension field, find a point in the disc of $P$ near the boundary |
986 | 1054 | |
987 | 1055 | INPUT: |
988 | | - curve_over_extn: self over a totally ramified extension |
989 | | - P: Weierstrass point |
| 1056 | |
| 1057 | - curve_over_extn: self over a totally ramified extension |
| 1058 | - P: Weierstrass point |
990 | 1059 | |
991 | 1060 | OUTPUT: |
992 | | a point in the disc of $P$ near the boundary |
| 1061 | |
| 1062 | a point in the disc of $P$ near the boundary |
993 | 1063 | |
994 | | EXAMPLES: |
| 1064 | EXAMPLES:: |
| 1065 | |
995 | 1066 | sage: R.<x> = QQ['x'] |
996 | 1067 | sage: H = HyperellipticCurve(x^3-10*x+9) |
997 | 1068 | sage: K = Qp(3,6) |
… |
… |
|
1004 | 1075 | (1 + 2*a^2 + 2*a^6 + 2*a^18 + a^32 + a^34 + a^36 + 2*a^38 + 2*a^40 + a^42 + 2*a^44 + a^48 + 2*a^50 + 2*a^52 + a^54 + a^56 + 2*a^60 + 2*a^62 + a^70 + 2*a^72 + a^76 + 2*a^78 + a^82 + a^88 + a^96 + 2*a^98 + 2*a^102 + a^104 + 2*a^106 + a^108 + 2*a^110 + a^112 + 2*a^116 + a^126 + 2*a^130 + 2*a^132 + a^144 + 2*a^148 + 2*a^150 + a^152 + 2*a^154 + a^162 + a^164 + a^166 + a^168 + a^170 + a^176 + a^178 + O(a^180) : a + O(a^181) : 1 + O(a^180)) |
1005 | 1076 | |
1006 | 1077 | AUTHOR: |
1007 | | - Jennifer Balakrishnan |
| 1078 | |
| 1079 | - Jennifer Balakrishnan |
1008 | 1080 | |
1009 | 1081 | """ |
1010 | 1082 | J = curve_over_extn.base_ring() |
… |
… |
|
1014 | 1086 | return curve_over_extn(x(a),y(a)) |
1015 | 1087 | |
1016 | 1088 | def P_to_S(self, P, S): |
1017 | | """ |
| 1089 | r""" |
1018 | 1090 | Given a finite Weierstrass point $P$ and a point $S$ |
1019 | 1091 | in the same disc, computes the Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ |
1020 | 1092 | |
1021 | 1093 | INPUT: |
1022 | | - P: finite Weierstrass point |
1023 | | - S: point in disc of P |
| 1094 | |
| 1095 | - P: finite Weierstrass point |
| 1096 | - S: point in disc of P |
1024 | 1097 | |
1025 | 1098 | OUTPUT: |
1026 | | Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ |
| 1099 | |
| 1100 | Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ |
1027 | 1101 | |
1028 | | EXAMPLES: |
| 1102 | EXAMPLES:: |
| 1103 | |
1029 | 1104 | sage: R.<x> = QQ['x'] |
1030 | 1105 | sage: H = HyperellipticCurve(x^3-10*x+9) |
1031 | 1106 | sage: K = Qp(5,4) |
… |
… |
|
1037 | 1112 | (2*a + 4*a^3 + 2*a^11 + 4*a^13 + 2*a^17 + 2*a^19 + a^21 + 4*a^23 + a^25 + 2*a^27 + 2*a^29 + 3*a^31 + 4*a^33 + O(a^35), a^-5 + 2*a + 2*a^3 + a^7 + 3*a^11 + a^13 + 3*a^15 + 3*a^17 + 2*a^19 + 4*a^21 + 4*a^23 + 4*a^25 + 2*a^27 + a^29 + a^31 + 3*a^33 + O(a^35)) |
1038 | 1113 | |
1039 | 1114 | AUTHOR: |
1040 | | - Jennifer Balakrishnan |
| 1115 | |
| 1116 | - Jennifer Balakrishnan |
1041 | 1117 | |
1042 | 1118 | """ |
1043 | 1119 | prec = self.base_ring().precision_cap() |
… |
… |
|
1050 | 1126 | return vector(val) |
1051 | 1127 | |
1052 | 1128 | def coleman_integral_P_to_S(self,w,P,S): |
1053 | | """ |
| 1129 | r""" |
1054 | 1130 | Given a finite Weierstrass point $P$ and a point $S$ |
1055 | 1131 | in the same disc, computes the Coleman integral $\int_P^S w$ |
1056 | 1132 | |
1057 | 1133 | INPUT: |
1058 | | - w: differential |
1059 | | - P: Weierstrass point |
1060 | | - S: point in the same disc of P (S is defined over an extension of $\Q_p$; coordinates |
1061 | | of S are given in terms of uniformizer $a$) |
| 1134 | |
| 1135 | - w: differential |
| 1136 | - P: Weierstrass point |
| 1137 | - S: point in the same disc of P (S is defined over an extension of $\Q_p$; coordinates |
| 1138 | of S are given in terms of uniformizer $a$) |
1062 | 1139 | |
1063 | 1140 | OUTPUT: |
1064 | | Coleman integral $\int_P^S w$ in terms of $a$ |
| 1141 | |
| 1142 | Coleman integral $\int_P^S w$ in terms of $a$ |
1065 | 1143 | |
1066 | | EXAMPLES: |
| 1144 | EXAMPLES:: |
| 1145 | |
1067 | 1146 | sage: R.<x> = QQ['x'] |
1068 | 1147 | sage: H = HyperellipticCurve(x^3-10*x+9) |
1069 | 1148 | sage: K = Qp(5,4) |
… |
… |
|
1079 | 1158 | True |
1080 | 1159 | |
1081 | 1160 | AUTHOR: |
1082 | | - Jennifer Balakrishnan |
| 1161 | |
| 1162 | - Jennifer Balakrishnan |
1083 | 1163 | |
1084 | 1164 | """ |
1085 | 1165 | prec = self.base_ring().precision_cap() |
… |
… |
|
1092 | 1172 | return int_sing_a |
1093 | 1173 | |
1094 | 1174 | def S_to_Q(self,S,Q): |
1095 | | """ |
| 1175 | r""" |
1096 | 1176 | Given $S$ a point on self over an extension field, computes the |
1097 | 1177 | Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ |
1098 | 1178 | |
1099 | 1179 | **one should be able to feed $S,Q$ into coleman_integral, |
1100 | | but currently that segfaults |
| 1180 | but currently that segfaults** |
1101 | 1181 | |
1102 | 1182 | INPUT: |
1103 | | - S: a point with coordinates in an extension of $\Q_p$ (with unif. a) |
1104 | | - Q: a non-Weierstrass point defined over $\Q_p$ |
| 1183 | |
| 1184 | - S: a point with coordinates in an extension of $\Q_p$ (with unif. a) |
| 1185 | - Q: a non-Weierstrass point defined over $\Q_p$ |
1105 | 1186 | |
1106 | 1187 | OUTPUT: |
1107 | | the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ in terms of $a$ |
| 1188 | |
| 1189 | the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ in terms of $a$ |
1108 | 1190 | |
1109 | | EXAMPLES: |
| 1191 | EXAMPLES:: |
| 1192 | |
1110 | 1193 | sage: R.<x> = QQ['x'] |
1111 | 1194 | sage: H = HyperellipticCurve(x^3-10*x+9) |
1112 | 1195 | sage: K = Qp(5,6) |
… |
… |
|
1126 | 1209 | (2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 5^6 + O(5^7)) |
1127 | 1210 | |
1128 | 1211 | AUTHOR: |
1129 | | - Jennifer Balakrishnan |
| 1212 | |
| 1213 | - Jennifer Balakrishnan |
1130 | 1214 | |
1131 | 1215 | """ |
1132 | 1216 | FS = self.frobenius(S) |
… |
… |
|
1174 | 1258 | return B*(b-S_to_FS-FQ_to_Q) |
1175 | 1259 | |
1176 | 1260 | def coleman_integral_S_to_Q(self,w,S,Q): |
1177 | | """ |
| 1261 | r""" |
1178 | 1262 | Computes the Coleman integral $\int_S^Q w$ |
1179 | 1263 | |
1180 | 1264 | **one should be able to feed $S,Q$ into coleman_integral, |
1181 | | but currently that segfaults |
| 1265 | but currently that segfaults** |
1182 | 1266 | |
1183 | 1267 | INPUT: |
1184 | | - w: a differential |
1185 | | - S: a point with coordinates in an extension of \Q_p |
1186 | | - Q: a non-Weierstrass point defined over \Q_p |
| 1268 | |
| 1269 | - w: a differential |
| 1270 | - S: a point with coordinates in an extension of $\Q_p$ |
| 1271 | - Q: a non-Weierstrass point defined over $\Q_p$ |
1187 | 1272 | |
1188 | 1273 | OUTPUT: |
1189 | | the Coleman integral $\int_S^Q w$ |
1190 | 1274 | |
1191 | | EXAMPLES: |
| 1275 | the Coleman integral $\int_S^Q w$ |
| 1276 | |
| 1277 | EXAMPLES:: |
| 1278 | |
1192 | 1279 | sage: R.<x> = QQ['x'] |
1193 | 1280 | sage: H = HyperellipticCurve(x^3-10*x+9) |
1194 | 1281 | sage: K = Qp(5,6) |
… |
… |
|
1207 | 1294 | 3 + O(5^6) |
1208 | 1295 | |
1209 | 1296 | AUTHOR: |
1210 | | - Jennifer Balakrishnan |
| 1297 | |
| 1298 | - Jennifer Balakrishnan |
1211 | 1299 | |
1212 | 1300 | """ |
1213 | 1301 | import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer |
… |
… |
|
1227 | 1315 | return const + dot |
1228 | 1316 | |
1229 | 1317 | def coleman_integral_from_weierstrass_via_boundary(self, w, P, Q, d): |
1230 | | """ |
| 1318 | r""" |
1231 | 1319 | Computes the Coleman integral $\int_P^Q w$ via a boundary point |
1232 | 1320 | in the disc of $P$, defined over a degree $d$ extension |
1233 | 1321 | |
1234 | 1322 | INPUT: |
1235 | | - w: a differential |
1236 | | - P: a Weierstrass point |
1237 | | - Q: a non-Weierstrass point |
1238 | | - d: degree of extension where coordinates of boundary point lie |
| 1323 | |
| 1324 | - w: a differential |
| 1325 | - P: a Weierstrass point |
| 1326 | - Q: a non-Weierstrass point |
| 1327 | - d: degree of extension where coordinates of boundary point lie |
1239 | 1328 | |
1240 | 1329 | OUTPUT: |
1241 | | the Coleman integral $\int_P^Q w$, written in terms of the uniformizer |
1242 | | $a$ of the degree $d$ extension |
1243 | 1330 | |
1244 | | EXAMPLES: |
| 1331 | the Coleman integral $\int_P^Q w$, written in terms of the uniformizer |
| 1332 | $a$ of the degree $d$ extension |
| 1333 | |
| 1334 | EXAMPLES:: |
| 1335 | |
1245 | 1336 | sage: R.<x> = QQ['x'] |
1246 | 1337 | sage: H = HyperellipticCurve(x^3-10*x+9) |
1247 | 1338 | sage: K = Qp(5,6) |
… |
… |
|
1260 | 1351 | 2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7) |
1261 | 1352 | |
1262 | 1353 | AUTHOR: |
1263 | | - Jennifer Balakrishnan |
| 1354 | |
| 1355 | - Jennifer Balakrishnan |
1264 | 1356 | |
1265 | 1357 | """ |
1266 | 1358 | HJ = self.curve_over_ram_extn(d) |
-
diff -r 216c066ba752 sage/structure/coerce.pyx
a
|
b
|
|
1099 | 1099 | (Call morphism: |
1100 | 1100 | From: Multivariate Polynomial Ring in x, y over Integer Ring |
1101 | 1101 | To: Multivariate Polynomial Ring in x, y over Real Double Field, |
1102 | | Call morphism: |
| 1102 | Polynomial base injection morphism: |
1103 | 1103 | From: Real Double Field |
1104 | 1104 | To: Multivariate Polynomial Ring in x, y over Real Double Field) |
1105 | 1105 | |
-
diff -r 216c066ba752 sage/structure/coerce_actions.pyx
a
|
b
|
|
226 | 226 | Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring |
227 | 227 | sage: LeftModuleAction(QQ, ZZ['x']['y']) |
228 | 228 | Left scalar multiplication by Rational Field on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring |
| 229 | |
| 230 | The following tests against a problem that was relevant during work on |
| 231 | trac ticket #9944:: |
| 232 | |
| 233 | sage: R.<x> = PolynomialRing(ZZ) |
| 234 | sage: S.<x> = PolynomialRing(ZZ, sparse=True) |
| 235 | sage: 1/R.0 |
| 236 | 1/x |
| 237 | sage: 1/S.0 |
| 238 | 1/x |
| 239 | |
229 | 240 | """ |
230 | 241 | Action.__init__(self, G, S, not PY_TYPE_CHECK(self, RightModuleAction), operator.mul) |
231 | 242 | if not isinstance(G, Parent): |
… |
… |
|
265 | 276 | # At this point, we can assert it is safe to call _Xmul_c |
266 | 277 | the_ring = G if self.connecting is None else self.connecting.codomain() |
267 | 278 | the_set = S if self.extended_base is None else self.extended_base |
268 | | assert the_ring is the_set.base(), "BUG in coercion model" |
| 279 | assert the_ring is the_set.base(), "BUG in coercion model\n Apparently there are two versions of\n %s\n in the cache."%the_ring |
269 | 280 | |
270 | 281 | g = G.an_element() |
271 | 282 | a = S.an_element() |
-
diff -r 216c066ba752 sage/structure/element.pyx
a
|
b
|
|
766 | 766 | sage: (v+w).__nonzero__() |
767 | 767 | False |
768 | 768 | """ |
769 | | return self != self._parent(0) |
| 769 | return self != self._parent.zero_element() |
770 | 770 | |
771 | 771 | def is_zero(self): |
772 | 772 | """ |
… |
… |
|
1278 | 1278 | cdef class RingElement(ModuleElement): |
1279 | 1279 | ################################################## |
1280 | 1280 | def is_one(self): |
1281 | | return self == self._parent(1) |
| 1281 | return self == self._parent.one_element() |
1282 | 1282 | |
1283 | 1283 | ################################## |
1284 | 1284 | # Fast long add/sub path. |
-
diff -r 216c066ba752 sage/structure/parent_old.pyx
a
|
b
|
|
10 | 10 | |
11 | 11 | |
12 | 12 | TESTS: |
| 13 | |
13 | 14 | This came up in some subtle bug once. |
| 15 | :: |
| 16 | |
14 | 17 | sage: gp(2) + gap(3) |
15 | 18 | 5 |
16 | 19 | """ |
… |
… |
|
102 | 105 | To: Multivariate Polynomial Ring in q, t over Rational Field |
103 | 106 | Defn: Native morphism: |
104 | 107 | From: Set of Python objects of type 'int' |
105 | | To: Integer Ring |
| 108 | To: Rational Field |
106 | 109 | then |
107 | | Call morphism: |
108 | | From: Integer Ring |
| 110 | Polynomial base injection morphism: |
| 111 | From: Rational Field |
109 | 112 | To: Multivariate Polynomial Ring in q, t over Rational Field |
110 | 113 | """ |
111 | 114 | check_old_coerce(self) |