1.多项式求值的秦九韶算法
设给定
n
n
n次多项式
p
(
x
)
=
a
0
x
n
+
a
1
x
n
−
1
+
⋯
+
a
n
−
1
x
+
a
n
,
a
0
≠
0
,
p(x)=a_0x^n+a_1x^{n-1}+\cdots+a_{n-1}x+a_n,\quad a_0\neq 0,
p(x)=a0xn+a1xn−1+⋯+an−1x+an,a0=0,
求
x
∗
处
的
值
p
(
x
∗
)
.
若
直
接
计
算
每
一
项
a
i
x
n
−
i
再
相
加
,
共
需
要
x^*处的值p(x^*).若直接计算每一项a_ix^{n-i}再相加,共需要
x∗处的值p(x∗).若直接计算每一项aixn−i再相加,共需要
∑
i
=
0
n
(
n
−
i
)
=
1
+
2
+
⋯
+
n
=
n
(
n
+
1
)
2
=
O
(
n
2
)
\sum_{i = 0}^{n}(n-i)=1+2+\cdots+n=\frac{n(n+1)}{2}=O(n^2)
i=0∑n(n−i)=1+2+⋯+n=2n(n+1)=O(n2)次乘法,
n
n
n次加法.若采用
p
(
x
)
=
(
⋯
(
a
0
x
+
a
1
)
x
+
⋯
+
a
n
−
1
)
x
+
a
n
,
p(x)=(\cdots(a_0x+a_1)x+\cdots+a_{n-1})x+a_n,
p(x)=(⋯(a0x+a1)x+⋯+an−1)x+an,它可表示为
{
b
0
=
a
0
,
b
i
=
b
i
−
1
x
∗
+
a
i
,
i
=
1
,
2
,
…
,
n
,
\begin{cases} b_0=a_0,\\ b_i=b_{i-1}x^*+a_i,i=1,2,\ldots,n, \end{cases}
{b0=a0,bi=bi−1x∗+ai,i=1,2,…,n,
则
b
n
=
p
(
x
∗
)
即
为
所
求
.
b_n=p(x^*)即为所求.
bn=p(x∗)即为所求.此算法称为秦九韶算法,用它计算
n
次
多
项
式
p
(
x
)
n次多项式p(x)
n次多项式p(x)的值只用
n
次
乘
法
和
n
次
加
法
n次乘法和n次加法
n次乘法和n次加法
乘
法
次
数
由
O
(
n
2
)
降
为
O
(
n
)
,
且
只
用
n
+
2
个
存
储
单
元
,
国
外
称
此
算
法
为
H
o
r
n
e
r
算
法
乘法次数由O(n^2)降为O(n),且只用n+2个存储单元,国外称此算法为Horner算法
乘法次数由O(n2)降为O(n),且只用n+2个存储单元,国外称此算法为Horner算法
2.Python实现秦九韶算法
import numpy as np
from sympy.abc import x
def polynomial(coefficient_array: np.ndarray, is_ascending_order: bool = False):
"""
构造指定系数的多项式
:param coefficient_array: 多项式系数数组
:param is_ascending_order: 多项式排列顺序
:return: 多项式
"""
degree = coefficient_array.shape[0]
if is_ascending_order:
coefficient_array = coefficient_array[::-1]
# default,descending order arrangement
p_x = coefficient_array[-1]
for i in range(degree - 1, 0, -1):
p_x += coefficient_array[degree - i - 1] * pow(x, i)
return p_x
def qin_jiu_shao(coefficient_array: np.ndarray, value, is_ascending_order: bool = False):
"""
多项式求值的秦九韶算法,即Horner算法
:param coefficient_array: 多项式系数数组
:param value: 自变量的值
:param is_ascending_order: 多项式排列顺序
:return: the value of polynomial
example:
2*x**4 - 3*x**2 + 3*x - 4=((((2x+0)x-3)x+3)x-4)
3*x**5 - 2*x**3 + x + 7=(((((3x+0)x-2)x+0)x+1)x+7)
"""
if is_ascending_order:
coefficient_array = coefficient_array[::-1]
degree = coefficient_array.shape[0]
b = coefficient_array[0]
for i in range(1, degree):
b = b * value + coefficient_array[i]
return b
3.多项式求值测试
if __name__ == '__main__':
# 测试成功,来源详见李庆扬数值分析第5版P14,e.g.11
# 降幂排列
coefficient0 = np.array([2, 0, -3, 3, -4])
print(polynomial(coefficient0))
print(qin_jiu_shao(coefficient0, -2))
# 升幂排列
coefficient1 = np.array([-4, 3, -3, 0, 2])
print(polynomial(coefficient1, is_ascending_order=True))
print(qin_jiu_shao(coefficient1, -2, is_ascending_order=True))
# 测试成功,来源详见李庆扬数值分析第5版P20,e.x.14
# 降幂排列
coefficient2 = np.array([3, 0, -2, 0, 1, 7])
print(polynomial(coefficient2))
print(qin_jiu_shao(coefficient2, 3))
# 升幂排列
coefficient3 = np.array([7, 1, 0, -2, 0, 3])
print(polynomial(coefficient3, is_ascending_order=True))
print(qin_jiu_shao(coefficient3, 3, is_ascending_order=True))