Mandel: software for real and complex dynamics

Mandel is an interactive program for drawing the Mandelbrot set and Julia sets, and for illustrating and researching their mathematical properties. It is available on Linux, Windows, and Mac with a graphical user interface based on the c++ toolkit Qt by The Qt Company. Features include: The latest release is Mandel 5.12 of 2014. The source code is available under the GNU General Public Licence. Compile it yourself on Linux, Windows, or Mac after installing Qt 4-5. For your convenience, a Windows executable is offered in addition.
Download the source code (0.5 MB) or the Windows exe (5.6 MB).
There is an executable for Mac as well (7.6 MB, Mandel 5.10).

Download Juliette 1.0 here, a Java applet providing external rays, renormalization, asymptotic and local similarity.

Other sites with programs on complex dynamics or fractals:
Arnaud Chéritat, Curt McMullen, Mitsuhiro Shishikura, Xaos, Fractint.

Just for fun ... a PostScript program for computing M. You may change parameters by editing the source code. Download mc.eps (1.4 kb).

The DOS-program logistic.exe deals with the real iteration of z2 + c, which is conjugate to the standard logistic map. It provides features like drawing q-curves, finding hyperbolic intervals or periodic points, cobweb graphics. This program may be used and redistributed without restriction. It comes with no warranty.
Download logistic.exe 2.0 of July 30, 1998. Preliminary manual

How to draw external rays:

Show more ...


In the iteration of quadratic polynomials fc(z) = z2 + c , the parameter c is fixed and the dynamic variable z is evolving when the mapping is applied again and again. Both c and z are complex numbers. The filled Julia set Kc contains those values z that are not going to the point at ∞ under iteration. The dynamics is chaotic on its boundary ∂Kc , which is the Julia set. The mapping fc(z) = z2 + c is conjugate to F(z) = z2 in a neighborhood of ∞. The conjugacy is provided by the Boettcher mapping Φc(z), which satisfies Φc(fc(z)) = F(Φc(z)). We have

(1)  Φc(z) = limn→∞ (fcn(z))1/2n

for a suitable choice of the 2n-th root. This is made precise by the following formula, which is valid for large |z| with the principal value of the roots:

(2)  Φc(z) = z ∏n=1 (1 + c/(fcn-1(z))2) 1/2n = z ∏n=1 (fcn(z)/(fcn(z)-c)) 1/2n.

In the dynamics of quadratic polynomials, there is a basic dichotomy: The mapping ΦM(c) is defined by evaluating the Boettcher mapping at the critcal value z = c, i.e., ΦM(c) = Φc(c). Adrien Douady has shown that it is a conformal mapping from the exterior of the Mandelbrot set M to the exterior of the unit disk, thus M is connected. By means of ΦM(c), external rays and equipotential lines are defined in the parameter plane as well. See the image above. When the argument θ of an external ray is a rational multiple of 2π, then the ray is landing at a distinguished boundary point: a rational dynamic ray is landing at a periodic or preperiodic point in the Julia set. A rational parameter ray is landing at a Misiurewicz point or a root point in the boundary of the Mandelbrot set. See the following papers by Dierk Schleicher (arXiv:math.DS/9711213) and John Milnor (arXiv:math.DS/9905169).

Computation of the external argument:

External rays are characterized by the fact that the argument argc(z) of Φc(z), or the argument argM(c) of ΦM(c), equals a given value θ. For large |z|, formula (2) implies

(3)  argc(z) = arg(z) + ∑n=1 1/2n arg(1 + c/(fcn-1(z))2) = arg(z) + ∑n=11/2n arg(fcn(z)/(fcn(z)-c)).

Here arg(z) denotes the argument of the complex number z, i.e., its angle to the positive real axis. This angle is defined only up to multiples of 2π. E.g., a point z on the negative real axis has the arguments ±π, ±3π, ±5π ... The principal value of the argument is the unique angle with -π<arg(z)≤π. This definition is used because a function should be single-valued. However, a discontinuity is introduced artificially when a point z is crossing the negative real axis, say going from i through -1 to -i: its argument should go from π/2 through π to 3π/2, but the principal value goes from π/2 to π, jumps to -π, and goes to -π/2.

Formula (3) means that the orbit zn=fcn(z) of z and the arguments arg(zn/(zn-c)) are computed. The function arg(z/(z-c)) is discontinuous on the straight line segment from the critical point z = 0 to the critical value z = c, which is drawn in red in the figure: when z belongs to this line segment, then z/(z-c) will be on the negative real axis. When the Julia set is connected, the location of the discontinuity can be moved onto a kind of curve joining 0 and c within the Julia set, such that the argument is continuous in the whole exterior: When the modified function arg(z/(z-c)) is used instead of the principal value for computing argc(z) according to (3), this formula will be valid not only for large |z| but everywhere outside the Julia set. In practice, the Julia set may be approximated by two straight line segments from the fixed point αc to 0 and c, respectively: when zn is in the triangle between 0, c, and αc, adjust the principal value of arg(zn/(zn-c)) by ±2π. The triangle is given by three simple inequalities, cf. mndlbrot::turn(). In the two images below, the different colors indicate values of argc(z), and thus, external rays. The computed value of argc(z), and thus the color, is jumping on certain curves joining preimages of 0, where some iterate zn is crossing the line where arg(z/(z-c)) is discontinuous. In the left image, the principal value of arg(z/(z-c)) is used, and in the right image, the argument is adjusted. The erroneous discontinuities of the computed argc(z) are moved closer to the Julia set.

The same modification seems to work for the computation of the argument argM(c) in the parameter plane as well, although the Julia set is disconnected. The left image below shows the discontinuities arising from the principal value of arg(z/(z-c)) in (3), they are appearing on curves joining centers of different periods. In the right image, the argument is adjusted, and the discontinuities are moved closer to the Mandelbrot set.

Drawing “all” rays:

To get an overview of all rays, compute the argument at every pixel and map it to a range of colors. The images above where obtained with Mandel's algorithm No. 6. The code of mndlbrot::turn() has been ported to Java by Evgeny Demidov. See also the algorithms 7 and 8, where no discontinuity appears, but only the ends of certain rays are visible. Adam Majewski has suggested that boundary scanning (below) can be used to draw several rays simultaneously.

Drawing a single ray:

The following methods apply with small modifications to the dynamic plane and the parameter plane as well: The inverse of Φc(z) or ΦM(c) can vary considerably on a small interval: the angles 1/7 (of period 3) and 321685687669320/2251799813685247 (of period 51) differ by about 10-15, but the landing points of the corresponding parameter rays are about 0.035 apart. On this scale, the rays cannot be drawn well by tracing the argument, unless high-precision arithmetics is used. The following image shows the parameter ray for 1/7 and two rays of period 51 in the slit betwen the main cardioid and the 1/3-component. The argument is not distinguishable (left), but the Newton method has no problem (right). In the dynamic plane, backwards iteration works as well.

Note that most of the methods above can be modified to draw equipotential lines. In this case there is no problem with the ambiguity of the argument. Boundary scanning is slow and the Newton method has three problems: finding a starting point, drawing several lines around a disconnected Julia set, and choosing the number of points depending on the chosen subset of the plane. Therefore I am using boundary tracing with starting points on several lines through the image. See QmnPlane::green(). Still, sometimes not the whole line is drawn, or not all components are found.