haskell中的复杂迭代

时间:2009-09-12 06:45:17

标签: math haskell functional-programming complex-numbers

我在TI Basic中编写了这个复杂的迭代程序,对复数执行基本迭代,然后给出结果的大小:

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

我想做的是制作一个Haskell版本,让我的老师在作业中惊叹。我仍然只是学习并且走得很远:

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

我不知道怎么做是如何让它只迭代n次,所以我想让它计算a,然后将它与n进行比较看看它是否已经完成。

我该怎么做?

3 个答案:

答案 0 :(得分:4)

Newacct的回答显示了方式:

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

Iterate生成重复应用程序的无限列表。 例如:

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

关于IO,你必须做一些monadic计算。

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)

由于Complex默认情况下可以从字符串转换为字符串,因此您可以使用readLn从控制台读取它们(格式为Re :+ Im)。

编辑:只是为了好玩,人们可以去掉monadic语法和类型签名,这会将整个程序压缩到这个:

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)

编辑#2:一些与绘图和Mandelbrot集相关的链接。

答案 1 :(得分:3)

您可以随时生成重复应用程序的无限结果列表,并使用n获取它们的第一个takeiterate函数对于生成重复应用程序的无限结果列表非常有用。

答案 2 :(得分:2)

如果您想要一个值列表:

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

如果你只关心最后的结果:

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

基本上,在这两种情况下,您都需要辅助函数来计算和累积。现在我确定有一个更好/更简洁的方法来做到这一点,但我自己就是一个Haskell新手。

编辑:只是为了踢,一个折叠单行:

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

(虽然(拿n(重复c))事情似乎没什么必要,但必须有更好的方法)