how I learned to plot a mandelbrot set

When I first met fractals in the school, I thought that they were if not magic, then something very close to it. The concept of a fractal dimension was something I couldn't react to logically, but only emotionally, basically, with a "wow" and nothing much else. I never tried though to write a program that plots the set, even though there plenty of examples around; a deity isn't there to be analyzed, only to be awed at.

Enter year 2013, and I find myself reading PDL mailing list where someone has posted a nicely written educational acticle that explains some concepts of Perl Data Language (i.e. PDL) and plotting the Mandelbrot set as an example. I liked it very much, the only trouble is that apparently PDL's plotting is done using external programs. I'd rather see a GUI toolkit used, withing the same program.

Now I rememeber that long time ago I wrote a bridge between PDL and Prima to make it possible to interchange image data between the two, PDL::PrimaImage. It is a module with low visibility, fitting into a small and very special niche; but now it was again up to the task. The only thing it does, it converts 2- and 3- dimensional PDL scalars into Prima images (that can be displayed, saved on disk etc) and back again.

This script runs an interactive session where one can explore the plot by "navigating" it with a mouse. There was a surprise though: there are animations (like this) that display the self-similarity of fractals by zooming depper and deeper into the function. The problem is that the deeper the zooming goes, the more computation it requires, and that eventually slows the frame rate down to zero. But I think it is still fun on lower zooms...

Well anyway, I wonder, is it a deadbeat topic already or there's some life to it? What do you think?


This is how I first plotted fractals in Perl, 13 years ago:

Dmitry, very nice!

By the way, the first time I ever heard of Prima was because I once looked up other modules that used PDL. PDL::PrimaImage was one of the few, and I was happy to see it. So it's a *darn* good thing you wrote that!


@Dmitry -

I have been thinking about this a bit lately. I suppose here is as good a forum as any for discussing some of my ideas.

One idea I have is to revise PDL::PrimaImage so that Prima and PDL can work on the exact same memory location. Presently, I believe PDL::PrimaImage copies data between the Image canvas and the piddle, but I'm pretty sure we could have them operate on the exact same memory for certain image formats and PDL data types.

An extension to that idea is to allow PDL to store a *stack* of images as a 3D piddle. This would make it effortless to produce a movie by simply updating the memory location of the pixel's lower-left corner. Using PDL::Parallel::threads, one could have one thread that buffers data into a piddle and a separate thread display the movie at a consistent frame rate.

On a somewhat related note, I haven't implemented raster image handling in PDL::Drawing::Prima because I haven't figured out a clever way to thread (i.e. auto-loop) it. Ideally, I would want to be able to say $widget->pdl_put_images($xs, $ys, $images), where $images contains a different image for each entry of $xs/$ys. However, this would force $images to be a piddle, making it difficult to accept a single image as an argument. On the other hand, $widget->pdl_put_image($xs, $ys, $image), where $image is a Prima image object, would suggest placing the same image at multiple ($x, $y) positions. That is easier to impelment, but has limitations, too.

And then there's the issue of how to incorporate this into PDL::Graphics::Prima. Unfortunately, if you want your image to represent data, scaled according to x/y axes, you can't use put_image at all because the raster image wouldn't respect nonlinear scaling, i.e. log scaling. This is why current imaging in PDL::Graphics::Prima uses rectangles for each pixel, even though it's terribly slow.

I think I will try to spend some time today on PDL::PrimaImage. I really want to get movies working with Prima. :-)

Mandelbrot is a cool example, I've been found about fractals for more than 20 years...

This year, while giving a Perl course to my students, I demo'ed a Mandelbrot sample with SDL (10 minutes). Then sped it up by rewriting the tight z=z*z+c loop in C via perlxs (10 minutes).

Students discover that what should be a master-fu hack is actually trivial (especially that compute code translates from Perl to C basically by removing the sigils ...), and reproduce this within an hour. They feel like the king of the world. And then the debate 'is Perl slow' is closed forever, it's fast to execute _and_ write.

Leave a comment

About Dmitry Karasik

user-pic I blog about Perl.