# Julia Sets

Caleb Sturges

``````

In [1]:

class JuliaSet:
def __init__(self, c, n=100):
self.c = c
self.n = n
self._d=.001
self._complexplane = []
for i in (0, 4/self._d):
for k in (0, 4/self._d):
self._complexplane.append(complex(-2+i*self._d,-2j+k*self._d))

def juliamap(self, z):
return self.c+z**2

def iterate(self, z):
m = 1
runningz = z
while True:
juliamap(self, z)
if abs(runningz)>2:
return m
elif m>=n:
return 0
else:
m+=1

def set_spacing(self, _d):
self._d = _d
self._complexplane = []
for i in frange(-2, 2, self._d):
for j in frange(-2, 2, self._d):
self._complexplane.append(complex(i, j))
return self._complexplane

def generate(self):
self._d
self.set=[]
for i in frange(-2, 2, self._d):
for j in frange(-2, 2, self._d):
self.set.append(complex(i,j))
return self.set

def frange(start, stop, step):
i = start
while i < stop:
yield i
i += step

myJuliaSet=JuliaSet(0, 100)

``````
``````

In [ ]:

``````
``````

In [2]:

from random import uniform, randint
from math import sqrt
from nose import with_setup

###
# Test Suite for specified JuliaSet interface
#
# Run with the command: "nosetests juliatests.py"
###

# Custom random numbers

def rand_range():
"""Return a random complex number bounded by real and imaginary axes [-2, 2]"""
return (uniform(-2,2) + uniform(-2,2)*1j)

def rand_circle():
"""Return a random complex number within the unit circle"""
r = uniform(-1,1)
dr = sqrt(1 - r**2)
i = uniform(-dr, dr)
return (r + i*1j)

# Test classes for several cases

class TestRandomC:
"""Define a julia set with a random c seed value, test interface"""

def setup(self):
"""Setup fixture is run before every test method separately"""
self.c = rand_range()
self.n = randint(2,100)
self.j = JuliaSet(self.c, self.n)

def test_c_value(self):
"""Test that c is an attribute"""
assert self.j.c == self.c

def test_n_value(self):
"""Test that n is an attribute"""
assert self.j.n == self.n

def test_juliamap(self):
"""Test that juliamap is implemented properly"""
z = rand_range()
print "z = ", z
print "z**2 = ", z**2
zcorrect = z**2 + self.c
print "z**2 + c = ", zcorrect
znew = self.j.juliamap(z)
print "juliamap(z) = ", znew
assert znew == zcorrect

def test_set_spacing(self):
"""Test that changing spacing works"""
print "Test original spacing _d = 0.001"
assert self.j._d == 0.001
print "Test new spacing of _d = 0.1"
self.j.set_spacing(0.1)
print "_d = ", self.j._d
assert self.j._d == 0.1
print "Test that complex plane is regenerated"
print "len(_complexplane) = ", len(self.j._complexplane)
print "int(4.0 / 0.1)**2 = ", int(4.0 / 0.1)**2
assert len(self.j._complexplane) == int(4.0 / 0.1)**2

def test_generate(self):
"""Test that generating the julia set works"""
self.j.set_spacing(0.1)
self.j.generate()
print "Test that j.set exists, and is of the same length as j._complexplane"
assert (len(self.j.set) == len(self.j._complexplane))

class TestTrivial:
"""Test that a seed value of c=0 leaves the unit circle invariant"""

@classmethod
def setup_class(cls):
cls.j = JuliaSet(0)

def test_trivial_seed(self):
def check_z(z):
"""Test all z inside unit circle return 0"""
m = TestTrivial.j.iterate(z)
print "m = ", m
assert m == 0
# A generator like this runs a test for every yield
for _ in xrange(100):
z = rand_circle()
yield check_z, z

class TestHuge:
"""Test that a huge seed always causes a divergence after 1 iteration"""

@classmethod
def setup_class(cls):
cls.j = JuliaSet(16)

def test_huge_seed(self):
def check_z(z):
"""Test all z escape after 1 iteration"""
print "z = ", z
print "z**2 = ", z**2
print "z**2 + c = ", z**2 + 16
print "juliamap(z) = ", TestHuge.j.juliamap(z)
assert TestHuge.j.iterate(z) == 1
# Again, a generator runs a test for every yield
for _ in xrange(100):
z = rand_range()
yield check_z, z

testRandC = TestRandomC()

``````
``````

In [3]:

testRandC.setup()
testRandC.test_juliamap()

testRandC.test_c_value()
testRandC.test_set_spacing()
testRandC.test_generate()

``````
``````

z =  (0.862442194936-0.853580381244j)
z**2 =  (0.0152070723625-1.47232747511j)
z**2 + c =  (0.512187307836-2.78400069935j)
juliamap(z) =  (0.512187307836-2.78400069935j)
Test original spacing _d = 0.001
Test new spacing of _d = 0.1
_d =  0.1
Test that complex plane is regenerated
len(_complexplane) =  1600
int(4.0 / 0.1)**2 =  1600
Test that j.set exists, and is of the same length as j._complexplane

``````
``````

In [ ]:

``````
``````

In [7]:

testTriv = TestTrivial()
testHuge = TestHuge()

``````
``````

In [5]:

testTriv.setup_class()
testTriv.test_trivial_seed()

``````
``````

Out[5]:

<generator object test_trivial_seed at 0x7fd03d5c8a00>

``````
``````

In [6]:

testHuge.setup_class()
testHuge.test_huge_seed()

``````
``````

Out[6]:

<generator object test_huge_seed at 0x7fd0440f43c0>

``````
``````

In [ ]:

``````
``````

In [ ]:

``````