Python Forum
Mandelbrot set in Python
Thread Rating:
  • 1 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Mandelbrot set in Python
#1
0


I have a problem. I'm doing a task for my lessons and I'm doing my best, but the teacher does not seem to care and I need to look for the problem myself facing his demands.

To begin with, I had to translate that task from my native language to english. So because of that there may be some misunderstandings as it was hard to explain it from mathematical point of view.

"There is a Mandelbrot set which is created by points defined on surface by complex numbers so as following recurrence equation does not go to infinity:

{ z0 = 0 // zn+1 = zn^2 + c

You have to make two-dimensional array T with a size of 600x600. Each element from that array T[k][l] will represent a complex number ckl = (−2 + k * 0.005, (−1.5 + l * 0.005)ˆi). Next for each of element from T[k][l] calculate first n_max = 100 numbers from series and save that value as n, for |zn| > 2."

Yea that was painful. I googled a lot about that but I could not use all other Python scripts to solve that task. I ended up using this: LINK, and made this:


import matplotlib.pyplot as plt


k = 600
l = 600

T = [0][0]


for i in range(k):
    for j in range(k):
        z = 0 + 0j
        c = complex(-2 + i * 0.005, -1.5 + j * 0.005)
        for g in range(100):
            z = z * z + c
            if abs(z) > 2.0:
                T = i
                break


plt.figure(dpi=200)
plt.imshow(T, cmap="hot")
plt.show()
And it is really bad, I really don't understand this. Plus I get an error: TypeError: Invalid shape () for image data. I found another solution couple of weeks ago, sent it but it has to be done the way described in script. Please help.. thanks for your time in advance. If you need any other screenshots of the task, I'll provide it.
Reply
#2
UP.UP.
Reply
#3
I have no idea how to go about completing this assignment (the math just makes my brain hurt); but in terms of your code, are you sure your variables are getting the values you think they are getting? Forgive my ignorance if I'm way off base here, but I tried a couple of simple tests to see what your code is doing...

For example, I tried entering your T assignment statement in IDLE:
T = [0][0]
This appears to just create T as a variable of type 'int' with a value of 0. I'm guessing T is meant to be something more than that, right?


Also, I tried running this loop:
for j in range(100):
    z = 0 + 0j
    print(z)
Regardless of the value of j, the value of z is always just 0j. Is that what's intended?
Reply
#4
From line 7 it appears you want T to be a 2 dimensional array. In line 17 you reassign the variable T to an integer. From that point forward, T is an integer, not an array.

Answering in spite of the fact that bumping is not good form.
Reply
#5
You want T to be a 2D array.
k = 600
l = 600
T = [[0]*l for i in range(k)]
When saving results for plotting you may want to do this:
if abs(z) > 2.0:
    T[i][j] = abs(z)
Bumping is self defeating. I tend to focus on posts that have zero reply's. I don't think the forum has a tool for collecting all posts with 1 reply.
Reply
#6
I was kinda in rush, that's why I bumped, sorry for that.

import matplotlib.pyplot as plt


def funkcja(c=0j, z=0 + 0j, n_max=100):
    for i in range(n_max):
        z = z * z + c
        if abs(z) > 2.0:
            T[i][j] = abs(z)
        break

k = 600
l = 600

T = [[0]*l for i in range(k)]

for i in range(k):
    for j in range(l):
        T = [(complex(-2 + i * 0.005, -1.5 + j * 0.005))]



plt.imshow(T, cmap="bone")
plt.show()
Came up before with this, still, don't really know how to excecute the numbers I need for final product. I get an error: TypeError: Image data of dtype complex128 cannot be converted to float. What do I need to change?
Reply
#7
This is a mess. Your first pass was actually pretty close to working. If you had just made a couple of changes (initialize the T array, store values in the T array and decide on the correct value you want to plot).

However, you can also solve the problem in this new way, using a function. The function is going to iterate the equation and return the number. Start by giving the function a better name. Perhaps Mandelbrot? We'll pull the code from your first attempt and use it to write the function.
def mandelbrot(x, y):
    z = 0
    c = complex(-2 + x * 0.005, -1.5 + y * 0.005)
    for n in range(100):  # n is the iteration counter
        z = z * z + c
        if abs(z) > 2:
            break
    return # Hmmmm.  What do I want to return here?
What are the arguments x and y? They are the coordinates of the point. x and y have long been used to reference the two dimensions of a plot. Using common conventions works better than using variable names like i and j. I has no meaning, and j can be lead to confusion when working with complex numbers.

If the Mandelbrot function is written correctly, all you have to do is call it 360,000 times, once for each point in T.
wide = 600    # wide has meaning, k did not provide any hints about what it did
high = 600    # l is the worst variable name of all.  It is easily confused with 1
T = [[0]*wide for _ in range(high)]  # wide and high,  T must be a rectangle

for y in range(high):  # y is commonly associated with the vertical axis
    for x in range(wide):  # x is commonly associated with the horizontal axis
        T[x][y] = mandelbrot(x, y) # T[x][y] is set to the Mandelbrot value for (x, y)

plt.imshow(T, cmap="rainbow")
plt.show()
Just one thing left to do, decide what value you want the Mandelbrot function to return. From your initial post:

" Next for each of element from T[k][l] calculate first n_max = 100 numbers from series and save that value as n, for |zn| > 2"

The instructions want you to plot the value for n where n is the iteration when the equation value exceeds the threshold (2). N starts at zero and as a maximum value of 100. The matplotlib imshow documentation says the values are normalized. That means the range for n is not important. The imshow function will rescale the values in T to use the full range of colors.
Reply
#8
(May-22-2020, 12:13 PM)deanhystad Wrote: This is a mess. Your first pass was actually pretty close to working. If you had just made a couple of changes (initialize the T array, store values in the T array and decide on the correct value you want to plot).

However, you can also solve the problem in this new way, using a function. The function is going to iterate the equation and return the number. Start by giving the function a better name. Perhaps Mandelbrot? We'll pull the code from your first attempt and use it to write the function.
def mandelbrot(x, y):
    z = 0
    c = complex(-2 + x * 0.005, -1.5 + y * 0.005)
    for n in range(100):  # n is the iteration counter
        z = z * z + c
        if abs(z) > 2:
            break
    return # Hmmmm.  What do I want to return here?
What are the arguments x and y? They are the coordinates of the point. x and y have long been used to reference the two dimensions of a plot. Using common conventions works better than using variable names like i and j. I has no meaning, and j can be lead to confusion when working with complex numbers.

If the Mandelbrot function is written correctly, all you have to do is call it 360,000 times, once for each point in T.
wide = 600    # wide has meaning, k did not provide any hints about what it did
high = 600    # l is the worst variable name of all.  It is easily confused with 1
T = [[0]*wide for _ in range(high)]  # wide and high,  T must be a rectangle

for y in range(high):  # y is commonly associated with the vertical axis
    for x in range(wide):  # x is commonly associated with the horizontal axis
        T[x][y] = mandelbrot(x, y) # T[x][y] is set to the Mandelbrot value for (x, y)

plt.imshow(T, cmap="rainbow")
plt.show()
Just one thing left to do, decide what value you want the Mandelbrot function to return. From your initial post:

" Next for each of element from T[k][l] calculate first n_max = 100 numbers from series and save that value as n, for |zn| > 2"

The instructions want you to plot the value for n where n is the iteration when the equation value exceeds the threshold (2). N starts at zero and as a maximum value of 100. The matplotlib imshow documentation says the values are normalized. That means the range for n is not important. The imshow function will rescale the values in T to use the full range of colors.


I ended up with this:

import matplotlib.pyplot as plt


def mandelbrot(k, l, n_max=100):
    z = 0
    c = complex(-2 + k * 0.005, -1.5 + l * 0.005)
    for i in range(n_max):
        z = z * z + c
        if abs(z) > 2:
            break
    return i


wide = 600
high = 600
T = [[0] * wide for i in range(high)]

for k in range(high):
    for l in range(wide):
        T[l][k] = mandelbrot(k, l)

plt.imshow(T, cmap="bone", extent=[-2, 1, -1.5, 1.5])
plt.show()
I know I changed some of the arguments for l and k, and I know it's unclear but sometimes they want them to be just as stupid as they are.

I just had a struggle, I had a solution for it once but I forgot. When I leave:

T[l][k] = mandelbrot(k, l)
Mandelbrot is facing upwards, and I forgot how to rotate the plot. So I changeg arguments. For now this seems to work, thanks for help. It's black magic to me..
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020