ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Sun, 28 Aug 2022 21:36:11 +0200Recursion directly in a listhttps://ask.sagemath.org/question/63790/recursion-directly-in-a-list/I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work
f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]Sat, 27 Aug 2022 09:31:35 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/Comment by John Palmieri for <p>I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work</p>
<pre><code>f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63812#post-id-63812@tmonteil. Right, I understand, although for a minimal example, it's far from minimal.Sun, 28 Aug 2022 21:36:11 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63812#post-id-63812Comment by tmonteil for <p>I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work</p>
<pre><code>f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63807#post-id-63807@john-palmieri i guess that the provided example is only a minimal example to show the issue, otherwise, one could simply put `h=range(8)` (or `list(range(9))`) from scratch. In particular, is it not clear to me whether `h` is supposed to be more complex than just accumulating sums from `g`.Sun, 28 Aug 2022 19:42:38 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63807#post-id-63807Comment by John Palmieri for <p>I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work</p>
<pre><code>f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63801#post-id-63801As written, the definitions of `f(x)`, `g(x)`, `c`, and `s` are not used in the final result. The definition of `d` can be simplified to `d = range(9)`. The line `g = [d[i]-d[i-1] for i in range(1,len(d))]` is just taking differences of consecutive integers (the entries of `range(9)`), so every entry of the list `g` is 1. So the code could be simplified to two lines: `g = [1] * 9` and (the broken line) `h = [...]`. Max Alekseyev's answer is a quick way to use recursion on the entries of the list `g`.Sun, 28 Aug 2022 02:38:30 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63801#post-id-63801Answer by Max Alekseyev for <p>I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work</p>
<pre><code>f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?answer=63796#post-id-63796This can be done via Python's [itertools.accumulate](https://docs.python.org/3/library/itertools.html#itertools.accumulate) function:
import itertools
h = list( itertools.accumulate(g, initial=0) )Sat, 27 Aug 2022 15:09:05 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?answer=63796#post-id-63796Answer by tmonteil for <p>I would like to know if there is a way to create a recursion directly in a list. The following command doesn't work</p>
<pre><code>f(x) = -(x-4)^2+16
g(x) = f(x)-f(0)
d=[x for x in range(9)]
c= list(map_threaded(g,d))
s=[(c[i]-c[i-1])/d[i]-d[i-1] for i in range(1,len(c))]
g=[d[i]-d[i-1] for i in range(1,len(d))]
h=[0 if (i<1) else h[i-1] + g[i] for i in range(len(d)-1) ]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?answer=63791#post-id-63791In your last line, you use `h` to define `h` itself.
**EDIT** (given the explanation provided in comments): it is not possible to do such a thing. Indeed, when you write `h=[...]`, the Python name `h` is created *after* the object `[...]` is created.
So, you have to define a recursive function as follows:
sage: def hh(i):
....: if i<1:
....: return 0
....: else:
....: return hh(i-1) + g[i]
....:
sage: h = [hh(i) for i in range(len(d)-1)]
sage: h
[0, 1, 2, 3, 4, 5, 6, 7]
That said, i guess (i might be wrong in your motivation), that you wanted to use a list so that when you compute `h[4]`, you do not have to do the whole recursion by computing `h[3]`, `h[2]`, `h[1]`, `h[0]` again, which is what `hh` does. The trick is to use the `@cached_function` decorator, that computes `h[i]` only once and [memoizes](https://en.wikipedia.org/wiki/Memoization) the result for further calls. So, you can do:
sage: @cached_function
....: def hh(i):
....: if i<1:
....: return 0
....: else:
....: return hh(i-1) + g[i]
....:
sage: h = [hh(i) for i in range(len(d)-1)]
sage: h
[0, 1, 2, 3, 4, 5, 6, 7]Sat, 27 Aug 2022 10:37:06 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?answer=63791#post-id-63791Comment by Cyrille for <p>In your last line, you use <code>h</code> to define <code>h</code> itself.</p>
<p><strong>EDIT</strong> (given the explanation provided in comments): it is not possible to do such a thing. Indeed, when you write <code>h=[...]</code>, the Python name <code>h</code> is created <em>after</em> the object <code>[...]</code> is created.</p>
<p>So, you have to define a recursive function as follows:</p>
<pre><code>sage: def hh(i):
....: if i<1:
....: return 0
....: else:
....: return hh(i-1) + g[i]
....:
sage: h = [hh(i) for i in range(len(d)-1)]
sage: h
[0, 1, 2, 3, 4, 5, 6, 7]
</code></pre>
<p>That said, i guess (i might be wrong in your motivation), that you wanted to use a list so that when you compute <code>h[4]</code>, you do not have to do the whole recursion by computing <code>h[3]</code>, <code>h[2]</code>, <code>h[1]</code>, <code>h[0]</code> again, which is what <code>hh</code> does. The trick is to use the <code>@cached_function</code> decorator, that computes <code>h[i]</code> only once and <a href="https://en.wikipedia.org/wiki/Memoization">memoizes</a> the result for further calls. So, you can do:</p>
<pre><code>sage: @cached_function
....: def hh(i):
....: if i<1:
....: return 0
....: else:
....: return hh(i-1) + g[i]
....:
sage: h = [hh(i) for i in range(len(d)-1)]
sage: h
[0, 1, 2, 3, 4, 5, 6, 7]
</code></pre>
https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63792#post-id-63792I know. What I ask is : is there a procedure which permit to define a recursion in a vector.Sat, 27 Aug 2022 11:14:29 +0200https://ask.sagemath.org/question/63790/recursion-directly-in-a-list/?comment=63792#post-id-63792