Python 正弦幂级数的最小二乘拟合
我试图拟合一个形式函数: 其中A和B是固定常数。在scipy中,我通常(我认为是合理的规范)处理此类问题的方法如下:Python 正弦幂级数的最小二乘拟合,python,numpy,scipy,mathematical-optimization,curve-fitting,Python,Numpy,Scipy,Mathematical Optimization,Curve Fitting,我试图拟合一个形式函数: 其中A和B是固定常数。在scipy中,我通常(我认为是合理的规范)处理此类问题的方法如下: def func(t, coefs): phase = np.poly1d(coefs)(t) return A * np.cos(phase) + B def fit(time, data, guess_coefs): residuals = lambda p: func(time, p) - data fit_coefs = scipy.
def func(t, coefs):
phase = np.poly1d(coefs)(t)
return A * np.cos(phase) + B
def fit(time, data, guess_coefs):
residuals = lambda p: func(time, p) - data
fit_coefs = scipy.optimize.leastsq(residuals, guess_coefs)
return fit_coefs
这是可行的,但我想提供一个分析雅可比矩阵来改进收敛性。因此:
def jacobian(t, coefs):
phase = np.poly1d(coefs, t)
the_jacobian = []
for i in np.arange(len(coefs)):
the_jac.append(-A*np.sin(phase)*(t**i))
return the_jac
def fit(time, data, guess_coefs):
residuals = lambda p: func(time, p) - data
jac = lambda p: jacobian(time, p)
fit_coefs = scipy.optimize.leastsq(residuals, guess_coefs,
Dfun=jac, col_deriv=True)
这也不起作用,即使是在2或更少的数量级。使用optimize.check_gradient()快速检查也不会给出积极的结果
我几乎可以肯定雅可比矩阵和代码是正确的(尽管请纠正我),问题更为根本:雅可比矩阵中的t**I项会导致溢出错误。这不是函数本身的问题,因为这里的单项项乘以它们的系数,系数非常小
我的问题是:
编辑:忘记了原始函数形式中的正方形,
poly1D
函数首先具有最高的系数,而雅可比函数首先假定最低的系数。如果在jacobian
中使用return语句返回_jac[:-1]
(并修复更明显的打字错误),您的函数将通过优化。检查_gradient()
并在leastsq()
中正确工作
关于数值稳定性的进一步问题也在这里得到了证实。如果你有大量的t值和大量的系数,你很容易会遇到数值精度问题:例如,在32位精度中,如果你的多项式计算值超过10^8,正弦的相位将在尾数中完全丢失,正弦计算的结果基本上是垃圾
您可以通过在多项式中使用模幂来解决这个问题:基本上,多项式的每个项都关心
(a_k t**k)%p
,其中p=2*np.pi
是正弦周期。对于大的t
(a_k*(t%(p/a_k))**k)%p,您可以以更高的精度计算此模指数;对于一般的准确性k
来说,事情变得有点复杂。请参阅,以了解有关这些内容的详细讨论。poly1D函数首先具有最高的系数,而雅可比函数首先假定最低的系数。如果在jacobian
中使用return语句返回_jac[:-1]
(并修复更明显的打字错误),您的函数将通过优化。检查_gradient()
并在leastsq()
中正确工作
关于数值稳定性的进一步问题也在这里得到了证实。如果你有大量的t值和大量的系数,你很容易会遇到数值精度问题:例如,在32位精度中,如果你的多项式计算值超过10^8,正弦的相位将在尾数中完全丢失,正弦计算的结果基本上是垃圾
您可以通过在多项式中使用模幂来解决这个问题:基本上,多项式的每个项都关心(a_k t**k)%p
,其中p=2*np.pi
是正弦周期。对于大的t
(a_k*(t%(p/a_k))**k)%p,您可以以更高的精度计算此模指数;对于一般的准确性k
来说,事情变得有点复杂。关于这些事情,请仔细讨论