Computer Science Canada

Mandelbrot Set Help

Author:  DivideByZero [ Fri Oct 30, 2009 9:47 am ]
Post subject:  Mandelbrot Set Help

What is the problem you are having?
I need to increase the speed of this program and I have no idea how....


Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)

Turing:


%ByDividedByZero

type TComplexNumber :
    record
        a, b : real
    end record
setscreen("graphics:320;240")
procedure setZ (var z : TComplexNumber, a, b : real)
    z.a := a
    z.b := b
end setZ
function addZ (z1, z2 : TComplexNumber) : TComplexNumber
    var z3 : TComplexNumber % Stores the answer
    z3.a := z1.a + z2.a
    z3.b := z1.b + z2.b
    result z3
end addZ
function squareZ (z1 : TComplexNumber) : TComplexNumber
    var z3 : TComplexNumber % Stores the answer
    z3.a := (z1.a * z1.a) - (z1.b * z1.b)
    z3.b := 2 * z1.a * z1.b
    result z3
end squareZ
function magnitudeZ (z1 : TComplexNumber) : real
    var realZ : real % Stores the answer
    realZ := sqrt ((z1.a * z1.a) + (z1.b * z1.b))
    result realZ
end magnitudeZ
var c, z1, z2, z3 : TComplexNumber
var realZ : real
var counter, x, y : int
x := 0
y := 0
c.a := -2
c.b := -1.5
setZ (c, -2, -1.5)
loop
    z1.a := 0
    z1.b := 0   
    counter := 0   
    loop   
        counter := counter + 1       
        z1 := addZ (squareZ (z1), (c))       
        exit when (magnitudeZ (z1) > 2) or (counter > 255)       
    end loop   
    if counter <= 255 then   
        drawdot (x, y, counter)       
    else   
        drawdot (x, y, black)       
    end if   
    x += 1   
    c.a += 1 / (maxx / 4)   
    if x > maxx then   
        x := 0       
        y += 1     
        c.b += 1 / (maxy / 4)
        c.a := -2       
    end if
    exit when y = maxy
end loop
put Time.Elapsed





Please specify what version of Turing you are using
Version 4.1

Author:  apomb [ Fri Oct 30, 2009 10:12 am ]
Post subject:  RE:Mandelbrot Set Help

write it in another language Wink

Author:  DivideByZero [ Fri Oct 30, 2009 11:08 am ]
Post subject:  Re: RE:Mandelbrot Set Help

apomb @ Fri Oct 30, 2009 10:12 am wrote:
write it in another language Wink


Has to be turing (its for a class)

Author:  apomb [ Fri Oct 30, 2009 11:26 am ]
Post subject:  RE:Mandelbrot Set Help

well, is the assignment to see how efficient you can make it? because if so, it looks like you have it down, the speed is a language-centric problem; Turing just isnt good at doing things like this. but congratulations on making something like this in turing, it is still impressive, no matter how slow it runs.

Author:  DivideByZero [ Fri Oct 30, 2009 1:23 pm ]
Post subject:  RE:Mandelbrot Set Help

Turing:

%ByDividedByZero
type TComplexNumber :
    record
        a, b : real
    end record
setscreen ("graphics:400;300")
%setscreen ("offscreenonly")
procedure setZ (var z : TComplexNumber, a, b : real)
    z.a := a
    z.b := b
end setZ
function addZ (z1, z2 : TComplexNumber) : TComplexNumber
    var z3 : TComplexNumber % Stores the answer
    z3.a := z1.a + z2.a
    z3.b := z1.b + z2.b
    result z3
end addZ
function squareZ (z1 : TComplexNumber) : TComplexNumber
    var z3 : TComplexNumber % Stores the answer
    z3.a := (z1.a * z1.a) - (z1.b * z1.b)
    z3.b := 2 * z1.a * z1.b
    result z3
end squareZ
function magnitudeZ (z1 : TComplexNumber) : real
    var realZ : real % Stores the answer
    realZ := sqrt ((z1.a * z1.a) + (z1.b * z1.b))
    result realZ
end magnitudeZ
var c, z1, z2, z3 : TComplexNumber
var realZ : real
var counter, x, y : int
x := 0
y := 0
c.a := -2
c.b := -1.5
setZ (c, -2, -1.5)
var k : int := 45
loop
    z1.a := 0
    z1.b := 0
    counter := 0
    loop
        counter := counter + 1
        z1 := addZ (squareZ (z1), (c))
        exit when (magnitudeZ (z1) > 2) or (counter > 255)

    end loop
    if counter <= 255 then
        if counter > 31 or counter < 72 then
            counter := counter + k
        end if
        if counter > 255 then
            counter := k
        end if
        drawdot (x, y, counter)
    else
        drawdot (x, y, black)
    end if
    x += 1
    c.a += 1 / (maxx / 4)
    if x > maxx then
        x := 0
        y += 1
        c.b += 1 / (maxy / 4)
        c.a := -2
    end if
    exit when y = maxy
end loop


Changed some colours to make it look nicer (havent improved speed at all)

Author:  Tony [ Fri Oct 30, 2009 2:04 pm ]
Post subject:  RE:Mandelbrot Set Help

I'm pretty sure that
code:

if counter <= 255 then
        if counter > 31 or counter < 72 then
            counter := counter + k
        end if
        if counter > 255 then
            counter := k
        end if
        drawdot (x, y, counter)
    else
        drawdot (x, y, black)
    end if

is equivalent to
code:

if counter <= 255 then
        drawdot (x, y, counter + k)
else
        drawdot (x, y, black)
end if


You could also set the value of "1 / (maxx / 4) " to a constant, and save yourself 2 divisions per pixel.

But those are minor effects. Your Big-O computation is in
code:

loop
        counter := counter + 1
        z1 := addZ (squareZ (z1), (c))
        exit when (magnitudeZ (z1) > 2) or (counter > 255)

    end loop


If you can skip the entire loop and get the counter value directly from the value of c, then you run much faster.

Hint: a pixel next to black (255+) has a high probability of also being black. See if you can reuse any of the results you've already computed.

Author:  DemonWasp [ Fri Oct 30, 2009 4:52 pm ]
Post subject:  RE:Mandelbrot Set Help

Tony: They aren't the same. His will increment counter by k if counter > 255, whereas yours will not. This isn't important in this case since he resets it to 0 at the end of the loop and never accesses the incremented value.

Author:  Tony [ Fri Oct 30, 2009 10:04 pm ]
Post subject:  RE:Mandelbrot Set Help

DemonWasp: but > 255 is inside the "if counter <= 255" statement, thus it will never be true.

Author:  Zren [ Sat Oct 31, 2009 6:04 pm ]
Post subject:  RE:Mandelbrot Set Help

Basic Mathematics

c.b += 1 / (maxy / 4)
c.b += 4 / maxy

You also have a few lines that don't change the variable.

Author:  DemonWasp [ Mon Nov 02, 2009 1:18 am ]
Post subject:  RE:Mandelbrot Set Help

Tony: Sorry, I mis-typed. I meant it will increment counter by k if counter <= 255 (since counter > 31 or counter < 72 is always true). Correct replacement code would be:

code:

if counter <= 255 then
    counter := counter + k
    drawdot (x, y, counter)
else
    drawdot (x, y, black)
end if

Author:  Tony [ Mon Nov 02, 2009 1:39 am ]
Post subject:  RE:Mandelbrot Set Help

Oh, I see what you mean. You're right; and also about the fact that it's not necessary to keep the new value since it's reset.


: