有没有办法为 SciPy curve_fit 函数固定和拟合多个变量?

发布于 2025-01-10 08:38:12 字数 1839 浏览 0 评论 0原文

我对 scipy.optimizecurve_fit 函数有疑问。我有一个相当复杂的类,可以计算光的传播,我希望它适合一些测量。对于这个线程,我将给出这个类的结构的一个简单示例

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

class Gauss():
    
    def __init__(self,x,parDict={}):
        self.default_dict = {"Amplitude": 1, "Center": 0, "FWHM":1} 
        self.x = x
        if parDict:
            self.parDict = self.fillDict(parDict)
        else:
            self.parDict = self.default_dict
    
    def fillDict(self,dictionary):
        return_dict={}
        if "Amplitude" in dictionary.keys():
            return_dict["Amplitude"] = dictionary["Amplitude"]
        else:
            return_dict["Amplitude"] =  self.default_dict["Amplitude"]
        if "Center" in dictionary.keys():
            return_dict["Center"] = dictionary["Center"]
        else:
            return_dict["Center"] =  self.default_dict["Center"]
        if "FWHM" in dictionary.keys():
            return_dict["FWHM"] = dictionary["FWHM"]
        else:
            return_dict["FWHM"] =  self.default_dict["FWHM"]
        
        return return_dict
    
    def calculate(self):
        return self.parDict["Amplitude"]*np.exp(-((self.x-self.parDict["Center"])**2/(self.parDict["FWHM"]**2*np.sqrt(2))))

x = np.linspace(-5,5,100)       
g = Gauss(x)
y = g.calculate()

plt.plot(x,y)
plt.show()

,因此人们可以看到,我将所有参数放在一个字典中以方便使用,并为我不想更改的所有缺失参数设置了一个默认参数字典。现在,我正在努力寻找一种巧妙的方法,甚至任何方法来编写可以使用此类来适应某些测量的函数或类。就像:

ynoise = y + np.random.normal(loc=0.2, scale=0.2, size=len(x))
param = {"Amplitude":1.2,"FWHM":0.5}
fit_par,_ = curve_fit(g.calculate, x, ynoise , p0=param)

问题是,这个类是一个更大的编程项目的一部分,并且在程序内部,所以我没有操作类本身的意义。你们中有人能想出一个解决办法吗?

I have a problem with the curve_fit function of scipy.optimize. I have a rather complex class which can calculate the propagation of light and I want it to be fitted to some measurements. For this thread, I will give a simple example of the structure of this class

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

class Gauss():
    
    def __init__(self,x,parDict={}):
        self.default_dict = {"Amplitude": 1, "Center": 0, "FWHM":1} 
        self.x = x
        if parDict:
            self.parDict = self.fillDict(parDict)
        else:
            self.parDict = self.default_dict
    
    def fillDict(self,dictionary):
        return_dict={}
        if "Amplitude" in dictionary.keys():
            return_dict["Amplitude"] = dictionary["Amplitude"]
        else:
            return_dict["Amplitude"] =  self.default_dict["Amplitude"]
        if "Center" in dictionary.keys():
            return_dict["Center"] = dictionary["Center"]
        else:
            return_dict["Center"] =  self.default_dict["Center"]
        if "FWHM" in dictionary.keys():
            return_dict["FWHM"] = dictionary["FWHM"]
        else:
            return_dict["FWHM"] =  self.default_dict["FWHM"]
        
        return return_dict
    
    def calculate(self):
        return self.parDict["Amplitude"]*np.exp(-((self.x-self.parDict["Center"])**2/(self.parDict["FWHM"]**2*np.sqrt(2))))

x = np.linspace(-5,5,100)       
g = Gauss(x)
y = g.calculate()

plt.plot(x,y)
plt.show()

So one can see, I have all the parameters inside a dictionary for simpler use and a default parameter dictionary for all the missing parameters I don't want to change. Now I am struggling to find a clever way or even any way to write a function or class which can use this class to fit it to some measurements. Like:

ynoise = y + np.random.normal(loc=0.2, scale=0.2, size=len(x))
param = {"Amplitude":1.2,"FWHM":0.5}
fit_par,_ = curve_fit(g.calculate, x, ynoise , p0=param)

The problem is, that this class is part of a much larger programming project and inside a program so I don't have the meaning of manipulating the class itself. Can one of you think of a solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咆哮 2025-01-17 08:38:12

根据 Bob 的评论以及他对此帖子的回答,我可以为我的问题创建一个解决方案。

对于所有想要解决方案的人:

def fitFunc(x, dictionary):
    g = Gauss(x,dictionary)
    return g.calculate()

fit_par,_ = curve_fit(lambda x,*args: fitFunc(x, {k:v for k,v in zip(param.keys(),args)}),x, ynoise, [param[k] for k in param.keys()])
fit_par = {k:v for k,v in zip(param.keys(), fit_par)}

非常感谢!

With the comment by Bob with his answer to this post, I could create a solution for my problem.

For everyone who want the solution:

def fitFunc(x, dictionary):
    g = Gauss(x,dictionary)
    return g.calculate()

fit_par,_ = curve_fit(lambda x,*args: fitFunc(x, {k:v for k,v in zip(param.keys(),args)}),x, ynoise, [param[k] for k in param.keys()])
fit_par = {k:v for k,v in zip(param.keys(), fit_par)}

Thank you very much!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文