Sage: Ticket #27347: Lazy Laurent series
https://trac.sagemath.org/ticket/27347
<p>
Introduce lazy Laurent series to Sage.
</p>
<p>
A lazy Laurent series computes coefficients only when demanded or needed. In a sense, lazy Laurent series are Laurent series of infinite precision.
</p>
<p>
A generating function example from the code:
</p>
<pre class="wiki">Generating functions are laurent series over the integer ring::
sage: from sage.rings.lazy_laurent_series_ring import LazyLaurentSeriesRing
sage: L = LazyLaurentSeriesRing(ZZ, 'z')
This defines the generating function of Fibonacci sequence::
sage: def coeff(s, i):
....: if i in [0, 1]:
....: return 1
....: else:
....: return s.coefficient(i - 1) + s.coefficient(i - 2)
....:
sage: f = L.series(coeff, valuation=0); f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + ...
The 100th element of Fibonacci sequence can be obtained from the generating
function::
sage: f.coefficient(100)
573147844013817084101
</pre><p>
Lazy Laurent series is of course useful for other things. This will be used to implement infinite precision Laurent series expansion of algebraic functions in function fields, as a sequel to <a class="closed ticket" href="https://trac.sagemath.org/ticket/27418" title="enhancement: Global function fields: completions (closed: fixed)">#27418</a>.
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/27347
Trac 1.1.6kleeSun, 24 Feb 2019 22:12:08 GMTbranch set
https://trac.sagemath.org/ticket/27347#comment:1
https://trac.sagemath.org/ticket/27347#comment:1
<ul>
<li><strong>branch</strong>
set to <em>u/klee/27347</em>
</li>
</ul>
TicketgitSun, 24 Feb 2019 22:14:08 GMTcommit set
https://trac.sagemath.org/ticket/27347#comment:2
https://trac.sagemath.org/ticket/27347#comment:2
<ul>
<li><strong>commit</strong>
set to <em>5d24a347b3f5bd6273bf678958c94d18b273b28f</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=5d24a347b3f5bd6273bf678958c94d18b273b28f"><span class="icon"></span>5d24a34</a></td><td><code>Introduce lazy laurent series</code>
</td></tr></table>
TicketkleeSun, 24 Feb 2019 22:16:30 GMTstatus changed; author set
https://trac.sagemath.org/ticket/27347#comment:3
https://trac.sagemath.org/ticket/27347#comment:3
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>author</strong>
set to <em>Kwankyu Lee</em>
</li>
</ul>
TicketgitMon, 25 Feb 2019 06:32:59 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:4
https://trac.sagemath.org/ticket/27347#comment:4
<ul>
<li><strong>commit</strong>
changed from <em>5d24a347b3f5bd6273bf678958c94d18b273b28f</em> to <em>ace42826cd8782e1aee3c596707b33f5102291d6</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=ace42826cd8782e1aee3c596707b33f5102291d6"><span class="icon"></span>ace4282</a></td><td><code>pyflakes fixes</code>
</td></tr></table>
TicketgitMon, 25 Feb 2019 08:34:38 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:5
https://trac.sagemath.org/ticket/27347#comment:5
<ul>
<li><strong>commit</strong>
changed from <em>ace42826cd8782e1aee3c596707b33f5102291d6</em> to <em>389798e1d7057545c7914f1456e32f9c47aff5be</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=389798e1d7057545c7914f1456e32f9c47aff5be"><span class="icon"></span>389798e</a></td><td><code>Add series method</code>
</td></tr></table>
TicketgitMon, 25 Feb 2019 19:15:02 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:6
https://trac.sagemath.org/ticket/27347#comment:6
<ul>
<li><strong>commit</strong>
changed from <em>389798e1d7057545c7914f1456e32f9c47aff5be</em> to <em>43ba7859f92d707e2f6f3cf93aafbc4f7f4b453a</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=43ba7859f92d707e2f6f3cf93aafbc4f7f4b453a"><span class="icon"></span>43ba785</a></td><td><code>Small fixes on docstrings</code>
</td></tr></table>
TicketkleeMon, 04 Mar 2019 09:10:49 GMTdescription changed
https://trac.sagemath.org/ticket/27347#comment:7
https://trac.sagemath.org/ticket/27347#comment:7
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/27347?action=diff&version=7">diff</a>)
</li>
</ul>
TicketembrayMon, 25 Mar 2019 10:56:15 GMTmilestone changed
https://trac.sagemath.org/ticket/27347#comment:8
https://trac.sagemath.org/ticket/27347#comment:8
<ul>
<li><strong>milestone</strong>
changed from <em>sage-8.7</em> to <em>sage-8.8</em>
</li>
</ul>
<p>
Ticket retargeted after milestone closed (if you don't believe this ticket is appropriate for the Sage 8.8 release please retarget manually)
</p>
TicketgitMon, 01 Apr 2019 00:49:15 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:9
https://trac.sagemath.org/ticket/27347#comment:9
<ul>
<li><strong>commit</strong>
changed from <em>43ba7859f92d707e2f6f3cf93aafbc4f7f4b453a</em> to <em>e7ff9993551778c67c6a6168f0e26c5943f14925</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=e7ff9993551778c67c6a6168f0e26c5943f14925"><span class="icon"></span>e7ff999</a></td><td><code>Add lazy laurent series</code>
</td></tr></table>
TicketgitThu, 04 Apr 2019 10:57:28 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:10
https://trac.sagemath.org/ticket/27347#comment:10
<ul>
<li><strong>commit</strong>
changed from <em>e7ff9993551778c67c6a6168f0e26c5943f14925</em> to <em>15e1b1c671d61ef279f1c32a715ddd56a2fa7997</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=15e1b1c671d61ef279f1c32a715ddd56a2fa7997"><span class="icon"></span>15e1b1c</a></td><td><code>Add lazy laurent series</code>
</td></tr></table>
TicketgitThu, 04 Apr 2019 20:05:57 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:11
https://trac.sagemath.org/ticket/27347#comment:11
<ul>
<li><strong>commit</strong>
changed from <em>15e1b1c671d61ef279f1c32a715ddd56a2fa7997</em> to <em>f70fca8e3303c51b98c3f9311da277fd954b1ebe</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=f70fca8e3303c51b98c3f9311da277fd954b1ebe"><span class="icon"></span>f70fca8</a></td><td><code>Add __bool__</code>
</td></tr></table>
TickettscrimFri, 05 Apr 2019 09:22:46 GMT
https://trac.sagemath.org/ticket/27347#comment:12
https://trac.sagemath.org/ticket/27347#comment:12
<p>
Some comments:
</p>
<p>
Is there a reason why you do not use the <code>LazyPowerSeriesRing</code> for the main element (with a non-zero constant term until the whole series is zero) and then just store the valuation? This is how things are done for the Laurent polynomials. That way there is less duplication of code and improvements to one improve both.
</p>
<p>
Why do you override <code>__eq__</code> and not use the one provided by <code>Element</code> and the coercion framework? It is more flexible and allows you do implement comparisons (if you want) all in one function of <code>_richcmp_</code>.
</p>
<p>
Do not have bare <code>except:</code> statements (see <code>coefficient</code>).
</p>
<p>
Does the elements pickle? I am a little worried that the addition of two power series will not pickling because of the little helper <code>add</code> function. You should add a <code>loads(dumps(foo))</code> test if it does work.
</p>
<p>
Typo <code>laurent</code> -> <code>Laurent</code> (it is proper noun).
</p>
<p>
<code>if len(s) == 0:</code> -> <code>if not s:</code>
</p>
TicketkleeFri, 05 Apr 2019 23:01:41 GMTstatus changed
https://trac.sagemath.org/ticket/27347#comment:13
https://trac.sagemath.org/ticket/27347#comment:13
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>needs_work</em>
</li>
</ul>
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:12" title="Comment 12">tscrim</a>:
</p>
<blockquote class="citation">
<p>
Is there a reason why you do not use the <code>LazyPowerSeriesRing</code> for the main element (with a non-zero constant term until the whole series is zero) and then just store the valuation? This is how things are done for the Laurent polynomials. That way there is less duplication of code and improvements to one improve both.
</p>
</blockquote>
<p>
I looked into the <code>LazyPowerSeriesRing</code> many years ago:
</p>
<p>
<a class="ext-link" href="https://groups.google.com/forum/#!searchin/sage-support/lazy$20power$20series%7Csort:date/sage-support/JZwDWKq3DtM/tyfxxdxPyXYJ"><span class="icon"></span>https://groups.google.com/forum/#!searchin/sage-support/lazy$20power$20series%7Csort:date/sage-support/JZwDWKq3DtM/tyfxxdxPyXYJ</a>
</p>
<p>
I think I didn't like it in several ways :-) Still I don't understand this behavior:
</p>
<pre class="wiki">sage: L.<t>=LazyPowerSeriesRing(QQ)
sage: s=L([0,0,1,2])
sage: s.coefficient(0)
0
sage: s.coefficient(1)
0
sage: s.coefficient(2)
1
sage: s.coefficient(3)
2
sage: s
t^2 + 2*t^3 + O(x^4)
sage: s.get_order()
1
sage: s.get_aorder()
1
</pre><p>
The reason was that it was easy to implement lazy laurent series with an interface and behaviors that I prefer, while I could not understand well enough <code>LazyPowerSeriesRing</code>...
</p>
<p>
I would reconsider basing lazy laurent series on <code>LazyPowerSeriesRing</code>, if you help me understand the strange behaviour above.
</p>
TickettscrimFri, 05 Apr 2019 23:44:56 GMT
https://trac.sagemath.org/ticket/27347#comment:14
https://trac.sagemath.org/ticket/27347#comment:14
<p>
So here is what <code>refine_aorder</code> does. It first checks if <code>self.order</code> has been set, if it has, do not do anything. Then it goes through all of the <code>n</code> computed entries <strong>if <code>self.aorder</code> is 0</strong> and we have already computed at least one entry. Then find the first nonzero entry. If we have found one, set the order.
</p>
<p>
The problem is the bold part. After the first iteration when <code>n = 1</code>, the <code>self.aorder</code> gets set to <code>1</code>, then on the second run through, that block does not get run, which then means <code>self.aorder < n</code> and we set the order to be <code>1</code>.
</p>
<pre class="wiki">sage: s.coefficient(1)
0
sage: s.aorder
1
sage: s.order
Unknown series order
sage: s.coefficient(2)
1
sage: s.aorder
1
sage: s.order
1
</pre><p>
IMO, this is a bug.
</p>
TicketgitSun, 07 Apr 2019 08:03:20 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:15
https://trac.sagemath.org/ticket/27347#comment:15
<ul>
<li><strong>commit</strong>
changed from <em>f70fca8e3303c51b98c3f9311da277fd954b1ebe</em> to <em>fb4d65d9dfdb53a735ca33e7800ef79e4ea8ece4</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=2f2c59c8d7e1cf7c1cf0b6141d145b5624f0f0c3"><span class="icon"></span>2f2c59c</a></td><td><code>Capitalize laurent as it is a proper noun</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=146205a05162a9b96d96f3f3b2130eddf7e70abe"><span class="icon"></span>146205a</a></td><td><code>No bare except clause</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=fb4d65d9dfdb53a735ca33e7800ef79e4ea8ece4"><span class="icon"></span>fb4d65d</a></td><td><code>Use _richcmp_ instead of primitive __eq__</code>
</td></tr></table>
TicketgitSun, 07 Apr 2019 08:48:37 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:16
https://trac.sagemath.org/ticket/27347#comment:16
<ul>
<li><strong>commit</strong>
changed from <em>fb4d65d9dfdb53a735ca33e7800ef79e4ea8ece4</em> to <em>41f3a4237cc0f574334a6e26e00f16d73d23972a</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=41f3a4237cc0f574334a6e26e00f16d73d23972a"><span class="icon"></span>41f3a42</a></td><td><code>Lazy Laurent series is not picklable</code>
</td></tr></table>
TicketkleeSun, 07 Apr 2019 08:53:29 GMT
https://trac.sagemath.org/ticket/27347#comment:17
https://trac.sagemath.org/ticket/27347#comment:17
<blockquote class="citation">
<p>
Why do you override <code>__eq__</code> and not use the one provided by <code>Element</code> and the coercion framework? It is more flexible and allows you do implement comparisons (if you want) all in one function of <code>_richcmp_</code>.
</p>
</blockquote>
<p>
Ok. Fixed.
</p>
<blockquote class="citation">
<p>
Do not have bare <code>except:</code> statements (see <code>coefficient</code>).
</p>
</blockquote>
<p>
Fixed.
</p>
<blockquote class="citation">
<p>
Does the elements pickle? I am a little worried that the addition of two power series will not pickling because of the little helper <code>add</code> function. You should add a <code>loads(dumps(foo))</code> test if it does work.
</p>
</blockquote>
<p>
No. Your worry is real; lazy Laurent series is not picklable in general. This seems an inherent nature of my implementation...
</p>
<p>
I added a test to show this.
</p>
<blockquote class="citation">
<p>
Typo <code>laurent</code> -> <code>Laurent</code> (it is proper noun).
</p>
</blockquote>
<p>
Right. Fixed.
</p>
<blockquote class="citation">
<p>
<code>if len(s) == 0:</code> -> <code>if not s:</code>
</p>
</blockquote>
<p>
Done.
</p>
<hr />
<p>
New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit?id=41f3a4237cc0f574334a6e26e00f16d73d23972a"><span class="icon"></span>41f3a42</a></td><td><code>Lazy Laurent series is not picklable</code>
</td></tr></table>
TicketkleeSun, 07 Apr 2019 09:40:27 GMT
https://trac.sagemath.org/ticket/27347#comment:18
https://trac.sagemath.org/ticket/27347#comment:18
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:12" title="Comment 12">tscrim</a>:
</p>
<blockquote class="citation">
<p>
Some comments:
</p>
<p>
Is there a reason why you do not use the <code>LazyPowerSeriesRing</code> for the main element (with a non-zero constant term until the whole series is zero) and then just store the valuation? This is how things are done for the Laurent polynomials. That way there is less duplication of code and improvements to one improve both.
</p>
</blockquote>
<p>
I thought about this. Now I think:
</p>
<p>
Lazy Laurent series is not just about Laurent series but also about how coefficients are computed lazily. A <code>LazyPowerSeriesRing</code> element gets its coefficients from a stream object, which essentially yields coefficients as required. On the other hand, lazy Laurent series <code>s</code> gets its coefficients from a python function that outputs n-th coefficient for input <code>s</code> and <code>n</code>. This allows coefficients to be computed recursively. For example, it is very easy to define the Fibonacci series.
</p>
<p>
So it is impossible to base my lazy Laurent series code on <code>LazyPowerSeriesRing</code> without abandoning the essential feature of the implementation.
</p>
<p>
Frankly, I would rather provide new lazy power series as a subclass of my lazy Laurent series. But this is of course highly biased opinion :-)
</p>
<p>
You may be reluctant to accept my implementation of lazy Laurent series into <code>sage.rings</code> as it then gets kind of standard status among different possible implementations of lazy Laurent series in Sage. Then I am willing to relocate it into <code>sage.rings.function_field</code>.
</p>
TicketgitSun, 07 Apr 2019 10:04:59 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:19
https://trac.sagemath.org/ticket/27347#comment:19
<ul>
<li><strong>commit</strong>
changed from <em>41f3a4237cc0f574334a6e26e00f16d73d23972a</em> to <em>b09cd84220dc5878d03db5d1ee1d721388457b4e</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=b09cd84220dc5878d03db5d1ee1d721388457b4e"><span class="icon"></span>b09cd84</a></td><td><code>Fix pickling doctest</code>
</td></tr></table>
TickettscrimSun, 07 Apr 2019 13:58:23 GMT
https://trac.sagemath.org/ticket/27347#comment:20
https://trac.sagemath.org/ticket/27347#comment:20
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:18" title="Comment 18">klee</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:12" title="Comment 12">tscrim</a>:
</p>
<blockquote class="citation">
<p>
Some comments:
</p>
<p>
Is there a reason why you do not use the <code>LazyPowerSeriesRing</code> for the main element (with a non-zero constant term until the whole series is zero) and then just store the valuation? This is how things are done for the Laurent polynomials. That way there is less duplication of code and improvements to one improve both.
</p>
</blockquote>
<p>
I thought about this. Now I think:
</p>
<p>
Lazy Laurent series is not just about Laurent series but also about how coefficients are computed lazily. A <code>LazyPowerSeriesRing</code> element gets its coefficients from a stream object, which essentially yields coefficients as required. On the other hand, lazy Laurent series <code>s</code> gets its coefficients from a python function that outputs n-th coefficient for input <code>s</code> and <code>n</code>. This allows coefficients to be computed recursively. For example, it is very easy to define the Fibonacci series.
</p>
</blockquote>
<p>
Well, I am fairly certain you could do this with an <code>RecursivelyEnumeratedSet</code> and a bit of know-how, but I agree that it is more complicated and less intuitive. I also agree that having general functions as input would probably be a good thing for <code>LazyPowerSeriesRing</code> to have, but I believe that was designed for more specific use for the <code>combinat/species</code> code.
</p>
<p>
One benefit I do see is that you do not need to explicitly know the valuation at creation-time. With my suggested implementation, it does need to be computed at element creation.
</p>
<blockquote class="citation">
<p>
Frankly, I would rather provide new lazy power series as a subclass of my lazy Laurent series. But this is of course highly biased opinion :-)
</p>
</blockquote>
<p>
I don't have an opinion on this matter, but there are likely some considerations required to replace or extend the current implementation.
</p>
<blockquote class="citation">
<p>
You may be reluctant to accept my implementation of lazy Laurent series into <code>sage.rings</code> as it then gets kind of standard status among different possible implementations of lazy Laurent series in Sage. Then I am willing to relocate it into <code>sage.rings.function_field</code>.
</p>
</blockquote>
<p>
This I don't really care about. I just am a little unhappy with the large difference between the semantics (and syntax) between the two implementations. I guess that is a bit unavoidable here because this definitely is serving a purpose.
</p>
<p>
However, I do think we should at least try to address the pickling issues. I believe this means you cannot use this in parallel implementations (IIRC this uses pickling to communicate between the processes). It also means you cannot (easily) store the data you compute. I think it is sufficient to separate out the <code>add</code> and similar operations into functions, but maybe they need to be small little helper class, such as
</p>
<div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">LaurentSeriesOperator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> lps<span class="p">,</span> op<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span>lps <span class="o">=</span> lps
<span class="bp">self</span><span class="o">.</span>op <span class="o">=</span> op
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> s<span class="p">,</span> n<span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span>op<span class="p">(</span><span class="bp">self</span><span class="o">.</span>lps<span class="p">[</span>n<span class="p">],</span> s<span class="p">[</span>n<span class="p">])</span>
<span class="k">def</span> <span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span>lps<span class="p">,</span> <span class="bp">self</span><span class="o">.</span>op<span class="p">),</span> <span class="p">{})</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> other<span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span>other<span class="p">,</span> LaurentSeriesOperator<span class="p">)</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span>lps <span class="o">==</span> other<span class="o">.</span>lps <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span>op <span class="o">==</span> other<span class="o">.</span>op<span class="p">)</span>
</pre></div></div><p>
where <code>op</code> is, e.g., <code>operator.add</code>. This way you might be able to do something with comparisons in some semi-reasonable capacity too.
</p>
TicketgitMon, 08 Apr 2019 05:45:32 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:21
https://trac.sagemath.org/ticket/27347#comment:21
<ul>
<li><strong>commit</strong>
changed from <em>b09cd84220dc5878d03db5d1ee1d721388457b4e</em> to <em>89992b806e2d534343bb57c2a6cec1d0fecd9394</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=89992b806e2d534343bb57c2a6cec1d0fecd9394"><span class="icon"></span>89992b8</a></td><td><code>Reimplement arithmetic operations for series to be picklable</code>
</td></tr></table>
TicketkleeMon, 08 Apr 2019 05:51:24 GMT
https://trac.sagemath.org/ticket/27347#comment:22
https://trac.sagemath.org/ticket/27347#comment:22
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:20" title="Comment 20">tscrim</a>:
</p>
<blockquote class="citation">
<p>
However, I do think we should at least try to address the pickling issues. I believe this means you cannot use this in parallel implementations (IIRC this uses pickling to communicate between the processes). It also means you cannot (easily) store the data you compute. I think it is sufficient to separate out the <code>add</code> and similar operations into functions, but maybe they need to be small little helper class, such as
</p>
<div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">LaurentSeriesOperator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> lps<span class="p">,</span> op<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span>lps <span class="o">=</span> lps
<span class="bp">self</span><span class="o">.</span>op <span class="o">=</span> op
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> s<span class="p">,</span> n<span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span>op<span class="p">(</span><span class="bp">self</span><span class="o">.</span>lps<span class="p">[</span>n<span class="p">],</span> s<span class="p">[</span>n<span class="p">])</span>
<span class="k">def</span> <span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span>lps<span class="p">,</span> <span class="bp">self</span><span class="o">.</span>op<span class="p">),</span> <span class="p">{})</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> other<span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span>other<span class="p">,</span> LaurentSeriesOperator<span class="p">)</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span>lps <span class="o">==</span> other<span class="o">.</span>lps <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span>op <span class="o">==</span> other<span class="o">.</span>op<span class="p">)</span>
</pre></div></div><p>
where <code>op</code> is, e.g., <code>operator.add</code>. This way you might be able to do something with comparisons in some semi-reasonable capacity too.
</p>
</blockquote>
<p>
Using module-level classes to define operators is a good idea. Hinted by your template class, I could reimplement lazy Laurent series to be picklable. Great!
</p>
TicketgitMon, 08 Apr 2019 07:12:32 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:23
https://trac.sagemath.org/ticket/27347#comment:23
<ul>
<li><strong>commit</strong>
changed from <em>89992b806e2d534343bb57c2a6cec1d0fecd9394</em> to <em>989a3ac561bed35c9466a848e2a9ef441f94f560</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=989a3ac561bed35c9466a848e2a9ef441f94f560"><span class="icon"></span>989a3ac</a></td><td><code>Comparison now works in semi-reasonable capacity</code>
</td></tr></table>
TicketgitMon, 08 Apr 2019 07:24:44 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:24
https://trac.sagemath.org/ticket/27347#comment:24
<ul>
<li><strong>commit</strong>
changed from <em>989a3ac561bed35c9466a848e2a9ef441f94f560</em> to <em>e12fd5b6511f90ccb9b5b7bc59cb61e30d75cc93</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=ce4db37902834445be96110501cff1aba7e229f1"><span class="icon"></span>ce4db37</a></td><td><code>Now pass _test_pickling</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=e12fd5b6511f90ccb9b5b7bc59cb61e30d75cc93"><span class="icon"></span>e12fd5b</a></td><td><code>Minor fixes in string formatting</code>
</td></tr></table>
TicketkleeMon, 08 Apr 2019 07:26:44 GMTdescription changed
https://trac.sagemath.org/ticket/27347#comment:25
https://trac.sagemath.org/ticket/27347#comment:25
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/27347?action=diff&version=25">diff</a>)
</li>
</ul>
TicketkleeMon, 08 Apr 2019 07:30:44 GMTsummary changed
https://trac.sagemath.org/ticket/27347#comment:26
https://trac.sagemath.org/ticket/27347#comment:26
<ul>
<li><strong>summary</strong>
changed from <em>Lazy laurent series</em> to <em>Lazy Laurent series</em>
</li>
</ul>
TicketgitMon, 08 Apr 2019 09:06:48 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:27
https://trac.sagemath.org/ticket/27347#comment:27
<ul>
<li><strong>commit</strong>
changed from <em>e12fd5b6511f90ccb9b5b7bc59cb61e30d75cc93</em> to <em>5214a3a020c8e268c62957990f3ef5351641bd3f</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. Last 10 new commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=afeae09cabf033abca6595239b9968e1d916c921"><span class="icon"></span>afeae09</a></td><td><code>Merge branch 'function-fields-infinity-precision' into function-fields</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=bf815095d21e19af2ee7f2cda294eb09ef922f64"><span class="icon"></span>bf81509</a></td><td><code>Merge branch 'lazy-power-series-trac27347' into function-fields</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=e552770b1950c6e27eb1c679bba1104487165b20"><span class="icon"></span>e552770</a></td><td><code>fix</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=6c5fc73a72dc93835dba558796743ab630763943"><span class="icon"></span>6c5fc73</a></td><td><code>Merge branch 'function-fields-infinity-precision' into function-fields</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=f616d206f03e01bbc10409e0091ba3bd9808443c"><span class="icon"></span>f616d20</a></td><td><code>Merge branch 'lazy-power-series-trac27347' into function-fields-infinity-precision</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=8d77ecca200465722696f2e9f59d8f4096c1fd02"><span class="icon"></span>8d77ecc</a></td><td><code>Merge branch 'function-fields-infinity-precision' into function-fields</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=bbeebef9b41a3f859c0b7eab1d5248a978689595"><span class="icon"></span>bbeebef</a></td><td><code>Merge branch 'function-fields' into curves-irreducible</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=64c9c6bf2151d07781460fb553f820302dea3613"><span class="icon"></span>64c9c6b</a></td><td><code>Add delta-invariant</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=61427501c57756caeb525386ee58cfff192066e1"><span class="icon"></span>6142750</a></td><td><code>Add ag codes</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=5214a3a020c8e268c62957990f3ef5351641bd3f"><span class="icon"></span>5214a3a</a></td><td><code>Add list operator and allow list input</code>
</td></tr></table>
TicketgitMon, 08 Apr 2019 09:09:41 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:28
https://trac.sagemath.org/ticket/27347#comment:28
<ul>
<li><strong>commit</strong>
changed from <em>5214a3a020c8e268c62957990f3ef5351641bd3f</em> to <em>eac7047c33c8fd1201e86493df34ef9cb805e893</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=eac7047c33c8fd1201e86493df34ef9cb805e893"><span class="icon"></span>eac7047</a></td><td><code>Add list operator and allow list input</code>
</td></tr></table>
TicketkleeMon, 08 Apr 2019 09:10:20 GMT
https://trac.sagemath.org/ticket/27347#comment:29
https://trac.sagemath.org/ticket/27347#comment:29
<p>
Oops. Pushed a wrong branch!
</p>
TicketkleeMon, 08 Apr 2019 09:21:32 GMTstatus changed
https://trac.sagemath.org/ticket/27347#comment:30
https://trac.sagemath.org/ticket/27347#comment:30
<ul>
<li><strong>status</strong>
changed from <em>needs_work</em> to <em>needs_review</em>
</li>
</ul>
TickettscrimMon, 08 Apr 2019 12:46:37 GMT
https://trac.sagemath.org/ticket/27347#comment:31
https://trac.sagemath.org/ticket/27347#comment:31
<p>
This is looking good.
</p>
<p>
Past experience tells me you should also implement a <code>__ne__</code> at the base class. I also think you should include more ABCs to avoid the extra duplication with the <code>__eq__</code> methods. Similarly, why not use the <code>op</code> version for <code>+-*/</code> to avoid class duplication? You may also want a <code>__hash__</code> and incorporate that into the hash of the lazy Laurent series. With how many operator classes you have, it may also be worthwhile pulling that out to a separate file for better separations-of-concerns between files.
</p>
TicketgitTue, 09 Apr 2019 04:00:40 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:32
https://trac.sagemath.org/ticket/27347#comment:32
<ul>
<li><strong>commit</strong>
changed from <em>eac7047c33c8fd1201e86493df34ef9cb805e893</em> to <em>f5b579285b0daf9bab2955dbb397174467fd3e47</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=f5b579285b0daf9bab2955dbb397174467fd3e47"><span class="icon"></span>f5b5792</a></td><td><code>Add hash and fix other issues from reviewer comments</code>
</td></tr></table>
TicketkleeTue, 09 Apr 2019 04:04:32 GMT
https://trac.sagemath.org/ticket/27347#comment:33
https://trac.sagemath.org/ticket/27347#comment:33
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:31" title="Comment 31">tscrim</a>:
</p>
<blockquote class="citation">
<p>
This is looking good.
</p>
<p>
Past experience tells me you should also implement a <code>__ne__</code> at the base class.
</p>
</blockquote>
<p>
Done.
</p>
<blockquote class="citation">
<p>
I also think you should include more ABCs to avoid the extra duplication with the <code>__eq__</code> methods.
</p>
</blockquote>
<p>
Ok.
</p>
<blockquote class="citation">
<p>
Similarly, why not use the <code>op</code> version for <code>+-*/</code> to avoid class duplication?
</p>
</blockquote>
<p>
I don't get it. They cannot be treated uniformly. Look at the <code>__call__</code> method.
</p>
<blockquote class="citation">
<p>
You may also want a <code>__hash__</code> and incorporate that into the hash of the lazy Laurent series.
</p>
</blockquote>
<p>
Done.
</p>
<blockquote class="citation">
<p>
With how many operator classes you have, it may also be worthwhile pulling that out to a separate file for better separations-of-concerns between files.
</p>
</blockquote>
<p>
Done.
</p>
TickettscrimTue, 09 Apr 2019 05:55:35 GMT
https://trac.sagemath.org/ticket/27347#comment:34
https://trac.sagemath.org/ticket/27347#comment:34
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:33" title="Comment 33">klee</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:31" title="Comment 31">tscrim</a>:
</p>
<blockquote class="citation">
<p>
Similarly, why not use the <code>op</code> version for <code>+-*/</code> to avoid class duplication?
</p>
</blockquote>
<p>
I don't get it. They cannot be treated uniformly. Look at the <code>__call__</code> method.
</p>
</blockquote>
<p>
You can do what I suggested in <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:20" title="Comment 20">comment:20</a> for these classes:
</p>
<ul><li><code>LazyLaurentSeriesOperator_add</code> (by passing <code>operator.add</code>)
</li><li><code>LazyLaurentSeriesOperator_sub</code> (by passing <code>operator.sub</code>)
</li></ul><p>
You're right that multiplication must be treated separately. Although you could also do this for a scalar multiplication version of this (which will be faster than coercion and multiplication). For 2 cases, there is a less compelling reason to factor the common code out like this.
</p>
<p>
There is not really a benefit for doing this for unitary operations (as there is only 1 that could work this way).
</p>
<p>
In some ways it feels like we are reinventing the wheel here because we are effectively building an evaluation tree, and we already have something like this within <code>SR</code> (or sympy/pynac/etc.). However, I don't see a way around this by using <code>SR</code> (and we might have to work a little bit to avoid doing computations unnecessarily inside of there). So I think we have to keep doing things this way. Just an observation.
</p>
TicketgitTue, 09 Apr 2019 08:20:23 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:35
https://trac.sagemath.org/ticket/27347#comment:35
<ul>
<li><strong>commit</strong>
changed from <em>f5b579285b0daf9bab2955dbb397174467fd3e47</em> to <em>3bf2101b59d3d13aca9815fbe907ff7ad6c33cdb</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=3bf2101b59d3d13aca9815fbe907ff7ad6c33cdb"><span class="icon"></span>3bf2101</a></td><td><code>Add scalar multiplication operator</code>
</td></tr></table>
TicketkleeTue, 09 Apr 2019 11:09:05 GMT
https://trac.sagemath.org/ticket/27347#comment:36
https://trac.sagemath.org/ticket/27347#comment:36
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:34" title="Comment 34">tscrim</a>:
</p>
<blockquote class="citation">
<p>
Although you could also do this for a scalar multiplication version of this (which will be faster than coercion and multiplication).
</p>
</blockquote>
<p>
Added scalar multiplication.
</p>
<blockquote class="citation">
<p>
In some ways it feels like we are reinventing the wheel here because we are effectively building an evaluation tree, and we already have something like this within <code>SR</code> (or sympy/pynac/etc.). However, I don't see a way around this by using <code>SR</code> (and we might have to work a little bit to avoid doing computations unnecessarily inside of there). So I think we have to keep doing things this way. Just an observation.
</p>
</blockquote>
<p>
True. It is just inevitable that sometimes we make wheels for different needs :-)
</p>
TicketmantepseTue, 09 Apr 2019 11:24:13 GMT
https://trac.sagemath.org/ticket/27347#comment:37
https://trac.sagemath.org/ticket/27347#comment:37
<p>
I find this quite wonderful! It would be great if we could replace <code>LazyPowerSeries</code> with this. One feature of <code>LazyPowerSeries</code> was that it allows recursive definitions "guessing" the correct initialisations, as for example in
</p>
<pre class="wiki"> sage: L = LazyPowerSeriesRing(QQ)
sage: one = L(1)
sage: monom = L.gen()
sage: s = L()
sage: s._name = 's'
sage: s.define(one+monom*s*s)
sage: [s.coefficient(i) for i in range(6)]
[1, 1, 2, 5, 14, 42]
</pre><p>
Although this is based on the original code by Ralf Hemmecke and myself, which in turn is based on code of Nicolas Thiery (I think), I am not sure anymore whether it is so important. Of course, if we could have something similar, even better.
</p>
TicketmantepseTue, 09 Apr 2019 11:26:32 GMT
https://trac.sagemath.org/ticket/27347#comment:38
https://trac.sagemath.org/ticket/27347#comment:38
<p>
One question with respect to equality. It seems to me that your implementation of <code>__eq__</code> is quite brittle. It is clear that one cannot have proper equality, so it should be clearly stated what it can do and what it can't.
</p>
<p>
Apart from that, in the case of truncation, one could make it exact easily.
</p>
TickettscrimTue, 09 Apr 2019 14:40:06 GMT
https://trac.sagemath.org/ticket/27347#comment:39
https://trac.sagemath.org/ticket/27347#comment:39
<p>
Some other comments on the code:
</p>
<p>
For <code>__bool__</code>, I think erroring out immediately when <code>self._constant is None</code> is not the way to go. I think you should check the computed coefficients in that case to see if any of them are non-zero. If they are all <code>0</code>, then you should error out. Also, a fast first check when <code>self._constant</code> is not <code>None</code> is to see if that constant is non-zero <code>0</code>.
</p>
<p>
In <code>_repr_</code>, I do not see how <code>self.valuation()</code> would normally raise a <code>ValueError</code>. That method does not raise one, nor does <code>self.coefficient()</code> (the only other method it calls).
</p>
<p>
Instead of <code>self.parent()(1)</code>, which calls the coercion framework, you should use <code>self.parent().one()</code>.
</p>
<p>
Are you sure you want <code>_div_</code> to be two separate operations and not one combined one? I feel like the latter would be faster (at least since it is implemented at the Python level).
</p>
<p>
Actually, you may want to make the operator file into a Cython file (since is forms the key computational part and it is in a separate file).
</p>
<p>
I think the truncate should return an honest Laurent polynomial. Furthermore, I don't think there are coercions (or at least conversions) from the corresponding Laurent polynomial ring. This feels like a very natural to have. I don't want to go too far with ticket expansion, but this feels like something people will try soon after having this.
</p>
TicketgitWed, 10 Apr 2019 04:49:53 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:40
https://trac.sagemath.org/ticket/27347#comment:40
<ul>
<li><strong>commit</strong>
changed from <em>3bf2101b59d3d13aca9815fbe907ff7ad6c33cdb</em> to <em>86ccdc42aab475d7ffb04e02eb210f58b79f04b6</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=4bf0f2f0a34d190ef2578050cb058b52dcea790c"><span class="icon"></span>4bf0f2f</a></td><td><code>Add coercion from Laurent polynomials</code>
</td></tr><tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=86ccdc42aab475d7ffb04e02eb210f58b79f04b6"><span class="icon"></span>86ccdc4</a></td><td><code>Add polynomial method and coercions from Laurent polynomial ring</code>
</td></tr></table>
TicketgitWed, 10 Apr 2019 04:54:11 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:41
https://trac.sagemath.org/ticket/27347#comment:41
<ul>
<li><strong>commit</strong>
changed from <em>86ccdc42aab475d7ffb04e02eb210f58b79f04b6</em> to <em>e028ed60fbfb7457a1302bc8ecef69300311a2da</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=e028ed60fbfb7457a1302bc8ecef69300311a2da"><span class="icon"></span>e028ed6</a></td><td><code>A little change in truncate method</code>
</td></tr></table>
TicketkleeWed, 10 Apr 2019 05:14:36 GMT
https://trac.sagemath.org/ticket/27347#comment:42
https://trac.sagemath.org/ticket/27347#comment:42
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:39" title="Comment 39">tscrim</a>:
</p>
<blockquote class="citation">
<p>
For <code>__bool__</code>, I think erroring out immediately when <code>self._constant is None</code> is not the way to go. I think you should check the computed coefficients in that case to see if any of them are non-zero. If they are all <code>0</code>, then you should error out.
</p>
</blockquote>
<p>
Good idea. Done.
</p>
<blockquote class="citation">
<p>
Also, a fast first check when <code>self._constant</code> is not <code>None</code> is to see if that constant is non-zero <code>0</code>.
</p>
</blockquote>
<p>
This check is already there.
</p>
<blockquote class="citation">
<p>
In <code>_repr_</code>, I do not see how <code>self.valuation()</code> would normally raise a <code>ValueError</code>. That method does not raise one, nor does <code>self.coefficient()</code> (the only other method it calls).
</p>
</blockquote>
<p>
Right. Fixed.
</p>
<blockquote class="citation">
<p>
Instead of <code>self.parent()(1)</code>, which calls the coercion framework, you should use <code>self.parent().one()</code>.
</p>
</blockquote>
<p>
Ok. Fixed.
</p>
<blockquote class="citation">
<p>
Are you sure you want <code>_div_</code> to be two separate operations and not one combined one? I feel like the latter would be faster (at least since it is implemented at the Python level).
</p>
</blockquote>
<p>
I don't feel so. I don't see a way to implement series division such that 1 + 1 < 2 with a significant margin.
</p>
<blockquote class="citation">
<p>
I think the truncate should return an honest Laurent polynomial.
</p>
</blockquote>
<p>
I don't agree. One might still want a truncated series with laziness. For your cases, I added <code>polynomial</code> method to convert to an honest polynomial.
</p>
<blockquote class="citation">
<p>
Furthermore, I don't think there are coercions (or at least conversions) from the corresponding Laurent polynomial ring. This feels like a very natural to have. I don't want to go too far with ticket expansion, but this feels like something people will try soon after having this.
</p>
</blockquote>
<p>
Right. I added coercions from (Laurent) polynomial rings.
</p>
<blockquote class="citation">
<p>
Actually, you may want to make the operator file into a Cython file (since is forms the key computational part and it is in a separate file).
</p>
</blockquote>
<p>
Hmm. I doubt if there would be significant speed boost, compensating increased build time (that I hate). Moreover I am not versed with Cython. So I don't want to do that, at least for this ticket. But if you do it, I would not object.
</p>
TicketkleeWed, 10 Apr 2019 05:24:10 GMT
https://trac.sagemath.org/ticket/27347#comment:43
https://trac.sagemath.org/ticket/27347#comment:43
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:38" title="Comment 38">mantepse</a>:
</p>
<blockquote class="citation">
<p>
One question with respect to equality. It seems to me that your implementation of <code>__eq__</code> is quite brittle. It is clear that one cannot have proper equality, so it should be clearly stated what it can do and what it can't.
</p>
</blockquote>
<p>
The implementation gives an answer if possible without computing coefficients indefinitely. Otherwise raise an exception.
</p>
<p>
I added a short explanation to the method.
</p>
<blockquote class="citation">
<p>
Apart from that, in the case of truncation, one could make it exact easily.
</p>
</blockquote>
<p>
Truncation still gives a lazy series. I added <code>polynomial</code> method to convert to an exact polynomial.
</p>
TicketkleeWed, 10 Apr 2019 05:31:03 GMT
https://trac.sagemath.org/ticket/27347#comment:44
https://trac.sagemath.org/ticket/27347#comment:44
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:37" title="Comment 37">mantepse</a>:
</p>
<blockquote class="citation">
<p>
I find this quite wonderful! It would be great if we could replace <code>LazyPowerSeries</code> with this. One feature of <code>LazyPowerSeries</code> was that it allows recursive definitions "guessing" the correct initialisations, as for example in
</p>
<pre class="wiki"> sage: L = LazyPowerSeriesRing(QQ)
sage: one = L(1)
sage: monom = L.gen()
sage: s = L()
sage: s._name = 's'
sage: s.define(one+monom*s*s)
sage: [s.coefficient(i) for i in range(6)]
[1, 1, 2, 5, 14, 42]
</pre><p>
Although this is based on the original code by Ralf Hemmecke and myself, which in turn is based on code of Nicolas Thiery (I think), I am not sure anymore whether it is so important. Of course, if we could have something similar, even better.
</p>
</blockquote>
<p>
Recursive definition is possible as a result of being lazy and being power series. Now you can do the same in the following way:
</p>
<pre class="wiki">sage: from sage.rings.lazy_laurent_series_ring import LazyLaurentSeriesRing
sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage:
sage: z = L.gen()
sage: def f(s,n):
....: return (1 + z*s^2).coefficient(n)
....:
sage: L.series(f, valuation=0)
1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + ...
</pre>
TicketgitWed, 10 Apr 2019 05:38:52 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:45
https://trac.sagemath.org/ticket/27347#comment:45
<ul>
<li><strong>commit</strong>
changed from <em>e028ed60fbfb7457a1302bc8ecef69300311a2da</em> to <em>8f8adf2ef2c0d209a63111e46354d8ead0e29cb0</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=8f8adf2ef2c0d209a63111e46354d8ead0e29cb0"><span class="icon"></span>8f8adf2</a></td><td><code>Add __getitem__ special method to series</code>
</td></tr></table>
TicketmantepseWed, 10 Apr 2019 05:56:14 GMT
https://trac.sagemath.org/ticket/27347#comment:46
https://trac.sagemath.org/ticket/27347#comment:46
<blockquote class="citation">
<blockquote class="citation">
<p>
Apart from that, in the case of truncation, one could make it exact easily.
</p>
</blockquote>
<p>
Truncation still gives a lazy series. I added <code>polynomial</code> method to convert to an exact polynomial.
</p>
</blockquote>
<p>
excellent point! I missed that!
</p>
TicketgitWed, 10 Apr 2019 07:01:02 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:47
https://trac.sagemath.org/ticket/27347#comment:47
<ul>
<li><strong>commit</strong>
changed from <em>8f8adf2ef2c0d209a63111e46354d8ead0e29cb0</em> to <em>b3a679216402c0db7d046c771012500ce1fd7595</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=b3a679216402c0db7d046c771012500ce1fd7595"><span class="icon"></span>b3a6792</a></td><td><code>Add division operator</code>
</td></tr></table>
TicketkleeWed, 10 Apr 2019 07:02:01 GMT
https://trac.sagemath.org/ticket/27347#comment:48
https://trac.sagemath.org/ticket/27347#comment:48
<blockquote class="citation">
<blockquote class="citation">
<p>
Are you sure you want <code>_div_</code> to be two separate operations and not one combined one? I feel like the latter would be faster (at least since it is implemented at the Python level).
</p>
</blockquote>
<p>
I don't feel so. I don't see a way to implement series division such that 1 + 1 < 2 with a significant margin.
</p>
</blockquote>
<p>
You are right. I was wrong!
</p>
TicketgitWed, 10 Apr 2019 07:04:34 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:49
https://trac.sagemath.org/ticket/27347#comment:49
<ul>
<li><strong>commit</strong>
changed from <em>b3a679216402c0db7d046c771012500ce1fd7595</em> to <em>575022ce0595e70d4c285651061b2286c9e3cbf7</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=575022ce0595e70d4c285651061b2286c9e3cbf7"><span class="icon"></span>575022c</a></td><td><code>Typos</code>
</td></tr></table>
TicketgitWed, 10 Apr 2019 07:13:57 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:50
https://trac.sagemath.org/ticket/27347#comment:50
<ul>
<li><strong>commit</strong>
changed from <em>575022ce0595e70d4c285651061b2286c9e3cbf7</em> to <em>c55925faeae43fc25fb76542b13e59233f4403af</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=c55925faeae43fc25fb76542b13e59233f4403af"><span class="icon"></span>c55925f</a></td><td><code>Added a recursive definition example</code>
</td></tr></table>
TicketmantepseThu, 11 Apr 2019 05:46:44 GMT
https://trac.sagemath.org/ticket/27347#comment:51
https://trac.sagemath.org/ticket/27347#comment:51
<p>
Are composition and reversion planned in a later ticket?
</p>
<p>
I am really looking forward to this! I hope very much we can rebase the species code on it. Should <code>LazyPowerSeriesRing</code> be a subclass?
</p>
TicketkleeThu, 11 Apr 2019 07:33:16 GMT
https://trac.sagemath.org/ticket/27347#comment:52
https://trac.sagemath.org/ticket/27347#comment:52
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/27347#comment:51" title="Comment 51">mantepse</a>:
</p>
<blockquote class="citation">
<p>
Are composition and reversion planned in a later ticket?
</p>
</blockquote>
<p>
Not by me. Anyone is invited to add them in a later ticket.
</p>
<blockquote class="citation">
<p>
I hope very much we can rebase the species code on it. Should <code>LazyPowerSeriesRing</code> be a subclass?
</p>
</blockquote>
<p>
Yes, in a separate file alongside with lazy Laurent series. It would be great. I don't have a plan to do it in any short time, simply because I don't need it now.
</p>
TicketgitThu, 11 Apr 2019 09:40:47 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:53
https://trac.sagemath.org/ticket/27347#comment:53
<ul>
<li><strong>commit</strong>
changed from <em>c55925faeae43fc25fb76542b13e59233f4403af</em> to <em>410ca3806500b2518485b74d0daaab1931e49ec8</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=410ca3806500b2518485b74d0daaab1931e49ec8"><span class="icon"></span>410ca38</a></td><td><code>Add prec and approximate_series method</code>
</td></tr></table>
TickettscrimSat, 13 Apr 2019 09:18:43 GMTreviewer set
https://trac.sagemath.org/ticket/27347#comment:54
https://trac.sagemath.org/ticket/27347#comment:54
<ul>
<li><strong>reviewer</strong>
set to <em>Travis Scrimshaw</em>
</li>
</ul>
<p>
Last little thing:
</p>
<p>
<code>R(0)</code> -> <code>R.zero()</code> (as it is cached and <code>R</code> is always a <code>LazyLaurentSeriesRing</code>).
</p>
<p>
Once done you can set a positive review on my behalf.
</p>
TicketgitSat, 13 Apr 2019 11:26:16 GMTcommit changed
https://trac.sagemath.org/ticket/27347#comment:55
https://trac.sagemath.org/ticket/27347#comment:55
<ul>
<li><strong>commit</strong>
changed from <em>410ca3806500b2518485b74d0daaab1931e49ec8</em> to <em>989f009a851c9dc91c8650d7e554138886951a3a</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="https://git.sagemath.org/sage.git/commit/?id=989f009a851c9dc91c8650d7e554138886951a3a"><span class="icon"></span>989f009</a></td><td><code>Fix R(0)</code>
</td></tr></table>
TicketkleeSat, 13 Apr 2019 11:28:44 GMTstatus changed
https://trac.sagemath.org/ticket/27347#comment:56
https://trac.sagemath.org/ticket/27347#comment:56
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>positive_review</em>
</li>
</ul>
<p>
Thank you, Travis!
</p>
TicketvbraunMon, 15 Apr 2019 17:47:48 GMTstatus, branch changed; resolution set
https://trac.sagemath.org/ticket/27347#comment:57
https://trac.sagemath.org/ticket/27347#comment:57
<ul>
<li><strong>status</strong>
changed from <em>positive_review</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>fixed</em>
</li>
<li><strong>branch</strong>
changed from <em>u/klee/27347</em> to <em>989f009a851c9dc91c8650d7e554138886951a3a</em>
</li>
</ul>
TicketslelievreWed, 17 Apr 2019 17:09:22 GMTcommit deleted
https://trac.sagemath.org/ticket/27347#comment:58
https://trac.sagemath.org/ticket/27347#comment:58
<ul>
<li><strong>commit</strong>
<em>989f009a851c9dc91c8650d7e554138886951a3a</em> deleted
</li>
</ul>
<p>
Nice work! Follow-up ticket at <a class="closed ticket" href="https://trac.sagemath.org/ticket/27694" title="enhancement: Make L.<x> syntax work for LazyLaurentSeriesRing (closed: fixed)">#27694</a> for allowing syntactic sugar
</p>
<pre class="wiki">sage: L.<x> = LazyLaurentSeriesRing(ZZ)
</pre>
Ticket