如何仅为一个参数设置边界 [英] How to set bounds for only one parameter
问题描述
我正在使用scipy.optimize中的curve_fit来拟合我的数据.我有一个适合三个参数(Z1,Z2,Z3)的函数.我想提供界限.但是,我只想提供Z2的边界(Z2必须小于40).我不想为Z1和Z3设置界限.那可能吗?
I'm using curve_fit from scipy.optimize to fit my data. I have a function that fits three parameters (Z1, Z2, Z3). I wannt to provide bounds. However, I'd like to only provide a bound to Z2 (Z2 shall be below 40). I do not want to set bounds for Z1 and Z3. Is that possible?
popt, pcov = curve_fit(func, xdata, ydata, p0 = [Z1, Z2, Z3],
bounds = ((10, 20, 5), (100, 50, 100,)))
# This way I provide bounds to Z1, Z2 and Z3
# I, however, only want to say that Z2 < 40
# Also interesting would be to say Z2 < Z1, with no bounds for Z1 or Z3
推荐答案
在这里,我提供了一个伪代码解决方案,该解决方案仅使用参数的重新映射而不是实际的边界条件
Here I provide a pseudo-code solution that uses just remapping of parameters instead of actual boundary conditions
最初,我们会做类似的事情:
originally we would do something like:
bestA, bestB, bestC = fit( function( x, a, b, c, guesses=( guessA, guessB, guessC) ) )
但是,我们希望b<C.在这种情况下,我们适合以下条件(忽略猜测)
However, we want the restriction that b < c. In such a case we fit the following instead (omitting the guesses)
wrapper_function( x, a, d, c ) = function( x, a, c - d**2, c )
bestA, bestD, bestC = fit( wrapper_function( x, a, d, c ) )
像这样,发送到 function()
的值 b
始终小于 c
.假设拟合收敛,我们只需计算 b = c-d ** 2
.如果我们也对 b
的错误感兴趣,我们必须进行包括相关在内的错误传播.(例如,参见Joel Tellinghuisen,J. Phys.Chem.A 2001,105,3917-3921)
like this the value b
send to function()
will always be less than c
.
Assuming the fit converges we just calculate b = c - d**2
. If we are also interested in the error of b
we have to do error-propagation including correlation. ( see e.g. Joel Tellinghuisen, J. Phys. Chem. A 2001, 105, 3917-3921)
所以 s_b ** 2 = gT V g
.其中 V
是方差-协方差矩阵,[a,d,c] 中的 g = df/du
和 u.那就是
gT =(0,-2 * bestD,1)
.
So s_b**2 = gT V g
. where V
is the variance-covariance matrix and g = df/du
and u in [a, d, c]
. That is gT=(0, -2 * bestD, 1 )
.
现在我们要 b<min(c,40)
.如我的评论中所述,这有点复杂,但也是可能的.我们重写包装函数,并具有
Now we want b < min( c, 40 )
. That is, as mentioned in my comment, a bit more complicated, but also possible. We rewrite the wrapper function and have
wrapper_function( x, a, d, c ) = function( x, a, 0.5 * ( c + 40 - abs( c - 40 ) ) - d**2, c )
bestA, bestD, bestC = fit( wrapper_function( x, a, d, c ) )
这种作法可能并不明显,但是如果绘制 0.5 *(c + 40-abs(c-40))
会很清楚.再次简单地计算 b
.但是对于错误,我们必须谨慎地计算 g
.我们得到
It might not be obvious that this does the trick, but if one plots 0.5 * ( c + 40 - abs( c - 40 ) )
it becomes clear. It is again straight forward to calculate b
. For the error we have to be careful with calculating g
, though. We get
g = ( 0, -2 * bestD, 1 - numpy.heaviside( bestC - 40, 0.5 ) )
注意:如果 c
的值和错误使得重新映射的不连续性在误差范围之内,则需要重新考虑.
Note: if the value and error of c
are such that the discontinuity of the remapping is within error margins, this needs to be reconsidered, though.
这篇关于如何仅为一个参数设置边界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!