Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 超高斯拟合_Python_Curve - Fatal编程技术网

Python 超高斯拟合

Python 超高斯拟合,python,curve,Python,Curve,我得研究一下激光束的轮廓。为此,我需要找到一条适合我的数据的超高斯曲线。 超高斯方程: I * exp(- 2 * ((x - x0) /sigma)^P) I * exp(-(x - x0)^2 / (2 * sigma^2)) 其中p考虑了平顶激光束曲线特性 我开始用Python对曲线进行简单的高斯拟合。拟合返回一条高斯曲线,其中I、x0和sigma的值得到优化。(我使用了函数曲线拟合) 高斯曲线方程: I * exp(- 2 * ((x - x0) /sigma)^P) I * ex

我得研究一下激光束的轮廓。为此,我需要找到一条适合我的数据的超高斯曲线。 超高斯方程:

I * exp(- 2 * ((x - x0) /sigma)^P)
I * exp(-(x - x0)^2 / (2 * sigma^2))
其中
p
考虑了平顶激光束曲线特性

我开始用Python对曲线进行简单的高斯拟合。拟合返回一条高斯曲线,其中
I
x0
sigma
的值得到优化。(我使用了函数曲线拟合) 高斯曲线方程:

I * exp(- 2 * ((x - x0) /sigma)^P)
I * exp(-(x - x0)^2 / (2 * sigma^2))
现在,我想向前迈出一步<我想做超高斯曲线拟合< <强>,因为我需要考虑光束的平顶特性。因此,我需要一个拟合来优化P参数

有人知道如何使用Python进行超高斯曲线拟合吗

我知道有一种方法可以用wolfram mathematica进行超高斯拟合,它不是开源的。我没有。因此,我还想知道是否有人知道一个开源软件,借助它可以进行超高斯曲线拟合或执行wolfram mathematica


谢谢

好吧,您需要编写一个函数来计算参数化的超高斯函数,并使用它来建模数据,比如说使用
scipy.optimize.curve\u fit
。作为LMFIT()的主要作者,它提供了拟合和曲线拟合的高级接口,我建议尝试使用该库。使用这种方法,您的超高斯模型函数和用于拟合数据的模型函数可能如下所示:

import numpy as np  
from lmfit import Model   

def super_gaussian(x, amplitude=1.0, center=0.0, sigma=1.0, expon=2.0):
    """super-Gaussian distribution
    super_gaussian(x, amplitude, center, sigma, expon) =
        (amplitude/(sqrt(2*pi)*sigma)) * exp(-abs(x-center)**expon / (2*sigma**expon))
    """
    sigma = max(1.e-15, sigma)
    return ((amplitude/(np.sqrt(2*np.pi)*sigma))
            * np.exp(-abs(x-center)**expon / 2*sigma**expon))

# generate some test data
x = np.linspace(0, 10, 101)
y = super_gaussian(x, amplitude=7.1, center=4.5, sigma=2.5, expon=1.5)
y += np.random.normal(size=len(x), scale=0.015)

# make Model from the super_gaussian function
model = Model(super_gaussian)

# build a set of Parameters to be adjusted in fit, named from the arguments 
# of the model function (super_gaussian), and providing initial values
params = model.make_params(amplitude=1, center=5, sigma=2., expon=2)

# you can place min/max bounds on parameters
params['amplitude'].min = 0
params['sigma'].min = 0
params['expon'].min = 0
params['expon'].max = 100

# note: if you wanted to make this strictly Gaussian, you could set 
# expon=2  and prevent it from varying in the fit:
### params['expon'].value = 2.0
### params['expon'].vary = False

# now do the fit
result = model.fit(y, params, x=x)

# print out the fit statistics, best-fit parameter values and uncertainties
print(result.fit_report())

# plot results
import matplotlib.pyplot as plt
plt.plot(x, y, label='data')
plt.plot(x, result.best_fit, label='fit')
plt.legend()
plt.show()
from scipy import optimize

opt, _ = optimize.curve_fit(super_gaussian, x, y)
vals = super_gaussian(x, *opt)
这将打印一份报告,如

[[Model]]
    Model(super_gaussian)
[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 53
    # data points      = 101
    # variables        = 4
    chi-square         = 0.02110713
    reduced chi-square = 2.1760e-04
    Akaike info crit   = -847.799755
    Bayesian info crit = -837.339273
[[Variables]]
    amplitude:  6.96892162 +/- 0.09939812 (1.43%) (init = 1)
    center:     4.50181661 +/- 0.00217719 (0.05%) (init = 5)
    sigma:      2.48339218 +/- 0.02134446 (0.86%) (init = 2)
    expon:      3.25148164 +/- 0.08379431 (2.58%) (init = 2)
[[Correlations]] (unreported correlations are < 0.100)
    C(amplitude, sigma) =  0.939
    C(sigma, expon)     = -0.774
    C(amplitude, expon) = -0.745
[[Model]]
模型(超高斯)
[[Fit统计数据]]
#拟合方法=最小二乘法
#函数evals=53
#数据点=101
#变量=4
卡方检验=0.02110713
缩减卡方检验=2.1760e-04
Akaike信息临界值=-847.799755
贝叶斯信息临界值=-837.339273
[[变量]]
振幅:6.96892162+/-0.09939812(1.43%)(初始值=1)
中心:4.50181661+/-0.00217719(0.05%)(初始值=5)
西格玛:2.48339218+/-0.02134446(0.86%)(初始值=2)
指数:3.25148164+/-0.08379431(2.58%)(初始值=2)
[[相关性]](未报告的相关性<0.100)
C(振幅,σ)=0.939
C(sigma,expon)=-0.774
C(振幅,指数)=-0.745
生成一个这样的图

将y(x)=a*exp(-b*(x-c)**p)拟合到参数a、b、c、p的数据

下面的数值演算示例显示了一种不需要初始猜测参数的非迭代方法

这是本文中解释的一般原则的应用:

在本文的当前版本中,没有明确处理超高斯的情况。没有必要阅读论文,因为下面的屏幕副本显示了整个演算的细节

请注意,数值结果a、b、c、p可用作回归的经典迭代方法的初始值

注:

所考虑的线性方程为:


A、 B、C、D是通过线性回归计算的参数。积分的数值S(k)通过对给定数据进行数值积分直接计算(如上例所示)。

这是超高斯函数

    def super_gaussian(x, amp, x0, sigma):
        rank = 2
        return amp * ((np.exp(-(2 ** (2 * rank - 1)) * np.log(2) * (((x - x0) ** 2) / ((sigma) ** 2)) ** (rank))) ** 2)
然后您需要使用scipy优化曲线拟合调用它,如下所示:

import numpy as np  
from lmfit import Model   

def super_gaussian(x, amplitude=1.0, center=0.0, sigma=1.0, expon=2.0):
    """super-Gaussian distribution
    super_gaussian(x, amplitude, center, sigma, expon) =
        (amplitude/(sqrt(2*pi)*sigma)) * exp(-abs(x-center)**expon / (2*sigma**expon))
    """
    sigma = max(1.e-15, sigma)
    return ((amplitude/(np.sqrt(2*np.pi)*sigma))
            * np.exp(-abs(x-center)**expon / 2*sigma**expon))

# generate some test data
x = np.linspace(0, 10, 101)
y = super_gaussian(x, amplitude=7.1, center=4.5, sigma=2.5, expon=1.5)
y += np.random.normal(size=len(x), scale=0.015)

# make Model from the super_gaussian function
model = Model(super_gaussian)

# build a set of Parameters to be adjusted in fit, named from the arguments 
# of the model function (super_gaussian), and providing initial values
params = model.make_params(amplitude=1, center=5, sigma=2., expon=2)

# you can place min/max bounds on parameters
params['amplitude'].min = 0
params['sigma'].min = 0
params['expon'].min = 0
params['expon'].max = 100

# note: if you wanted to make this strictly Gaussian, you could set 
# expon=2  and prevent it from varying in the fit:
### params['expon'].value = 2.0
### params['expon'].vary = False

# now do the fit
result = model.fit(y, params, x=x)

# print out the fit statistics, best-fit parameter values and uncertainties
print(result.fit_report())

# plot results
import matplotlib.pyplot as plt
plt.plot(x, y, label='data')
plt.plot(x, result.best_fit, label='fit')
plt.legend()
plt.show()
from scipy import optimize

opt, _ = optimize.curve_fit(super_gaussian, x, y)
vals = super_gaussian(x, *opt)
“VAL”是需要绘制的,即拟合的超高斯函数

这是使用秩=1得到的结果:

排名=2:

等级=3:
我对@M Newville的回答非常满意

但要小心括号在
超高斯函数定义中的指数商中被忽略

def super_gaussian(x, amplitude=1.0, center=0.0, sigma=1.0, expon=2.0):
    ...
    return ((amplitude/(np.sqrt(2*np.pi)*sigma))
            * np.exp(-abs(x-center)**expon / 2*sigma**expon))
应该由

def super_gaussian(x, amplitude=1.0, center=0.0, sigma=1.0, expon=2.0):
    ...
    return (amplitude/(np.sqrt(2*np.pi)*sigma))
           * np.exp(-abs(x-center)**expon / (2*sigma**expon))
然后是超高斯函数的半高宽,其中写道:

FWHM = 2.*sigma*(2.*np.log(2.))**(1/expon)
计算良好,与绘图非常一致


我很抱歉写这篇文章作为回答。但我的声誉评分很低,无法在M Newville post中添加评论…

您能发布完整的代码吗?还优化了w.r.t.哪个指标?MSE?您正在使用哪些软件包?下面是一组优化器:方程式I*exp(-2*((x-x0)/sigma)^p)为xthanks@JJacquelin生成复杂值,我将尝试按照您的方法执行said@MNewville,如何调用最佳拟合得到的参数振幅、中心、西格玛、指数?我想在合身后使用它们。感谢
result。params
是最佳拟合参数的字典,每个参数都有
stderr
属性(以及其他属性)。因此
result.params['Amplificate'].value
是振幅的最佳拟合值,等等。更多信息,请查看docs()。对于非线性(或可非线性)函数,在该函数中,回归不能保证有效,需要迭代方法,需要初始值,并且无法保证解是全局的。对于某些函数形式和数据集,可以迭代初始值或开发方法来估计初始值(例如,使用峰值位置作为高斯曲线的中心),但仍在进行局部搜索以优化值。初始值总是必需的。@M Newville。我对这种说法并不感到惊讶。这意味着线性化方法的原理仍然被误解。通常被认为是非线性的东西有时是线性的,这要归功于一个包含方便的积分方程的变换。获得线性形式后,线性回归不需要初始值。如果认为当前假定为非线性的所有函数都是可确定为非线性的,这是一个错误。如果您有一种方法来估计类高斯峰的参数值,请绝对使用该方法。事实上,如果它是一个健壮的Python实现,请考虑将其添加到代码< > LMFIT 或类似的工具——这将是非常有用的。