首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scipy.optimize.leastsq返回最佳猜测参数,而不是新的最佳匹配

scipy.optimize.leastsq返回最佳猜测参数,而不是新的最佳匹配
EN

Stack Overflow用户
提问于 2012-09-18 16:46:33
回答 1查看 6.1K关注 0票数 4

我想要将洛伦兹峰拟合到一组数据x和y上,数据很好。其他程序,如OriginLab,完全适合它,但我想用http://mesa.ac.nz/?page_id=1800自动化拟合,所以我有以下基于python的代码

我遇到的问题是,scipy.optimize.leastsq返回的最符合我传递给它的相同初始猜测参数,实际上什么也不做。下面是代码。

代码语言:javascript
复制
#x, y are the arrays with the x,y  axes respectively
#defining funcitons
def lorentzian(x,p):
  return p[2]*(p[0]**2)/(( x - (p[1]) )**2 + p[0]**2)

def residuals(p,y,x):
  err = y - lorentzian(x,p)
  return err      

p = [0.055, wv[midIdx], y[midIdx-minIdx]]   
pbest = leastsq(residuals, p, args=(y, x), full_output=1)
best_parameters = pbest[0]
print p
print pbest

P是初始猜测,best_parameters是从leastsq返回的“最佳匹配”参数,但它们总是相同的。

这是full_output=1返回的内容(长数字数组已缩短,但仍具有代表性)

代码语言:javascript
复制
    [0.055, 855.50732, 1327.0]
    (array([  5.50000000e-02,   8.55507324e+02,   1.32700000e+03]), 
    None, {'qtf':array([ 62.05192947,  69.98033905,  57.90628052]), 
    'nfev': 4, 
    'fjac': array([[-0.,  0.,  0., 0.,  0.,  0.,  0.,],
    [ 0., -0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.],
    [ 0.,  0., -0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.]]), 
    'fvec': array([  62.05192947,   69.98033905,   
    53.41218567,   45.49879837,   49.58242035,   36.66483688,
    34.74443436,   50.82238007,   34.89669037]), 
    'ipvt': array([1, 2, 3])},  
    'The cosine of the angle between func(x) and any column of the\n  Jacobian 
    is at most 0.000000 in absolute value', 4)

有没有人能看出来哪里不对劲?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-18 20:36:27

在谷歌上快速搜索一下,就会发现数据是单精度的问题(你的其他程序几乎肯定也会调高到双精度,尽管这显然也是scipy的问题,请参阅此bug report)。如果你看你的full_output=1结果,你会发现雅可比在任何地方都近似为零。因此,明确地给出雅可比可能会有所帮助(尽管即使这样,您也可能希望向上转换,因为使用单一精度可以获得的相对误差的最小精度是非常有限的)。

解决方案:最简单且在数值上最好的解决方案(当然,给出真实的雅可比也是一个额外的好处)就是将xy数据转换为双精度(例如,x = x.astype(np.float64)就可以)。

我不建议这样做,但您也可以通过手动设置epsfcn关键字参数(可能还包括容差关键字参数)来修复它,类似于epsfcn=np.finfo(np.float32).eps。这似乎在某种程度上解决了这个问题,但是(因为大多数计算都是标量,并且标量不会强制计算中的向上转换)计算是在float32中完成的,精度损失似乎相当大,至少在不提供Dfunc的情况下是这样。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12473406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档