文章目录
- 多项式简介
- 构造函数与图像
- 运算符重载
- 常用方法
多项式简介
Numpy.polynomial
中封装了六种多项式类,除了常规的多项式
a
0
+
a
1
x
+
⋯
+
a
n
x
n
a_0+a_1x+\cdots+a_nx^n
a0+a1x+⋯+anxn之外,还有五种在数学、物理中常用的正交多项式,例如Hermite多项式在量子力学中是谐振子的本征态;Legendre多项式可表示点电荷在空间中的激发电势;切比雪夫多项式可用于缓解龙格现象;拉盖尔多项式则是氢原子基函数的径向部分,下表是这些多项式在numpy
中封装的类以及各阶表达式。
类 | 中文名称 | 第n阶表达式 |
---|---|---|
Polynomial | 多项式 | x n x^n xn |
Chebyshev | 第一类切比雪夫多项式 | cos ( n arccos x ) \cos(n\arccos x) cos(narccosx) |
Legendre | 勒让德多项式 | 1 2 n n ! d n d x n ( x 2 − 1 ) n \frac{1}{2^nn!}\frac{\text d^n}{\text dx^n}(x^2-1)^n 2nn!1dxndn(x2−1)n |
Laguerre | 拉盖尔多项式 | e x n ! d n d x n ( e − x x n ) \frac{e^x}{n!}\frac{\text d^n}{\text dx^n}(e^{-x}x^n) n!exdxndn(e−xxn) |
Hermite | 埃尔米特多项式(物理) | ( − 1 ) n e x 2 d n d x n e − x 2 (-1)^ne^{x^2}\frac{\text d^n}{\text dx^n}e^{-x^2} (−1)nex2dxndne−x2 |
HermiteE | 埃尔米特多项式(统计) | ( − 1 ) n e x 2 / 2 d n d x n e − x 2 / 2 (-1)^ne^{x^2/2}\frac{\text d^n}{\text dx^n}e^{-x^2/2} (−1)nex2/2dxndne−x2/2 |
numpy
为埃尔米特多项式提供了两种形式,Hermite
为物理学家常用的形式,可记作
H
n
p
h
y
s
H_n^{phys}
Hnphys,HermiteE
为统计学家常用的形式,记作
H
n
p
r
o
b
H_n^{prob}
Hnprob,二者之间满足
H
n
p
h
y
s
(
x
)
=
2
n
/
2
H
n
p
r
o
b
(
2
x
)
H_n^{phys}(x)=2^{n/2}H_n^{prob}(\sqrt2 x)
Hnphys(x)=2n/2Hnprob(2x)。
这些多项式均满足一定的递推关系,如下表所示
多项式 | X n + 1 X_{n+1} Xn+1 | 导数 X n ′ X_n' Xn′ | |
---|---|---|---|
Chebyshev | 2 x T n − T n − 1 2xT_n-T_{n-1} 2xTn−Tn−1 | n 1 − x 2 ( T n − 1 − x T n ) \frac{n}{1-x^2}(T_{n-1}-xT_n) 1−x2n(Tn−1−xTn) | |
Legendre | 2 n + 1 n + 1 x P n − n n + 1 P n − 1 \frac{2n+1}{n+1}xP_n-\frac{n}{n+1}P_{n-1} n+12n+1xPn−n+1nPn−1 | 1 + ∑ i = 1 n − 1 ( 2 i + 1 ) P i 1+\sum_{i=1}^{n-1}(2i+1)P_i 1+∑i=1n−1(2i+1)Pi | |
Laguerre | ( 2 n + 1 − x ) L n − n L n − 1 n + 1 \frac{(2n+1-x)L_n-nL_{n-1}}{n+1} n+1(2n+1−x)Ln−nLn−1 | ∑ i = 0 n − 1 L i n − i \sum_{i=0}^{n-1}\frac{L_i}{n-i} ∑i=0n−1n−iLi | |
Hermite | 2 x H n − 2 n H n − 1 2xH_n-2nH_{n-1} 2xHn−2nHn−1 | 2 n H n − 1 2nH_{n-1} 2nHn−1 |
构造函数与图像
这些多项式采用了相同的构造函数,使用起来非常方便,以Polynomial类为例,其构造函数为
Polynomial(coef, domain=None, window=None, symbol='x')
其中coef
为多项式的系数,domian
为
x
x
x的定义域,window
为定义域的放缩因子;symbol
为多项式的自变量符号,默认为x
。
下面以常规多项式和埃米尔特多项式为例,写出 4 + 3 x + 2 x 2 + x 3 4+3x+2x^2+x^3 4+3x+2x2+x3和 4 + 3 H 1 ( x ) + 2 H 2 ( x ) + 3 H 3 ( x ) 4+3H_1(x)+2H_2(x)+3H_3(x) 4+3H1(x)+2H2(x)+3H3(x)的构造方法
from numpy.polynomial import Polynomial
p3 = poly.Polynomial(coef=[4,3,2,1])
print(p3)
# 输出为4.0 + 3.0 x**1 + 2.0 x**2 + 1.0 x**3
from numpy.polynomial.hermite import Hermite
# 此为埃尔米特多项式
h3 = Hermite(coef=[4,3,2,1])
print(h3)
# 输出为4.0 + 3.0 H_1(x) + 2.0 H_2(x) + 1.0 H_3(x)
接下来,将这些多项式的前六阶画出来
import matplotlib.pyplot as plt
import numpy as np
from numpy import polynomial as poly
polyDct = {
"Polynomial":poly.polynomial.Polynomial,
"Chebyshev":poly.chebyshev.Chebyshev,
"Legendre":poly.legendre.Legendre,
"Laguerre":poly.laguerre.Laguerre,
"Hermite":poly.hermite.Hermite,
"HermiteE":poly.hermite_e.HermiteE,
}
axes = plt.subplots(2,3)[1].reshape(-1)
for key,ax in zip(polyDct, axes):
for i in range(6):
c = np.zeros(i+1)
c[i] = 1
p = polyDct[key](coef=c, domain=(-5,5))
xs, ys = p.linspace()
ax.plot(xs, ys, label=str(i))
ax.set_title(key)
ax.legend()
plt.show()
效果为
运算符重载
多项式之间可以进行加减乘除这些运算并不奇怪,例如
p
(
x
)
=
x
3
+
x
p(x)=x^3+x
p(x)=x3+x,其系数由低到高为[0,1,0,1]
,则
p
(
x
)
∗
p
(
x
)
=
x
6
+
2
x
4
+
x
2
p(x)*p(x)=x^6+2x^4+x^2
p(x)∗p(x)=x6+2x4+x2,系数变为[0,0,1,0,2,0,1]
。
numpy
中对多项式提供了+-*/
的运算符重载,支持多项式与多项式,或多项式与数值之间的计算。
from numpy.polynomial.polynomial import Polynomial
pTest = Polynomial([0,1,0,1])
print(pTest*pTest)
# 0.0 + 0.0 x**1 + 1.0 x**2 + 0.0 x**3 + 2.0 x**4 + 0.0 x**5 + 1.0 x**6
和我们预想的情况完全相符。
多项式类还封装了一些用于比较的函数,相当于是运算符重载的补充,包括:has_samecoef
, has_samedomain
, has_sametype
, has_samewindow
,这些函数命名非常直观,相当于是相等的扩展。
常用方法
这些多项式采用了相同的接口,使用起来非常便捷。
方法 | 说明 | 方法 | 说明 |
---|---|---|---|
deriv | 求导 | integ | 积分 |
roots | 求根 | fromroot | 反演 |
linspace | 采样 | fit | 拟合 |
cutdeg | 阶数截断 | basis | 生成 |
trim | 移除系数 |
下面以Hermite多项式为例,对这些方法进行调用,
from numpy.polynomial.hermite import Hermite
h3 = Hermite(coef=[4,3,2,1])
print(h3)
# 输出为4.0 + 3.0 H_1(x) + 2.0 H_2(x) + 1.0 H_3(x)
h3.deriv(1) # 求1阶导数
# 结果为Hermite([6., 8., 6.])
h3.deriv(3) # 求3阶导数
# 结果为Hermite([48.])
h3.integ(2) # 求2阶积分
# 结果为Hermite([0.5 , 0. , 0.5 , 0.125 , 0.04166667, 0.0125 ])
rs = h3.roots() # 求根
print(rs) # 反演结果 保留4位有效数字
# [-1.500e+00, -3.617e-16, 5.000e-01]
pNew = p3.fromroots(rs)
print(pNew) # 反演结果 保留3位小数
# 0.500 + 0.375H_1(x) + 0.250H_2(x) + 0.125 H_3(x)
xs, ys = h3.linspace() # 对h3进行采样
h3_3 = h3.fit(xs, ys, 3) # 根据xs, ys做3阶Hermite多项式拟合
print(h3_3) # 拟合结果,保留2位小数
# 4.0 + 3.0 H_1(x) + 2.0 H_2(x) + 1.0 H_3(x)
h3_4 = h3.fit(xs, ys, 4) #4阶Hermite多项式拟合
print(h3_4) # 拟合结果,保留2位小数
# 4.0 + 3.0 H_1(x) + 2.0 H_2(x) + 1.0H_3(x) -9.8e-16 H_4(x)
root
用于求根,fromroots
在已知根的情况下,反演出多项式的形式,这两者并不是严格互为相反的。