Complex iteration in haskell

I have this complex iteration program I wrote in TI Basic to do basic iteration on a complex number and then give the magnitude of the result:

INPUT "SEED?", C
INPUT "ITERATIONS?", N
Cā†’Z
For (I,1,N)
Z^2 + C ā†’ Z
DISP Z
DISP "MAGNITUDE", sqrt ((real(Z)^2 + imag(Z)^2))
PAUSE
END

      

What I would like to do is make a version of Haskell in order to fire my teacher on the assignment. I am still just learning and got to this:

fractal ::(RealFloat a) =>
          (Complex a) -> (Integer a) -> [Complex a]
fractal c n | n == a = z : fractal (z^2 + c)
   | otherwise = error "Finished"

      

What I dont know how to do is to do it only repetition n

times, so I wanted it to count a

and then compare it with n

to see if it ended.

How can i do this?

+2


source to share


3 answers


Newacct's answer shows a way:

fractal c n = take n $ iterate (\z -> z^2 + c) c

      

Iterate

generates an endless list of duplicate applications. Example:

iterate (2*) 1 == [1, 2, 4, 8, 16, 32, ...]

      

As far as IO goes, you will need to do some monadic computation.

import Data.Complex
import Control.Monad

fractal c n = take n $ iterate (\z -> z^2 + c) c

main :: IO ()
main = do
    -- Print and read (you could even omit the type signatures here)
    putStr "Seed: "
    c <- readLn :: IO (Complex Double)

    putStr "Number of iterations: "
    n <- readLn :: IO Int

    -- Working with each element the result list
    forM_ (fractal c n) $ \current -> do
        putStrLn $ show current
        putStrLn $ "Magnitude: " ++ (show $ magnitude current)

      



Since Complex is converted to and from strings by default, you can use readLn

(format Re :+ Im

) to read them from the console .

Editing: just for fun, we can drop the monadic syntax and tick signatures that would compress the entire program before:

main = 
    (putStr "Seed: ") >> readLn >>= \c -> 
    (putStr "Number of iterations: ") >> readLn >>= \n -> 
    forM_ (take n $ iterate (\z -> z^2 + c) c) $ \current ->
    putStrLn $ show current ++ "\nMagnitude: " ++ (show $ magnitude current)

      

Edit # 2: Some links related to construction and Mandelbrot sets.

+4


source


Ok, you can always generate an endless list of reapplication results and use the first n

one using take

. And the function iterate

is useful for creating an endless list of repeated application results.



+3


source


If you want a list of values:

fractalList c n = fractalListHelper c c n
                  where 
                     fractalListHelper z c 0 = []
                     fractalListHelper z c n = z : fractalListHelper (z^2 + c) c (n-1)

      

If you only care about the last result:

fractal c n = fractalHelper c c n
                  where
                    fractalHelper z c 0 = z
                    fractalHelper z c n = fractalHelper (z^2 + c) c (n-1)

      

Basically, in both cases, you need a helper function to count and accumulate. Now I'm sure there is a better / less surefire way to do this, but I'm pretty much a Haskell newbie.

Edit: for kicks only, one-line warehouse:

fractalFold c n = foldr (\c z -> z^2 + c) c (take n (repeat c)) 

      

(although, (take n (repeat c)) thing seems unnecessary, there must be an even better way)

+2


source







All Articles