我需要使用非线性调整从Van Der Waals方程中的a和b确定值。我对sci-py几乎一无所知。我发现scipy.optimize.curve_fit进行了最小二乘的非线性调整,但是我不确定是否使用正确。我已经搜索了,但是什么都没改变。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
r = 8.314472
t = 273
data = pd.read_excel("gases_data.xls", skiprows=2)
pressure = np.array(data.get(data.columns[0]))
hydrogen = np.array(data.get(data.columns[1]))
nitrogen = np.array(data.get(data.columns[3]))
def ff(L, a, b):
return (r*t)/(L - b) - (a/L**2)
pfit, perr = curve_fit(ff,hydrogen,pressure)
y_fit = ff(hydrogen, *pfit)
plt.plot(hydrogen, pressure, "ro", label = "data")
plt.plot(hydrogen, y_fit, "b", label = "fit")
plt.text(10, 3, "a = " + str(pfit[0]) + "\nb = " + str(pfit[1]))
plt.legend()
plt.grid(True)
plt.show()
答案 0 :(得分:0)
curve_fit
,范德华力不是最好的功能。尝试增加传递给函数的参数(例如创建jacobian并添加边界)
from scipy.optimize import curve_fit
import numpy as np
import scipy.constants as spc
import matplotlib.pyplot as plt
R = spc.R
T = spc.convert_temperature(0, 'C', 'K')
l_data = np.linspace(0.1, 20, 30)
a, b = 2.45e-2 , 26.61e-6
def P_vdw(L, a, b):
return R * T / (L - b) - a / L**2
def jac(L, a, b):
return np.array([-1 / L**2, R * T / (L - b)**2]).T
p_data = P_vdw(l_data, a * np.random.normal(1, 0.001, 30), b* np.random.normal(1, 0.001, 30))
plt.semilogy(l_data, p_data)
popt, popv = curve_fit(P_vdw, l_data, p_data, jac=jac,
bounds=[(1e-3, 1e-7), (1.0, 1e-6)],
method='trf')
plt.semilogy(l_data, P_vdw(l_data, *popt), 'ro')
print(popt)