在SciPy中,optimize
库提供了几个求函数最小值的算法: fmin
, fmin_powell
, fmin_cg
, fmin_bfgs
。
反卷积运算
下面的程序通过求解卷积的逆运算演示 fmin
的功能。
对于一个离散的线性时不变系统h, 如果它的输入是x,那么其输出y可以用x和h的卷积表示:
y = x ∗ h
现在的问题是如果已知系统的输入x和输出y,如何计算系统的传递函数h;
或者如果已知系统的传递函数h和系统的输出y,如何计算系统的输入x。
这种运算被称为反卷积运算,是十分困难的,特别是在实际的运用中,测量系统的输出总是存在误差的。
下面用 fmin
计算反卷积,这种方法只能用在很小规模的数列之上,因此没有很大的实用价值,
不过用来评价 fmin
函数的性能还是不错的。
import scipy.optimize as opt
import numpy as np
定义函数: x (*) h = y, (*)
表示卷积,yn
为在 y
的基础上添加一些干扰噪声的结果,
x0
为求解 x
的初始值:
def test_fmin_convolve(fminfunc, x, h, y, yn, x0):
"""
"""
def convolve_func(h):
"""
计算 yn - x (*) h 的power
fmin将通过计算使得此power最小
"""
return np.sum((yn - np.convolve(x, h))**2)
# 调用fmin函数,以x0为初始值
h0 = fminfunc(convolve_func, x0)
print(fminfunc.__name__)
print("---------------------")
# 输出 x (*) h0 和 y 之间的相对误差
print("error of y:", np.sum((np.convolve(x, h0)-y)**2)/np.sum(y**2))
# 输出 h0 和 h 之间的相对误差
print("error of h:", np.sum((h0-h)**2)/np.sum(h**2))
print
随机产生x, h, y, yn, x0等数列,调用各种 fmin
函数求解b。
m为x的长度, n为h的长度, nscale
为干扰的强度。
def test_n(m, n, nscale):
"""
"""
x = np.random.rand(m)
h = np.random.rand(n)
y = np.convolve(x, h)
yn = y + np.random.rand(len(y)) * nscale
x0 = np.random.rand(n)
test_fmin_convolve(opt.fmin, x, h, y, yn, x0)
test_fmin_convolve(opt.fmin_powell, x, h, y, yn, x0)
test_fmin_convolve(opt.fmin_cg, x, h, y, yn, x0)
test_fmin_convolve(opt.fmin_bfgs, x, h, y, yn, x0)
然后运行程序,检查最后的结果:
test_n(200, 20, 0.1)
/tmp/ipykernel_1470/2448148131.py:13: RuntimeWarning: Maximum number of function evaluations has been exceeded. h0 = fminfunc(convolve_func, x0)
fmin --------------------- error of y: 0.0017834708641570568 error of h: 0.08921048343561559 Optimization terminated successfully. Current function value: 0.194163 Iterations: 41 Function evaluations: 6818 fmin_powell --------------------- error of y: 0.0001480335369991133 error of h: 0.00030893674663319087 Optimization terminated successfully. Current function value: 0.194103 Iterations: 17 Function evaluations: 798 Gradient evaluations: 38 fmin_cg --------------------- error of y: 0.00014741771714699115 error of h: 0.00029899307077054573 Optimization terminated successfully. Current function value: 0.194103 Iterations: 29 Function evaluations: 861 Gradient evaluations: 41 fmin_bfgs --------------------- error of y: 0.00014741767573175912 error of h: 0.0002989926687294253