使用lmfit.Model或scipy.optimize.curve_fit我必须优化一个函数,该函数的输出需要与一些实验数据进行卷积,然后才能拟合到其他一些实验数据。总结一下,工作流程如下:
(1)定义函数A(例如,高斯函数)。(2)函数A的输出与称为数据B的实验信号卷积。(3)函数A的参数针对(2)中提到的卷积进行优化,以完全匹配称为数据C的某些其他实验数据。
我使用傅立叶变换将函数A的输出与数据B卷积,如下所示:
from scipy.fftpack import fft, ifft
def convolve(data_B, function_A):
convolved = ifft(fft(IRF) * fft(model)).real
return convolved
字符串
如何使用lmfit.Model或scipy.optimize.curve_fit来拟合数据C的“卷积”?
编辑:为了回应提交的答案,我已经将我的卷积步骤以以下方式纳入用于拟合的方程中:
#1 component exponential distribution:
def ExpDecay_1(x, ampl1, tau1, y0, x0, args=(new_y_irf)): # new_y_irf is a list.
h = np.zeros(x.size)
lengthVec = len(new_y_decay)
shift_1 = np.remainder(np.remainder(x-np.floor(x0)-1, lengthVec) + lengthVec, lengthVec)
shift_Incr1 = (1 - x0 + np.floor(x0))*new_y_irf[shift_1.astype(int)]
shift_2 = np.remainder(np.remainder(x-np.ceil(x0)-1, lengthVec) + lengthVec, lengthVec)
shift_Incr2 = (x0 - np.floor(x0))*new_y_irf[shift_2.astype(int)]
irf_shifted = (shift_Incr1 + shift_Incr2)
irf_norm = irf_shifted/sum(irf_shifted)
h = ampl1*np.exp(-(x)/tau1)
conv = ifft(fft(h) * fft(irf_norm)).real # This is the convolution step.
return conv
型
然而,当我尝试这个:
gmodel = Model(ExpDecay_1)
型
我得到了这个:
gmodel = Model(ExpDecay_1)追溯(最近的调用):
文件“",第1行,gmodel = Model(ExpDecay_1)
文件“C:\Users\洛佩斯\Anaconda 3\lib\site-packages\lmfit\model.py”,第273行,在initself._parse_params()中
文件“C:\Users\洛佩斯\Anaconda3\lib\site-packages\lmfit\model.py”,第477行,in _parse_params if fpar.default == fpar.empty:
ValueError:包含多个元素的数组的真值是不明确的。使用.any()或.all()
编辑2:我设法使它工作如下:
import pandas as pd
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
import numpy as np
from lmfit import Model
from scipy.fftpack import fft, ifft
def Test_fit2(x, arg=new_y_irf, data=new_y_decay, num_decay=1):
IRF = arg
DATA = data
def Exp(x, ampl1=1.0, tau1=3.0): # This generates an exponential model.
res = ampl1*np.exp(-x/tau1)
return res
def Conv(IRF,decay): # This convolves a model with the data (data = Instrument Response Function, IRF).
conv = ifft(fft(decay) * fft(IRF)).real
return conv
if num_decay == 1: # If the user chooses to use a model equation with one exponential term.
def fitting(x, ampl1=1.0, tau1=3.0):
exponential = Exp(x,ampl1,tau1)
convolved = Conv(IRF,exponential)
return convolved
modelling = Model(fitting)
res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
if num_decay == 2: # If the user chooses to use a model equation with two exponential terms.
def fitting(x, ampl1=1.0, tau1=3.0, ampl2=1.0, tau2=1.0):
exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)
convolved = Conv(IRF,exponential)
return convolved
modelling = Model(fitting)
res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
if num_decay == 3: # If the user chooses to use a model equation with three exponential terms.
def fitting(x, ampl1=1.0, tau1=3.0, ampl2=2.0, tau2=1.0, ampl3=3.0, tau3=5.0):
exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)+Exp(x,ampl3,tau3)
convolved = Conv(IRF,exponential)
return convolved
modelling = Model(fitting)
res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
if num_decay == 4: # If the user chooses to use a model equation with four exponential terms.
def fitting(x, ampl1=1.0, tau1=0.1, ampl2=2.0, tau2=1.0, ampl3=3.0, tau3=5.0, ampl4=1.0, tau4=10.0):
exponential = Exp(x,ampl1,tau1)+Exp(x,ampl2,tau2)+Exp(x,ampl3,tau3)+Exp(x,ampl4,tau4)
convolved = Conv(IRF,exponential)
return convolved
modelling = Model(fitting)
res = modelling.fit(DATA,x=new_x_decay,ampl1=1.0,tau1=2.0)
return res
型
1条答案
按热度按时间nnvyjq4y1#
您可以简单地在由
lmfit.Model
Package 的模型函数中进行卷积,传入卷积中使用的内核数组。或者您可以创建卷积内核和函数,并将卷积作为建模过程的一部分,如https://lmfit.github.io/lmfit-py/examples/documentation/model_composite.html中的示例所述我想如果内核实际上并不打算在fit期间被更改,那么第一种方法会更简单。