Ticket #13433: trac_13433lazy_power_serie_gen_fixfh.patch
File trac_13433lazy_power_serie_gen_fixfh.patch, 36.8 KB (added by , 9 years ago) 


sage/combinat/species/series.py
# HG changeset patch # User Mike Hansen <mhansen@gmail.com> # Date 1374443204 3600 # Node ID e8d03c4cbd96b861553c41026cffc29d7bd1c55e # Parent b279f242b360ddf3d356ed04571bcf8d91be4281 Lazy power series: fix bad handling of base ring and categorification diff git a/sage/combinat/species/series.py b/sage/combinat/species/series.py
a b 15 15 http://www.risc.unilinz.ac.at/people/hemmecke/AldorCombinat/combinatse9.html. 16 16 """ 17 17 #***************************************************************************** 18 # Copyright (C) 2008 Mike Hansen <mhansen@gmail.com>, 18 # Copyright (C) 2008 Mike Hansen <mhansen@gmail.com>, 19 19 # 20 20 # Distributed under the terms of the GNU General Public License (GPL) 21 21 # … … 34 34 from functools import partial 35 35 from sage.misc.misc import repr_lincomb, is_iterator 36 36 37 from sage.algebras.algebra import Algebra 38 from sage.algebras.algebra_element import AlgebraElement 39 import sage.structure.parent_base 40 from sage.categories.all import Rings 37 from sage.structure.unique_representation import UniqueRepresentation 38 from sage.structure.element import Element 39 from sage.structure.parent_base import ParentWithBase 40 from sage.categories.all import (Rings, CommutativeRings, 41 Algebras, CommutativeAlgebras) 41 42 42 class LazyPowerSeriesRing( Algebra):43 class LazyPowerSeriesRing(UniqueRepresentation, ParentWithBase): 43 44 def __init__(self, R, element_class = None, names=None): 44 45 """ 45 46 TESTS:: 46 47 47 48 sage: from sage.combinat.species.series import LazyPowerSeriesRing 48 sage: L = LazyPowerSeriesRing(QQ) 49 sage: loads(dumps(L)) 49 sage: L = LazyPowerSeriesRing(QQ); L 50 50 Lazy Power Series Ring over Rational Field 51 sage: L.category() 52 Category of commutative algebras over Rational Field 53 54 We try to check that LazyPowerSeries works in non commutative cases (:trac:`13433`):: 55 56 sage: G = SymmetricGroup(3) 57 sage: R = G.algebra(QQ) 58 sage: L = LazyPowerSeriesRing(R) 59 sage: L.category() 60 Category of algebras over Group algebra of Symmetric group of order 3! as a permutation group over Rational Field 61 sage: s = sum(R(p)*L.gen()^p.length() for p in G); s 62 Uninitialized lazy power series 63 sage: s.coefficient(10) 64 0 65 sage: s 66 B[()]*1 + (B[(2,3)]+B[(1,2)])*x + (B[(1,2,3)]+B[(1,3,2)])*x^2 + B[(1,3)]*x^3 + O(x^11) 67 sage: s.aorder 68 0 69 70 sage: p = R.monomial(G.an_element()); p 71 B[(1,2,3)] 72 sage: s1 = s*L(p); s1.coefficient(10); s1 73 0 74 B[(1,2,3)]*1 + (B[(1,2)]+B[(1,3)])*x + (B[()]+B[(1,3,2)])*x^2 + B[(2,3)]*x^3 + O(x^11) 75 76 sage: s2 = L(p)*s; s2.coefficient(10); s2 77 0 78 B[(1,2,3)]*1 + (B[(2,3)]+B[(1,3)])*x + (B[()]+B[(1,3,2)])*x^2 + B[(1,2)]*x^3 + O(x^11) 79 sage: s.aorder 80 0 81 82 Equality is not decidable, so most tests are skipped:: 83 84 sage: TestSuite(L).run( 85 ... skip = ['_test_additive_associativity', '_test_associativity', 86 ... '_test_distributivity', '_test_elements', '_test_one', 87 ... '_test_prod', '_test_zero']) 51 88 """ 52 89 #Make sure R is a ring with unit element 53 90 if not R in Rings(): 54 91 raise TypeError, "Argument R must be a ring." 55 try:56 z = R(Integer(1))57 except StandardError:58 raise ValueError, "R must have a unit element"59 92 60 93 #Take care of the names 61 94 if names is None: 62 95 names = 'x' 63 96 else: 64 97 names = names[0] 65 66 self. _element_class= element_class if element_class is not None else LazyPowerSeries98 99 self.Element = element_class if element_class is not None else LazyPowerSeries 67 100 self._order = None 68 101 self._name = names 69 sage.structure.parent_base.ParentWithBase.__init__(self, R) 102 if R in CommutativeRings(): 103 category = CommutativeAlgebras(R) 104 else: 105 category = Algebras(R) 106 ParentWithBase.__init__( 107 self, R, category = category) 70 108 71 109 def ngens(self): 72 110 """ 73 111 EXAMPLES:: 74 112 75 113 sage: LazyPowerSeriesRing(QQ).ngens() 76 114 1 77 115 """ 78 116 return 1 79 117 80 def _ _repr__(self):118 def _repr_(self): 81 119 """ 82 120 EXAMPLES:: 83 121 84 122 sage: LazyPowerSeriesRing(QQ) 85 123 Lazy Power Series Ring over Rational Field 86 124 """ … … 89 127 def __cmp__(self, x): 90 128 """ 91 129 EXAMPLES:: 92 130 93 131 sage: LQ = LazyPowerSeriesRing(QQ) 94 132 sage: LZ = LazyPowerSeriesRing(ZZ) 95 133 sage: LQ == LQ … … 104 142 def _coerce_impl(self, x): 105 143 """ 106 144 EXAMPLES:: 107 145 108 146 sage: L1 = LazyPowerSeriesRing(QQ) 109 147 sage: L2 = LazyPowerSeriesRing(RR) 110 148 sage: L2.has_coerce_map_from(L1) 111 149 True 112 150 sage: L1.has_coerce_map_from(L2) 113 151 False 114 152 115 153 :: 116 154 117 155 sage: a = L1([1]) + L2([1]) 118 156 sage: a.coefficients(3) 119 157 [2.00000000000000, 2.00000000000000, 2.00000000000000] 120 158 """ 121 159 return self(x) 122 160 123 161 124 162 def __call__(self, x=None, order=unk): 125 163 """ 126 164 EXAMPLES:: 127 165 128 166 sage: from sage.combinat.species.stream import Stream 129 167 sage: L = LazyPowerSeriesRing(QQ) 130 168 sage: L() … … 137 175 [0, 1, 1, 2, 2, 3, 3, 4, 4, 5] 138 176 sage: L(Stream(ZZ)).coefficients(10) 139 177 [0, 1, 1, 2, 2, 3, 3, 4, 4, 5] 140 178 141 179 :: 142 180 143 181 sage: a = L([1,2,3]) 144 182 sage: a.coefficients(3) 145 183 [1, 2, 3] … … 153 191 Traceback (most recent call last): 154 192 ... 155 193 TypeError: do not know how to coerce ... into self 156 194 157 195 TESTS:: 158 196 159 197 sage: L(pi) 160 198 Traceback (most recent call last): 161 199 ... 162 200 TypeError: do not know how to coerce pi into self 163 201 """ 164 cls = self. _element_class202 cls = self.element_class 165 203 BR = self.base_ring() 166 204 167 205 if x is None: 168 206 res = cls(self, stream=None, order=unk, aorder=unk, 169 207 aorder_changed=True, is_initialized=False) … … 172 210 173 211 if isinstance(x, LazyPowerSeries): 174 212 x_parent = x.parent() 175 if x_parent.__class__ != self.__class__: 213 214 # Same kind (ordinary/exponential...) of power series ring. 215 # __base__ removes _with_category 216 if x_parent.__class__.__base__ != self.__class__.__base__: 176 217 raise ValueError 177 218 178 219 if x_parent.base_ring() == self.base_ring(): 179 220 return x 180 221 else: 181 222 if self.base_ring().has_coerce_map_from(x_parent.base_ring()): 182 223 return x._new(partial(x._change_ring_gen, self.base_ring()), lambda ao: ao, x, parent=self) 183 224 184 225 185 226 if hasattr(x, "parent") and BR.has_coerce_map_from(x.parent()): 186 227 x = BR(x) … … 199 240 elif not hasattr(x, "parent"): 200 241 x = BR(x) 201 242 return self.term(x, 0) 202 243 203 244 raise TypeError, "do not know how to coerce %s into self"%x 204 245 205 246 def zero_element(self): 206 247 """ 207 248 Returns the zero power series. 208 249 209 250 EXAMPLES:: 210 251 211 252 sage: L = LazyPowerSeriesRing(QQ) 212 253 sage: L.zero_element() 213 254 0 214 255 """ 215 return self(self.base_ring() (0))256 return self(self.base_ring().zero()) 216 257 217 258 def identity_element(self): 218 259 """ 219 260 Returns the one power series. 220 261 221 262 EXAMPLES:: 222 263 223 264 sage: L = LazyPowerSeriesRing(QQ) 224 265 sage: L.identity_element() 225 266 1 226 267 """ 227 return self(self.base_ring() (1))268 return self(self.base_ring().one()) 228 269 229 def gen(self , i=0):270 def gen(self): 230 271 """ 272 Returns the generator for `self` 273 231 274 EXAMPLES:: 232 275 233 276 sage: L = LazyPowerSeriesRing(QQ) 234 277 sage: L.gen().coefficients(5) 235 278 [0, 1, 0, 0, 0] 279 sage: L.gen()[1].parent() is QQ 280 True 236 281 """ 237 res = self._new_initial(1, Stream([0,1,0])) 282 R0 = self.base_ring().zero() 283 R1 = self.base_ring().one() 284 res = self._new_initial(1, Stream([R0, R1, R0])) 238 285 res._name = self._name 239 286 return res 240 287 288 def gens(self): 289 r""" 290 Returns the generators for `self` 291 292 EXAMPLES:: 293 294 sage: L.<z> = LazyPowerSeriesRing(QQ) 295 sage: z 296 z 297 sage: z.parent() 298 Lazy Power Series Ring over Rational Field 299 300 TESTS:: 301 302 sage: z.parent() is L 303 True 304 """ 305 return [self.gen()] 306 241 307 def term(self, r, n): 242 308 """ 243 309 EXAMPLES:: 244 310 245 311 sage: L = LazyPowerSeriesRing(QQ) 246 312 sage: L.term(0,0) 247 313 0 … … 255 321 res = self._new_initial(inf, Stream([0])) 256 322 res._name = "0" 257 323 else: 258 zero = BR (0)324 zero = BR.zero() 259 325 s = [zero]*n+[BR(r),zero] 260 326 res = self._new_initial(n, Stream(s)) 261 327 … … 271 337 def _new_initial(self, order, stream): 272 338 """ 273 339 Returns a new power series with specified order. 274 340 275 341 INPUT: 276 277 342 343 278 344  ``order``  a nonnegative integer 279 345 280 346  ``stream``  a Stream object 281 282 347 348 283 349 EXAMPLES:: 284 350 285 351 sage: from sage.combinat.species.stream import Stream 286 352 sage: L = LazyPowerSeriesRing(QQ) 287 353 sage: L._new_initial(0, Stream([1,2,3,0])).coefficients(5) 288 354 [1, 2, 3, 0, 0] 289 355 """ 290 return self. _element_class(self, stream=stream, order=order, aorder=order,356 return self.element_class(self, stream=stream, order=order, aorder=order, 291 357 aorder_changed=False, is_initialized=True) 292 358 293 359 … … 295 361 """ 296 362 Returns a generator for the coefficients of the sum the the lazy 297 363 power series in series_list. 298 364 299 365 INPUT: 300 301 366 367 302 368  ``series_list``  a list of lazy power series 303 304 369 370 305 371 EXAMPLES:: 306 372 307 373 sage: L = LazyPowerSeriesRing(QQ) 308 374 sage: series_list = [ L([1]), L([0,1]), L([0,0,1]) ] 309 375 sage: g = L._sum_gen(series_list) … … 321 387 def sum(self, a): 322 388 """ 323 389 EXAMPLES:: 324 390 325 391 sage: L = LazyPowerSeriesRing(QQ) 326 392 sage: l = [L(ZZ)]*3 327 393 sage: L.sum(l).coefficients(10) … … 333 399 def _sum_generator_gen(self, g): 334 400 """ 335 401 EXAMPLES:: 336 402 337 403 sage: L = LazyPowerSeriesRing(QQ) 338 404 sage: s = L([1]) 339 405 sage: def f(): … … 346 412 s = Stream(g) 347 413 n = 0 348 414 while True: 349 r = s[n].coefficient(n) 415 r = s[n].coefficient(n) 350 416 for i in range(len(s)1): 351 417 r += s[i].coefficient(n) 352 418 yield r … … 355 421 def sum_generator(self, g): 356 422 """ 357 423 EXAMPLES:: 358 424 359 425 sage: L = LazyPowerSeriesRing(QQ) 360 426 sage: g = [L([1])]*6 + [L(0)] 361 427 sage: t = L.sum_generator(g) 362 428 sage: t.coefficients(10) 363 429 [1, 2, 3, 4, 5, 6, 6, 6, 6, 6] 364 430 365 431 :: 366 432 367 433 sage: s = L([1]) 368 434 sage: def g(): 369 435 ... while True: … … 378 444 def _product_generator_gen(self, g): 379 445 """ 380 446 EXAMPLES:: 381 447 382 448 sage: from itertools import imap 383 449 sage: from sage.combinat.species.stream import _integers_from 384 450 sage: L = LazyPowerSeriesRing(QQ) … … 405 471 def product_generator(self, g): 406 472 """ 407 473 EXAMPLES:: 408 474 409 475 sage: L = LazyPowerSeriesRing(QQ) 410 476 sage: s1 = L([1,1,0]) 411 477 sage: s2 = L([1,0,1,0]) … … 420 486 sage: p = L.product_generator(g()) 421 487 sage: p.coefficients(26) 422 488 [1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0] 423 489 424 490 :: 425 491 426 492 sage: def m(n): 427 493 ... yield 1 428 494 ... while True: … … 438 504 ... yield 0 439 505 ... yield q 440 506 ... 441 507 442 508 :: 443 509 444 510 sage: def lhs_gen(): 445 511 ... n = 1 446 512 ... while True: 447 513 ... yield L(m(n)) 448 514 ... n += 1 449 515 ... 450 516 451 517 :: 452 518 453 519 sage: def rhs_gen(): 454 520 ... n = 1 455 521 ... while True: … … 465 531 """ 466 532 return self(self._product_generator_gen(g)) 467 533 468 469 470 class LazyPowerSeries(AlgebraElement): 534 class LazyPowerSeries(Element): 471 535 def __init__(self, A, stream=None, order=None, aorder=None, aorder_changed=True, is_initialized=False, name=None): 472 536 """ 473 537 EXAMPLES:: 474 538 475 539 sage: L = LazyPowerSeriesRing(QQ) 476 540 sage: f = L() 477 541 sage: loads(dumps(f)) 478 542 Uninitialized lazy power series 479 543 """ 480 AlgebraElement.__init__(self, A)544 Element.__init__(self, A) 481 545 self._stream = stream 482 546 self.order = unk if order is None else order 483 547 self.aorder = unk if aorder is None else aorder … … 491 555 def compute_aorder(*args, **kwargs): 492 556 """ 493 557 The default compute_aorder does nothing. 494 558 495 559 EXAMPLES:: 496 560 497 561 sage: L = LazyPowerSeriesRing(QQ) 498 562 sage: a = L(1) 499 563 sage: a.compute_aorder() is None … … 504 568 def _get_repr_info(self, x): 505 569 """ 506 570 EXAMPLES:: 507 571 508 572 sage: L = LazyPowerSeriesRing(QQ) 509 573 sage: a = L([1,2,3]) 510 574 sage: a.compute_coefficients(5) … … 517 581 c = [ self._stream[i] for i in range(n) ] 518 582 return [ (m,c) for m,c in zip(m,c) if c != 0] 519 583 520 def _ _repr__(self):584 def _repr_(self): 521 585 """ 522 586 EXAMPLES:: 523 587 524 588 sage: L = LazyPowerSeriesRing(QQ) 525 589 sage: s = L(); s._name = 's'; s 526 590 s 527 591 528 592 :: 529 593 530 594 sage: L() 531 595 Uninitialized lazy power series 532 596 533 597 :: 534 598 535 599 sage: a = L([1,2,3]) 536 600 sage: a 537 601 O(1) … … 541 605 sage: a.compute_coefficients(4) 542 606 sage: a 543 607 1 + 2*x + 3*x^2 + 3*x^3 + 3*x^4 + 3*x^5 + ... 544 608 545 609 :: 546 610 547 611 sage: a = L([1,2,3,0]) 548 612 sage: a.compute_coefficients(5) 549 613 sage: a … … 551 615 """ 552 616 if self._name is not None: 553 617 return self._name 554 618 555 619 if self.is_initialized: 556 620 n = len(self._stream) 557 621 x = self.parent()._name … … 572 636 """ 573 637 Refines the approximate order of self as much as possible without 574 638 computing any coefficients. 575 639 576 640 EXAMPLES:: 577 641 578 642 sage: L = LazyPowerSeriesRing(QQ) 579 643 sage: a = L([0,0,0,0,1]) 580 644 sage: a.aorder … … 586 650 sage: a.refine_aorder() 587 651 sage: a.aorder 588 652 3 589 653 590 654 :: 591 655 592 656 sage: a = L([0,0]) 593 657 sage: a.aorder 594 658 0 … … 597 661 sage: a.refine_aorder() 598 662 sage: a.aorder 599 663 Infinite series order 600 664 601 665 :: 602 666 603 667 sage: a = L([0,0,1,0,0,0]) 604 668 sage: a[4] 605 669 0 … … 633 697 #aorder can never be infinity since order would have to 634 698 #be infinity as well 635 699 assert self.aorder != inf 636 700 637 701 if self.aorder == unk or not self.is_initialized: 638 702 self.compute_aorder() 639 703 else: … … 659 723 self.aorder = inf 660 724 self.order = inf 661 725 return 662 726 663 727 if hasattr(self, '_reference') and self._reference is not None: 664 728 self._reference._copy(self) 665 729 666 730 def initialize_coefficient_stream(self, compute_coefficients): 667 731 """ 668 732 Initializes the coefficient stream. 669 733 670 734 INPUT: compute_coefficients 671 735 672 736 TESTS:: 673 737 674 738 sage: from sage.combinat.species.series_order import inf, unk 675 739 sage: L = LazyPowerSeriesRing(QQ) 676 740 sage: f = L() … … 680 744 sage: f.initialize_coefficient_stream(compute_coefficients) 681 745 sage: f.coefficients(5) 682 746 [0, 0, 0, 0, 0] 683 747 684 748 :: 685 749 686 750 sage: f = L() 687 751 sage: compute_coefficients = lambda ao: iter(ZZ) 688 752 sage: f.order = 1 689 753 sage: f.aorder = 1 690 754 sage: f.initialize_coefficient_stream(compute_coefficients) 691 sage: f.coefficients(5) 755 sage: f.coefficients(5) 692 756 [0, 1, 1, 2, 2] 693 757 """ 694 758 ao = self.aorder … … 705 769 def compute_coefficients(self, i): 706 770 """ 707 771 Computes all the coefficients of self up to i. 708 772 709 773 EXAMPLES:: 710 774 711 775 sage: L = LazyPowerSeriesRing(QQ) 712 776 sage: a = L([1,2,3]) 713 777 sage: a.compute_coefficients(5) … … 719 783 def coefficients(self, n): 720 784 """ 721 785 Returns the first n coefficients of self. 722 786 723 787 EXAMPLES:: 724 788 725 789 sage: L = LazyPowerSeriesRing(QQ) 726 790 sage: f = L([1,2,3,0]) 727 791 sage: f.coefficients(5) … … 732 796 def is_zero(self): 733 797 """ 734 798 Returns True if and only if self is zero. 735 799 736 800 EXAMPLES:: 737 801 738 802 sage: L = LazyPowerSeriesRing(QQ) 739 803 sage: s = L([0,2,3,0]) 740 804 sage: s.is_zero() 741 805 False 742 806 743 807 :: 744 808 745 809 sage: s = L(0) 746 810 sage: s.is_zero() 747 811 True 748 812 749 813 :: 750 814 751 815 sage: s = L([0]) 752 816 sage: s.is_zero() 753 817 False … … 765 829 """ 766 830 Sets the approximate order of self and returns True if the 767 831 approximate order has changed otherwise it will return False. 768 832 769 833 EXAMPLES:: 770 834 771 835 sage: L = LazyPowerSeriesRing(QQ) 772 836 sage: f = L([0,0,0,3,2,1,0]) 773 837 sage: f.get_aorder() … … 784 848 def _copy(self, x): 785 849 """ 786 850 EXAMPLES:: 787 851 788 852 sage: L = LazyPowerSeriesRing(QQ) 789 853 sage: f = L.term(2, 2) 790 854 sage: g = L() … … 804 868 self.compute_aorder = x.compute_aorder 805 869 self.is_initialized = x.is_initialized 806 870 self._stream = x._stream 807 871 808 872 def define(self, x): 809 873 """ 810 874 EXAMPLES: Test Recursive 0 811 875 812 876 :: 813 877 814 878 sage: L = LazyPowerSeriesRing(QQ) 815 879 sage: one = L(1) 816 880 sage: monom = L.gen() … … 823 887 Unknown series order 824 888 sage: [s.coefficient(i) for i in range(6)] 825 889 [1, 1, 1, 1, 1, 1] 826 890 827 891 Test Recursive 1 828 892 829 893 :: 830 894 831 895 sage: s = L() 832 896 sage: s._name = 's' 833 897 sage: s.define(one+monom*s*s) … … 837 901 Unknown series order 838 902 sage: [s.coefficient(i) for i in range(6)] 839 903 [1, 1, 2, 5, 14, 42] 840 904 841 905 Test Recursive 1b 842 906 843 907 :: 844 908 845 909 sage: s = L() 846 910 sage: s._name = 's' 847 911 sage: s.define(monom + s*s) 848 912 sage: s.aorder 849 1913 Unknown series order 850 914 sage: s.order 851 915 Unknown series order 852 916 sage: [s.coefficient(i) for i in range(7)] 853 917 [0, 1, 1, 2, 5, 14, 42] 854 918 sage: s.aorder 919 1 920 sage: s.order 921 1 922 855 923 Test Recursive 2 856 924 857 925 :: 858 926 859 927 sage: s = L() 860 928 sage: s._name = 's' 861 929 sage: t = L() … … 866 934 [1, 1, 3, 9, 34, 132, 546, 2327, 10191] 867 935 sage: [t.coefficient(i) for i in range(9)] 868 936 [1, 1, 2, 7, 24, 95, 386, 1641, 7150] 869 937 870 938 Test Recursive 2b 871 939 872 940 :: 873 941 874 942 sage: s = L() 875 943 sage: s._name = 's' 876 944 sage: t = L() … … 881 949 [0, 1, 0, 1, 3, 3, 7, 30, 63] 882 950 sage: [t.coefficient(i) for i in range(9)] 883 951 [0, 1, 1, 0, 2, 6, 7, 20, 75] 884 952 885 953 Test Recursive 3 886 954 887 955 :: 888 956 889 957 sage: s = L() 890 958 sage: s._name = 's' 891 959 sage: s.define(one+monom*s*s*s) … … 898 966 def coefficient(self, n): 899 967 """ 900 968 Returns the coefficient of xn in self. 901 969 902 970 EXAMPLES:: 903 971 904 972 sage: L = LazyPowerSeriesRing(QQ) 905 973 sage: f = L(ZZ) 906 974 sage: [f.coefficient(i) for i in range(5)] 907 975 [0, 1, 1, 2, 2] 908 976 """ 909 977 # The following line must not be written n < self.get_aorder() 910 # because comparison of Integer and OnfinityOrder is not implemented. 978 # because comparison of Integer and OnfinityOrder is not implemented. 911 979 if self.get_aorder() > n: 912 980 return self._zero 913 981 … … 918 986 def get_aorder(self): 919 987 """ 920 988 Returns the approximate order of self. 921 989 922 990 EXAMPLES:: 923 991 924 992 sage: L = LazyPowerSeriesRing(QQ) 925 993 sage: a = L.gen() 926 994 sage: a.get_aorder() … … 932 1000 def get_order(self): 933 1001 """ 934 1002 Returns the order of self. 935 1003 936 1004 EXAMPLES:: 937 1005 938 1006 sage: L = LazyPowerSeriesRing(QQ) 939 1007 sage: a = L.gen() 940 1008 sage: a.get_order() … … 946 1014 def get_stream(self): 947 1015 """ 948 1016 Returns self's underlying Stream object. 949 1017 950 1018 EXAMPLES:: 951 1019 952 1020 sage: L = LazyPowerSeriesRing(QQ) 953 1021 sage: a = L.gen() 954 1022 sage: s = a.get_stream() … … 993 1061 parent = kwds['parent'] if 'parent' in kwds else self.parent() 994 1062 new_fps = self.__class__(parent, stream=None, order=unk, aorder=self.aorder, 995 1063 aorder_changed=True, is_initialized=False) 996 1064 997 1065 new_fps.compute_aorder = lambda: new_fps._approximate_order(compute_coefficients, order_op, *series) 998 1066 return new_fps 999 1067 1000 1068 def _add_(self, y): 1001 1069 """ 1002 1070 EXAMPLES: Test Plus 1 1003 1071 1004 1072 :: 1005 1073 1006 1074 sage: from sage.combinat.species.series import * 1007 1075 sage: from sage.combinat.species.stream import Stream 1008 1076 sage: L = LazyPowerSeriesRing(QQ) … … 1021 1089 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] 1022 1090 sage: [sum3.coefficient(i) for i in range(11)] 1023 1091 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 1024 1092 1025 1093 Test Plus 2 1026 1094 1027 1095 :: 1028 1096 1029 1097 sage: gs1 = L([1,2,4,8,0]) 1030 1098 sage: gs2 = L([1, 0,1,9,22,0]) 1031 1099 sage: sum = gs1 + gs2 … … 1038 1106 [0, 2, 3, 1, 22] 1039 1107 sage: [ sum2.coefficient(i) for i in range(5, 11) ] 1040 1108 [0, 0, 0, 0, 0, 0] 1109 1110 1111 TESTS: 1112 1113 Check that :trac:`13433` is fixed:: 1114 1115 sage: from sage.combinat.species.series import LazyPowerSeriesRing 1116 sage: L = LazyPowerSeriesRing(QQ) 1117 sage: g = L.gen(); z = L.zero() 1118 sage: s = z+g; s 1119 Uninitialized lazy power series 1120 sage: s.coefficients(10) 1121 [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 1122 sage: s 1123 x + O(x^10) 1041 1124 """ 1125 # print self.aorder, y.aorder 1126 if ( self.aorder != unk and 1127 ( y.aorder == unk or self.aorder > y.aorder ) ): 1128 y, self = self, y 1042 1129 return self._new(partial(self._plus_gen, y), min, self, y) 1043 1044 1130 add = _add_ 1045 1131 1046 1132 … … 1048 1134 def _plus_gen(self, y, ao): 1049 1135 """ 1050 1136 EXAMPLES:: 1051 1137 1052 1138 sage: L = LazyPowerSeriesRing(QQ) 1053 1139 sage: gs1 = L([1]) 1054 1140 sage: g = gs1._plus_gen(gs1, 0) 1055 1141 sage: [g.next() for i in range(5)] 1056 1142 [2, 2, 2, 2, 2] 1057 1143 1058 1144 :: 1059 1145 1060 1146 sage: g = gs1._plus_gen(gs1, 2) 1061 1147 sage: [g.next() for i in range(5)] 1062 1148 [0, 0, 2, 2, 2] … … 1073 1159 def _mul_(self, y): 1074 1160 """ 1075 1161 EXAMPLES:: 1076 1162 1077 1163 sage: L = LazyPowerSeriesRing(QQ) 1078 1164 sage: gs0 = L(0) 1079 1165 sage: gs1 = L([1]) 1080 1166 1081 1167 :: 1082 1168 1083 1169 sage: prod0 = gs0 * gs1 1084 1170 sage: [prod0.coefficient(i) for i in range(11)] 1085 1171 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 1086 1172 1087 1173 :: 1088 1174 1089 1175 sage: prod1 = gs1 * gs0 1090 1176 sage: [prod1.coefficient(i) for i in range(11)] 1091 1177 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 1092 1178 1093 1179 :: 1094 1180 1095 1181 sage: prod2 = gs1 * gs1 1096 1182 sage: [prod2.coefficient(i) for i in range(11)] 1097 1183 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 1098 1184 1099 1185 :: 1100 1186 1101 1187 sage: gs1 = L([1,2,4,8,0]) 1102 1188 sage: gs2 = L([1, 0,1,9,22,0]) 1103 1189 1104 1190 :: 1105 1191 1106 1192 sage: prod1 = gs1 * gs2 1107 1193 sage: [prod1.coefficient(i) for i in range(11)] 1108 1194 [1, 2, 5, 19, 0, 0, 16, 176, 0, 0, 0] 1109 1195 1110 1196 :: 1111 1197 1112 1198 sage: prod2 = gs2 * gs1 1113 1199 sage: [prod2.coefficient(i) for i in range(11)] 1114 1200 [1, 2, 5, 19, 0, 0, 16, 176, 0, 0, 0] 1115 1201 """ 1116 1202 1117 return self._new(partial(self._times_gen, y), lambda a,b:a+b, self, y) 1203 return self._new(partial(self._times_gen, y), lambda a,b:a+b, self, y) 1118 1204 1119 1205 times = _mul_ 1120 1206 1121 1207 def _times_gen(self, y, ao): 1122 1208 """ 1123 1209 Returns an iterator for the coefficients of self \* y. 1124 1210 1125 1211 EXAMPLES:: 1126 1212 1127 1213 sage: L = LazyPowerSeriesRing(QQ) 1128 1214 sage: f = L([1,1,0]) 1129 1215 sage: g = f._times_gen(f,0) … … 1143 1229 nth_coefficient = zero 1144 1230 1145 1231 #Handle the zero series 1146 if low == inf or high == inf: 1232 if low == inf or high == inf: 1147 1233 yield zero 1148 n += 1 1149 continue 1234 n += 1 1235 continue 1150 1236 1151 1237 for k in range(low, high+1): 1152 1238 cx = self._stream[k] … … 1159 1245 def __pow__(self, n): 1160 1246 """ 1161 1247 EXAMPLES:: 1162 1248 1163 1249 sage: L = LazyPowerSeriesRing(QQ) 1164 1250 sage: f = L([1,1,0]) # 1+x 1165 1251 sage: g = f^3 1166 1252 sage: g.coefficients(4) 1167 1253 [1, 3, 3, 1] 1168 1254 1169 1255 :: 1170 1256 1171 1257 sage: f^0 1172 1258 1 1173 1259 """ … … 1179 1265 """ 1180 1266 Returns the composition of this power series and the power series 1181 1267 y. 1182 1268 1183 1269 EXAMPLES:: 1184 1270 1185 1271 sage: L = LazyPowerSeriesRing(QQ) 1186 1272 sage: s = L([1]) 1187 1273 sage: t = L([0,0,1]) 1188 1274 sage: u = s(t) 1189 1275 sage: u.coefficients(11) 1190 1276 [1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 1191 1277 1192 1278 Test Compose 2 1193 1279 1194 1280 :: 1195 1281 1196 1282 sage: s = L([1]) 1197 1283 sage: t = L([0,0,1,0]) 1198 1284 sage: u = s(t) … … 1206 1292 0 1207 1293 sage: u.order 1208 1294 0 1209 1295 1210 1296 Test Compose 3 s = 1/(1x), t = x/(1x) s(t) = (1x)/(12x) 1211 1297 1212 1298 :: 1213 1299 1214 1300 sage: s = L([1]) 1215 1301 sage: t = L([0,1]) 1216 1302 sage: u = s(t) … … 1225 1311 """ 1226 1312 Returns a iterator for the coefficients of the composition of this 1227 1313 power series with the power series y. 1228 1314 1229 1315 EXAMPLES:: 1230 1316 1231 1317 sage: L = LazyPowerSeriesRing(QQ) 1232 1318 sage: s = L([1]) 1233 1319 sage: t = L([0,1]) … … 1250 1336 """ 1251 1337 Returns the power series whose coefficients obtained by subtracting 1252 1338 the constant term from this series and then dividing by x. 1253 1339 1254 1340 EXAMPLES:: 1255 1341 1256 1342 sage: from sage.combinat.species.stream import Stream 1257 1343 sage: L = LazyPowerSeriesRing(QQ) 1258 1344 sage: f = L(range(20)) … … 1265 1351 def iterator(self, n=0, initial=None): 1266 1352 """ 1267 1353 Returns an iterator for the coefficients of self starting at n. 1268 1354 1269 1355 EXAMPLES:: 1270 1356 1271 1357 sage: from sage.combinat.species.stream import Stream 1272 1358 sage: L = LazyPowerSeriesRing(QQ) 1273 1359 sage: f = L(range(10)) … … 1290 1376 def _power_gen(self): 1291 1377 """ 1292 1378 Returns a generator for all the powers self^k starting with k = 1. 1293 1379 1294 1380 EXAMPLES:: 1295 1381 1296 1382 sage: L = LazyPowerSeriesRing(QQ) 1297 1383 sage: f = L([1,1,0]) 1298 1384 sage: g = f._power_gen() … … 1311 1397 def derivative(self): 1312 1398 """ 1313 1399 EXAMPLES:: 1314 1400 1315 1401 sage: from sage.combinat.species.stream import Stream 1316 1402 sage: L = LazyPowerSeriesRing(QQ) 1317 1403 sage: one = L(1) … … 1320 1406 sage: u = s.derivative() 1321 1407 sage: u.coefficients(10) 1322 1408 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 1323 1409 1324 1410 :: 1325 1411 1326 1412 sage: s = L() 1327 1413 sage: s._name = 's' 1328 1414 sage: s.define(one+monom*s*s) 1329 1415 sage: u = s.derivative() 1330 1416 sage: u.coefficients(5) #[1*1, 2*2, 3*5, 4*14, 5*42] 1331 1417 [1, 4, 15, 56, 210] 1332 1418 1333 1419 :: 1334 1420 1335 1421 sage: s = L([1]) 1336 1422 sage: t = L([0,1]) 1337 1423 sage: u = s(t).derivative() … … 1340 1426 [1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264] 1341 1427 sage: v.coefficients(11) 1342 1428 [1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264] 1343 1429 1344 1430 :: 1345 1431 1346 1432 sage: s = L(); s._name='s' 1347 1433 sage: t = L(); t._name='t' 1348 1434 sage: s.define(monom+t*t*t) … … 1355 1441 [0, 2, 3, 4, 30, 72, 133, 552, 1791, 4260] 1356 1442 sage: u.coefficients(10) == v.coefficients(10) 1357 1443 True 1358 1444 1359 1445 :: 1360 1446 1361 1447 sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])) 1362 1448 sage: d = f.derivative() 1363 1449 sage: d.get_aorder() … … 1371 1457 """ 1372 1458 Returns an iterator for the coefficients of the derivative of 1373 1459 self. 1374 1460 1375 1461 EXAMPLES:: 1376 1462 1377 1463 sage: L = LazyPowerSeriesRing(QQ) 1378 1464 sage: f = L([1]) 1379 1465 sage: g = f._diff_gen(0) … … 1384 1470 while True: 1385 1471 yield n*self._stream[n] 1386 1472 n += 1 1387 1388 ########### 1473 1474 ########### 1389 1475 #Integrals# 1390 1476 ########### 1391 1477 def integral(self, integration_constant = 0): 1392 1478 """ 1393 1479 EXAMPLES:: 1394 1480 1395 1481 sage: L = LazyPowerSeriesRing(QQ) 1396 1482 sage: zero = L(0) 1397 1483 sage: s = zero 1398 1484 sage: t = s.integral() 1399 1485 sage: t.is_zero() 1400 1486 True 1401 1487 1402 1488 :: 1403 1489 1404 1490 sage: s = zero 1405 1491 sage: t = s.integral(1) 1406 1492 sage: t.coefficients(6) 1407 1493 [1, 0, 0, 0, 0, 0] 1408 1494 sage: t._stream.is_constant() 1409 1495 True 1410 1496 1411 1497 :: 1412 1498 1413 1499 sage: s = L.term(1, 0) 1414 1500 sage: t = s.integral() 1415 1501 sage: t.coefficients(6) 1416 1502 [0, 1, 0, 0, 0, 0] 1417 1503 sage: t._stream.is_constant() 1418 1504 True 1419 1505 1420 1506 :: 1421 1507 1422 1508 sage: s = L.term(1,0) 1423 1509 sage: t = s.integral(1) 1424 1510 sage: t.coefficients(6) 1425 1511 [1, 1, 0, 0, 0, 0] 1426 1512 sage: t._stream.is_constant() 1427 1513 True 1428 1514 1429 1515 :: 1430 1516 1431 1517 sage: s = L.term(1, 4) 1432 1518 sage: t = s.integral() 1433 1519 sage: t.coefficients(10) 1434 1520 [0, 0, 0, 0, 0, 1/5, 0, 0, 0, 0] 1435 1521 1436 1522 :: 1437 1523 1438 1524 sage: s = L.term(1,4) 1439 1525 sage: t = s.integral(1) 1440 1526 sage: t.coefficients(10) 1441 1527 [1, 0, 0, 0, 0, 1/5, 0, 0, 0, 0] 1442 1528 1443 1529 TESTS:: 1444 1530 1445 1531 sage: from sage.combinat.species.stream import Stream 1446 1532 sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])) 1447 1533 sage: i = f.derivative().integral() … … 1464 1550 def _integral_zero_gen(self, ao): 1465 1551 """ 1466 1552 EXAMPLES:: 1467 1553 1468 1554 sage: L = LazyPowerSeriesRing(QQ) 1469 1555 sage: s = L.gen() 1470 1556 sage: g = s._integral_zero_gen(1) … … 1487 1573 def _integral_nonzero_gen(self, integration_constant): 1488 1574 """ 1489 1575 EXAMPLES:: 1490 1576 1491 1577 sage: from sage.combinat.species.stream import Stream 1492 1578 sage: L = LazyPowerSeriesRing(QQ) 1493 1579 sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])).derivative() … … 1505 1591 else: 1506 1592 for _ in range(ao1): 1507 1593 yield self._zero 1508 1594 1509 1595 n = max(1,ao) 1510 1596 while True: 1511 1597 c = self.coefficient(n1) … … 1521 1607 def is_finite(self, n=None): 1522 1608 """ 1523 1609 EXAMPLES:: 1524 1610 1525 1611 sage: L = LazyPowerSeriesRing(QQ) 1526 1612 sage: a = L([0,0,1,0,0]); a 1527 1613 O(1) … … 1545 1631 1546 1632 if n is None: 1547 1633 n = len(s) 1548 1634 1549 1635 if s.is_constant() and all(s[i] == 0 for i in range(n1, max(n,len(s)))): 1550 1636 return True 1551 1637 … … 1554 1640 def exponential(self): 1555 1641 """ 1556 1642 TESTS:: 1557 1643 1558 1644 sage: def inv_factorial(): 1559 1645 ... q = 1 1560 1646 ... yield 0 … … 1584 1670 def __getitem__(self, i): 1585 1671 """ 1586 1672 Returns the ith coefficient of self. 1587 1673 1588 1674 EXAMPLES:: 1589 1675 1590 1676 sage: L = LazyPowerSeriesRing(QQ) 1591 1677 sage: f = L([1,2,3,0]) 1592 1678 sage: [f[i] for i in range(5)] … … 1604 1690 min and going up to, but not including max. If min is not 1605 1691 specified, then it is assumed to be zero. If max is not specified, 1606 1692 then it is assumed to be infinity. 1607 1693 1608 1694 EXAMPLES:: 1609 1695 1610 1696 sage: L = LazyPowerSeriesRing(QQ) 1611 1697 sage: a = L([1]) 1612 1698 sage: a.restricted().coefficients(10) … … 1622 1708 if ((min is None and max is None) or 1623 1709 (max is None and self.get_aorder() >= min)): 1624 1710 return self 1625 1711 1626 1712 return self._new(partial(self._restricted_gen, min, max), 1627 1713 lambda ao: __builtin__.max(ao, min), self) 1628 1714 1629 1715 def _restricted_gen(self, mn, mx, ao): 1630 1716 """ 1631 1717 EXAMPLES:: 1632 1718 1633 1719 sage: L = LazyPowerSeriesRing(QQ) 1634 1720 sage: a = L([1]) 1635 1721 sage: g = a._restricted_gen(None, None, 2) … … 1641 1727 sage: g = a._restricted_gen(3, None, 2) 1642 1728 sage: [g.next() for i in range(10)] 1643 1729 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1] 1644 1730 1645 1731 :: 1646 1732 1647 1733 sage: g = a._restricted_gen(1, 5, 2) 1648 1734 sage: [g.next() for i in range(6)] 1649 1735 [0, 0, 1, 1, 1, 0] 1650 1736 """ 1651 1737 BR = self.parent().base_ring() 1652 1738 for n in range(max(mn,ao)): 1653 yield BR (0)1739 yield BR.zero() 1654 1740 1655 1741 n = max(mn, ao) 1656 1742 while True: 1657 1743 if mx is not None and n >= mx: 1658 yield BR (0)1744 yield BR.zero() 1659 1745 break 1660 1746 else: 1661 1747 yield self._stream[n] … … 1668 1754 def _change_ring_gen(self, R, ao): 1669 1755 """ 1670 1756 EXAMPLES:: 1671 1757 1672 1758 sage: L = LazyPowerSeriesRing(QQ) 1673 1759 sage: L2 = LazyPowerSeriesRing(RR) 1674 1760 sage: a = L([1]) … … 1688 1774 1689 1775 ################################# 1690 1776 1691 1692 1693 1777 def uninitialized(): 1694 1778 """ 1695 1779 EXAMPLES:: 1696 1780 1697 1781 sage: from sage.combinat.species.series import uninitialized 1698 1782 sage: uninitialized() 1699 1783 Traceback (most recent call last):