Fractals/Iterations in the complex plane/q-iterations
Introduction
Iteration in mathematics refer to the process of iterating a function i.e. applying a function repeatedly, using the output from one iteration as the input to the next.[1] Iteration of apparently simple functions can produce complex behaviours and difficult problems.
One can make inverse ( backward iteration) :
- of repeller for drawing Julia set ( IIM/J)[2]
- of circle outside Jlia set (radius=ER) for drawing level curves of escape time ( which tend to Julia set)[3]
- of circle inside Julia set (radius=AR) for drawing level curves of attract time ( which tend to Julia set)
- of critical orbit ( in Siegel disc case) for drawing Julia set ( probably only in case of Goldem Mean )
- for drawing external ray
Repellor for forward iteration is attractor for backward iteration
Iteration
Test
One can iterate ad infinitum. Test tells when one can stop
- bailout test for forward iteration
Target set or trap
Target set is used in test. When zn is inside target set then one can stop the iterations.
Planes
Dynamic plane
for c=0
Lets take c=0, then one can call dynamical plane
plane.
Here dynamical plane can be divided into :
- Fatou set
- Julia set =

Fatou set consist from 2 subsets :
- interior of Julia set = basin of attraction of finite attractor =

- exterior of Julia set = basin of attraction of infinity =

Forward iteration

where 
so

and forward iteration :[4]

Forward iteration gives forward orbit = list of points {z0, z1, z2, z3... , zn} which lays on exponential spirals.[5][6]
Escape test
If distance between point z of exterior of Julia set and Julia set is :
then point escapes ( measured using bailout test and escape time )
after :
steps in non-parabolic case
steps in parabolic case [7]
See here for the precision needed for escape test
Backward iteration
Every angle α ∈ R/Z measured in turns has :
- one image = 2α mod 1 under doubling map
- "two preimages under the doubling map: α/2 and (α + 1)/2." [8]. Inverse of doubling map is multivalued function.
Note that difference between these 2 preimages
is half a turn = 180 degrees = Pi radians.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
On complex dynamical plane backward iteration using quadratic polynomial 
gives backward orbit = binary tree of preimages :



One can't choose good path in such tree without extra informations.
Not that preimages show rotational symmetry ( 180 degrees)
Dynamic plane for 
Level curves of escape time
Julia set by IIM/J
In escape time one computes forward iteration of point z.
In IIM/J one computes:
- repelling fixed point[9] of complex quadratic polynomial

- preimages of
by inverse iterations

Because square root is multivalued function then each
has two preimages
. Thus inverse iteration creates binary tree.
Root of tree
- repelling fixed point[10] of complex quadratic polynomial

- - beta
- other repelling periodic points ( cut points of filled Julia set ). It will be important especially in case of the parabolic Julia set.
"... preimages of the repelling fixed point beta. These form a tree like
beta
beta -beta
beta -beta x y
So every point is computed at last twice when you start the tree with beta. If you start with -beta, you will get the same points with half the number of computations.
Something similar applies to the preimages of the critical orbit. If z is in the critical orbit, one of its two preimages will be there as well, so you should draw -z and the tree of its preimages to avoid getting the same points twice." (Wolf Jung )
Variants of IIM
- random choose one of two roots IIM ( up to chosen level max). Random walk through the tree. Simplest to code and fast, but inefficient. Start from it.
- both roots with the same probability
- more often one then other root
- draw all roots ( up to chosen level max)[11]
- using recurrence
- using stack ( faster ?)
- draw some rare paths in binary tree = MIIM. This is modification of drawing all roots. Stop using some rare paths.
Examples of code :
| Maxima CAS source code - simple IIM . Click on the right to view |
|---|
| It is only one function for all code see here |
finverseplus(z,c):=sqrt(z-c);
finverseminus(z,c):=-sqrt(z-c);
c:%i; /* define c value */
iMax:5000; /* maximal number of reversed iterations */
fixed:float(rectform(solve([z*z+c=z],[z]))); /* compute fixed points of f(z,c) : z=f(z,c) */
if (abs(2*rhs(fixed[1]))<1) /* Find which is repelling */
then block(beta:rhs(fixed[1]),alfa:rhs(fixed[2]))
else block(alfa:rhs(fixed[1]),beta:rhs(fixed[2]));
z:beta; /* choose repeller as a starting point */
/* make 2 list of points and copy beta to lists */
xx:makelist (realpart(beta), i, 1, 1); /* list of re(z) */
yy:makelist (imagpart(beta), i, 1, 1); /* list of im(z) */
for i:1 thru iMax step 1 do /* reversed iteration of beta */
block
(if random(1.0)>0.5 /* random choose of one of two roots */
then z:finverseplus(z,c)
else z:finverseminus(z,c),
xx:cons(realpart(z),xx), /* save values to draw it later */
yy:cons(imagpart(z),yy)
);
plot2d([discrete,xx,yy],[style,[points,1,0,1]]); /* draw reversed orbit of beta */
|
Compare it with:
| Maxima CAS source code - MIIM using hit table . Click on the right to view |
|---|
| It is only one function for all code see here |
/* Maxima CAS code */
/* Gives points of backward orbit of z=repellor */
GiveBackwardOrbit(c,repellor,zxMin,zxMax,zyMin,zyMax,iXmax,iYmax):=
block(
hit_limit:4, /* proportional to number of details and time of drawing */
PixelWidth:(zxMax-zxMin)/iXmax,
PixelHeight:(zyMax-zyMin)/iYmax,
/* 2D array of hits pixels . Hit > 0 means that point was in orbit */
array(Hits,fixnum,iXmax,iYmax), /* no hits for beginning */
/* choose repeller z=repellor as a starting point */
stack:[repellor], /*save repellor in stack */
/* save first point to list of pixels */
x_y:[repellor],
/* reversed iteration of repellor */
loop,
/* pop = take one point from the stack */
z:last(stack),
stack:delete(z,stack),
/*inverse iteration - first preimage (root) */
z:finverseplus(z,c),
/* translate from world to screen coordinate */
iX:fix((realpart(z)-zxMin)/PixelWidth),
iY:fix((imagpart(z)-zyMin)/PixelHeight),
hit:Hits[iX,iY],
if hit<hit_limit
then
(
Hits[iX,iY]:hit+1,
stack:endcons(z,stack), /* push = add z at the end of list stack */
if hit=0 then x_y:endcons( z,x_y)
),
/*inverse iteration - second preimage (root) */
z:-z,
/* translate from world to screen coordinate, coversion to integer */
iX:fix((realpart(z)-zxMin)/PixelWidth),
iY:fix((imagpart(z)-zyMin)/PixelHeight),
hit:Hits[iX,iY],
if hit<hit_limit
then
(
Hits[iX,iY]:hit+1,
stack:endcons(z,stack), /* push = add z at the end of list stack to continue iteration */
if hit=0 then x_y:endcons( z,x_y)
),
if is(not emptyp(stack)) then go(loop),
return(x_y) /* list of pixels in the form [z1,z2] */
)$
|
| Octave source code - MIIM using hit table . Click on the right to view |
|---|
| iimm_hit.m: |
# octave m-file # IIM using Hit table # save as a iimm_hit.m in octave working dir # run octave and iimm_hit # # stack-like operation # http://www.gnu.org/software/octave/doc/interpreter/Miscellaneous-Techniques.html#Miscellaneous-Techniques # octave can resize array # a = []; # while (condition) # a(end+1) = value; # "push" operation # a(end) = []; # "pop" operation # # -------------- general octave settings ---------- clear all; more off; pkg load image; # imwrite pkg load miscellaneous; # waitbar # --------------- const and var ----------------------------- # define some global var AT EACH LEVEL where you want to use it ( Pascal CdeMills) # ? for global variables one can't define and give initial value at the same time # integer ( screen ) coordinate iSide = 1000 ixMax = iSide iyMax = iSide # global HitLimit; HitLimit=1 # proportional to number of details and time of drawing global Hits; # 2D array of pixels . Hit > 0 means that point was in orbit Hits = zeros(iyMax,ixMax); # image as a 2D matrix of 24 bit colors coded from 0.0 to 1.0 global MyImage; MyImage = zeros(iyMax,ixMax,3); # matrix filled with 0.0 ( black image)= [rows, columns, color_depth] # world ( float) coordinate - dynamical (Z) plane global dSide; global ZxMin ; global ZxMax; global ZyMin; global ZyMax ; global z; global PixelHeight ; global PixelWidth ; # add values to global variables dSide=1.25 ZxMin = -dSide ZxMax = dSide ZyMin = -dSide ZyMax = dSide PixelHeight = (ZyMax - ZyMin)/(iyMax - 1) PixelWidth = (ZxMax - ZxMin)/(ixMax - 1) # pseudo stack = resizable array global Stack; Stack=[]; global StackIndex; StackIndex=0; c = complex(.27327401, 0.00756218); global Color24White; Color24White=[1.0, 1.0, 1.0]; # ---------------- functions ------------------ function [iY, iX] = f(z) # define some global var AT EACH LEVEL where you want to use it ( Pascal CdeMills) global ZxMin; global ZyMax; global PixelWidth; global PixelHeight; # translate from world to screen coordinate iX=int32((real(z)-ZxMin)/PixelWidth); iY=int32((ZyMax - imag(z))/PixelHeight); # invert y axis endfunction; # plot point with integer coorfinate to array MyImage function Plot( iY, iX , color ) global MyImage; MyImage(iY, iX, 1) = color(1); MyImage(iY, iX, 2) = color(2); MyImage(iY, iX, 3) = color(3); endfunction; # push = put point z on the stack function push(z) global Stack; global StackIndex; StackIndex =size(Stack,2); # update global var StackIndex = StackIndex +1; # update global var Stack(StackIndex) = z; # "push" z on pseudo stack endfunction; # pop = take point z from the stack function z = pop() global Stack; global StackIndex; StackIndex =size(Stack,2); # update global var z = Stack(StackIndex); # pop z from pseudo stack Stack(StackIndex) = []; # make pseudo stack shorter StackIndex = StackIndex -1 ; # update global var endfunction; function CheckPoint(z) # error is here global Hits; global HitLimit; global Color24White; [iY, iX] = f(z); hit = Hits(iY, iX); if (hit < HitLimit) push(z); # (put z on the stack) to continue iteration if (hit<1) Plot( iY, iX , Color24White ); endif; # plot Hits(iY, iX) = hit + 1; # update Hits table endif; endfunction; # CheckPoint # -------------------- main --------------------------------------- # Determine the unstable fixed point beta # http://en.wikipedia.org/wiki/Periodic_points_of_complex_quadratic_mappings beta = 0.5+sqrt(0.25-c) z=-beta CheckPoint(z); while (StackIndex>0) # if stack is not empty z = pop(); # take point z from the stack # compute its 2 preimages z and -z ( inverse function of complex quadratic polynomial) z= sqrt(z-c); # check points : draw, put on the stack to continue iterations CheckPoint(z); CheckPoint(-z); endwhile; # ------------------- image -------------------------------------- imread("a7.png");# first load any existing image to resolve bug : panic crash using imwrite: octave: magick/semaphore.c:525 first load any image image(MyImage); # Display Image name = strcat("iim",int2str(HitLimit), " .png"); imwrite(MyImage,name); # save image to file. this requires the ImageMagick "convert" utility. |
References
- ↑ wikipedia : Iteration
- ↑ Inverse Iteration Algorithms for Julia Sets by Mark McClure
- ↑ Complex iteration by Microcomputadoras
- ↑ Real and imaginary parts of polynomial iterates by Julia A. Barnes, Clinton P. Curry and Lisbeth E. Schaubroeck. New York J. Math. 16 (2010) 749–761.
- ↑ Complex numbers by David E Joyce
- ↑ Powers of complex numbers from Suitcase of Dreams
- ↑ Parabolic Julia Sets are Polynomial Time Computable by Mark Braverman
- ↑ SYMBOLIC DYNAMICS AND SELF-SIMILAR GROUPS by VOLODYMYR NEKRASHEVYCH
- ↑ wikipedia : repelling fixed point
- ↑ wikipedia : repelling fixed point
- ↑ Fractint documentation - Inverse Julias
- ↑ Image and c source code : IIMM using hit limit
- ↑ Exploding the Dark Heart of Chaos by Chris King





steps in non-parabolic case
steps in 





















by inverse iterations