Haskell Hermite 多项式实现
Haskell Hermite polynomials implementation
Haskell 允许以非常简洁的方式表示循环函数。例如,包含斐波那契数列的无限列表可以定义如下:
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
我正在处理 'probabilists' Hermite 多项式,它具有以下递归关系:
对于给定的 x,构造第 n 个 Hermite 多项式的无限列表的最佳方法是什么?
我们可以写成:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s@(_:ts) = 1 : x : zipWith3 (\hn2 hn1 n1 -> x*hn1 - n1*hn2) s ts [1..]
其中第一项1 : x : ...
是hermite
的第一个元素(可以填写其他值)。
对于下一个,我们压缩原始值 s
(以 H0
开头),s
的尾部 ts
(以 H1
) 和索引(以 2
、3
、... 开头)并执行操作 x*hn1 - x*hn2
(nh1
代表 Hn-1,而nh2
代表Hn-2), 所以我们每次都计算下一个元素。
x = 0.75
的前 11 个值是:
Prelude> take 11 (hermite 0.75)
[1.0,0.75,-0.4375,-1.828125,-5.859375e-2,7.2685546875,5.744384765625,-39.30303955078125,-69.68797302246094,262.1583366394043,823.8105096817017]
所以第一个值为1,第二个为x
,第三个为x*x-2
,第四个为x*x*x-2*x-3*x
,依此类推。
也就是说,如果我没记错的话,Hermite多项式的递归公式是:
Hn(x) = 2×x×Hn-1(x)-2× (n-1)Hn-2(x)
而不是问题中引用的那个。
在这种情况下,公式为:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s@(_:ts) = 1 : 2 * x : zipWith3 helper s ts [1..]
helper hn2 hn1 n1 = 2 * (x * hn1 - n1 * hn2)
则前11个值为:
Prelude> take 11 (hermite 0.75)
[1.0,1.5,0.25,-5.625,-9.9375,30.09375,144.515625,-144.3515625,-2239.74609375,-1049.994140625,38740.4384765625]
根据这个Wolfram article:
哪个是正确的
H0 = 1
H1 = 2*x
H2 = 4˙x2 - 2
H3 = 8˙x3 - 4˙x
H4 = 16˙x4 - 48˙x2 + 12
这与我们获得的值完全一致:
Prelude> let x = 0.75 in [1,2*x,4*x*x-2,8*x*x*x-4*x,16*x*x*x*x-48*x*x+12]
[1.0,1.5,0.25,0.375,-9.9375]
Haskell 允许以非常简洁的方式表示循环函数。例如,包含斐波那契数列的无限列表可以定义如下:
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
我正在处理 'probabilists' Hermite 多项式,它具有以下递归关系:
对于给定的 x,构造第 n 个 Hermite 多项式的无限列表的最佳方法是什么?
我们可以写成:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s@(_:ts) = 1 : x : zipWith3 (\hn2 hn1 n1 -> x*hn1 - n1*hn2) s ts [1..]
其中第一项1 : x : ...
是hermite
的第一个元素(可以填写其他值)。
对于下一个,我们压缩原始值 s
(以 H0
开头),s
的尾部 ts
(以 H1
) 和索引(以 2
、3
、... 开头)并执行操作 x*hn1 - x*hn2
(nh1
代表 Hn-1,而nh2
代表Hn-2), 所以我们每次都计算下一个元素。
x = 0.75
的前 11 个值是:
Prelude> take 11 (hermite 0.75)
[1.0,0.75,-0.4375,-1.828125,-5.859375e-2,7.2685546875,5.744384765625,-39.30303955078125,-69.68797302246094,262.1583366394043,823.8105096817017]
所以第一个值为1,第二个为x
,第三个为x*x-2
,第四个为x*x*x-2*x-3*x
,依此类推。
也就是说,如果我没记错的话,Hermite多项式的递归公式是:
Hn(x) = 2×x×Hn-1(x)-2× (n-1)Hn-2(x)
而不是问题中引用的那个。
在这种情况下,公式为:
hermite :: (Enum n, Num n) => n -> [n]
hermite x = s
where s@(_:ts) = 1 : 2 * x : zipWith3 helper s ts [1..]
helper hn2 hn1 n1 = 2 * (x * hn1 - n1 * hn2)
则前11个值为:
Prelude> take 11 (hermite 0.75)
[1.0,1.5,0.25,-5.625,-9.9375,30.09375,144.515625,-144.3515625,-2239.74609375,-1049.994140625,38740.4384765625]
根据这个Wolfram article:
哪个是正确的H0 = 1
H1 = 2*x
H2 = 4˙x2 - 2
H3 = 8˙x3 - 4˙x
H4 = 16˙x4 - 48˙x2 + 12
这与我们获得的值完全一致:
Prelude> let x = 0.75 in [1,2*x,4*x*x-2,8*x*x*x-4*x,16*x*x*x*x-48*x*x+12]
[1.0,1.5,0.25,0.375,-9.9375]