请原谅我,如果这更适合MathOverflow,但我的问题可能太简单了。
我正在阅读SK Lando关于生成函数的讲座,它给出了两个生成函数 A 和 B 的乘积的定义:
A(s)*B(s) = a0*b0 + (a0*b1 + a1*b0)*s + (a0*b2 + a1*b1 + a2*b0)*s^2 ...
我了解 s 只是正式的。但是 - 我知道它对我很迟钝 - 我无法理解组合系数的术语模式应该如何继续。如果有人可以将定义扩展到一个或两个以上的术语,它可能会对我有很大的帮助。非常感谢!
对于奖励积分,Haskell中用于乘以两个系列(表示为系数列表)的算法也将非常受欢迎 - 但仅仅理解上述定义就足够了。
答案 0 :(得分:4)
请注意,系数指数的总和在每个项中都是常数。例如a0*b0 -> 0+0=0
,a0*b1 -> 0+1=1
和a1*b0 -> 1+0=1
。
回想一下story of young Gauss,他发现通过将一个连续数字列表与其反向相加,我们得到一个常量的列表。同样的技巧适用于此。我们将采用第一个k a_i
和b_i
系数,反转b_i
系数列表,并采用列表中的分量产品。
以下是一些Haskell代码,为s^i
生成系数i>=0
,给定i
以及as=[a0,a1,...]
和bs=[b0,b1,...]
列表:
genCoeff :: [Double] -> [Double] -> Int -> Double
genCoeff as bs i = sum $ zipWith (*) (take (i+1) as) (reverse (take (i+1) bs))
要生成所有系数,我们只需将部分应用的函数genCoeff as bs
映射到列表[0,1,...]
,即
genAllCeoffs :: [Double] -> [Double] -> [Double]
genAllCoeffs as bs = map (genCoeff as bs) [0..]
答案 1 :(得分:3)
这是一个不使用reverse
的解决方案:
add [] bs = bs
add as [] = as
add (a:as) (b:bs) = (a+b) : add as bs
mult :: [Int] -> [Int] -> [Int]
mult [] bs = [] -- note: [] = 0
mult as [] = []
mult (a:as) (b:bs) = (a*b) : add (add (map (*a) bs) (map (*b) as)) (0:mult as bs)
test1 = do
let as = [1,2,3]
bs = [4,5]
putStrLn $ "as = " ++ show as
putStrLn $ "bs = " ++ show bs
putStrLn $ "as * bs = " ++ show (mult as bs)
输出:
as = [1,2,3]
bs = [4,5]
as * bs = [4,13,22,15]
它来自以下身份:
(a0+a1*x) * (b0 + b1*x) = a0*b0 + a0*b1*x + b0*a1*x + a1*b1*x^2
对应关系是:
a0*b0 <-> a*b
a0*b1*x <-> map (*a) bs
b0*a1*x <-> map (*b) as
a1*b1*x^2 <-> (0:mult as bs)