题意:为什么我不能准确地将我的模型拟合到杨氏干涉数据上
问题背景:
I'm trying to fit my experimental data from Young's interference experiment to a theoretical model using Python's scipy.optimize
module.
我正在尝试使用Python的scipy.optimize
模块将我的杨氏干涉实验数据拟合到一个理论模型上。
I've tried several optimization techniques including curve_fit
, differential_evolution
, minimize
, and brute
from scipy.optimize
. However, the amplitude of the fitted model is always incorrect and the overall fit is not satisfactory. Here is an example of one of my attempts:
我已经尝试了几种优化技术,包括来自scipy.optimize
的curve_fit
、differential_evolution
、minimize
和brute
。然而,拟合模型的振幅总是不正确,整体拟合效果也不令人满意。以下是我尝试的一个例子:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
# Define the sinc function as in the script
def sinc(x):
return np.sinc(x / np.pi)
# Define the model function
def model(x, a, b, c):
return a * (sinc(b * x) * np.cos(c * x)) ** 2
# Load the data
y = np.array( [0.02085486, 0.0223252, 0.02287308, 0.02270019, 0.02165024, 0.02005928, 0.01743775, 0.0149572, 0.0127511, 0.01004054, 0.00811284, 0.007099063, 0.00657881, 0.006856126, 0.007609479, 0.009156624, 0.01071112, 0.01193813, 0.0133568, 0.01425095, 0.01462454, 0.01458669, 0.01398208, 0.01311625, 0.01195015, 0.01092385, 0.009446857, 0.008498062, 0.007723048, 0.00723161, 0.006764316, 0.006555261, 0.006450833, 0.006393105, 0.006337164, 0.006285795, 0.006239493, 0.006288776, 0.006387143, 0.006603352, 0.007147451, 0.00761385, 0.008180803, 0.008720332, 0.009198257, 0.009372933, 0.009216638, 0.008799125, 0.008328055, 0.007694531, 0.007099659, 0.006994138, 0.007395456, 0.008732553, 0.01094184, 0.01371192, 0.01834799, 0.02259169, 0.02650898, 0.03151805, 0.03531701, 0.03728535, 0.03818665, 0.03729002, 0.03501645, 0.03131357, 0.02488543, 0.01959507, 0.01460477, 0.01044951, 0.008278077, 0.007820024, 0.009991255, 0.01418855, 0.01960242, 0.02838769, 0.03670101, 0.04311405, 0.05049705, 0.05495119, 0.05677555, 0.05654126, 0.05389648, 0.04956594, 0.04227723, 0.03421838, 0.02738763, 0.01975116, 0.01412466, 0.01061951, 0.008191236, 0.007492233, 0.008472824, 0.01039993, 0.01288762, 0.01499844, 0.01732537, 0.01898877, 0.01964157, 0.01958294, 0.0188592, 0.01776891, 0.01671609, 0.01545868, 0.01444321, 0.01316325, 0.01217093, 0.01137744, 0.01042178, 0.009623819, 0.009118967, 0.0090206, 0.00982572, 0.01145305, 0.01548968, 0.02116049, 0.02889235, 0.03786581, 0.04742064, 0.05725695, 0.06563773, 0.07137343, 0.07280552, 0.07067801, 0.06525013, 0.05404244, 0.04225587, 0.03289122, 0.02349269, 0.02088854, 0.02553167, 0.04387555, 0.07114182, 0.1022669, 0.1545005, 0.2113436, 0.2602106, 0.3174337, 0.3586576, 0.3816918, 0.3972849, 0.3845007, 0.3595436, 0.307694, 0.2459982, 0.1791345, 0.113812, 0.06640867, 0.04444061, 0.03683028, 0.06902593, 0.136388, 0.2288054, 0.3427509, 0.4399163, 0.6077638, 0.732687, 0.820149, 0.8823909, 0.9029142, 0.8845277, 0.8007603, 0.6942111, 0.5852779, 0.4573111, 0.3023198, 0.1578105, 0.0812789, 0.04687118, 0.06213398, 0.1317424, 0.2511457, 0.3779524, 0.5646756, 0.7380874, 0.8812292, 1.008369, 1.114495, 1.138206, 1.122715, 1.027061, 0.8927684, 0.7369416, 0.5732217, 0.435046, 0.2471665, 0.1278893, 0.07075422, 0.04694907, 0.069715, 0.1655695, 0.2901206, 0.4262551, 0.5651156, 0.6757905, 0.8063518, 0.8792977, 0.9029801, 0.8880144, 0.8292124, 0.7302995, 0.603397, 0.473018, 0.3493579, 0.2565541, 0.1331605, 0.06674094, 0.03888953, 0.04060887, 0.06176127, 0.1224137, 0.1896157, 0.2544133, 0.313964, 0.3554176, 0.3991497, 0.4080271, 0.3967536, 0.3775236, 0.326548, 0.2711567, 0.2121477, 0.159039, 0.1128689, 0.07391876, 0.04551013, 0.03057611, 0.0267551, 0.02981312, 0.04159025, 0.05534625, 0.06766469, 0.08035206, 0.08743082, 0.09017357, 0.08782707, 0.08087897, 0.07145471, 0.06082222, 0.04931634, 0.03846287, 0.02930221, 0.02328343, 0.02028681, 0.01826383, 0.01898429, 0.02077994, 0.02427734, 0.02759668, 0.0309365, 0.03383167, 0.03604543, 0.03731575, 0.03779199, 0.03748834, 0.03652236, 0.03481484, 0.03264838, 0.03008329, 0.02718682, 0.02404106, 0.0210508, 0.01875547, 0.01719342, 0.01673825, 0.01768505, 0.01994929, 0.02433527, 0.0298477, 0.03639925, 0.04381732, 0.05142935, 0.05761922, 0.06284451, 0.06566555, 0.06708095, 0.06545451, 0.06223324, 0.05592343, 0.04883862, 0.04052401, 0.03243476, 0.0258847, 0.02060795, 0.0171497, 0.01585682, 0.01689822, 0.01963769, 0.02379713, 0.02876735, 0.03413194, 0.03883329, 0.04191427, 0.04391778, 0.04425918, 0.04292377, 0.0401843, 0.03668839, 0.03233341, 0.02770399, 0.02401175, 0.01920945, 0.01641483, 0.01436611, 0.01309737, 0.01256162, 0.01261328, 0.01294793, 0.01330036, 0.0137766, 0.01398099, 0.01395406, 0.01371202, 0.01329808, 0.01280237, 0.01227576, 0.01190186, 0.01150203, 0.01128751, 0.01118984, 0.01117633, 0.01121856, 0.01126715, 0.01133739, 0.01141082, 0.01155251, 0.01176385, 0.01208379, 0.01258546, 0.0132947, 0.01422243, 0.01528698, 0.01630563, 0.0171802, 0.01791438, 0.01823571, 0.01826701, 0.01779207, 0.01702599, 0.0158907, 0.01459225, 0.0133724, 0.01243285, 0.01187027, 0.01180995])
x = np.array([45.6, 45.8, 46.0, 46.2, 46.4, 46.6, 46.8, 47.0, 47.2, 47.4, 47.6, 47.8, 48.0, 48.2, 48.4, 48.6, 48.8, 49.0, 49.2, 49.4, 49.6, 49.8, 50.0, 50.2, 50.4, 50.6, 50.8, 51.0, 51.2, 51.4, 51.6, 51.8, 52.0, 52.2, 52.4, 52.6, 52.8, 53.0, 53.2, 53.4, 53.6, 53.8, 54.0, 54.2, 54.4, 54.6, 54.8, 55.0, 55.2, 55.4, 55.6, 55.8, 56.0, 56.2, 56.4, 56.6, 56.8, 57.0, 57.2, 57.4, 57.6, 57.8, 58.0, 58.2, 58.4, 58.6, 58.8, 59.0, 59.2, 59.4, 59.6, 59.8, 60.0, 60.2, 60.4, 60.6, 60.8, 61.0, 61.2, 61.4, 61.6, 61.8, 62.0, 62.2, 62.4, 62.6, 62.8, 63.0, 63.2, 63.4, 63.6, 63.8, 64.0, 64.2, 64.4, 64.6, 64.8, 65.0, 65.2, 65.4, 65.6, 65.8, 66.0, 66.2, 66.4, 66.6, 66.8, 67.0, 67.2, 67.4, 67.6, 67.8, 68.0, 68.2, 68.4, 68.6, 68.8, 69.0, 69.2, 69.4, 69.6, 69.8, 70.0, 70.2, 70.4, 70.6, 70.8, 71.0, 71.2, 71.4, 71.6, 71.8, 72.0, 72.2, 72.4, 72.6, 72.8, 73.0, 73.2, 73.4, 73.6, 73.8, 74.0, 74.2, 74.4, 74.6, 74.8, 75.0, 75.2, 75.4, 75.6, 75.8, 76.0, 76.2, 76.4, 76.6, 76.8, 77.0, 77.2, 77.4, 77.6, 77.8, 78.0, 78.2, 78.4, 78.6, 78.8, 79.0, 79.2, 79.4, 79.6, 79.8, 80.0, 80.2, 80.4, 80.6, 80.8, 81.0, 81.2, 81.4, 81.6, 81.8, 82.0, 82.2, 82.4, 82.6, 82.8, 83.0, 83.2, 83.4, 83.6, 83.8, 84.0, 84.2, 84.4, 84.6, 84.8, 85.0, 85.2, 85.4, 85.6, 85.8, 86.0, 86.2, 86.4, 86.6, 86.8, 87.0, 87.2, 87.4, 87.6, 87.8, 88.0, 88.2, 88.4, 88.6, 88.8, 89.0, 89.2, 89.4, 89.6, 89.8, 90.0, 90.2, 90.4, 90.6, 90.8, 91.0, 91.2, 91.4, 91.6, 91.8, 92.0, 92.2, 92.4, 92.6, 92.8, 93.0, 93.2, 93.4, 93.6, 93.8, 94.0, 94.2, 94.4, 94.6, 94.8, 95.0, 95.2, 95.4, 95.6, 95.8, 96.0, 96.2, 96.4, 96.6, 96.8, 97.0, 97.2, 97.4, 97.6, 97.8, 98.0, 98.2, 98.4, 98.6, 98.8, 99.0, 99.2, 99.4, 99.6, 99.8, 100.0, 100.2, 100.4, 100.6, 100.8, 101.0, 101.2, 101.4, 101.6, 101.8, 102.0, 102.2, 102.4, 102.6, 102.8, 103.0, 103.2, 103.4, 103.6, 103.8, 104.0, 104.2, 104.4, 104.6, 104.8, 105.0, 105.2, 105.4, 105.6, 105.8, 106.0, 106.2, 106.4, 106.6, 106.8, 107.0, 107.2, 107.4, 107.6, 107.8, 108.0, 108.2, 108.4, 108.6, 108.8, 109.0, 109.2, 109.4, 109.6, 109.8, 110.0, 110.2, 110.4, 110.6, 110.8, 111.0, 111.2, 111.4, 111.6, 111.8, 112.0, 112.2, 112.4, 112.6, 112.8, 113.0, 113.2, 113.4, 113.6, 113.8, 114.0, 114.2, 114.4])
# Perform the fit
param_init = [13, 0.01, 0.8] # Initial fit parameters
params, params_covariance = curve_fit(model, x, y, p0=param_init)
# Plot results
x_fit = np.linspace(min(x), max(x), 100001)
# Plot raw data
plt.plot(x, y, label='Data', markersize=10)
# Plot initial parameters and fit results
plt.plot(x_fit, model(x_fit, *param_init), '-', label='Param Init', linewidth=2)
plt.plot(x_fit, model(x_fit, *params), '-', label='Fit', linewidth=2)
plt.legend()
# Show the plot
plt.show()
问题解决:
You need to include the x offset to your model: 你需要将x偏移量包含到你的模型中
def model(x, a, b, c, d):
x = x - d
return a * (sinc(b * x) * np.cos(c * x)) ** 2
and also use decent init params:
并且还要使用合适的初始参数(init params)
param_init = [1.2, 0.2, 0.8, 81] # Initial fit parameters