Archive for August, 2009

Mandelbrot set taxonomy

Tuesday, August 4th, 2009

Lots of videos have been made of zooms into the Mandelbrot set. These videos almost all follow the same pattern. The initial image is the familiar one of the entire set. One zooms in on some tendril or other, gathering details, passing various minibrots and possibly some embedded Julia sets on the way until one reaches a final minibrot and the zoom stops.

The reason for this is that these sequences are relatively quick to calculate, they show a variety of the different types of behaviors that the Mandelbrot set has to offer, and they have a natural endpoint which causes the video not to seem like it has been cut off part-way through.

If we relax these conditions, what interesting zoom sequences open up to us?

To answer this question requires classification of the complex numbers according to the roles they play in the Mandelbrot set.

The first taxon separates exterior points (whose z sequences are unbounded, example: +1), interior points (limit of z sequence is a finite attracting cycle, example: 0) and boundary points (all other z sequence behaviours). Zooming into either of the first two will leave us with an image of uniform colour after a finite amount of time. Most zoom movies actually target the second of these.

Zooming in on the boundary will leave us with an infinite sequence of "interesting" images, so let's explore this group further. The second taxon separates shore points (those which are on the edge of an atom), Feignbaum points (which are at the limit of a sequence of atoms of increasing period) and filament points (all other boundary points).

Feignbaum points make quite interesting infinite zoom sequences. The canonical example is ~-1.401155, the westernmost point of the main molecule. Each time you zoom in by a factor of ~4.669201, the lakes look the same but the the filaments get denser. Filaments connect to molecules at these points. These are the only places filaments attach to the continent but each mu-molecule has one additional filament emerging from its cardioid cusp.

Filament points can be divided into two types based on orbit dynamics - those whose orbit is chaotic (irrational external angle) and those whose orbit converges to a finite repelling cycle. The latter includes two subtypes - branch points (where there are more than one but fewer than infinity paths to other points in the set) and terminal points (where there is only one). Well-known terminal points include -2 and +i. Zooming into terminal points and branch points gives a video which is infinite but which devolves into very same-y spirals after a short time as the mu-molecules shrink to less than a pixel.

I don't know an exact formula for any chaotic filament points, but they're easy to find using a fractal plotter - just zoom in, keeping away from any mu-molecules, branch points and terminal points. As with terminal and branch points, the minibrots tend to shrink to less than a pixel quite quickly, so the images obtained will become same-y after a while - the structures formed by the filaments tend to look like L-system fractals.

Shore points can be divided into two categories, parabolic points and Siegel points. Parabolic points come in two flavors, cardioid cusps (the point of maximum curvature of a cardioid, example: +0.25) and bond points (where two atoms meet, example: -0.75). If you zoom in a cusp you'll technically always have detail on the screen but the picture gets very boring very quickly as the cusps shrink to sub-pixel widths.

This leaves the Siegel points. You can find these by zooming into the edge of an atom but avoiding the cusps. For example:

  1. Start off with the large circle to the west (call it A) and the slightly smaller circle to the north (call it B).
  2. Zoom in until you can pick out the largest circle C between A and B on the boundary of the set.
  3. Rename B as A and C as B.
  4. Go to step 2.

This particular algorithm takes you to the point whose Julia set is known as the Siegel disk fractal, \displaystyle \frac{1}{4}(1-(e^{i(1-\sqrt{5})\pi}-1)^2) which is about -.390541+.586788i.

All points on the boundary of the continent cardioid can be found using the formula \displaystyle c=\frac{1}{4}(1-(e^{i\theta}-1)^2). For rational \displaystyle \frac{\theta\pi}{2}, this gives a parabolic point and for irrational \displaystyle \frac{\theta\pi}{2} this gives a Siegel point (a point whose Julia set has Siegel discs). The "most irrational" number (in the sense that it is least well approximated by rational numbers) is the Golden ratio \displaystyle \frac{1}{2}(1-\sqrt{5}). The Siegel point corresponding to this number is the point reached by the algorithm given above. In some sense then, this area is the most difficult area of the Mandelbrot set to plot, and indeed if you attempt to zoom into it you'll quickly discover that you have to increase the maximum number of iterations exponentially to avoid losing detail. I don't think it's really practical to explore this area very far without a Mandelbrot set program that can do SOI, such as Fractint, Fractal Witchcraft (which is a pain to get working now as it's a DOS program), almondbread (which is a pain to get working now as one of its prerequisites seems to no longer be available) or the program I'm writing.

If you could zoom a long way into it, what would the Siegel area of the Mandelbrot set look like? Well, we know the part inside the cardioid is inside the set. We also know it's not a bond point so at least part of the remainder is outside the set. The pattern of circles on the cardioid is self-similar (it's related to Farey addition) so the continent part would look similar to a shallow zoom on the same point. The rest is a bit hazy, though. My experiments suggest that the density and relative size of mu-molecules gets greater as one zooms in on this area, so an interesting question to ask is what the limit of this process is? Would the area outside the continent be covered with (possibly highly deformed) tesselating mu-molecules, leading to a black screen? Or would only part of the image be covered by mu-molecules, the rest being extremely dense filament structures? Both possibilities seem to be compatible with the local Hausdorff dimension being 2. Either way I suspect there are some seriously beautiful images hiding here if we can zoom in far enough.

Summary of the taxonomy:

  • Exterior points (example: infinity)
  • Member points
    • Interior points
      • Superstable points (examples: 0, -1)
      • Non-superstable points
    • Boundary points
      • Filaments
        • Repelling points
          • Terminal points (examples: -2, +/- i)
          • Branch points
        • Chaotic, irrational external angle filaments
      • Feignbaum points (example: ~-1.401155)
      • Shore points
        • Parabolic points
          • Cardioid cusps (examples, 0.25, -1.75)
          • Bond points (examples, -0.75, -1 +/- 0.25i, -1.25, 0.25 +/- 0.5i)
        • Siegel points (example: \displaystyle \frac{1}{4}(1-(e^{i(1-\sqrt{5})\pi}-1)^2) ~= -.39054087021840008+.58678790734696872i)

Bugs are good

Monday, August 3rd, 2009

This may strike horror into the hearts of the test-driven-development crowd, but it makes me nervous when I write a program and it works correctly the first time. Sure it works, but maybe the code is subtly broken in some way and it only works by accident. Maybe if you sneeze too loudly nearby it will blow up. Maybe if I add some feature it will blow up. Until I've given it a decent workout there's just no way of knowing.

But a program with a bug is a puzzle - solving the puzzle gives one purpose, and an opportunity to learn more about how the code works (or why it doesn't). Sometimes in the process of debugging I'll change parameters or add debugging code, exploring the design space in order to get a better idea about what's going on. Sometimes doing this will give me ideas for improvements unrelated to fixing a particular bug - a way to improve performance or a new feature to add.

I have much greater confidence in a program that I've fixed lots of bugs in than one that works first time.

Determining if a point is in the Mandelbrot set

Sunday, August 2nd, 2009

I'm writing a super-fast, super-accurate Mandelbrot set plotter. This one is unusual in that no explicit iteration limit is ever set - it will keep iterating any point until it either escapes or is determined to be in the set. This works pretty well and produces much sharper cusps than any other program I've seen.

However, the downside is that it can take an arbitrarily long to determine if any given point is in the set or not. Points on the edge of the set are (as always) the particularly tricky ones - some of them exhibit chaotic behavior for a very long time before becoming periodic or escaping.

Currently I use two methods for determining if a point is in the set. I have explicit formulae for the main cardioid and the period-2 bulb, and I look for periodic orbits using Floyd's algorithm.

I'm wondering if a third method might be practical - one that determines if a point is in the set without waiting for it to become periodic. Here's the method I'm considering.

Let the Mandelbrot iteration function f(z) = z2 + c. Suppose we have a point c, and we suspect that it might be periodic with period N. We can determine if it is or not by finding a point zf that is unchanged under N applications of f, i.e. a solution to fN(zf) = zf. There will generally be 2N such solutions, of which only N will be relevant to the case at hand. However, if we have a z that is likely to be near one of these fixed points we should be able to converge on one of them quickly by using Newton's method or something similar.

Once we have our fixed point, we take the derivative of fN with respect to c and evaluate it at zf. This is easy to do numerically - just evaluate fN at zf and a nearby point, take the difference and divide by the original distance. If the modulus of the result is 1 or less, then the attractor is stable and c is in the set. If it isn't, the point could still be in the set as we might have picked the wrong zf or N - that is we are likely to get false negatives but no false positives using this method (which is exactly what we want - if we get a false negative we can
iterate some more, try a new N and/or a new zf and eventually get the right answer).

Working through these steps symbolically gives us closed form solutions for the period-1 and period-2 attractors but if we try it for period 3 we get a polynomial of order 6 in z (23 = 8 minus the two from factoring out the period-1 attractor) - I'm not sure if we can get a closed form solution for period-3 attractors from this.

The tricky part is choosing an appropriate N and an approximation to zf for any given point. I think the way to do it is this: whenever we find a periodic point with Floyd's algorithm, iterate a further N times to figure out the period, and store the period and fixed point. When we start a new set of iterations on a point, check to see if any neighbouring points are periodic. If they are, try this method using the N from that point and the zf (appropriately adjusted for the new c). When we find a periodic point this way, we store the found N and zf just as for Floyd's algorithm.

Installing Vista the difficult way

Saturday, August 1st, 2009

I recently swapped the 100Gb hard drive that my laptop came with for a 320Gb model. I kept running out of space and deleting operating system components that I wasn't using, which is all very well except that when I tried to install Vista SP2 it complained that important files were missing. The SP2 installer doesn't really need those files either, it just does an integrity check.

After having installed the new drive I started to install Windows and then discovered that my laptop's DVD drive was in bad shape. It could read CDs fine but not DVDs at all.

I had read that it was possible to install Vista from a USB key so I tried this. Unfortunately the only USB key I have handy is a 1Gb one and Vista claims it needs a 4Gb one to install from. There doesn't appear to be anywhere close by that sells USB keys.

I wondered if it was possible to boot from the USB key, copy the required files to the hard drive over the network using the preinstallation environment and then install from the hard drive. With a bit of fiddling I got it to work, and here is how I did it.

  1. Format the USB key to NTFS, copy the files over but excluding install.wim. This only takes about 256Mb. Make the key bootable with "bootsect /nt60" and boot from it.
  2. Choose "repair" at the computer and open a command prompt. Use diskpart to partition and format the drive.
  3. Now we need to get the installation files onto the hard drive, including install.wim. We can get TCP/IP networking up and running with netsh but the Vista preinstallation environment doesn't include SMB file sharing. It does however include the ftp client, so we can set up a small FTP server another machine and then ftp install.wim over. The rest of the files can just be copied from the USB key.
  4. The next part is tricky - we need to convince the installer to run from the hard drive and also install to the hard drive. If we make the hard drive bootable the same way we made the USB key bootable and try to boot from it, the installer gets very confused and gets stuck in a loop after a couple of reboots. However, I hit upon another way which does work. Unmount the USB key and the hard drive with "mountvol /d" and then mount the hard drive with the same drive letter that was being used for the USB key. Then run "setup" and install Vista as normal.

Addendum: I tried to do this again with a new computer I built, but the Vista preinstallation environment didn't have drivers for my network card. Obviously if this is the case, another method must be used.