【问题标题】:Taylor series in haskellHaskell中的泰勒级数
【发布时间】:2014-02-23 08:34:41
【问题描述】:

如何编写这样的泰勒级数递归数据:

fib = 0 : scanl (+) 1 fib

例如,我想要这样的提示:

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

得到正弦泰勒级数的前10个元素之和。

【问题讨论】:

  • 泰勒级数对每个 x^n 都有一个系数。你能写一个从n到x^n对应系数的函数吗?
  • 你说得对,我忘了串联元素的符号。系数的函数是:(-1)^(n-1) 因此,序列中每个元素的正弦函数是:(-1)^(n-1) * x^n / n!,其中 n = [1 ..无穷大]
  • 我已经做了这个代码:pastebin.com/7MAxFqNy 但目前有错误。我怎样才能运行这段代码?

标签: math haskell recursion taylor-series


【解决方案1】:

这不完全是泰勒级数!但这里有一个线索......

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

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

【讨论】:

  • scan 和 zipWith 的使用在这里特别讨喜。这非常地道。
  • powers x 的更有效实现是iterate (x*) 1
  • @LouisWasserman 更好,不需要productsexp' x = scanl (*) 1 $ map (x /) [1..](或通过将不同的函数传递给scanl来消除map
【解决方案2】:

一种常见的方法是使用一个列表来仅表示幂级数的系数,并编写另一个函数来评估特定值的幂级数。

例如,幂级数 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 不会在无限列表上终止,所以你必须确保只给它有限列表:

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

现在您只需为sin' 生成系数。请注意,在这种情况下,10 是指您想要求和的 x 的最高幂,而不是求和中非零项的数量。

【讨论】:

  • 您还可以将Num a => [a] 定义为Num 类型类的实例,以表示多项式加法和乘法,这样您就可以像sin' 和@987654333 这样的泰勒级数进行加法和乘法运算@(同样是有限精度)。
猜你喜欢
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 2017-06-22
  • 2018-10-07
  • 2016-07-26
  • 2018-06-23
相关资源
最近更新 更多