我有一个monic多项式的根,即
p(x) = (x-x_1)*...*(x-x_n)
我需要来自
的系数a_n,...,a_0p(x) = x^n + a_{n-1}x^{n-1} + ... + a_0.
是否有人知道计算效率这样做的方式?如果有人知道C / C ++实现,这实际上是最好的。 (我已经看过GSL,但它没有提供功能。)
当然,我知道如何以数学方式。我知道,系数a_i
是具有n-i
元素的子集的所有乘积的总和。但如果我以愚蠢的方式做到这一点,这意味着迭代所有子集,我需要
sum^{n-1}_{k=1} ( k choose n) * (k-1)
乘法和
sum^n_{k=0} ( k choose n) - n
加法。因此,这两个项都以O(n!)
增长,这是一个太多的计算,无法将n
根列表转换为n
系数列表。我相信必须有一些聪明的方法来重用大多数中间结果,但我找不到一个。
答案 0 :(得分:7)
如果逐步构建多项式,则可以非常轻松地在O(n^2)
中执行此操作。我们来定义:
p_k(x) = (x-x_1)*...*(x-x_k)
即p_k(x)
是k
的第一个(x-x_i)
p(x)
的乘法。我们有:
p_1(x) = x-x_1
换句话说,系数数组(a
)将是(索引从0开始,从左开始):
-x_1 1
现在假设我们有p_k(x)
的系数数组:
a_0 a_1 a_2 ... a_k
(旁注:a_k
是1)。现在我们想要计算p_k+1(x)
,这是(请注意k+1
是索引,并且没有总和1):
p_k+1(x) = p_k(x)*(x-x_k+1)
=> p_k+1(x) = x*p_k(x) - x_k+1*p_k(x)
将其转换为系数数组,意味着新系数是向前移动的(x*p_k(x)
)减去k+1
根再乘以相同的系数({{1 }}):
x_k+1*p_k(x)
(旁注:这就是 0 a_0 a_1 a_2 ... a_k-1 a_k
- x_k+1 * (a_0 a_1 a_2 a_3 ... a_k)
-----------------------------------------
-x_k+1*a_0 (a_0-x_k+1*a_1) (a_1-x_k+1*a_2) (a_2-x_k+1*a_3) ... (a_k-x_k+1*a_k-1) a_k
保持1的方式)有你的算法。从a_k
(或甚至p_1(x)
)开始,并按多项式的每个根的上述公式逐步构建系数数组。