为什么会这样scipy.odr公司适合使用自定义雅各比色故障?

2024-09-28 23:22:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用scipy.odr将测量的数据点拟合到我的模型中。虽然在不指定jacobians的情况下进行拟合是有效的,但是对于某些模型,我只使用一些模型指定自己的jacobians时会出现分段错误。在

#!/usr/bin/python2
from __future__ import print_function

import numpy as np
import scipy.odr as odr

tspace = np.linspace(0, 10, 100)

def fun(p, x):
    a, x0 = p
    r = a * (x - x0)**2
    return r

def param_jacobian(p, x, *args):
    a, x0 = p
    r = np.array([
        (x.T - x0)**2,
        -2*a*x0*(x.T - x0),
    ])
    return r

def value_jacobian(p, x, *args):
    a, x0 = p
    r = np.array([
        2*a*(x.T - x0),
    ])
    return r

correct = fun((0.5, 3), tspace)

p0 = (0.1, 1)

model = odr.Model(fun, fjacb=param_jacobian, fjacd=value_jacobian)
data = odr.Data(tspace, correct)

fitter = odr.ODR(data, model, beta0=p0)
fitter.set_job(0, 2)
fitter.run()
fitter.output.pprint()

这个例子在python 2.7,64位,scipy0.9.0上发生segfault崩溃。如果您通过调用fitter.set_job(0, 0)fitter.set_job(0, 1)来切换自定义雅可比的用法,那么它是有效的(fit结果在这个示例中很好,但在其他示例中则不行)。在

我的错误在哪里?是我的错吗?在

更新:我又遇到了这个问题。我在fit脚本上运行了gdb和valgrind。gdb向malloc_consolidate显示了一个stacktrace,它是由syslog模块的一些导入尝试所深深调用的……对我来说似乎很奇怪,但我认为这无关紧要,因为valgrind在第一次调用param_jacobian之后(即value_jacobian之后)显示了以下两次。尝试获取结果时发生segfault。我怀疑segfault是由于堆损坏造成的,这可能是odrpack.so中的一个错误。在

^{pr2}$

甚至在第二次调用*_jacobian函数之后:

==32100== Invalid read of size 8
==32100==    at 0x18189BFB: gen_output (in /usr/lib64/python2.7/site-packages/scipy/odr/__odrpack.so)
==32100==    by 0x1818C4BA: odr (in /usr/lib64/python2.7/site-packages/scipy/odr/__odrpack.so)
==32100==    by 0x3A41249382: PyObject_Call (abstract.c:2529)
==32100==    by 0x3A412DA8F6: PyEval_CallObjectWithKeywords (ceval.c:3967)
==32100==    by 0x3A412D89E9: builtin_apply (bltinmodule.c:195)
==32100==    by 0x3A412E03DA: PyEval_EvalFrameEx (ceval.c:4098)
==32100==    by 0x3A412E075D: PyEval_EvalFrameEx (ceval.c:4184)
==32100==    by 0x3A412E19A4: PyEval_EvalCodeEx (ceval.c:3330)
==32100==    by 0x3A412DFF02: PyEval_EvalFrameEx (ceval.c:4194)
==32100==    by 0x3A412E19A4: PyEval_EvalCodeEx (ceval.c:3330)
==32100==    by 0x3A412E1AD1: PyEval_EvalCode (ceval.c:689)
==32100==    by 0x3A412FBD5B: run_mod (pythonrun.c:1361)
==32100==  Address 0x10207b40 is 0 bytes inside a block of size 80 free'd
==32100==    at 0x4A0662E: free (vg_replace_malloc.c:366)
==32100==    by 0xC1050FF: ??? (in /usr/lib64/python2.7/site-packages/numpy/core/multiarray.so)
==32100==    by 0xC110199: ??? (in /usr/lib64/python2.7/site-packages/numpy/core/multiarray.so)
==32100==    by 0x18189A7E: gen_output (in /usr/lib64/python2.7/site-packages/scipy/odr/__odrpack.so)
==32100==    by 0x1818C4BA: odr (in /usr/lib64/python2.7/site-packages/scipy/odr/__odrpack.so)
==32100==    by 0x3A41249382: PyObject_Call (abstract.c:2529)
==32100==    by 0x3A412DA8F6: PyEval_CallObjectWithKeywords (ceval.c:3967)
==32100==    by 0x3A412D89E9: builtin_apply (bltinmodule.c:195)
==32100==    by 0x3A412E03DA: PyEval_EvalFrameEx (ceval.c:4098)
==32100==    by 0x3A412E075D: PyEval_EvalFrameEx (ceval.c:4184)
==32100==    by 0x3A412E19A4: PyEval_EvalCodeEx (ceval.c:3330)
==32100==    by 0x3A412DFF02: PyEval_EvalFrameEx (ceval.c:4194)

以及多次类似的错误(Invalid read of size 8来自同一函数)。在

我尝试了LD_PRELOAD来替换发布在this (mostly unrelated) bugreport上的小memcpy,但没用。在


Tags: inbysopackagesusrsitescipyfitter