Python 使用scipy.optimize.minimize()

Python 使用scipy.optimize.minimize(),python,scipy-optimize,Python,Scipy Optimize,我需要将模型与数据进行比较,以找到最佳拟合输入。我的数据是物体在不同波长下的表面反射率(=散射光+热发射),我用普朗克定律模拟热发射部分的反射率。我需要找到模拟发射(以及反射率)与观测值相符的温度 为此,我将普朗克定律定义为: h = 6.626070e-34 # the Planck constant c = 2.997924e+8 # the speed of light in vacuum k = 1.380649e-23 # the Boltzmann constant def pl

我需要将模型与数据进行比较,以找到最佳拟合输入。我的数据是物体在不同波长下的表面反射率(=散射光+热发射),我用普朗克定律模拟热发射部分的反射率。我需要找到模拟发射(以及反射率)与观测值相符的温度

为此,我将普朗克定律定义为:

h = 6.626070e-34 # the Planck constant
c = 2.997924e+8  # the speed of light in vacuum
k = 1.380649e-23 # the Boltzmann constant

def planck(T):  # Planck's law for black body radiation
    intensity = (2*h*c**2) / ( ((wvleng*1e-9)**5) * (np.exp(h*c/((wvleng*1e-9)*k*T)) - 1.0) )
    thermal = 0.95 * (intensity*np.pi*D**2)/(SSI*1e9)
    return thermal
它以不同的波长返回身体的热辐射。 然后,我定义了将限定拟合的函数(每个波长下模型和数据之间的平方差之和):

式中,T是黑色体温。最后,我使用
optimize.minimize
来找出哪个T导致S(模拟反射率)和数据反射率之间的最佳拟合:

x0 = 345.0  # initial guess, temperature is the only variable
res = scipy.optimize.minimize(residuals, x0, method='SLSQP') # optimization
fitted_temperature = res.x

问题是:它给我的温度比它应该的温度低了很多(~220K)(大约340K),根本不符合数据。有人知道它为什么不能正确收敛吗?提前感谢。

根据
scipy.optimize.minimize
文档x0应该是“初始猜测。大小为(n,)的实数元素数组,其中'n'是自变量的数量。”因此您猜测温度T=345将最小化平方差之和。然后,这将为数据中的所有T返回一个最佳T(假设您有多个样本),以最小化此函数。显然,你知道答案应该是340K左右,所以我想你的公式中有一个错误,导致了
planck()
函数的导入或导出


查看
res
输出的其他属性,看看是否有额外的线索,也不会有什么坏处。

根据
scipy.optimize.minimize
文档x0应该是,“初始猜测。大小为(n,)的实元素数组,其中'n'是自变量的数量。”所以你猜温度T=345会使平方差之和最小化。然后,这将为数据中的所有T返回一个最佳T(假设您有多个样本),以最小化此函数。显然,你知道答案应该是340K左右,所以我想你的公式中有一个错误,导致了
planck()
函数的导入或导出


查看
res
输出的其他属性,看看是否有额外的线索,也不会有什么坏处。

好的,我的代码中有几个问题:

1) 在我的
planck
函数中,我的热辐射相对于太阳光谱辐照度是
thermal=0.95*(强度*4*np.pi)/(SSI*1e9)
而不是
thermal=0.95*(强度*np.pi*D**2)/(SSI*1e9)

2) 最大的错误是在我的
残差
函数中,它给了我~200K而不是~300。其目的是将观察到的“整体”反射光谱(=背散射光+热发射)与模拟的“整体”光谱(正确计算为
S=散射光+0.95*普朗克(T))之间的差异降至最低
残差中
。此函数返回后向散射光和模拟的总反射光谱之间的平方差之和(=baskscaterred+thermal)这一事实导致了错误:由于背散射光的“量”比研究波长的热发射要“小”得多,因此它试图拟合“小”数据(从而解释低温拟合)

我改变了这一点,现在我得到了~313K的温度,这与我观察到的整体反射曲线非常吻合


谢谢大家的回复!

好的,我的代码中有几个问题:

1) 在我的
planck
函数中,我的热辐射相对于太阳光谱辐照度是
thermal=0.95*(强度*4*np.pi)/(SSI*1e9)
而不是
thermal=0.95*(强度*np.pi*D**2)/(SSI*1e9)

2) 最大的错误是在我的
残差
函数中,它给了我~200K而不是~300。其目的是将观察到的“整体”反射光谱(=背散射光+热发射)与模拟的“整体”光谱(正确计算为
S=散射光+0.95*普朗克(T))之间的差异降至最低
残差中
。此函数返回后向散射光和模拟的总反射光谱之间的平方差之和(=baskscaterred+thermal)这一事实导致了错误:由于背散射光的“量”比研究波长的热发射要“小”得多,因此它试图拟合“小”数据(从而解释低温拟合)

我改变了这一点,现在我得到了~313K的温度,这与我观察到的整体反射曲线非常吻合


谢谢大家的回答!

你可能遇到了数值问题。你有没有可能在对数空间中进行计算?你的黑体辐射方程可能是错的吗?我看到的黑体辐射普朗克定律的方程与你的编码不同。强度一是正确的,但是的,我是错的如果将强度[W./m²/nm]转换为热通量密度[W/m2]有问题,我会修改它。但是我使用minimize的方法正确吗?我花了一整天的时间来弄清楚它是如何工作的,我仍然不确定这部分代码是否正确。谢谢你的回答!这里有几个项目让我绊倒了。1)
plank()
函数中有几个未定义的参数:SSI和wvleng。这些是自变量还是常数?2) 剩余的是什么?我不相信
Scipy.optimize.minimize
关心残差-残差通常是为了尝试适应一个
x0 = 345.0  # initial guess, temperature is the only variable
res = scipy.optimize.minimize(residuals, x0, method='SLSQP') # optimization
fitted_temperature = res.x