我想为一般函数编写一个或多或少的通用拟合函数。
$f_i = \sum_i a_i exp(-t/τ_i)$
我有一些数据。
下面是一个双指数函数的示例代码,但我希望能够用最小的代码适配来拟合单指数函数或三指数函数。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
t = np.linspace(0, 10, 100)
a_1 = 1
a_2 = 1
tau_1 = 5
tau_2 = 1
data = 1*np.exp(-t/5) + 1*np.exp(-t/1)
data += 0.2 * np.random.normal(size=t.size)
def func(t, a_1, tau_1, a_2, tau_2): # plus more exponential functions
return a_1*np.exp(-t/tau_1)+a_2*np.exp(-t/tau_2)
popt, pcov = curve_fit(func, t, data)
print(popt)
plt.plot(t, data, label="data")
plt.plot(t, func(t, *popt), label="fit")
plt.legend()
plt.show()
原则上,我考虑将函数重新定义为一般形式。
def func(t, a, tau): # with a and tau as a list
tmp = 0
tmp += a[i]*np.exp(-t/tau[i])
return tmp
并以列表或元组的形式将参数传递给curve_fit。但是,我得到了一个TypeError,如下所示。
TypeError: func() takes 4 positional arguments but 7 were given
是否有重写代码,您只能通过curve_fit的输入参数“确定”多指数函数的程度?所以经过
a = (1)
结果是一个单指数函数
a = (1, 2, 3)
结果是一个三指数函数?
问候
发布于 2018-07-11 17:19:03
是的,用np.broadcasting
可以很容易地做到
def func(t, a, taus): # plus more exponential functions
a=np.array(a)[:,None]
taus=np.array(taus)[:,None]
return (a*np.exp(-t/taus)).sum(axis=0)
func
接受2个列表,将它们转换为2 np.array,用所有指数计算一个矩阵,然后对其进行汇总。示例:
t=np.arange(100).astype(float)
out=func(t,[1,2],[0.3,4])
plt.plot(out)
请记住,a
和taus
必须保持相同的长度,因此根据需要对输入进行消毒。或者您也可以直接传递np.arrays而不是列表。
https://stackoverflow.com/questions/51290914
复制相似问题