Generating cool fractals
A benchmark comparison of PDL, IDL, MATLAB, Octave, C and FORTRAN77 generating fractals
Download the whole article as PDF
Short URL: http://fsmsh.com/2108
- 2007-07-25
- Server side | Intermediate
-
Write a full post in response to this!
Whether you are a professional or amateur scientist, engineer or mathematician, if you need to make numerical calculations and plots quickly and easily, then PDL (Perl Data Language) is certainly one of the best free software tools to use. PDL has everything that similar high-level, proprietary, numerical calculation languages (like IDL or MATLAB) have. And it certainly comes with all the features you would expect to have in a numerical calculation package.
Introduction
In this article, I will explore a fun application of the numerical calculation field: the Mandelbrot fractal. To generate fractals you need to perform several computations and then plot the results. The examples that follow are also simple enough for anyone to follow, but have enough features to get a feel for the language used. For this particular task, high-level, numerical calculation languages are the ideal tool. They provide a rapid development cycle due to its high-level nature. It is also easy to generate quality plots with these tools. And, as you shall see later, the speed performance penalty you pay by using these languages is relatively minor.
The Mandelbrot fractal example reviewed in this article will be developed in both proprietary and free software languages: PDL, IDL, MATLAB and Octave. This will allow us to compare them qualitatively in a table highlighting the pros and cons of each language. Also, a quantitative benchmark comparison will be done to illustrate the speed of each one of the languages. For comparison purposes, C and FORTRAN code for these examples will also be shown.
The Mandelbrot fractal
The Mandelbrot set is one of the most popular fractals
According to Wikipedia, a fractal is a rough or fragmented geometric shape that can be subdivided into parts, each of which is (at least approximately) a reduced size copy of the whole. The Mandelbrot set is one of the most popular fractals. In this article I will color the fractals in a slightly different and artistic way (as seen in figure 1). The Mandelbrot fractal is generated by iterating a mathematical relationship between complex numbers (see Complex Number Arithmetic for a quick introduction to complex numbers). Starting with a zero value of a complex variable (z), the fractal is materialised by iterating the following assigment:
z = z * z + k,
…where k is a complex number which is kept constant throughout the iterations. The final value of z depends very much on the value of the complex number k. For some values of k, the final z converges to a certain finite value and for some others, z diverges to infinity. To avoid numerical problems with the divergences in the calculations we will introduce a programming trick that consists of constraining the z values between -5 and 5 after each iteration. In the final fractal image, the x axis will represent the real values of k and the y axis its imaginary values. In the Mandelbrot fractal, normally the divergent z values are given one color and the convergent ones another. The frontier between one color and the other is a fractal. Here I will color the images using a rainbow palette to plot the values of the formula:
image = log (sqrt(Re(z) * Re(z) + Im(z) * Im(z)) + 1)
…where Re and Im denote the real and imaginary part of z respectively. The final Madelbrot fractal image can be seen in figure 1.
PDL
PDL is an extension of the Perl language for number crunching and scientific plotting
PDL is an extension of the Perl language for number crunching and scientific plotting. Because of its Perl heritage it has the clean syntax of a well settled programming language. You can also use one of the wealth of available module-packages in the Perl archive (CPAN), to use the language for other purposes like database access, date handling, inter-process communication, GUI toolkit, just to name a few.
Installing PDL
Unfortunately, PDL is not installed by default on many of the popular GNU/Linux distributions. Even worse, some distributions have the PDL related packages missing or partly broken. If you are running a GNU/Linux distribution based on Debian (Ubuntu, Knoppix, etc.), and have access to the regular Debian repositories, it is fairly easy to install PDL. You should install the pdl, pgplot5 and pgperl packages in order to follow the examples in this article. This can be done (as root) via the usual:
apt-get install pdl pgplot5 pgperl
If this is not your case, follow the instructions in [Installing PDL the quick and easy way](http://wiki.jach.hawaii.edu/pdl_wiki-bin/wiki/Getting_Started_with_PDL/Installing_PDL_the quick and easy way).
The PDL command line
Once you have PDL installed you should be able to run it in the command line. For this just type perldl on a terminal.
It should greet you with a message like:
xcalbet@debian:~$ perldl perlDL shell v1.33 PDL comes with ABSOLUTELY NO WARRANTY. For details, see the file 'COPYING' in the PDL distribution. This is free software and you are welcome to redistribute it under certain conditions, see the same file for details. ReadLines, NiceSlice, MultiLines enabled Reading PDL/default.perldlrc... Found docs database /usr/local/lib/perl/5.8.4/PDL/pdldoc.db Type 'help' for online help Type 'demo' for online demos Loaded PDL v2.4.2 perldl>
You can try out now some of PDL features by typing demo after the PDL prompt:
perldl> demo
Write a full post in response to this!
Do you like this post?
Vote for it!
Copyright information
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation. A copy of the license is available at http://www.gnu.org/copyleft/gpl.html.
Biography
Xavier Calbet: Xavier Calbet (xcalbet AT googlemail DOT com) is a long time free software user who started using Linux distributions in the ancient times when Slackware had to be installed using tens of floppy disks. He is currently working on his two pet projects: a meteorological field and satellite image display system, SAPO, and the best available free numerical computer language to date, PDL (Perl Data Language).
- Login or register to post comments
- 47582 reads
- Printer friendly version (unavailable!)




Best voted contents
-
Special 301: FOSS users. Now we're all Communists and Criminals
Gary Richmond, 2010-03-05 -
Microsoft's Internet Driving Licence: stupid, unworkable and unenforceable
Gary Richmond, 2010-03-10 -
The Bizarre Cathedral - 69
Ryan Cartwright, 2010-03-12 -
Making a videoloop with Kino and Audacity
Terry Hancock, 2010-02-18
Buzz authors
Free Software news
- When are YOU get your copy of this AWSOME FREEsoftware? Check it out at http://bit.ly/5NJCME
- ♺ @ubuntumy #ubuntu #linux ##Ubuntu Weekly Newsletter #184 http://goo.gl/fb/LRKL #business #cloud #freesoftware #gos #launchpad
- #ubuntu #linux ##Ubuntu Weekly Newsletter #184 http://goo.gl/fb/LRKL #business #cloud #freesoftware #gos #launchpad
- RT @wiimaster_123: When are YOU get your copy of this AWSOME FREEsoftware? Check it out at http://bit.ly/5NJCME
- Openness in #Hardware a Sign of #FreeSoftware Impact http://ur1.ca/pp5n
Other sites
- The Top 10 Everything (Dave). The good, the bad and the ugly.
- Free Software news (Dave & Bridget). All about free software -- free as in freedom!
- Book Reviews: Illiterarty (Bridget). Book reviews, blogs, and short stories.
Hot topics - last 60 days
-
Linux performance: is Linux becoming just too slow and bloated?
Mitch Meyran, 2010-01-26 -
Web code is already open - why not make it free as well
Ryan Cartwright, 2010-01-20 -
Save "Sita Sings the Blues" from the Flash format: can you convert FLA?
Terry Hancock, 2010-01-29 -
Question Copyright's "Minute Memes" challenge copyright rhetoric
Terry Hancock, 2010-01-15 -
Special 301: FOSS users. Now we're all Communists and Criminals
Gary Richmond, 2010-03-05
Hot topics - last 21 days
Odiogo
Free Software Magazine uses Apollo, project management and CRM for its everyday activities!


AWESOME!!!
Submitted by Anonymous visitor (not verified) on Tue, 2007-06-05 07:30.
Vote!Very nice article! I've never heard of PDL, though I do computational math (not numerical) everyday. I'm definitely going to find a use for it now.
Matalb and Octave code
Submitted by mWo on Tue, 2007-06-05 10:02.
Vote!Last line in MATLAB and Octave code, i.e., 'exit' causes that Matlab exits; hence, it is not possible to look at this fractal image.
mWo
It helps to know the problem you're solving a bit better.
Submitted by Dan S. (not verified) on Tue, 2007-06-05 15:53.
Vote!Let me preface this by saying that PDL looks neat. But,
You're iterating over the whole image with every iteration, doing gobs of work for pixels/locations that have diverged. I don't believe that there is any useful information retained by your clamping-to-5 step. (It is pretty, though!) With Mandelbrot, if the distance from the origin is > 2 then divergence to infinity is inevitable. The Mandelbrot set itself is defined as those starting values which never diverge to infinity; I think but am not sure that your clamping makes it impossible to tell even what is in/out of the set.
(( I believe the canonical/typical coloring is based on #-of-iterations-before-divergence for those pixels that diverge and black for those that don't. ))
Here is a patch (sorry about lost whitespace/indenting):
37,39c37,39
< for(k=0;k < niter;k++){
< for (i=0;i < NPTS;i++) {
< for (j=0;j < NPTS;j++) {
---
> for (i=0;i < NPTS;i++) {
> for (j=0;j < NPTS;j++) {
> for(k=0;k < niter;k++){
48,52c48,51
< if (zRe[i][j] < -5.) zRe[i][j]=-5.;
< if (zRe[i][j] > 5.) zRe[i][j]=5.;
< if (zIm[i][j] < -5.) zIm[i][j]=-5.;
< if (zIm[i][j] > 5.) zIm[i][j]=5.;
---
> if (zRe[i][j]* zRe[i][j] + zIm[i][j]*zIm[i][j] > 4.) // Divergence criteria
> break;
How much improvement? 2000x2000 array of points, 1000 iterations, my laptop/gcc 4.1.2 (Note: I had to add 'static' to the local arrays to make it work):
- Old: 4m46.654s
- New: 0m16.373s
C wins again! ;)
I don't know how to get this speedup effect in any of the "whole-array" approaches/languages. (Probably because I don't know them well at all.) It seems hard to get any effect other than foreach(iteration) { foreach(location in image) { /*..do something.. */ } } ; with this order of operations there's no way to bail out of iterations early at diverging locations.
I would speculate that, for this problem, plain old perl would be faster than your PDL approach... ;)
Poor matlab/octave implementation
Submitted by David Bateman (not verified) on Tue, 2007-06-05 20:35.
Vote!If you replace the lines like
qgtfive= find(qRe > 5.);
zRe(qgtfive)=5.;
with
zRe(qRe>5)=5
at least in Octave the code is about twice as fast. I believe the same indexing trick can be used in recent versions of matlab as well. You are basically getting your speed improvement from the PDL clip function.
D.
Dan, Something like
Submitted by David Bateman (not verified) on Tue, 2007-06-05 20:51.
Vote!Dan,
Something like
function z = mandel
npts=1000;
niter=51;
z=zeros(npts,npts);
[kRe,kIm] = meshgrid(linspace(-1.5,.5,npts),linspace(-1,1,npts));
k = kRe + 1i*kIm;
idx = [1:npts*npts];
while (niter)
z(idx) = z(idx).^ 2 + k(idx);
idx(abs(z(idx))>2) = [];
niter = niter - 1;
end
end
will do it for Octave/Matlab. However, at least in Octave the above indexed assignment can be quite expensive, and so the above is actually slower for this example. It might be faster with matlab...
D.
indexed assignment
Submitted by Alexander Barth (not verified) on Tue, 2007-06-05 22:01.
Vote!Hi David and Dan,
Here too, you can avoid indexed assignment by using a logical mask which is much faster in octave.
Cheers,
Alex
octave:7> tic; z=mandel(); toc;
Elapsed time is 43.521179 seconds.
octave:8> tic; z2=mandel2(); toc;
Elapsed time is 24.081490 seconds.
octave:9> max(abs(z(:)-z2(:)))
ans = 0
function z = mandel2
npts=1000;
niter=51;
z=zeros(npts,npts);
[kRe,kIm] = meshgrid(linspace(-1.5,.5,npts),linspace(-1,1,npts));
k = kRe + 1i*kIm;
while (niter)
mask = abs(z) < 2;
z(mask) = z(mask).^ 2 + k(mask);
niter = niter - 1;
end
David,
Submitted by Dan S. (not verified) on Tue, 2007-06-05 22:39.
Vote!That looks like it might work. Do octave/matlab have a way to apply a function to each element of a 2d array? Then the solution becomes very nice and clear, just creating a per-pixel 'mandelbrot' function and then applying it to each element of the (complex) image matrix.
Fortran 95 is a huge improvement over Fortran 77
Submitted by Anonymous visitor (not verified) on Tue, 2007-06-05 23:53.
Vote!gcc 4.x now provides for Fortran 90/95, which has a syntax similar to Matlab/Octave. A good Fortran 95 compiler should provide the ease of development of Matlab, with the speed quoted for Fortran 77. While you have the claim that Fortran is not rich in IO & maths functions you omit that there is more maths code in Fortran than in any other language - Netlib and Statlib being two of the best examples. I agree that Fortran is not terribly good for graphical IO.
I think C wins
Submitted by Rafael Verduzco on Wed, 2007-06-06 02:20.
Vote!Personally, i think C wins. I have to be honest and say that as a first approach to explore the problem I use the Matlab that my university provides me, but when it comes to flexibility, control, speed of execution and the ability to share code with my peers at the university, then C is the choice. Needless to say that there are available free paralelization tools to Fortran and C, and even though they need high computer skills, let's face it: if you are coping with mathematical, numerical computation software, high chances are that you are computer skilled.
I know, there's a lot of people (biologists, finance people, etc.) But you should look at the present in science, sneak into the current research journals and note that there's a tendency to people get more and more skilled in performing in silico simulations, coming from very different fields, not only math or computer science.
Nah!, IMHO, C (Fortran, if you like it better) win.
A different c implementation.
Submitted by Brandon Andrews (not verified) on Thu, 2007-06-07 03:52.
Vote!Compile with: gcc -lm -lpng mandlebrot.c .I used gcc 4.2.0.
#include <stdio.h>
#include <math.h>
#include <png.h>
#define NPTS 1000 //=width=height
png_uint_16 img[NPTS][NPTS][3];
void genImg();
void addPixel();
void writePng();
int main(void){ genImg(); writePng(); return 0; }
void genImg() {
int i,j,k,niter;
double zRe, zIm, kRe, kIm, qRe, qIm;
niter=51; // Number of iterations
for (i=0;i<NPTS;i++) {
for (j=0;j<NPTS;j++) {
// Generating z = 0 (real and imaginary part)
zRe=0.;
zIm=0.;
// Generating the constant k (real and imaginary part)
kRe=(double)i*2.0/((double)NPTS-1.)-1.5;
kIm=(double)j*2.0/((double)NPTS-1.)-1.;
//Iterating
for (k=0;k<niter;k++){
// Calculating q = z*z + k in complex space
// q is a temporary variable to store the result
qRe=zRe*zRe-zIm*zIm+kRe;
qIm=2.*zRe*zIm+kIm;
// Assigning the q values to z constraining between
// -10 and 10 to avoid numerical divergences
zRe=qRe;
zIm=qIm;
if (zRe < -10.) zRe=-10.; if (zRe > 10.) zRe=10.; if (zIm < -10.) zIm=-10.; if (zIm > 10.) zIm=10.;
}
addPixel(i,j,zRe,zIm);
}
}
}
void addPixel(int i, int j, double zRe, double zIm){
img[i][j][0] = (png_uint_16)(sin(log( sqrt(zRe*zRe+zIm*zIm)))*65536);
img[i][j][1] = (png_uint_16)(cos(log( sqrt(zRe*zRe+zIm*zIm)))*65536);
img[i][j][2] = (png_uint_16)(log( sqrt(zRe*zRe+zIm*zIm))*65536);
}
void writePng(){
FILE *fp = fopen("mandle.png", "wb");
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_set_IHDR(png_ptr, info_ptr, NPTS, NPTS, 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_init_io(png_ptr, fp);
png_write_info(png_ptr, info_ptr);
png_set_swap(png_ptr); //big -> little endian
int i; for (i=0;i<NPTS;i++){ png_write_row(png_ptr, (png_bytep)img[i]); }
png_write_end(png_ptr,info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
}
Other useful linux fractal resources
Submitted by Fzzy on Tue, 2007-07-31 12:02.
Vote!Well, i know nothing of all this math. How do i get up my brownie points? Here are some interesting Linux fractal resources:
1. A cool open source screensaver which also uses fractal math to do it's thing. (http://electricsheep.org/)
2. Gnofract. The author says he think's it's the best fractal package currently available for Linux. Test it and decide for yourself (http://gnofract4d.sourceforge.net/)
3. For the purists, fractals are about math. For the arty, here's some fun fractal stuff you can do in GIMP (http://gentoo-wiki.com/TIP_GIMP_Fractal_Backgrounds)
4. Fyre is a tool for producing computational artwork based on histograms of iterated chaotic functions. Source is included on the site. (http://fyre.navi.cx/)
Some Remarks
Submitted by Anonymous visitor (not verified) on Tue, 2007-07-31 13:41.
Vote!Fortran has a complex data type which would be appropriate here.
Also there is a FOSS implementation of IDL called GNUDL.
An finally R is a very interesting language that has not been looked at in this
comparison.