Appendix A
Misc. Options and algorithms
_________________________________________________________________
INSIDE=BOF60|BOF61|ZMAG|FMOD|PERIOD|ATAN
Here is an *ATTEMPTED* explanation of what the inside=bof60 and
inside=bof61 options do. This explanation is hereby dedicated
to Adrian Mariano, who badgered it out of us! For the *REAL*
explanation, see "Beauty of Fractals", page 62.
Let p(z) be the function that is repeatedly iterated to
generate a fractal using the escape-time algorithm. For
example, p(z) = z^2+c in the case of a Julia set. Then let
pk(z) be the result of iterating the function p for k
iterations. (The "k" should be shown as a superscript.) We
could also use the notation pkc(z) when the function p has a
parameter c, as it does in our example. Now hold your breath
and get your thinking cap on. Define a(c) =
inf{|pkc(0)|:k=1,2,3,...}. In English - a(c) is the greatest
lower bound of the images of zero of as many iterations as you
like. Put another way, a(c) is the closest to the origin any
point in the orbit starting with 0 gets. Then the index (c) is
the value of k (the iteration) when that closest point was
achieved. Since there may be more than one, index(c) is the
least such. Got it? Good, because the "Beauty of Fractals"
explanation of this, is, ahhhh, *TERSE* ! Now for the punch
line. Inside=bof60 colors the lake alternating shades according
to the level sets of a(c). Each band represents solid areas of
the fractal where the closest value of the orbit to the origin
is the same. Inside=bof61 show domains where index(c) is
constant. That is, areas where the iteration when the orbit
swooped closest to the origin has the same value. Well, folks,
that's the best we can do! Improved explanations will be
accepted for the next edition!
In response to this request for lucidity, Herb Savage offers
this explanation the bof60 and bof61 options:
The picture on page 60 of The Beauty of Fractals shows the
distance to origin of the closest point to the origin in the
sequence of points generated from a given X,Y coordinate. The
picture on page 61 shows the index (or number) in the sequence
of the closest point.
INSIDE=ZMAG
is similar. This option colors inside pixels according to the
magnitude of the orbit point when maxiter was reached, using
the formula color = (x^2 + y^2) * maxiter/2 + 1.
INSIDE=FMOD
colors inside pixels according to the magnitude of the last
orbit point which within a set distance from the origin. Then:
color = magnitude * colors / closeprox The value of closeprox
can be varied interactively. This feature was contributed by
Iain Stirling.
INSIDE=PERIOD
colors pixels according to the length of their eventual cycle.
For example, points that approach a fixed point have color=1.
Points that approach a 2-cycle have color=2. Points that do not
approach a cycle during the iterations performed have
color=maxit. This option works best with a fairly large number
of iterations.
INSIDE=ATAN
colors by determining the angle in degrees the last iterated
value has with respect to the real axis, and using the absolute
value. This feature should be used with periodicity=0
INSIDE=EPSCROSS|STARTRAIL
Kenneth Hooper has written a paper entitled "A Note On Some
Internal Structures Of The Mandelbrot Set" published in
"Computers and Graphics", Vol 15, No.2, pp. 295-297. In that
article he describes Clifford Pickover's "epsilon cross" method
which creates some mysterious plant- like tendrils in the
Mandelbrot set. The algorithm is this. In the escape-time
calculation of a fractal, if the orbit comes within .01 of the
Y-axis, the orbit is terminated and the pixel is colored green.
Similarly, the pixel is colored yellow if it approaches the
X-axis. Strictly speaking, this is not an "inside" option
because a point destined to escape could be caught by this
bailout criterion.
The test distance, 0.01, can now be changed interactively on
the screen and via the proximity= command line
parameter. A negative value of the test distance triggers an
alternative variation of epsilon cross that colors the epsilon
bands with the iteration; otherwise they are colored normally
to maintain compatibility.
Hooper has another coloring scheme called "star trails" that
involves detecting clusters of points being traversed by the
orbit. A table of tangents of each orbit point is built, and
the pixel colored according to how many orbit points are near
the first one before the orbit flies out of the cluster. This
option looks fine with maxiter=16, which greatly speeds the
calculation.
Both of these options should be tried with the outside color
fixed (outside=[nnn]) so that the "lake" structure revealed by
the algorithms can be more clearly seen. Epsilon Cross is fun
to watch with boundary tracing turned on - even though the
result is incorrect it is interesting! Shucks - what does
"incorrect" mean in chaos theory anyway?!
FINITE ATTRACTORS
Many of Fractint's fractals involve the iteration of functions
of complex numbers until some "bailout" value is exceeded, then
coloring the associated pixel according to the number of
iterations performed. This process identifies which values tend
to infinity when iterated, and gives us a rough measure of how
"quickly" they get there.
In dynamical terms, we say that "Infinity is an Attractor", as
many initial values get "attracted" to it when iterated. The
set of all points that are attracted to infinity is termed The
Basin of Attraction of Infinity. The coloring algorithm used
divides this Basin of Attraction into many distinct sets, each
a single band of one color, representing all the points that
are "attracted" to Infinity at the same "rate". These sets
(bands of color) are termed "Level Sets" - all points in such a
set are at the same "Level" away from the attractor, in terms
of numbers of iterations required to exceed the bailout value.
Thus, Fractint produces colored images of the Level Sets of the
Basin of Attraction of Infinity, for all fractals that iterate
functions of Complex numbers, at least. Now we have a sound
mathematical definition of what Fractint's "bailout" processing
generates, and we have formally introduced the terms Attractor,
Basin of Attraction, and Level Set, so you should have little
trouble following the rest of this section!
For certain Julia-type fractals, Fractint can also display the
Level Sets of Basins of Attraction of Finite Attractors. This
capability is a by-product of the implementation of the
MAGNETic fractal types, which always have at least one Finite
Attractor.
This option can be invoked by setting the "Look for finite
attractor" option on the [Y] options screen, or by giving the
"finattract=yes" command-line option.
Most Julia-types that have a "lake" (normally colored blue by
default) have a Finite Attractor within this lake, and the lake
turns out to be, quite appropriately, the Basin of Attraction
of this Attractor. The "finattract=yes" option (command-line or
[Y] options screen) instructs Fractint to seek out and identify
a possible Finite Attractor and, if found, to display the Level
Sets of its Basin of Attraction, in addition to those of the
Basin of Attraction of Infinity. In many cases this results in
a "lake" with colored "waves" in it; in other cases there may
be little change in the lake's appearance.
For a quick demonstration, select a fractal type of LAMBDA,
with a parameter of 0.5 + 0.5i. You will obtain an image with a
large blue lake. Now set "Look for finite attractor" to 1 with
the "Y" menu. The image will be re-drawn with a much more
colorful lake. A Finite Attractor lives in the center of one of
the resulting "ripple" patterns in the lake - turn the [O]rbits
display on to see where it is - the orbits of all initial
points that are in the lake converge there.
Fractint tests for the presence of a Finite Attractor by
iterating a Critical Value of the fractal's function. If the
iteration doesn't bail out before exceeding twice the iteration
limit, it is almost certain that we have a Finite Attractor -
we assume that we have.
Next we define a small circle around it and, after each
iteration, as well as testing for the usual bailout value being
exceeded, we test to see if we've hit the circle. If so, we
bail out and color our pixels according to the number of
iterations performed. Result - a nicely colored-in lake that
displays the Level Sets of the Basin of Attraction of the
Finite Attractor. Sometimes !
First exception: This does not work for the lakes of
Mandel-types. Every point in a Mandel-type is, in effect, a
single point plucked from one of its related Julia-types. A
Mandel-type's lake has an infinite number of points, and thus
an infinite number of related Julia-type sets, and consequently
an infinite number of finite attractors too. It *MAY* be
possible to color in such a lake, by determining the attractor
for EVERY pixel, but this would probably treble (at least) the
number of iterations needed to draw the image. Due to this
overhead, Finite Attractor logic has not been implemented for
Mandel-types.
Secondly, certain Julia-types with lakes may not respond to
this treatment, depending on the parameter value used. E.g.,
the Lambda Set for 0.5 + 0.5i responds well; the Lambda Set for
0.0 + 1.0i does not - its lake stays blue. Attractors that
consist of single points, or a cycle of a finite number of
points are ok. Others are not. If you're into fractal
technospeak, the implemented approach fails if the Julia- type
is a Parabolic case, or has Siegel Disks, or has Herman Rings.
However, all the difficult cases have one thing in common -
they all have a parameter value that falls exactly on the edge
of the related Mandel-type's lake. You can avoid them by
intelligent use of the Mandel-Julia Space-Bar toggle: Pick a
view of the related Mandel-type where the center of the screen
is inside the lake, but not too close to its edge, then use the
space-bar toggle. You should obtain a usable Julia-type with a
lake, if you follow this guideline.
Thirdly, the initial implementation only works for Julia-types
that use the "Standard" fractal engine in Fractint. Fractals
with their own special algorithms are not affected by Finite
Attractor logic, as yet. Finally, the finite attractor code
will not work if it fails to detect a finite attractor. If the
number of iterations is set too low, the finite attractor may
be missed.
Despite these restrictions, the Finite Attractor logic can
produce interesting results. Just bear in mind that it is
principally a bonus off-shoot from the development of the
MAGNETic fractal types, and is not specifically tuned for
optimal performance for other Julia types.
(Thanks to Kevin Allen for the above).
There is a second type of finite attractor coloring, which is
selected by setting "Look for Finite Attractor" to a negative
value. This colors points by the phase of the convergence to
the finite attractor, instead of by the speed of convergence.
For example, consider the Julia set for -0.1 + 0.7i, which is
the three- lobed "rabbit" set. The Finite Attractor is an orbit
of length three; call these values a, b, and c. Then, the Julia
set iteration can converge to one of three sequences:
a,b,c,a,b,c,..., or b,c,a,b,c,..., or c,a,b,c,a,b,... The
Finite Attractor phase option colors the interior of the Julia
set with three colors, depending on which of the three
sequences the orbit converges to. Internally, the code
determines one point of the orbit, say "a", and the length of
the orbit cycle, say 3. It then iterates until the sequence
converges to a, and then uses the iteration number modulo 3 to
determine the color.
TRIG IDENTITIES
The following trig identities are invaluable for coding
fractals that use complex-valued transcendental functions of a
complex variable in terms of real-valued functions of a real
variable, which are usually found in compiler math libraries.
In what follows, we sometimes use "*" for multiplication, but
leave it out when clarity is not lost. We use "^" for
exponentiation; x^y is x to the y power.
(u+iv) + (x+iy) = (u+x) + i(v+y)
(u+iv) - (x+iy) = (u-x) + i(v-y)
(u+iv) * (x+iy) = (ux - vy) + i(vx + uy)
(u+iv) / (x+iy) = ((ux + vy) + i(vx - uy)) / (x^2 + y^2)
e^(x+iy) = (e^x) (cos(y) + i sin(y))
log(x+iy) = (1/2)log(x^2 + y^2) + i(atan(y/x) + 2kPi)
for k = 0, -1, 1, -2, 2, ...
(The log function refers to log base e, or ln. The expression
atan(y/x) is an angle between -pi and pi in the quadrant
containing (x,y) implemented in C as the atan2() function.)
z^w = e^(w*log(z))
sin(x+iy) = sin(x)cosh(y) + i cos(x)sinh(y)
cos(x+iy) = cos(x)cosh(y) - i sin(x)sinh(y)
tan(x+iy) = sin(x+iy) / cos(x+iy)
sinh(x+iy) = sinh(x)cos(y) + i cosh(x)sin(y)
cosh(x+iy) = cosh(x)cos(y) + i sinh(x)sin(y)
tanh(x+iy) = sinh(x+iy) / cosh(x+iy)
cosxx(x+iy) = cos(x)cosh(y) + i sin(x)sinh(y)
(cosxx is present in Fractint to provide compatibility with a
bug which was in its cos calculation before version 16)
sin(2x) sinh(2y)
tan(x+iy) = ------------------ + i------------------
cos(2x) + cosh(2y) cos(2x) + cosh(2y)
sin(2x) - i*sinh(2y)
cotan(x+iy) = --------------------
cosh(2y) - cos(2x)
sinh(2x) sin(2y)
tanh(x+iy) = ------------------ + i------------------
cosh(2x) + cos(2y) cosh(2x) + cos(2y)
sinh(2x) - i*sin(2y)
cotanh(x+iy) = --------------------
cosh(2x) - cos(2y)
asin(z) = -i * log(i*z+sqrt(1-z*z))
acos(z) = -i * log(z+sqrt(z*z-1))
atan(z) = i/2* log((1-i*z)/(1+i*z))
asinh(z) = log(z+sqrt(z*z+1))
acosh(z) = log(z+sqrt(z*z-1))
atanh(z) = 1/2 * log((1+z)/(1-z))
sqr(x+iy) = (x^2-y^2) + i*2xy
sqrt(x+iy) = sqrt(sqrt(x^2+y^2)) * (cos(atan(y/x)/2) + i sin(atan(y/x)/2))
ident(x+iy) = x + iy
conj(x+iy) = x - iy
recip(x+iy) = (x-iy) / (x^2+y^2)
flip(x+iy) = y + ix
zero(x+iy) = 0
one(x+iy) = 1
cabs(x+iy) = sqrt(x^2 + y^2)
floor(x+iy) = floor(x) + i*floor(y)
ceil(x+iy) = ceil(x) + i*ceil(y)
trunc(x+iy) = trunc(x) + i*trunc(y)
round(x+iy) = round(x) + i*round(y)
Fractint's definitions of abs(x+iy) and |x+iy| below are
non-standard. Math texts define both absolute value and modulus
of a complex number to be the same thing. They are both equal
to cabs(x+iy) as defined above.
|x+iy| = x^2 + y^2
abs(x+iy) = sqrt(x^2) + i sqrt(y^2)
QUATERNION MATH
Quaternions are four dimensional generalizations of complex
numbers. They almost obey the familiar field properties of real
numbers, but fail the commutative law of multiplication, since
x*y is not generally equal to y*x.
Quaternion algebra is most compactly described by specifying
the rules for multiplying the basis vectors 1, i, j, and k.
Quaternions form a superset of the complex numbers, and the
basis vectors 1 and i are the familiar basis vectors for the
complex algebra. Any quaternion q can be represented as a
linear combination q = x + yi + zj + wk of the basis vectors
just as any complex number can be written in the form z = a +
bi.
Multiplication rules for quaternion basis vectors:
ij = k jk = i ki = j
ji = -k kj = -i ik = -j
ii = jj = kk = -1
ijk = -1
Note that ij = k but ji = -k, showing the failure of the
commutative law. The rules for multiplying any two quaternions
follow from the behavior of the basis vectors just described.
However, for your convenience, the following formula works out
the details.
Let q1 = x1 + y1i + z1j + w1k and q2 = x2 + y2i + z2j + w2k.
Then q1q2 = 1(x1x2 - y1y2 - z1z2 - w1w2) +
i(y1x2 + x1y2 + w1z2 - z1w2) +
j(z1x2 - w1y2 + x1z2 + y1w2) +
k(w1x2 + z1y2 - y1z2 + x1w2)
HYPERCOMPLEX MATH
Quaternions are not the only possible four dimensional
supersets of the complex numbers. William Rowan Hamilton, who
discovered quaternions in 1843, considered the alternative
called the hypercomplex number system. Unlike quaternions, the
hypercomplex numbers satisfy the commutative law of
multiplication. The law which fails is the field property that
states that all non-zero elements of a field have a
multiplicative inverse. For a non-zero hypercomplex number h,
the multiplicative inverse 1/h does not always exist.
As with quaternions, we will define multiplication in terms of
the basis vectors 1, i, j, and k, but with subtly different
rules.
Multiplication rules for hypercomplex basis vectors:
ij = k jk = -i ki = -j
ji = k kj = -i ik = -j
ii = jj = -kk = -1
ijk = 1
Note that now ij = k and ji = k, and similarly for other
products of pairs of basis vectors, so the commutative law
holds.
Hypercomplex multiplication formula:
Let h1 = x1 + y1i + z1j + w1k and h2 = x2 + y2i + z2j + w2k.
Then h1h2 = 1(x1x2 - y1y2 - z1z2 + w1w2) +
i(y1x2 + x1y2 - w1z2 - z1w2) +
j(z1x2 - w1y2 + x1z2 - y1w2) +
k(w1x2 + z1y2 + y1z2 + x1w2)
As an added bonus, we'll give you the formula for the
reciprocal.
Let det = [((x-w)^2+(y+z)^2)((x+w)^2+(y-z)^2)]
Then 1/h = 1[ x(x^2+y^2+z^2+w^2)-2w(xw-yz)]/det +
i[-y(x^2+y^2+z^2+w^2)-2z(xw-yz)]/det +
j[-z(x^2+y^2+z^2+w^2)-2y(xw-yz)]/det +
k[ w(x^2+y^2+z^2+w^2)-2x(xw-yz)]/det
A look at this formula shows the difficulty with hypercomplex
numbers. In order to calculate 1/h, you have to divide by the
quantity det = [((x-w)^2+(y+z)^2)((x+w)^2+(y-z)^2)]. So when
this quantity is zero, the multiplicative inverse will not
exist.
Hypercomplex numbers numbers have an elegant generalization of
any unary complex valued function defined on the complex
numbers. First, note that hypercomplex numbers can be
represented as a pair of complex numbers in the following way.
Let h = x + yi + zj + wk.
a = (x-w) + i(y+z)
b = (x+w) + i(y-z)
The numbers a and b are complex numbers. We can represent h as
the pair of complex numbers (a,b). Conversely, if we have a
hypercomplex number given to us in the form (a,b), we can solve
for x, y, z, and w. The solution to
c = (x-w) + i(y+z)
d = (x+w) + i(y-z)
is
x = (real(c) + real(d))/2
y = (imag(c) + imag(d))/2
z = (imag(c) - imag(d))/2
w = (real(d) - real(c))/2
We can now, for example, compute sin(h). First compute the two
complex numbers a and b as above, then set c = sin(a) and d =
sin(b) where sin() is the complex version of the sin function.
Now use the equations above to solve for x, y, z, and w in
terms of c and d. The hypercomplex number (x,y,z,w) thus
obtained is sin(h).
The beauty of this is that it really doesn't make any
difference what function we use. Instead of sin, we could have
used cos, sinh, ln, or z^2. Using this technique, Fractint can
create 3-D fractals using the formula h' = fn(h) + c, where
"fn" is any of the built-in functions. Where fn is sqr(), this
is the famous mandelbrot formula, generalized to four
dimensions.
For more information, see _Fractal Creations, Second Edition_
by Tim Wegner and Bert Tyler, Waite Group Press, 1993.
_________________________________________________________________
Back to The Fractint Home Page. or back to The Fractint Index Page.
_________________________________________________________________
This page maintained by
Noel Giffin,
noel@triumf.ca