一、问题描述
设
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(marc_pony@163.com)
*************************************************/
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版)(第四版) 周璐,陈渝,钱方等译