2009-09-12 59 views
2

我有这个复杂的迭代程序我在TI基本写信给在复数执行基本的迭代,然后给结果的大小:复杂的迭代

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 

我想这样做是做一个哈斯克尔版本,让我的老师在任务中。我仍然只是在学习,走到这一步:

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看看它是否完成。

我该怎么办?

回答

4

Newacct的回答显示方式:

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

Iterate产生重复应用的无限名单。 例如:

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

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

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) 

由于复杂的是默认的,并串转换,你可以使用readLn从控制台读取它们(格式为Re :+ Im)。

编辑:只是为了好玩,人们可以desugar的单子语法和类型签名这将整个PROGRAMM压缩到这一点:

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的集合的几个环节。

+0

谢谢,如果结果出现在mandlebrot集(当幅度<2)时,有没有什么办法可以用一些疯狂的颜色来绘制这个图? – 2009-09-12 13:11:46

+0

编辑我的文章 - 一些非常有趣的链接;-) – Dario 2009-09-12 13:37:33

+0

我正在编译所有这些和分形绘图仪,并发送我的老师一个可执行文件。 – 2009-09-12 14:43:31

3

那么你总是可以生成一个无限重复应用程序的结果列表,并采取take他们的第一个n。而iterate函数对于生成重复应用程序的无限列表结果非常有用。

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新手自己。

编辑:只是踢,一个foldr相似的一行:

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

(虽然,在(取n(重复c))的东西似乎有点多余,必须有一个更好的方法)

+0

我认为这是更好地使用'foldl'',而不是'foldr'像'fractalFold CN =与foldl”(\ ZC - > Z 2 2 + c)c(取n(重复c))'。因为'foldr'是懒惰的。这意味着它会根据给定列表的长度创建thunk,但返回类型“fractalFold”不需要懒惰。 – nonowarn 2010-01-29 03:46:53