一、问题描述
设 n n n阶多项式 P n ( x ) P_n(x) Pn(x)有以下形式:
P n ( x ) = a n x n + a n − 1 x n − 1 + . . . + a 2 x 2 + a 1 x + a 0 (1) P_n(x)=a_nx^n+a_{n-1}x^{n-1}+...+a_2x^2+a_1x+a_0\tag 1 Pn(x)=anxn+an−1xn−1+...+a2x2+a1x+a0(1)
秦九韶方法(1247年提出)或霍纳方法(Horner’s method),是计算多项式值的一种有效算法,其本质上是一种嵌套乘法。例如可以将5次多项式写成嵌套乘法形式:
P 5 ( x ) = ( ( ( ( a 5 x + a 4 ) x + a 3 ) x + a 2 ) x + a 1 ) x + a 0 (2) P_5(x)=((((a_5x+a_4)x+a_3)x+a_2)x+a_1)x+a_0\tag 2 P5(x)=((((a5x+a4)x+a3)x+a2)x+a1)x+a0(2)
采用此方法, n n n次多项式求值只需要 n n n次乘法和 n n n次加法运算,而直接采用式 ( 1 ) (1) (1)计算,则需要 n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1)次乘法和 n n n次加法运算。将多项式写成嵌套乘法的形式不直观,而且不方便编程,特别对于高次多项式。下面推导霍纳方法(或秦九韶方法)递推计算多项式的值 P n ( c ) P_n(c) Pn(c)。
二、多项式求值的霍纳方法(或秦九韶方法)
将 n n n阶多项式 P n ( x ) P_n(x) Pn(x)写成:
P n ( x ) = ( x − c ) Q 0 ( x ) + R 0 (3) P_n(x)=(x-c)Q_0(x)+R_0\tag 3 Pn(x)=(x−c)Q0(x)+R0(3)
其中, n − 1 n-1 n−1阶多项式的商: Q 0 ( x ) = b n x n − 1 + b n − 1 x n − 2 + . . . + b 3 x 2 + b 2 x + b 1 (4) Q_0(x)=b_nx^{n-1}+b_{n-1}x^{n-2}+...+b_3x^2+b_2x+b_1\tag 4 Q0(x)=bnxn−1+bn−1xn−2+...+b3x2+b2x+b1(4)
余数: R 0 = b 0 (5) R_0=b_0\tag 5 R0=b0(5)
将式 ( 4 ) (4) (4)和式 ( 5 ) (5) (5)代入式 ( 3 ) (3) (3)得:
P n ( x ) = ( x − c ) Q 0 ( x ) + R 0 = ( x − c ) ( b n x n − 1 + b n − 1 x n − 2 + . . . + b 3 x 2 + b 2 x + b 1 ) + b 0 = b n x n + ( b n − 1 − c b n ) x n − 1 + . . . + ( b 2 − c b 3 ) x 2 + ( b 1 − c b 2 ) x + ( b 0 − c b 1 ) \begin{aligned} \ \ \ \ \ \ P_n(x)&=(x-c)Q_0(x)+R_0\\ &=(x-c)(b_nx^{n-1}+b_{n-1}x^{n-2}+...+b_3x^2+b_2x+b_1)+b_0 \\ &=b_nx^n+(b_{n-1}-cb_n)x^{n-1}+...+(b_2-cb_3)x^2+(b_1-cb_2)x+(b_0-cb_1) \end{aligned} Pn(x)=(x−c)Q0(x)+R0=(x−c)(bnxn−1+bn−1xn−2+...+b3x2+b2x+b1)+b0=bnxn+(bn−1−cbn)xn−1+...+(b2−cb3)x2+(b1−cb2)x+(b0−cb1)
对比式 ( 1 ) (1) (1)可得:
a n = b n , a n − 1 = b n − 1 − c b n , . . . , a k = b k − c b k + 1 , . . . , a 0 = b 0 − c b 1 (6) a_n=b_n,a_{n-1}=b_{n-1}-cb_n,...,a_k=b_k-cb_{k+1},...,a_0=b_0-cb_1\tag 6 an=bn,an−1=bn−1−cbn,...,ak=bk−cbk+1,...,a0=b0−cb1(6)
可求得:
b n = a n , b n − 1 = a n − 1 + c b n , . . . , b k = a k + c b k + 1 , . . . , b 0 = a 0 + c b 1 (7) b_n=a_n,b_{n-1}=a_{n-1}+cb_n,...,b_k=a_k+cb_{k+1},...,b_0=a_0+cb_1\tag 7 bn=an,bn−1=an−1+cbn,...,bk=ak+cbk+1,...,b0=a0+cb1(7)
从而:
P n ( c ) = ( c − c ) Q 0 ( x ) + R 0 = b 0 (8) P_n(c) = (c-c)Q_0(x)+R_0=b_0\tag 8 Pn(c)=(c−c)Q0(x)+R0=b0(8)
因而,式 ( 7 ) (7) (7)则为多项式求值的霍纳方法(或秦九韶方法)的递推公式,自 b n b_n bn递推到 b 0 b_0 b0,得到多项式的值 P n ( c ) = b 0 P_n(c)=b_0 Pn(c)=b0。
三、C代码
/*************************************************
Function: polynomial_evaluation
Description: 霍纳方法(或秦九韶算法)求多项式y = a0 + a1*x + a2*x^2 + ... + an*x^n的值
算法描述:
S[n] = a[n]
S[k] = x*S[k+1] + a[k], k = n - 1, n - 2, ..., 0
Pn(x) = S0
算法时间复杂度: O(n)
算法空间复杂度: O(1)
Input: 多项式的系数a,多项式的阶数,自变量值x
Output: 无
Return: 多项式的值
Author: Marc Pony([email protected])
*************************************************/
float polynomial_evaluation(float a[], int order, float x)
{
float b;
int i;
b = a[order];
for (i = order - 1; i >= 0; i--)
{
b = x * b + a[i];
}
return b;
}
void main()
{
float y;
float a[6] = {
14, -4, 1, 4, -4, 1}; //(x - 2)^2*(x^3 + 1) + 10 = x^5 - 4*x^4 + 4*x^3 + x^2 - 4*x + 14
y = polynomial_evaluation(a, 5, 2);
}
四、参考文献/资料
Numerical Methods Using MATLAB Fourth Edition. John Mathews, Kurtis D.Fink
数值方法(MATLAB版)(第四版) 周璐,陈渝,钱方等译