通过lmfit进行最小化

问题描述 投票:0回答:1

我想估计x的值。所以这是我将x设为参数时对我有用的代码。

`

import numpy as np
import matplotlib.pyplot as plt
from lmfit import Parameters, minimize
from numpy import exp, linspace, random


def gaussian(x, amp, cen, wid):
    return amp * exp(-(x-cen)**2 / wid)


x = linspace(-10, 10, 101)
data = gaussian(x, 2.33, 0.21, 1.51) + random.normal(0, 0.2, x.size)
Model = gaussian(x, 2.33,0.21,1.51)

plt.plot(x, data, label = 'data')
plt.plot(x, Model, label = 'Model')
plt.legend()
plt.grid(True)
plt.show()


d = 50
print ("\nThe data value at {} is {}\n".format(0, data[0+d]))

params = Parameters()
params.add('x', value =-3)    


def objective(params, amp, cen, wid, data):
    x = params['x']
    m = gaussian(x, amp, cen, wid)
    return data - m


result = minimize(objective, params=params, args=(2.33, 0.21, 1.51,data[d]))
print(result.params)

`

所以这里我的参数是x。在目标函数中,我给出的数据值为50,它对应于0处的x。我正在将参数的初始值初始化为接近0的值,因此将其设置为-3。

当打​​印结果时,参数将显示为收敛到0。

现在,如果我将amp cen和wid作为参数,它会给我一个错误

TypeError:Objective()*后的参数必须是可迭代的,而不是numpy.float64

`

import numpy as np
import matplotlib.pyplot as plt
from lmfit import Parameters, minimize
from numpy import exp, linspace, random

def gaussian(x, amp, cen, wid):
    return amp * exp(-(x-cen)**2 / wid)    

x = linspace(-10, 10, 101)
data = gaussian(x, 2.33, 0.21, 1.51) + random.normal(0, 0.2, x.size)
Model = gaussian(x, 2.33,0.21,1.51)

plt.plot(x, data, label = 'data')
plt.plot(x, Model, label = 'Model')
plt.legend()
plt.grid(True)
plt.show()


d = 50
print ("\nThe data value at {} is {}\n".format(0, data[0+d]))

params = Parameters()
params.add('x', value =-5)
params.add('amp', value = 1)
params.add('cen', value = 1)
params.add('wid', value = 1)

def objective(params, data):    
    x = params['x']
    amp = params['amp']
    cen = params['cen']
    wid = params['wid']

    m = gaussian(x, amp, cen, wid)
    return data - m


result = minimize(objective, params=params, args=( data[d]))
print(result.params)

`

我在做什么错?

python numpy minimize minimization lmfit
1个回答
0
投票

嗯,基本上,您要更改4个不同的变量(xampcenwid)以匹配1个数据点:data[d]。您收到的错误消息:

......
    out = self.userfcn(params, *self.userargs, **self.userkws)
TypeError: objective() argument after * must be an iterable, not numpy.float64

适合告诉您目标函数的返回值必须是数组,而不是单个浮点数。

具有4个变量的拟合至少需要4个y值。否则,您可以在连续的值范围内更改xampcenwid,以使gaussian(x, amp, can, wid)data[d]匹配-问题没有单一的解决方案。

[如果想法是找到一个高斯函数采用单个特定x值的y值,则可以使用“寻根”方法-至少在可能的范围内做到这一点每个有效的x值至少要有2个y值。

为此,您可以使用scipy.optimize.root查找gaussian(x, amp, cen, wid) - data[d]为零的值:

def objective(x, amp, cen, wid, yval):
     return gaussian(x, amp, cen, wid) - yval

from scipy.optimize import root
init_x = 0.0  # initial guess for `x` value
result = root(objective, init_x, (100, 1.22, 2.5, data[50]))
print(result.x) 
© www.soinside.com 2019 - 2024. All rights reserved.