激光束半径W(z)与传输距离z拟合结果异常求助
激光束腰参数拟合异常问题分析与解决思路
我在1-200cm范围内选取14个点位测量了激光束半径,尝试用curve_fit()求解束腰半径Wo和束腰位置Zo的最优值,但拟合结果异常:得到Wo=0.75mm,Zo=0.1cm,可实测数据显示z=160cm处半径仅0.595mm(小于0.75mm),显然束腰应该在z=160cm附近。不确定是否该用curve_fit,也不了解fitpredict用法,试过监督学习没进展,求思路和反馈。
附上原代码
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt def BeamRadius(z, Wo, Zo): return Wo * np.sqrt(1 + (((4.03225 * 10**-13) / (np.pi**2)) * ((z-Zo) / Wo)**2)) def difdiv(l, Wo): return 2*(l/(np.pi*Wo)) def main(): # z : distance from laser, zo: where the waist/ laser focus is z1 = 10*10 z2= 20*10 # *10 to get mm z3= 30*10 z4= 50*10 z5= 70*10 z6= 100*10 z7 = 110*10 z8= 140*10 z9= 150*10 z10= 155*10 z11= 160*10 z12= 165*10 z13= 170*10 z14= 180*10 # Beam Radius in mm at z cm from the laser wz1 = 1.02 wz2= 1.0035 # mm wz3= 0.9695 wz4= 0.9385 wz5= 0.885 wz6= 0.7465 wz7 = 0.715 wz8= 0.625 wz9= 0.613775 wz10= 0.60936 wz11= 0.595 wz12= 0.605 wz13= 0.61815 wz14= 0.6465 z_array = np.array([z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14]) wz_array = np.array([wz1, wz2, wz3, wz4, wz5, wz6, wz7, wz8, wz9,wz10,wz11,wz12,wz13,wz14]) print(z_array, "and ", wz_array) p_opt, p_cov = curve_fit(BeamRadius, z_array, wz_array) BeamFit = BeamRadius(z_array, p_opt[0], p_opt[1])
问题根源排查
- 公式错误:原
BeamRadius函数的高斯光束半径公式完全错误。标准高斯光束半径公式为:
$w(z) = w_0 \sqrt{1 + \left( \frac{\lambda (z - z_0)}{\pi w_0^2} \right)^2}$
你代码中的系数4.03225e-13单位转换混乱,导致函数形状与实测数据完全不匹配,这是拟合结果离谱的核心原因。 - 初始值缺失:
curve_fit默认初始值为[1,1],但你的数据束腰在1600mm(160cm)附近、Wo接近0.6mm,无合理初始值的话,优化器极易陷入局部最优解。 - 单位不一致:z已转换为毫米,但波长的单位转换错误,进一步放大了公式计算误差。
修正方案
修正高斯光束公式
统一单位为毫米(假设激光波长为403.225nm,转换为毫米是403.225e-6),正确实现公式:def BeamRadius(z, Wo, Zo): λ = 403.225e-6 # 激光波长,单位mm return Wo * np.sqrt(1 + ((λ * (z - Zo)) / (np.pi * Wo**2))**2)给curve_fit指定合理初始值
根据实测数据设置初始参数,引导优化器向正确方向搜索:p_opt, p_cov = curve_fit(BeamRadius, z_array, wz_array, p0=[0.6, 1600])添加绘图验证与结果输出
在main函数末尾添加代码,直观对比拟合效果并输出结果:plt.scatter(z_array, wz_array, label='实测数据') plt.plot(z_array, BeamFit, label='拟合曲线', color='red') plt.xlabel('距离z (mm)') plt.ylabel('光束半径w(z) (mm)') plt.legend() plt.show() print(f"拟合束腰半径Wo: {p_opt[0]:.4f} mm") print(f"拟合束腰位置Zo: {p_opt[1]/10:.2f} cm")
其他建议
- 无需使用监督学习:这是典型的参数拟合问题,
curve_fit完全足够,监督学习属于过度复杂的方案。 - 验证拟合质量:可计算均方误差评估拟合效果:
mse = np.mean((BeamFit - wz_array)**2) print(f"拟合均方误差MSE: {mse:.6f}") - 严格统一单位:所有物理量(波长、距离、半径)的单位必须一致,避免计算错误。
内容的提问来源于stack exchange,提问作者Kelia
相关产品推荐
相关产品推荐

