如何仅为一个参数设置边界 [英] How to set bounds for only one parameter

查看:78
本文介绍了如何仅为一个参数设置边界的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆