Sage: Ticket #11837: Make Newton basin plotting fun and easy
https://trac.sagemath.org/ticket/11837
<p>
One of the best fractals for actually finding out <em>new</em> things is looking at <a class="ext-link" href="http://en.wikipedia.org/wiki/Newton_fractal"><span class="icon"></span>Newton basins</a> - see <a class="ext-link" href="http://aleph0.clarku.edu/~djoyce/newton/newtongen.html"><span class="icon"></span>David Joyce's beautiful generator</a>, for instance.
</p>
<p>
This is not yet in Sage. It should be, and isn't that hard to get a rough mockup by modifying the complex plot code.
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/11837
Trac 1.1.6kcrismanFri, 23 Sep 2011 03:28:25 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>newton_basins.spyx</em>
</li>
</ul>
<p>
VERY rough draft of eventual file - not a Mercurial patch
</p>
TicketkcrismanFri, 23 Sep 2011 03:31:27 GMT
https://trac.sagemath.org/ticket/11837#comment:1
https://trac.sagemath.org/ticket/11837#comment:1
<p>
Here is how I envision one using the current file.
</p>
<ul><li>Download the raw file.
</li><li>Cut and paste the entire file into one notebook cell.
</li><li>Prepend the line <code>%cython</code> to the cell.
</li><li>Evaluate.
</li><li>Have fun!
</li></ul><p>
With this code, the next picture attached gives at least something recognizable after a few minutes. It needs MUCH more efficient use of Cython, primarily; the algorithm is right, as far as I can tell, except maybe the counter can be ditched or needs to be improved.
</p>
TicketkcrismanFri, 23 Sep 2011 03:31:55 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>cubicbasin.png</em>
</li>
</ul>
<p>
What you get with this slow implementation - at least it works!
</p>
TicketkcrismanFri, 23 Sep 2011 03:33:46 GMT
https://trac.sagemath.org/ticket/11837#comment:2
https://trac.sagemath.org/ticket/11837#comment:2
<p>
The <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/cubicbasin.png" title="Attachment 'cubicbasin.png' in Ticket #11837">picture</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/cubicbasin.png" title="Download"></a> is of the fractal associated with <code>(x^2-1)(x-I)</code>. The code is
</p>
<pre class="wiki">basin_plot([-1,i,1],(-3,3),(-3,3),plot_points=100,figsize=7)
</pre><p>
Note that the documentation in the spyx file is all wrong. This is VERY rough, as noted above.
</p>
<p>
Feedback welcome!
</p>
TicketSimonKingFri, 23 Sep 2011 09:17:41 GMT
https://trac.sagemath.org/ticket/11837#comment:3
https://trac.sagemath.org/ticket/11837#comment:3
<p>
If you evaluate the contents of your spyx file in a %cython cell in the notebook, you will find two links just below the cell. The first contains the c-file created from the cython code. The second is the annotated version of the code.
</p>
<p>
I suggest to look at the annotated code. The lines of the cython code are individually coloured in different shades of yellow. If a line is very dark then the single cython line corresponds to <em>many</em> c-lines. By clicking on the line number, you can see how each line is translated into c.
</p>
<p>
You will find that your code is mostly dark yellow. If you want to make it fast, the lines that are most frequently executed should be white.
</p>
<p>
Another tool: Use %prun on your functions (but it could be that it will only work on the command line - I tried in the notebook, but it didn't work). It will show you the internal Python function calls that took the most time (I think it can not show you calls to Cython functions). So, %prun may give you an idea what part of your code needs work most urgently.
</p>
<p>
Using
</p>
<pre class="wiki">sage: %prun basin_plot([-1,i,1],(-3,3),(-3,3),plot_points=100,figsize=7)
</pre><p>
on the command line, where I had replaces <code>2/3</code> by <code>2./3</code> in the code, I found:
</p>
<pre class="wiki"> ncalls tottime percall cumtime percall filename:lineno(function)
1 5.396 5.396 15.362 15.362 {_home_king_SAGE_work_attributes_newton_basins_spyx_1.basin_plot}
104309/71386 3.291 0.000 5.029 0.000 complex_interval_field.py:261(__call__)
1049154 0.771 0.000 0.771 0.000 {isinstance}
59576 0.700 0.000 0.721 0.000 polynomial_ring.py:301(_element_constructor_)
38450/19225 0.638 0.000 3.372 0.000 complex_field.py:279(_element_constructor_)
38458 0.521 0.000 3.043 0.000 qqbar.py:2951(interval)
59576 0.507 0.000 1.629 0.000 polynomial_ring_constructor.py:47(PolynomialRing)
57675 0.474 0.000 2.629 0.000 complex_field.py:246(__call__)
59576 0.297 0.000 0.369 0.000 {sage.structure.parent_gens.normalize_names}
38458 0.296 0.000 0.597 0.000 qqbar.py:2927(interval_diameter)
186759 0.262 0.000 0.262 0.000 complex_interval_field.py:242(_real_field)
59576 0.215 0.000 0.733 0.000 polynomial_ring_constructor.py:442(_single_variate)
13738 0.213 0.000 0.307 0.000 number_field.py:5075(_coerce_non_number_field_element_in)
</pre><p>
So, it seems to me that most time is spent for internal calls to the complex interval field, and to the function <code>interval</code> in qqbar.py. That may be surprising, because, if I am not mistaken, you simply want to work with complex numbers, but not with algebraic numbers.
</p>
<p>
In other words, it would be worth while to find out how your code uses complex interval fields and algebraic numbers, and to rewrite it such that only "usual" complex doubles are used. It may very well be that the algebraic numbers arise in a coercion happening behind the scenes.
</p>
TicketkcrismanFri, 23 Sep 2011 12:48:34 GMT
https://trac.sagemath.org/ticket/11837#comment:4
https://trac.sagemath.org/ticket/11837#comment:4
<p>
Simon,
</p>
<p>
Thanks for the prun tip - I had forgotten about that. I'm certainly aware of the yellow html :) but unfortunately it was nearly ALL yellow and I'm not sure how to effectively Cythonize much of it, hence my email to sage-devel/edu.
</p>
<p>
Just adding cdefs is, in my experience, a recipe for disaster.
</p>
<p>
Also interesting about the prun. This is mostly just taken from the complex plot stuff, but prunning (?) that shows just a couple calls to complex intervals. I assume it is mostly happening in the <code>which_root</code>, maybe <code>if abs(varia-root)<2/3</code>. I don't like all the calls to <code>isinstance</code> and the polynomial ring consructors, either. Someone who understands how <code>fast_callable</code> constructs things better might be able to help, too :(
</p>
<p>
Thank you!
</p>
TicketSimonKingFri, 23 Sep 2011 13:04:36 GMT
https://trac.sagemath.org/ticket/11837#comment:5
https://trac.sagemath.org/ticket/11837#comment:5
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/11837#comment:4" title="Comment 4">kcrisman</a>:
</p>
<blockquote class="citation">
<p>
Just adding cdefs is, in my experience, a recipe for disaster.
</p>
</blockquote>
<p>
That's true. One first needs to have a good guess what yellow code is most frequently executed. %prun might indicate where the problem is hidden, and the annotation indicates how to get rid of it.
</p>
<blockquote class="citation">
<p>
Also interesting about the prun. This is mostly just taken from the complex plot stuff, but prunning (?) that shows just a couple calls to complex intervals. I assume it is mostly happening in the <code>which_root</code>, maybe <code>if abs(varia-root)<2/3</code>.
</p>
</blockquote>
<p>
It makes sense to try that separately. I.e., %prun one call to <code>which_root</code>.
</p>
<blockquote class="citation">
<blockquote>
<p>
I don't like all the calls to <code>isinstance</code> and the polynomial ring consructors, either.
</p>
</blockquote>
</blockquote>
<p>
Yes. They are irritating. I am rather sure that <code>isinstance</code> is called in things like <code>sage.rings.ring.is_Ring</code> or so.
</p>
<blockquote class="citation">
<blockquote>
<p>
Someone who understands how <code>fast_callable</code> constructs things better might be able to help,
</p>
</blockquote>
</blockquote>
<p>
Sorry, <code>fast_callable</code> is a mystery to me.
</p>
TicketSimonKingFri, 23 Sep 2011 13:32:32 GMT
https://trac.sagemath.org/ticket/11837#comment:6
https://trac.sagemath.org/ticket/11837#comment:6
<p>
Here are some more detailed remarks on the code:
</p>
<ul><li>In <code>which_root</code>, the expression <code>abs(varia-root)</code> seems to be rather expensive. If you know the type of <code>varia</code> and <code>root</code> and if you know how <code>abs</code> is computed for that type, you may help the compiler. See below: Indeed that seems to be part of the problem.
</li><li>Since <code>which_root</code> is frequently called, it would make sense to improve the inner loop:
<pre class="wiki">cdef int counter
for counter from 0<=counter<20:
varia = newtf(varia)
...
</pre></li><li>Again, since <code>which_root is frequently called, it would make sense to reveal that </code>roots<code> is a list (could be done in the argument line of </code>basin_plot`).
</li><li>I just tested that one gets
<pre class="wiki">AttributeError: 'function' object has no attribute 'variables'
</pre>when trying to create <code>f1</code> as a fast callable. I don't know how that can be worked around.
</li><li>The strange calls to complex interval field and so on really occur when you do <code>varia-root</code>. This is because varia is a complex double, but root (depending on the input) may be a symbolic expression. In the application, you have
<pre class="wiki">sage: roots = [-1,i,1]
sage: prefunc = prod([(x-root) for root in roots])
sage: newtf = fast_callable(newt(prefunc), domain=CDF, expect_one_var=True)
sage: varia = newtf(roots[1])
sage: root = roots[1]
sage: type(varia)
<type 'sage.rings.complex_double.ComplexDoubleElement'>
sage: type(root)
<type 'sage.symbolic.expression.Expression'>
sage: %prun varia-root
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
4/3 0.000 0.000 0.000 0.000 complex_interval_field.py:261(__call__)
2/1 0.000 0.000 0.000 0.000 complex_field.py:279(_element_constructor_)
39 0.000 0.000 0.000 0.000 {isinstance}
2 0.000 0.000 0.000 0.000 qqbar.py:2951(interval)
2 0.000 0.000 0.000 0.000 polynomial_ring.py:301(_element_constructor_)
3 0.000 0.000 0.000 0.000 complex_field.py:246(__call__)
2 0.000 0.000 0.000 0.000 polynomial_ring_constructor.py:47(PolynomialRing)
2 0.000 0.000 0.000 0.000 qqbar.py:2927(interval_diameter)
...
</pre></li></ul><p>
So, it would make sense to first convert the given roots to complex doubles. If that isn't good enough, one may even cdef them as such. And, in addition, cythonise the innermost loop. I'll soon test if it helps...
</p>
TicketSimonKingFri, 23 Sep 2011 14:26:04 GMTauthor changed
https://trac.sagemath.org/ticket/11837#comment:7
https://trac.sagemath.org/ticket/11837#comment:7
<ul>
<li><strong>author</strong>
changed from <em>Karl-Dieter Crisman</em> to <em>Karl-Dieter Crisman, SImon King</em>
</li>
</ul>
<p>
I just attached <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/newton_basins_more_cython.spyx" title="Attachment 'newton_basins_more_cython.spyx' in Ticket #11837">newton_basins_more_cython.spyx</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/newton_basins_more_cython.spyx" title="Download"></a>, which improves the timing by a factor of almost 100:
</p>
<p>
With the original version of the code together with the <code>2./3</code>, I get
</p>
<pre class="wiki">sage: %time basin_plot([-1,i,1],(-3,3),(-3,3),plot_points=100,figsize=7)
CPU times: user 13.70 s, sys: 0.00 s, total: 13.70 s
Wall time: 13.74 s
</pre><p>
With the code that I just attached, I get
</p>
<pre class="wiki">sage: %time basin_plot([-1,i,1],(-3,3),(-3,3),plot_points=100,figsize=7)
CPU times: user 0.15 s, sys: 0.00 s, total: 0.15 s
Wall time: 0.15 s
</pre><p>
How is that done?
</p>
<p>
Apparently, the optimization should mainly take place in <code>which_root</code>. Since it is not possible to turn it into a fast_callable, I cythonised it instead. More precisely, I introduced a cdef'd class <code>RootFinder</code>, that carries all relevant data (the list of roots, the function newtf and also the cutoff 2/3) as a cdef'd attribute.
</p>
<p>
Originally, the function f1 is a lambda function (slow!) that calls the Python function <code>which_root</code> (slow!) by providing two arguments, where the first argument is always the same (redundant!). I replaced it by the method <code>Finder.which_root</code>, where <code>Finder</code> is an appropriate instance of <code>RootFinder</code>.
</p>
<p>
Inside <code>which_root</code>, further improvements happened:
</p>
<ul><li>First of all, the list of roots is transformed into a list of complex doubles (because, in your original example, the complex unit <code>i</code> is a symbolic expression, not a complex double, which was responsible for the slowness).
</li><li>Moreover, Cython is informed that the list of roots is a list, and that both the root and "varia" are complex doubles.
</li><li>We know that all our complex doubles have the same parent. Hence, we avoid the parental tests that are part of <code>__sub__</code> and call <code>_sub_</code> instead (single underscore).
</li><li>Since the <code>counter</code> loop is rather tight, <code>counter</code> is declared as an int.
</li></ul>
TicketkcrismanFri, 23 Sep 2011 14:57:52 GMT
https://trac.sagemath.org/ticket/11837#comment:8
https://trac.sagemath.org/ticket/11837#comment:8
<p>
This is great work, Simon. I'll try it out over the weekend. All of these ideas make a lot of sense, but it would have taken me many, many hours of stumbling to do things like this. The only one I did after I posted last night was to make <code>counter</code> an int :)
</p>
<p>
Even the list of roots all being complex doubles is <strong>very</strong> sensible and should have occurred to me immediately, but never did - and I wouldn't have know how to Cythonize that in any case, I only knew about the most basic Cython types. There are all kinds of optimizations in this code of that kind, and I doubt I would have ever gotten there on my own. But it makes a GREAT case study in how to use Cython, because there are so many places things are improved.
</p>
<p>
Thanks.
</p>
TicketkcrismanFri, 23 Sep 2011 15:40:30 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>Betterfractal.png</em>
</li>
</ul>
<p>
With Simon's improvements
</p>
TicketkcrismanFri, 23 Sep 2011 15:47:34 GMT
https://trac.sagemath.org/ticket/11837#comment:9
https://trac.sagemath.org/ticket/11837#comment:9
<p>
Okay, this is great.
</p>
<pre class="wiki">basin_plot([-1,1,3],(-.2,.1),(-.1,.1),plot_points=1000,figsize=7)
</pre><p>
is <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/Betterfractal.png" title="Attachment 'Betterfractal.png' in Ticket #11837">here</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/Betterfractal.png" title="Download"></a>. It only takes 20 seconds. Still not ideal, but usable for this kind of detail.
</p>
<hr />
<p>
I still feel like there are possible speedups - especially in terms of doing something smarter than just searching through all the roots each time looking for whether they are close enough. But I think that this is probably sufficient for turning into a patch. I would want to base it on the long-suffering <a class="closed ticket" href="https://trac.sagemath.org/ticket/11273" title="enhancement: Riemann Enhancements: Docs, Exterior, Multiple Spiderweb, Error Testing (closed: fixed)">#11273</a>, which I need to finally finish reviewing, and which has modularized the color plotting a bit. Thank you VERY much for this teamwork.
</p>
TicketkcrismanFri, 23 Sep 2011 17:32:21 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>WithIterations.png</em>
</li>
</ul>
<p>
With Simon's Cython and naive keeping track of iterations needed to converge
</p>
TicketkcrismanFri, 23 Sep 2011 17:39:33 GMT
https://trac.sagemath.org/ticket/11837#comment:10
https://trac.sagemath.org/ticket/11837#comment:10
<p>
Okay, now I have something very naive with iterations. Picture (same code) <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/WithIterations.png" title="Attachment 'WithIterations.png' in Ticket #11837">here</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/WithIterations.png" title="Download"></a> and code <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/newton_basins_with_iterations.spyx" title="Attachment 'newton_basins_with_iterations.spyx' in Ticket #11837">here</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/newton_basins_with_iterations.spyx" title="Download"></a>.
</p>
<p>
Caveats:
</p>
<ul><li>I am pretty sure that the lightness thing could be improved - there are infinitely many functions to pick from, and messing with the one from <code>complex_plot</code> didn't help in my first tries.
</li><li>The way the alpha is used is almost assuredly inefficient. Ideally we would have a 'master list' of the roots and then one would search for one of the n times 20 combinations of root and iteration level, and assign a color to that from the 'master list' (dictionary?) instead of multiplying by alpha 3 times for every single point!
</li><li>Probably the way I just slapped in a tuple for the new output of the <code>which_root</code> is inefficient too - presumably one could at least define the type coming out of it, if not find some better way to represent it.
</li><li>The exact (blue) circle in the picture, which is not flush with the second iteration ellipse, probably indicates that the way the iterations are determined is too aggressive/not aggressive enough (not sure which).
</li></ul><p>
But it does work, and even looks somewhat decent. Can't compete with Java yet, but it would be really nice to have this in Sage.
</p>
TicketSimonKingFri, 23 Sep 2011 18:20:31 GMT
https://trac.sagemath.org/ticket/11837#comment:11
https://trac.sagemath.org/ticket/11837#comment:11
<p>
Outch! I just saw that my code had a bug: In the loop for <code>counter</code>, I had <code>for counter from 0<=counter<20</code>, and <em>additionally</em> I had <code>counter += 1</code>. So, both my and your new spyx file need to be modified.
</p>
TicketSimonKingFri, 23 Sep 2011 18:24:24 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>newton_basins_more_cython.spyx</em>
</li>
</ul>
<p>
Put more cython into the basins
</p>
TicketSimonKingFri, 23 Sep 2011 18:25:10 GMT
https://trac.sagemath.org/ticket/11837#comment:12
https://trac.sagemath.org/ticket/11837#comment:12
<p>
Just updated my patch. I hope that this change does not alter the pictures too much.
</p>
TicketSimonKingFri, 23 Sep 2011 19:38:37 GMT
https://trac.sagemath.org/ticket/11837#comment:13
https://trac.sagemath.org/ticket/11837#comment:13
<p>
Here is another slowness of the current code: <code>varia._sub_(root).abs()</code>, which needs to compute a square root. But in order to find out whether <code>varia._sub_(root).abs()<2/3</code>, we could more easily test whether the sum of the squares of real and imaginary part is smaller than <code>4/3</code>.
</p>
TicketkcrismanFri, 23 Sep 2011 19:45:18 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>newton_basins_with_iterations.spyx</em>
</li>
</ul>
<p>
Incorporates Simon's improvements and adds naive keeping track of iterations
</p>
TicketSimonKingFri, 23 Sep 2011 19:46:02 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>newton_basins_with_iterations_and_double.spyx.txt</em>
</li>
</ul>
<p>
Naive keeping track of iterations, using a simplified distance test
</p>
TicketkcrismanFri, 23 Sep 2011 19:46:47 GMT
https://trac.sagemath.org/ticket/11837#comment:14
https://trac.sagemath.org/ticket/11837#comment:14
<p>
Thanks for catching that!
</p>
TicketSimonKingFri, 23 Sep 2011 19:56:05 GMT
https://trac.sagemath.org/ticket/11837#comment:15
https://trac.sagemath.org/ticket/11837#comment:15
<p>
I have attached <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx.txt" title="Attachment 'newton_basins_with_iterations_and_double.spyx.txt' in Ticket #11837">newton_basins_with_iterations_and_double.spyx.txt</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx.txt" title="Download"></a>. I am sorry that I have not been aware of Windows' automatic name extension (I don't usually write texts under windows), and also I hope that it did not use any fancy format.
</p>
<p>
Also I just noticed that the first line of the file contains %cython - of course that needs to be removed if you want to attach it.
</p>
<p>
Anyway. The trick is to define <code>self.cutoff = 4./9</code>, and to use a temporary <code>cdef ComplexDoubleElement diff = varia._sub_(root)</code>, so that <code>(diff._complex.dat[0]**2 + diff._complex.dat[1]**2) < self.cutoff</code> is fairly cheap.
</p>
<p>
Here are the data on sagenb:
</p>
<pre class="wiki">%time
basin_plot([-1,1,3],(-.2,.1),(-.1,.1),plot_points=1000,figsize=7)
CPU time: 15.59 s, Wall time: 15.60 s
</pre><p>
The same computation with the first "iteration" code takes <code>CPU time: 24.15 s, Wall time: 24.17 s</code>.
</p>
TicketSimonKingFri, 23 Sep 2011 19:56:27 GMTauthor changed
https://trac.sagemath.org/ticket/11837#comment:16
https://trac.sagemath.org/ticket/11837#comment:16
<ul>
<li><strong>author</strong>
changed from <em>Karl-Dieter Crisman, SImon King</em> to <em>Karl-Dieter Crisman, Simon King</em>
</li>
</ul>
TicketkcrismanThu, 06 Jun 2013 16:15:15 GMT
https://trac.sagemath.org/ticket/11837#comment:17
https://trac.sagemath.org/ticket/11837#comment:17
<p>
Possibly also related: a "pure Python" GPU (I guess?) implementation by "kriskda" on <a class="ext-link" href="https://github.com/kriskda/BasinsOfAttraction"><span class="icon"></span>github</a>.
</p>
TicketkcrismanMon, 26 Jun 2017 16:45:25 GMT
https://trac.sagemath.org/ticket/11837#comment:18
https://trac.sagemath.org/ticket/11837#comment:18
<p>
Probably related: <a class="closed ticket" href="https://trac.sagemath.org/ticket/23257" title="enhancement: Plotting the Mandelbrot set in Sage (closed: fixed)">#23257</a>
</p>
Ticketgh-bryangingechenThu, 24 May 2018 17:26:14 GMTattachment set
https://trac.sagemath.org/ticket/11837
https://trac.sagemath.org/ticket/11837
<ul>
<li><strong>attachment</strong>
set to <em>newton_basins_with_iterations_and_double.spyx</em>
</li>
</ul>
<p>
A version of "newton_basins_with_iterations_and_double.spyx.txt (8.7 KB) - added by <a class="missing wiki">SimonKing?</a>" minimally updated to work with <a class="wiki" href="https://trac.sagemath.org/wiki/SageMath">SageMath</a> 8.2
</p>
Ticketgh-bryangingechenThu, 24 May 2018 17:33:17 GMT
https://trac.sagemath.org/ticket/11837#comment:19
https://trac.sagemath.org/ticket/11837#comment:19
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/11837#comment:15" title="Comment 15">SimonKing</a>:
</p>
<blockquote class="citation">
<p>
I have attached <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx.txt" title="Attachment 'newton_basins_with_iterations_and_double.spyx.txt' in Ticket #11837">newton_basins_with_iterations_and_double.spyx.txt</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx.txt" title="Download"></a>. I am sorry that I have not been aware of Windows' automatic name extension (I don't usually write texts under windows), and also I hope that it did not use any fancy format.
</p>
</blockquote>
<p>
I found this ticket when googling for Sage functionality to plot Newton basins. I guess this ticket has been abandoned, but just in case it's useful to anyone else that finds this, I've just attached <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx" title="Attachment 'newton_basins_with_iterations_and_double.spyx' in Ticket #11837">newton_basins_with_iterations_and_double.spyx</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/11837/newton_basins_with_iterations_and_double.spyx" title="Download"></a> which updates this (mainly by adding / changing the imported modules) so that it works with my <a class="wiki" href="https://trac.sagemath.org/wiki/SageMath">SageMath</a> 8.2 (in the jupyter notebook on Mac OS X 10.13.4).
</p>
TicketkcrismanThu, 24 May 2018 17:53:40 GMT
https://trac.sagemath.org/ticket/11837#comment:20
https://trac.sagemath.org/ticket/11837#comment:20
<p>
Tickets are never abandoned, only forgotten ... that is great news. If you would like to, we would appreciate a "formal" review of the code and attaching it as a branch. Basically, one wants someone to verify that the code is correct and that things work, and especially that there are sufficient tests and examples for people to use.
</p>
<p>
Simon, if you're listening, thoughts? No one person has to vouch for the entire package, it can be a review of previous people's work too.
</p>
TicketSimonKingThu, 24 May 2018 18:01:40 GMT
https://trac.sagemath.org/ticket/11837#comment:21
https://trac.sagemath.org/ticket/11837#comment:21
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/11837#comment:20" title="Comment 20">kcrisman</a>:
</p>
<blockquote class="citation">
<p>
Tickets are never abandoned, only forgotten ...
</p>
</blockquote>
<p>
Indeed. Even after reading the attachment that I supplied, I don't recognise that I wrote it. So, total amnesia.
</p>
<blockquote class="citation">
<p>
Simon, if you're listening, thoughts? No one person has to vouch for the entire package, it can be a review of previous people's work too.
</p>
</blockquote>
<p>
What would be the plan?
</p>
<p>
The fact that the attachment is a .spyx file means that it used to be an experimental piece of code that people could play with by attaching it. In order to create a proper branch, it would be needed to find a folder in sage/src/ where the code could fit. And so far I am not sure where it could belong.
</p>
<p>
It could perhaps be classified as "educational". But do we have a dedicated folder for educational stuff?
</p>
TicketkcrismanThu, 24 May 2018 19:58:43 GMT
https://trac.sagemath.org/ticket/11837#comment:22
https://trac.sagemath.org/ticket/11837#comment:22
<p>
Actually I think it could fit in a few different folders. The <a class="ext-link" href="https://github.com/sagemath/sage/tree/master/src/sage/dynamics"><span class="icon"></span>dynamics</a> may be appropriate - indeed, see <a class="ext-link" href="https://github.com/sagemath/sage/blob/master/src/sage/dynamics/complex_dynamics/mandel_julia.py"><span class="icon"></span>this file</a> which may duplicate some or all of this (it's quite likely). Weird things have landed in src/sage/calculus as well.
</p>
<p>
However, what I meant by asking you was whether you had already reviewed some of the code in said .spyx file. If not, that is fine, just checking.
</p>
Ticket