2014-01-30 65 views
2

如何寫泰勒級數遞歸數據像這樣的:泰勒級數在Haskell

fib = 0 : scanl (+) 1 fib 

例如,我想PROMT是這樣的:

fac n = product[1..n] 
sin' x = x : x^3/fac(3) : x^5/fac(5) : ... 
sum $ take 10 (sin' (pi/6)) 

,並獲得10個第一要素總和正弦泰勒系列。

+1

泰勒級數對每個x^n都有一個係數。你能寫一個函數從n到相應的係數x^n嗎? –

+0

你說得對,我忘記了系列元素的標誌。係數的函數爲: (-1)^(n-1) 因此,系列每個元素的正弦函數爲: (-1)^(n-1)* x^n/n !,其中n = [1..infinity] – mustafa1453

+0

我已經提出這樣的代碼: http://pastebin.com/7MAxFqNy 但是目前有錯誤。我怎麼能運行這個代碼? – mustafa1453

回答

8

這不完全是罪惡的泰勒系列!但這裏有一個線索......

products = scanl (*) 1 [1..] 
powers x = map (x^) [0..] 
exp' x = zipWith (/) (powers x) products 

*Main> sum (take 10 (exp' 1)) 
2.7182815255731922 
+1

掃描和zipWith的使用在這裏特別令人滿意。這是非常地道的。 –

+2

'powers x'的更有效的實現將是'iterate(x *)1'。 –

+0

@LouisWasserman更好,不需要'products':'exp'x = scanl(*)1 $ map(x /)[1 ..]'(或者通過向scanl傳遞一個不同的函數來消除'map') –

3

一種常見的方法是使用一個列表來表示冪級數的只是係數和另寫函數在某一特定值,以評估冪級數。

例如,冪級數1 /(1-x)^ 2 = 1 + 2x + 3x^2 + ...將由列表[1,2,3,...]表示。

爲了評價它,我們需要一個函數:

eval :: [Float] -> Float -> Float 

基礎案例是容易的:

eval [] x = 0 

感應情況下,可以遞歸地定義爲:

eval (a:as) x = a + x*... -- left as an exercise 

當然,這個eval不會在無限列表上終止,所以你必須確保只給它一個f inite列表:

sin' = [ 1, 0, - 1/fac 3, 0, 1/fac 5, 0, ... ] 
eval (take 10 sin') (pi/6) 

現在你只需要生成係數sin'。請注意,在這種情況下,10指的是您想要求和的最高功率x,而不是總和中的非零項數。

+1

您還可以用代表多項式加法和乘法的方式將'Num a => [a]'定義爲'Num'類型的一個實例,以便您可以添加和乘以泰勒級數,如'sin'和'cos' '(同樣具有有限的精度)。 – Emil