使用lmfit.Model或scipy.optimize.curve_fit优化函数的卷积

7rtdyuoh  于 7个月前  发布在  其他
关注(0)|答案(1)|浏览(56)

使用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

nnvyjq4y

nnvyjq4y1#

您可以简单地在由lmfit.Model Package 的模型函数中进行卷积,传入卷积中使用的内核数组。或者您可以创建卷积内核和函数,并将卷积作为建模过程的一部分,如https://lmfit.github.io/lmfit-py/examples/documentation/model_composite.html中的示例所述
我想如果内核实际上并不打算在fit期间被更改,那么第一种方法会更简单。

相关问题