如何在Python中将拟合生成的函数转为数学表达式并进行求导等运算——以Scipy curve_fit高斯拟合为例
获取高斯拟合函数的各阶导数方法
看起来你已经成功用scipy.curve_fit完成了高斯函数对散点的拟合,现在要搞定拟合后高斯函数的各阶导数,其实可以分两种方式来做:手动推导表达式实现,或者用符号计算工具自动生成,下面给你详细说:
先明确你的拟合高斯函数
你定义的高斯函数是:
def gaus(x,a,x0,sigma): return a*np.exp(-(x-x0)**2/(2*sigma**2))/(sigma*np.sqrt(2*np.pi))
用数学表达式写出来就是:
$$g(x) = \frac{a}{\sigma\sqrt{2\pi}} e{-\frac{(x-x_0)2}{2\sigma^2}}$$
其中a, x0, sigma是你通过curve_fit得到的拟合参数(也就是popt里的三个值)。
手动推导低阶导数(一阶、二阶)
一阶导数
用链式法则对x求导:
指数部分的导数是 $-\frac{x-x_0}{\sigma^2}$,再乘以原函数,所以一阶导数表达式为:
$$g'(x) = g(x) \cdot \left( -\frac{x-x_0}{\sigma^2} \right)$$
对应的Python函数可以这么写:
def gaus_deriv1(x, a, x0, sigma): original = gaus(x, a, x0, sigma) return original * (-(x - x0) / (sigma**2))
二阶导数
对一阶导数再求导,用乘积法则展开后整理,得到:
$$g''(x) = g(x) \cdot \left( \frac{(x-x_0)2}{\sigma4} - \frac{1}{\sigma^2} \right)$$
对应的Python函数:
def gaus_deriv2(x, a, x0, sigma): original = gaus(x, a, x0, sigma) term = ((x - x0)**2)/(sigma**4) - 1/(sigma**2) return original * term
高阶导数(三阶及以上)
手动推导高阶导数容易出错,推荐用sympy符号计算库自动推导,步骤如下:
- 先定义符号变量和符号形式的高斯函数
- 调用
sp.diff()求任意阶导数 - 转换成numpy可调用的函数,直接用于你的数组计算
代码示例:
import sympy as sp import numpy as np # 定义符号变量 x_sym, a_sym, x0_sym, sigma_sym = sp.symbols('x a x0 sigma') # 定义符号版高斯函数 gaus_sym = (a_sym / (sigma_sym * sp.sqrt(2*sp.pi))) * sp.exp(-(x_sym - x0_sym)**2 / (2*sigma_sym**2)) # 求一阶导数并转成可调用函数 deriv1_sym = sp.diff(gaus_sym, x_sym) gaus_deriv1 = sp.lambdify((x_sym, a_sym, x0_sym, sigma_sym), deriv1_sym, 'numpy') # 求二阶导数并转成可调用函数 deriv2_sym = sp.diff(gaus_sym, x_sym, 2) gaus_deriv2 = sp.lambdify((x_sym, a_sym, x0_sym, sigma_sym), deriv2_sym, 'numpy') # 求n阶导数(比如三阶) n = 3 derivn_sym = sp.diff(gaus_sym, x_sym, n) gaus_derivn = sp.lambdify((x_sym, a_sym, x0_sym, sigma_sym), derivn_sym, 'numpy')
使用示例
用你拟合得到的popt参数,计算x对应的导数数组:
# 提取拟合参数 a_fit, x0_fit, sigma_fit = popt # 计算一阶导数数组 deriv1_array = gaus_deriv1(x, a_fit, x0_fit, sigma_fit) # 计算三阶导数数组 deriv3_array = gaus_derivn(x, a_fit, x0_fit, sigma_fit)
这样不管是低阶还是高阶导数,都能轻松搞定啦~
内容的提问来源于stack exchange,提问作者imnw_058
相关产品推荐
相关产品推荐

