在Python中为高斯光束斩波实验数据拟合误差函数
高斯光束遮挡拟合问题的解决方案
问题分析
你的代码存在几个关键问题导致拟合效果不佳:
- 语法错误:
ydata数组末尾的0.0)是语法错误,会直接导致代码运行失败。 - 拟合函数刚性过强:硬编码了总功率为
2.55,但实验测量的初始功率可能存在误差,限制了算法的优化空间。 - 缺少初始参数猜测:
curve_fit默认用全1的初始值,与wx(腰斑半径)的真实值偏差过大,容易收敛到局部最优。 - 未考虑系统偏移:实验中很难保证x=0时刀片完全对准高斯光束中心,位置偏移会导致拟合偏差。
修正后的代码
import matplotlib.pyplot as plt from scipy.optimize import curve_fit import numpy as np # 补充缺失的numpy导入 from math import sqrt from scipy.special import erf # 修正语法错误后的实验数据 xdata = np.array([0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165]) ydata = np.array([2.55, 2.54, 2.54, 2.53, 2.52, 2.5 , 2.48, 2.45, 2.4 , 2.34, 2.27, 2.17, 2.04, 1.9 , 1.73, 1.53, 1.33, 1.12, 0.92, 0.73, 0.56, 0.42, 0.31, 0.22, 0.15, 0.1, 0.07, 0.04, 0.03, 0.02, 0.01, 0.01, 0.01, 0.0]) # 优化后的拟合函数:新增总功率P0和位置偏移x0参数 def P(x, P0, wx, x0): return (P0/2)*(1 - erf(sqrt(2)*(x - x0)/wx)) # 提供初始参数猜测,贴合实验数据趋势 initial_guess = [2.55, 50, 0] # 执行拟合,提升迭代次数确保收敛 popt, pcov = curve_fit(P, xdata, ydata, p0=initial_guess, maxfev=10000) # 输出拟合结果 P0_fit, wx_fit, x0_fit = popt print(f"拟合总功率P0: {P0_fit:.2f} mW") print(f"拟合腰斑半径wx: {wx_fit:.2f} mm") print(f"拟合位置偏移x0: {x0_fit:.2f} mm") # 绘图展示 plt.plot(xdata, ydata, 'b+:', label='实验数据') plt.plot(xdata, P(xdata, *popt), 'r-', label='拟合曲线') plt.legend() plt.xlabel('距离 [mm]') plt.ylabel('功率 [mW]') plt.show()
关键改动说明
- 补充
numpy导入:原代码使用np.array但未导入库,会引发运行错误。 - 修正
ydata语法错误:解决数组定义的语法问题。 - 重构拟合函数:新增
P0(总功率)和x0(位置偏移)参数,让算法自动适配实验误差。 - 添加初始参数猜测:基于实验数据趋势给出初始值,帮助
curve_fit快速收敛到全局最优。 - 输出拟合参数:便于直接读取腰斑半径等关键结果。
后续优化建议
如果拟合效果仍不理想,可以:
- 调整
initial_guess中的wx初始值,比如根据数据下降一半的位置估算。 - 检查实验数据的测量噪声,考虑对数据做平滑处理。
- 增加
curve_fit的迭代次数,或设置参数的边界范围(通过bounds参数)。
内容的提问来源于stack exchange,提问作者Francisco García
相关产品推荐
相关产品推荐

