I have my own implementation generating correct-looking images from just past the limits of double precision. The inner loop seems to be about 2.5 times slower than SuperFractalThing's, but that's within spitting distance. It's also running on a JVM (64-bit server VM to be exact), but it's written in Clojure (a dialect of Lisp for the JVM). No user interface as yet.
So there are now three Mandelbrot renderers using the OP's technology:
Name | Speed | Series approximation included? | Other features |
SuperFractalThing | 2.5 | Yes | Zooming UI |
Kalles Fractaler | ? | No | Render animations |
Nanoscope | 1.0 | Yes | Multiwave coloring |
of which at least one is publicly available and open-sourced. An open-source Nanoscope with a real UI may exist eventually, but my next priority is going to be adding animation capability to it (designed to be combined with VirtualDub or other external images-to-avi converter), now that I've gotten it working, and working at a non-dismal speed. I will also investigate at least one possibility for moderately upping its speed.
Oh: Nanoscope
should be able to zoom past e300, with a bit of a slowdown at that point, but I haven't tested that yet. When zoomed deeper than that, it uses a different inner loop that is divided into two parts: an innermost part that works with delta-times-10
p for some power p > 300, with the delta-squared term ignored (it's 10
300 or more smaller than delta, and delta has 16 bits of precision!) and a copy of delta-nought pre-multiplied by 10
p. The innermost part runs for 500 iterations at a time. The outer loop moves some of the growing exponent of delta into p, shrinking delta and growing p (and renormalizing delta-zero), between each run of the inner loop, until the true value of delta is larger than 10
-300. At that point, it switches to the other version of the loop, with delta squared term included (as it's now not guaranteed to be negligible) for the rest of the iterations. Only the loop with delta squared checks for bailout, as it can't be anywhere near bailing out yet until delta's way larger than 10
-300; I just check delta itself against the bailout, as with any bailout suitable for smoothed iterations (10
7, say) the difference between delta and the actual orbit point (the reference orbit point!) will be small in comparison (a couple parts per million, if the reference orbit is trapped in a disk of radius 2 centered on the origin).
The 500 above is because if the rescaled delta starts at O(1), being multiplied by 2*reference-point each iteration and added to a (swiftly negligibly smaller) delta-nought, then given a trapped reference point it will grow at most 4* bigger each iteration, and 4
500 ~ 10
301 is still a bit short of the point of double exponent overflow.
My above E-300 inner loop has 8 adds and 7 multiplies (I *could* make a third, "was smaller than E-300 originally" version with 5 adds by dropping the delta-zero term which will be negligible in these cases; and 2 multiplies and an add are needed to calculate radius for bailout, or I could drop to 5 multiplies and 7 adds) and my below E-300 inner loop has 4 adds and 4 multiplies. If anyone has optimized this loop to remove more multiplies I'd be curious to know how.