HW Problems

1) Three weeks into your new job you get your first big challenge.  The marketing
guys have written a Python script to generate Mandelbrot images for a new movie.  It
works great, but it takes an hour to generate each image, and they want an entire
movie with thousands of images.  After some testing of the script, it looks like 99%
of the time is in a routine 'getpts' (see below).  Re-write this routine in C. Check to make sure it returns the same sequence of integers as shown in the "doctest".

2) How much faster can you generate the required images?  Use the speedtest()
function in the original script, but substitute your own code for the "inline" code string in the stub function.  To run this script, use the command:
    $ python mandel_weave.py
 


### Python function to compute Mandelbrot images.

def getpts(cx0, cy0, dx):
    '''Given a starting point cx0, cy0 in the complex plane, and an increment dx
for the space between points, for each point, iterate the Mandelbrot generator
z = z**2 + c, and save the number of iterations before the "orbit" of z reaches
"escape altitude" |z| > 2.  This number is an indication of how close c is to
the "Mandelbrot Set".

If the escape condition is not reached by iteration 999, save that
number as an indicator that the iteration is most likely convergent (i.e. the
point c is in the Mandelbrot set).
  z = zx + i*zy     # a point in the complex plane
  c = cx0 + i*cy0   # starting point (z = 0)

Return the iteration counts in an array for the next 100 points to the right of
the starting point.  Doing 100 at a time will minimize the function-call
overhead.

>>> getpts(-.222, 0.8, 0.00001)
[279, 314, 266, 311, 273, 321, 302, 329, 496, 999,\
 482, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 635, 564, 604, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999,\
 999, 999, 999, 999, 999, 999, 999, 999, 999, 999]
    '''
    vals = []
    for p in range(100):     # 100 points
        cx = cx0 + p * dx        #  moving right    x . . . . . .
        zx = zy = 0.0
        for i in range(1000):    # 999 max iteration
            zx2 = zx*zx
            zy2 = zy*zy
            if (zx2 + zy2) > 4.0 : break  # escape
            zy = 2*zx*zy + cy0
            zx = zx2 - zy2 + cx

        vals.append(i)

    return vals


### Notes:
- The docstring (all lines inside triple quotes) has no effect on execution.
- vals = [] is an empty list to start.
- vals.append(i) appends integer i to the list
- range(100) is a function returning a sequence of integers 0, 1, 2, ... 99.
- algorithm:
  z = zx + i*zy
  c = cx + i*cy0
  z**2 = zx*zx - zy*zy + i * 2*zx*zy
  znext = z**2 + c = (zx*zx - zy*zy + cx)  +  i * (2*zx*xy + cy0)