# HG changeset patch
# User Simon King <simon.king@uni-jena.de>
# Date 1346332026 -7200
# Node ID 7956267cdba8eebcd928587db2384b629218c021
# Parent e39420b4a8a950c8a51dabb70a1ca88a3b4df720
#13412: Implement category and coercion framework for power series rings
diff --git a/sage/rings/multi_power_series_ring.py b/sage/rings/multi_power_series_ring.py
a
|
b
|
|
9 | 9 | |
10 | 10 | sage: R.<t,u,v> = PowerSeriesRing(QQ); R |
11 | 11 | Multivariate Power Series Ring in t, u, v over Rational Field |
| 12 | sage: TestSuite(R).run() |
12 | 13 | sage: p = -t + 1/2*t^3*u - 1/4*t^4*u + 2/3*v^5 + R.O(6); p |
13 | 14 | -t + 1/2*t^3*u - 1/4*t^4*u + 2/3*v^5 + O(t, u, v)^6 |
14 | 15 | sage: p in R |
… |
… |
|
43 | 44 | |
44 | 45 | sage: M = PowerSeriesRing(QQ, 4, 'k'); M |
45 | 46 | Multivariate Power Series Ring in k0, k1, k2, k3 over Rational Field |
| 47 | sage: loads(dumps(M)) is M |
| 48 | True |
| 49 | sage: TestSuite(M).run() |
46 | 50 | |
47 | 51 | sage: H = PowerSeriesRing(PolynomialRing(ZZ,3,'z'),4,'f'); H |
48 | 52 | Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate |
49 | 53 | Polynomial Ring in z0, z1, z2 over Integer Ring |
| 54 | sage: TestSuite(H).run() |
| 55 | sage: loads(dumps(H)) is H |
| 56 | True |
50 | 57 | |
51 | 58 | sage: z = H.base_ring().gens() |
52 | 59 | sage: f = H.gens() |
… |
… |
|
73 | 80 | -30077*x + 9485*x*y - 6260*y^3 + 12870*x^2*y^2 - 20289*y^4 + O(x, y)^5 |
74 | 81 | sage: s in S |
75 | 82 | True |
| 83 | sage: TestSuite(S).run() |
| 84 | sage: loads(dumps(S)) is S |
| 85 | True |
76 | 86 | |
77 | 87 | - Use double square bracket notation:: |
78 | 88 | |
… |
… |
|
87 | 97 | |
88 | 98 | sage: T.<a,b> = PowerSeriesRing(ZZ,order='deglex'); T |
89 | 99 | Multivariate Power Series Ring in a, b over Integer Ring |
| 100 | sage: TestSuite(T).run() |
| 101 | sage: loads(dumps(T)) is T |
| 102 | True |
90 | 103 | sage: T.term_order() |
91 | 104 | Degree lexicographic term order |
92 | 105 | sage: p = - 2*b^6 + a^5*b^2 + a^7 - b^2 - a*b^3 + T.O(9); p |
… |
… |
|
151 | 164 | sage: type(x) |
152 | 165 | <type 'sage.symbolic.expression.Expression'> |
153 | 166 | sage: type(S(x)) |
154 | | <class 'sage.rings.multi_power_series_ring_element.MPowerSeries'> |
| 167 | <class 'sage.rings.multi_power_series_ring_element.MPowerSeriesRing_generic_with_category.element_class'> |
155 | 168 | |
156 | 169 | sage: f = S(2/7 -100*x^2 + 1/3*x*y + y^2).O(3); f |
157 | 170 | 5 - x^2 + 4*x*y + y^2 + O(x, y)^3 |
… |
… |
|
164 | 177 | AUTHORS: |
165 | 178 | |
166 | 179 | - Niles Johnson (2010-07): initial code |
| 180 | - Simon King (2012-08): Use category and coercion framework, :trac:`13412` |
167 | 181 | |
168 | 182 | |
169 | 183 | """ |
… |
… |
|
177 | 191 | #***************************************************************************** |
178 | 192 | |
179 | 193 | |
180 | | from sage.rings.commutative_ring import is_CommutativeRing |
| 194 | from sage.rings.commutative_ring import is_CommutativeRing, CommutativeRing |
181 | 195 | from sage.rings.polynomial.all import PolynomialRing, is_MPolynomialRing, is_PolynomialRing |
182 | 196 | from sage.rings.polynomial.term_order import TermOrder |
183 | 197 | from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic, is_PowerSeriesRing |
… |
… |
|
186 | 200 | import sage.misc.latex as latex |
187 | 201 | from sage.structure.nonexact import Nonexact |
188 | 202 | |
189 | | from sage.structure.parent_gens import ParentWithGens |
190 | | |
191 | 203 | from sage.rings.multi_power_series_ring_element import MPowerSeries |
192 | 204 | |
193 | 205 | |
… |
… |
|
211 | 223 | False |
212 | 224 | |
213 | 225 | """ |
214 | | return type(x) == MPowerSeriesRing_generic |
| 226 | return isinstance(x, MPowerSeriesRing_generic) |
215 | 227 | |
216 | 228 | |
217 | 229 | class MPowerSeriesRing_generic(PowerSeriesRing_generic, Nonexact): |
… |
… |
|
231 | 243 | # |
232 | 244 | # variable_names_recursive : works just fine |
233 | 245 | # |
234 | | # __call__ : works just fine |
235 | | # |
236 | 246 | # __contains__ : works just fine |
237 | 247 | # |
238 | 248 | # base_extend : works just fine |
… |
… |
|
253 | 263 | #### notes |
254 | 264 | # |
255 | 265 | # sparse setting may not be implemented completely |
256 | | # |
257 | | |
258 | | |
259 | | |
260 | | |
| 266 | Element = MPowerSeries |
261 | 267 | def __init__(self, base_ring, num_gens, name_list, |
262 | 268 | order='negdeglex', default_prec=10, sparse=False): |
263 | 269 | """ |
… |
… |
|
302 | 308 | raise ValueError("Multivariate Polynomial Rings must have more than 0 variables.") |
303 | 309 | self._ngens = n |
304 | 310 | self._has_singular = False #cannot convert to Singular by default |
305 | | ParentWithGens.__init__(self, base_ring, name_list) |
| 311 | # Multivariate power series rings inherit from power series rings. But |
| 312 | # apparently we can not call their initialisation. Instead, initialise |
| 313 | # CommutativeRing and Nonexact: |
| 314 | CommutativeRing.__init__(self, base_ring, name_list) |
306 | 315 | Nonexact.__init__(self, default_prec) |
307 | 316 | |
308 | 317 | # underlying polynomial ring in which to represent elements |
… |
… |
|
314 | 323 | self._bg_power_series_ring = PowerSeriesRing(self._poly_ring_, 'Tbg', sparse=sparse, default_prec=default_prec) |
315 | 324 | self._bg_indeterminate = self._bg_power_series_ring.gen() |
316 | 325 | |
317 | | ## use the following in PowerSeriesRing_generic.__call__ |
318 | | self._PowerSeriesRing_generic__power_series_class = MPowerSeries |
319 | | |
320 | 326 | self._is_sparse = sparse |
321 | 327 | self._params = (base_ring, num_gens, name_list, |
322 | 328 | order, default_prec, sparse) |
323 | 329 | self._populate_coercion_lists_() |
324 | 330 | |
325 | | def __reduce__(self): |
326 | | """ |
327 | | EXAMPLES:: |
328 | | |
329 | | sage: R.<t,u,v> = PowerSeriesRing(ZZ) |
330 | | sage: S = loads(dumps(R)); S |
331 | | Multivariate Power Series Ring in t, u, v over Integer Ring |
332 | | sage: type(S) |
333 | | <class 'sage.rings.multi_power_series_ring.MPowerSeriesRing_generic'> |
334 | | sage: R.<x,y,z> = PowerSeriesRing(QQ, default_prec=10, sparse=True) |
335 | | sage: S = loads(dumps(R)); S |
336 | | Sparse Multivariate Power Series Ring in x, y, z over Rational Field |
337 | | sage: type(S) |
338 | | <class 'sage.rings.multi_power_series_ring.MPowerSeriesRing_generic'> |
339 | | """ |
340 | | return unpickle_multi_power_series_ring_v0, self._params |
341 | | |
342 | | |
343 | 331 | def _repr_(self): |
344 | 332 | """ |
345 | 333 | Prints out a multivariate power series ring. |
… |
… |
|
675 | 663 | |
676 | 664 | - any ring that coerces into the foreground polynomial ring of this ring |
677 | 665 | |
| 666 | EXAMPLES:: |
| 667 | |
| 668 | sage: A = GF(17)[['x','y']] |
| 669 | sage: A.has_coerce_map_from(ZZ) |
| 670 | True |
| 671 | sage: A.has_coerce_map_from(ZZ['x']) |
| 672 | True |
| 673 | sage: A.has_coerce_map_from(ZZ['y','x']) |
| 674 | True |
| 675 | sage: A.has_coerce_map_from(ZZ[['x']]) |
| 676 | True |
| 677 | sage: A.has_coerce_map_from(ZZ[['y','x']]) |
| 678 | True |
| 679 | sage: A.has_coerce_map_from(ZZ['x','z']) |
| 680 | False |
| 681 | sage: A.has_coerce_map_from(GF(3)['x','y']) |
| 682 | False |
| 683 | sage: A.has_coerce_map_from(Frac(ZZ['y','x'])) |
| 684 | False |
678 | 685 | |
679 | 686 | TESTS:: |
680 | 687 | |
… |
… |
|
719 | 726 | return self._poly_ring().has_coerce_map_from(P) |
720 | 727 | |
721 | 728 | |
722 | | def _element_constructor_(self,f): |
| 729 | def _element_constructor_(self,f,prec=None): |
723 | 730 | """ |
724 | 731 | TESTS:: |
725 | 732 | |
… |
… |
|
740 | 747 | Multivariate Power Series Ring in t0, t1, t2, t3, t4 over |
741 | 748 | Integer Ring |
742 | 749 | """ |
743 | | try: |
744 | | prec = f.prec() |
745 | | except AttributeError: |
746 | | prec = infinity |
747 | | return MPowerSeries(self, f, prec) |
| 750 | if prec is None: |
| 751 | try: |
| 752 | prec = f.prec() |
| 753 | except AttributeError: |
| 754 | prec = infinity |
| 755 | return self.element_class(parent=self, x=f, prec=prec) |
748 | 756 | |
749 | 757 | def __cmp__(self, other): |
750 | 758 | """ |
… |
… |
|
899 | 907 | if n < 0 or n >= self._ngens: |
900 | 908 | raise ValueError("Generator not defined.") |
901 | 909 | #return self(self._poly_ring().gens()[int(n)]) |
902 | | return MPowerSeries(self,self._poly_ring().gens()[int(n)], is_gen=True) |
| 910 | return self.element_class(parent=self,x=self._poly_ring().gens()[int(n)], is_gen=True) |
903 | 911 | |
904 | 912 | def ngens(self): |
905 | 913 | """ |
diff --git a/sage/rings/multi_power_series_ring_element.py b/sage/rings/multi_power_series_ring_element.py
a
|
b
|
|
150 | 150 | AUTHORS: |
151 | 151 | |
152 | 152 | - Niles Johnson (07/2010): initial code |
| 153 | - Simon King (08/2012): Use category and coercion framework, :trac:`13412` |
153 | 154 | |
154 | 155 | """ |
155 | 156 | |
… |
… |
|
195 | 196 | |
196 | 197 | """ |
197 | 198 | |
198 | | return type(f) == MPowerSeries |
| 199 | return isinstance(f, MPowerSeries) |
199 | 200 | |
200 | 201 | |
201 | 202 | |
… |
… |
|
420 | 421 | sage: loads(dumps(f)) == f |
421 | 422 | True |
422 | 423 | """ |
423 | | |
424 | | from sage.rings.power_series_ring_element import make_element_from_parent_v0 |
425 | | return make_element_from_parent_v0, (self._parent,self._bg_value,self._prec) |
| 424 | return self.__class__, (self._parent,self._bg_value,self._prec) |
426 | 425 | |
427 | 426 | def __call__(self, *x, **kwds): |
428 | 427 | """ |
diff --git a/sage/rings/power_series_poly.pyx b/sage/rings/power_series_poly.pyx
a
|
b
|
|
88 | 88 | sage: f == loads(dumps(f)) # indirect doctest |
89 | 89 | True |
90 | 90 | """ |
91 | | # do *not* delete old versions. |
92 | | return make_powerseries_poly_v0, (self._parent, self.__f, self._prec, self.__is_gen) |
| 91 | return self.__class__, (self._parent, self.__f, self._prec, self.__is_gen) |
93 | 92 | |
94 | 93 | def __richcmp__(left, right, int op): |
95 | 94 | """ |
diff --git a/sage/rings/power_series_ring.py b/sage/rings/power_series_ring.py
a
|
b
|
|
89 | 89 | AUTHORS: |
90 | 90 | |
91 | 91 | - William Stein: the code |
92 | | |
93 | 92 | - Jeremy Cho (2006-05-17): some examples (above) |
94 | | |
95 | 93 | - Niles Johnson (2010-09): implement multivariate power series |
| 94 | - Simon King (2012-08): use category and coercion framework, :trac:`13412` |
96 | 95 | |
97 | 96 | TESTS:: |
98 | 97 | |
99 | 98 | sage: R.<t> = PowerSeriesRing(QQ) |
100 | | sage: R == loads(dumps(R)) |
| 99 | sage: R is loads(dumps(R)) |
101 | 100 | True |
| 101 | sage: TestSuite(R).run() |
102 | 102 | |
103 | 103 | :: |
104 | 104 | |
105 | 105 | sage: R.<x> = PowerSeriesRing(QQ, sparse=True) |
106 | | sage: R == loads(dumps(R)) |
| 106 | sage: R is loads(dumps(R)) |
107 | 107 | True |
| 108 | sage: TestSuite(R).run() |
108 | 109 | |
109 | 110 | :: |
110 | 111 | |
111 | 112 | sage: M = PowerSeriesRing(QQ, 't,u,v,w', default_prec=20) |
112 | | sage: M == loads(dumps(M)) |
| 113 | sage: M is loads(dumps(M)) |
113 | 114 | True |
| 115 | sage: TestSuite(M).run() |
114 | 116 | |
115 | 117 | """ |
116 | 118 | |
… |
… |
|
134 | 136 | from sage.interfaces.magma import MagmaElement |
135 | 137 | from sage.misc.sage_eval import sage_eval |
136 | 138 | |
137 | | from sage.structure.parent_gens import ParentWithGens |
138 | | |
139 | | |
140 | | _cache = {} |
| 139 | from sage.structure.unique_representation import UniqueRepresentation |
| 140 | from sage.structure.parent import normalize_names |
| 141 | import sage.categories.commutative_rings as commutative_rings |
141 | 142 | |
142 | 143 | def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, |
143 | 144 | sparse=False, default_prec=None, order='negdeglex', num_gens=None): |
… |
… |
|
184 | 185 | sage: R = PowerSeriesRing(QQ, 10) |
185 | 186 | Traceback (most recent call last): |
186 | 187 | ... |
187 | | ValueError: first letter of variable name must be a letter |
| 188 | ValueError: first letter of variable name must be a letter: 10 |
188 | 189 | |
189 | 190 | :: |
190 | 191 | |
… |
… |
|
335 | 336 | if not names is None: |
336 | 337 | name = names |
337 | 338 | try: |
338 | | name = gens.normalize_names(1, name) |
| 339 | name = normalize_names(1, name) |
339 | 340 | except TypeError: |
340 | 341 | raise TypeError, "illegal variable name" |
341 | 342 | |
… |
… |
|
343 | 344 | raise TypeError, "You must specify the name of the indeterminate of the Power series ring." |
344 | 345 | |
345 | 346 | key = (base_ring, name, default_prec, sparse) |
346 | | if _cache.has_key(key): |
347 | | R = _cache[key]() |
348 | | if not R is None: |
349 | | return R |
| 347 | if PowerSeriesRing_generic.__classcall__.is_in_cache(key): |
| 348 | return PowerSeriesRing_generic(*key) |
350 | 349 | |
351 | 350 | if isinstance(name, (tuple, list)): |
352 | 351 | assert len(name) == 1 |
… |
… |
|
355 | 354 | if not (name is None or isinstance(name, str)): |
356 | 355 | raise TypeError, "variable name must be a string or None" |
357 | 356 | |
358 | | |
359 | 357 | if isinstance(base_ring, field.Field): |
360 | 358 | R = PowerSeriesRing_over_field(base_ring, name, default_prec, sparse=sparse) |
361 | 359 | elif isinstance(base_ring, integral_domain.IntegralDomain): |
… |
… |
|
364 | 362 | R = PowerSeriesRing_generic(base_ring, name, default_prec, sparse=sparse) |
365 | 363 | else: |
366 | 364 | raise TypeError, "base_ring must be a commutative ring" |
367 | | _cache[key] = weakref.ref(R) |
368 | 365 | return R |
369 | 366 | |
370 | 367 | def _multi_variate(base_ring, num_gens=None, names=None, |
… |
… |
|
385 | 382 | num_gens = len(names) |
386 | 383 | else: |
387 | 384 | raise TypeError("variable names must be a string, tuple or list") |
388 | | |
| 385 | names = normalize_names(num_gens, names) |
| 386 | num_gens = len(names) |
389 | 387 | if default_prec is None: |
390 | 388 | default_prec = 12 |
391 | 389 | |
392 | | |
393 | | key = (base_ring, num_gens, str(names), order, default_prec, sparse) |
394 | | if _cache.has_key(key): |
395 | | R = _cache[key]() |
396 | | if not R is None: |
397 | | return R |
398 | | |
399 | | if isinstance(base_ring, field.Field): |
400 | | pass |
401 | | elif isinstance(base_ring, integral_domain.IntegralDomain): |
402 | | pass |
403 | | elif isinstance(base_ring, commutative_ring.CommutativeRing): |
404 | | pass |
405 | | else: |
| 390 | if base_ring not in commutative_rings.CommutativeRings(): |
406 | 391 | raise TypeError, "base_ring must be a commutative ring" |
407 | 392 | from sage.rings.multi_power_series_ring import MPowerSeriesRing_generic |
408 | 393 | R = MPowerSeriesRing_generic(base_ring, num_gens, names, |
409 | 394 | order=order, default_prec=default_prec, sparse=sparse) |
410 | | _cache[key] = weakref.ref(R) |
411 | 395 | return R |
412 | 396 | |
413 | 397 | |
… |
… |
|
433 | 417 | else: |
434 | 418 | return False |
435 | 419 | |
436 | | class PowerSeriesRing_generic(commutative_ring.CommutativeRing, Nonexact): |
| 420 | class PowerSeriesRing_generic(UniqueRepresentation, commutative_ring.CommutativeRing, Nonexact): |
437 | 421 | """ |
438 | 422 | A power series ring. |
439 | 423 | |
… |
… |
|
448 | 432 | sage: TestSuite(R).run() |
449 | 433 | |
450 | 434 | """ |
| 435 | Element = power_series_poly.PowerSeries_poly |
451 | 436 | def __init__(self, base_ring, name=None, default_prec=20, sparse=False, |
452 | 437 | use_lazy_mpoly_ring=False): |
453 | 438 | """ |
… |
… |
|
473 | 458 | for it to truncate away higher order terms (this is called |
474 | 459 | automatically before printing). |
475 | 460 | """ |
476 | | commutative_ring.CommutativeRing.__init__(self, base_ring, names=name) |
477 | | Nonexact.__init__(self, default_prec) |
478 | 461 | R = PolynomialRing(base_ring, name, sparse=sparse) |
479 | 462 | self.__poly_ring = R |
480 | | self.__power_series_class = power_series_poly.PowerSeries_poly |
481 | | self.__generator = self.__power_series_class(self, R.gen(), check=True, is_gen=True) |
482 | 463 | self.__is_sparse = sparse |
483 | 464 | self.__params = (base_ring, name, default_prec, sparse) |
484 | 465 | |
… |
… |
|
488 | 469 | names = K.variable_names() + (name,) |
489 | 470 | self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names) |
490 | 471 | assert is_MPolynomialRing(self.__mpoly_ring) |
491 | | self.__power_series_class = power_series_mpoly.PowerSeries_mpoly |
| 472 | self.Element = power_series_mpoly.PowerSeries_mpoly |
| 473 | commutative_ring.CommutativeRing.__init__(self, base_ring, names=name) |
| 474 | Nonexact.__init__(self, default_prec) |
| 475 | self.__generator = self.element_class(self, R.gen(), check=True, is_gen=True) |
492 | 476 | |
493 | 477 | def variable_names_recursive(self, depth=None): |
494 | 478 | r""" |
… |
… |
|
520 | 504 | all = all[-depth:] |
521 | 505 | return all |
522 | 506 | |
523 | | def __reduce__(self): |
524 | | """ |
525 | | TESTS:: |
526 | | |
527 | | sage: R.<t> = PowerSeriesRing(ZZ) |
528 | | sage: S = loads(dumps(R)); S |
529 | | Power Series Ring in t over Integer Ring |
530 | | sage: type(S) |
531 | | <class 'sage.rings.power_series_ring.PowerSeriesRing_domain_with_category'> |
532 | | sage: R.<t> = PowerSeriesRing(QQ, default_prec=10, sparse=True); R |
533 | | Sparse Power Series Ring in t over Rational Field |
534 | | sage: S = loads(dumps(R)); S |
535 | | Sparse Power Series Ring in t over Rational Field |
536 | | sage: type(S) |
537 | | <class 'sage.rings.power_series_ring.PowerSeriesRing_over_field_with_category'> |
538 | | """ |
539 | | return unpickle_power_series_ring_v0, self.__params |
540 | | |
541 | 507 | def _repr_(self): |
542 | 508 | """ |
543 | 509 | Prints out a power series ring. |
… |
… |
|
571 | 537 | EXAMPLES:: |
572 | 538 | |
573 | 539 | sage: R = GF(17)[['y']] |
574 | | sage: latex(R) |
| 540 | sage: latex(R) # indirect doctest |
575 | 541 | \Bold{F}_{17}[[y]] |
576 | 542 | sage: R = GF(17)[['y12']] |
577 | 543 | sage: latex(R) |
… |
… |
|
579 | 545 | """ |
580 | 546 | return "%s[[%s]]"%(latex.latex(self.base_ring()), self.latex_variable_names()[0]) |
581 | 547 | |
582 | | def __call__(self, f, prec=infinity, check=True): |
| 548 | def _coerce_map_from_(self, S): |
| 549 | """ |
| 550 | A coercion from `S` exists, if `S` coerces into ``self``'s base ring, |
| 551 | or if `S` is a univariate polynomial or power series ring with the |
| 552 | same variable name as self, defined over a base ring that coerces into |
| 553 | ``self``'s base ring. |
| 554 | |
| 555 | EXAMPLES:: |
| 556 | |
| 557 | sage: A = GF(17)[['x']] |
| 558 | sage: A.has_coerce_map_from(ZZ) # indirect doctest |
| 559 | True |
| 560 | sage: A.has_coerce_map_from(ZZ['x']) |
| 561 | True |
| 562 | sage: A.has_coerce_map_from(ZZ['y']) |
| 563 | False |
| 564 | sage: A.has_coerce_map_from(ZZ[['x']]) |
| 565 | True |
| 566 | |
| 567 | """ |
| 568 | if self.base_ring().has_coerce_map_from(S): |
| 569 | return True |
| 570 | if (is_PolynomialRing(S) or is_PowerSeriesRing(S)) and self.base_ring().has_coerce_map_from(S.base_ring()) \ |
| 571 | and self.variable_names()==S.variable_names(): |
| 572 | return True |
| 573 | |
| 574 | def _element_constructor_(self, f, prec=infinity, check=True): |
583 | 575 | """ |
584 | 576 | Coerce object to this power series ring. |
585 | 577 | |
… |
… |
|
601 | 593 | EXAMPLES:: |
602 | 594 | |
603 | 595 | sage: R.<t> = PowerSeriesRing(ZZ) |
604 | | sage: R(t+O(t^5)) |
| 596 | sage: R(t+O(t^5)) # indirect doctest |
605 | 597 | t + O(t^5) |
606 | 598 | sage: R(13) |
607 | 599 | 13 |
… |
… |
|
625 | 617 | elif isinstance(f, MagmaElement) and str(f.Type()) == 'RngSerPowElt': |
626 | 618 | v = sage_eval(f.Eltseq()) |
627 | 619 | return self(v) * (self.gen(0)**f.Valuation()) |
628 | | return self.__power_series_class(self, f, prec, check=check) |
| 620 | return self.element_class(self, f, prec, check=check) |
629 | 621 | |
630 | 622 | def construction(self): |
631 | 623 | """ |
… |
… |
|
663 | 655 | EXAMPLES:: |
664 | 656 | |
665 | 657 | sage: R.<t> = PowerSeriesRing(ZZ) |
666 | | sage: R._coerce_(t + t^2) |
| 658 | sage: R._coerce_(t + t^2) # indirect doctest |
667 | 659 | t + t^2 |
668 | 660 | sage: R._coerce_(1/t) |
669 | 661 | Traceback (most recent call last): |
670 | 662 | ... |
671 | | TypeError: no canonical coercion of element into self |
| 663 | TypeError: no canonical coercion from Laurent Series Ring in t over Integer Ring to Power Series Ring in t over Integer Ring |
672 | 664 | sage: R._coerce_(5) |
673 | 665 | 5 |
674 | 666 | sage: tt = PolynomialRing(ZZ,'t').gen() |
… |
… |
|
677 | 669 | sage: R._coerce_(1/2) |
678 | 670 | Traceback (most recent call last): |
679 | 671 | ... |
680 | | TypeError: no canonical coercion of element into self |
| 672 | TypeError: no canonical coercion from Rational Field to Power Series Ring in t over Integer Ring |
681 | 673 | sage: S.<s> = PowerSeriesRing(ZZ) |
682 | 674 | sage: R._coerce_(s) |
683 | 675 | Traceback (most recent call last): |
684 | 676 | ... |
685 | | TypeError: no canonical coercion of element into self |
| 677 | TypeError: no canonical coercion from Power Series Ring in s over Integer Ring to Power Series Ring in t over Integer Ring |
686 | 678 | |
687 | 679 | We illustrate canonical coercion between power series rings with |
688 | 680 | compatible base rings:: |
… |
… |
|
698 | 690 | sage: S._coerce_(g) |
699 | 691 | Traceback (most recent call last): |
700 | 692 | ... |
701 | | TypeError: no natural map between bases of power series rings |
| 693 | TypeError: no canonical coercion from Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 to Power Series Ring in t over Integer Ring |
702 | 694 | """ |
703 | 695 | try: |
704 | 696 | P = x.parent() |
diff --git a/sage/rings/power_series_ring_element.pyx b/sage/rings/power_series_ring_element.pyx
a
|
b
|
|
7 | 7 | AUTHORS: |
8 | 8 | |
9 | 9 | - William Stein |
10 | | |
11 | 10 | - David Harvey (2006-09-11): added solve_linear_de() method |
12 | | |
13 | 11 | - Robert Bradshaw (2007-04): sqrt, rmul, lmul, shifting |
14 | | |
15 | 12 | - Robert Bradshaw (2007-04): Cython version |
| 13 | - Simon King (2012-08): use category and coercion framework, :trac:`13412` |
16 | 14 | |
17 | 15 | EXAMPLE:: |
18 | 16 | |
19 | 17 | sage: R.<x> = PowerSeriesRing(ZZ) |
| 18 | sage: TestSuite(R).run() |
20 | 19 | sage: R([1,2,3]) |
21 | 20 | 1 + 2*x + 3*x^2 |
22 | 21 | sage: R([1,2,3], 10) |
… |
… |
|
1881 | 1880 | |
1882 | 1881 | |
1883 | 1882 | def make_powerseries_poly_v0(parent, f, prec, is_gen): |
| 1883 | # This is only used to unpickle old pickles. The new pickling |
| 1884 | # works differently! |
1884 | 1885 | import power_series_poly |
1885 | 1886 | return power_series_poly.PowerSeries_poly(parent, f, prec, 0, is_gen) |
1886 | 1887 | |
1887 | 1888 | def make_element_from_parent_v0(parent, *args): |
| 1889 | # This is only used to unpickle old pickles. The new pickling |
| 1890 | # works differently! |
1888 | 1891 | return parent(*args) |