【问题标题】:curve_fit: calculations with x before fitcurve_fit:在拟合之前使用 x 进行计算
【发布时间】:2016-01-27 13:14:54
【问题描述】:

我正在使用 scipy 包的 curve_fit 函数来拟合一些实验数据。我这样写了我的目标函数:

def binding21(G0, eps1, eps2, K1, K2):

    A = K1 * K2
    B = K1 * (2 * K2 * H0 - K2 * G0 + 1)
    C = K1 * (H0 - G0) + 1
    D = G0

    roots = np.roots([A, B, C, -D])
    roots = [value for value in roots if np.isreal(value)]
    G = max(roots)

    y = (eps1 * H0 * K1 * G + eps2 * H0 * K1 * K2 * G**2) / \
        (1 + K1 * G + K1 * K2 * G**2)

    return y

G0 是我的 x 值数组。但是,我在目标函数中使用的模型并未定义为 y=f(G0),而是定义为 y=f(G=f(G0))。

在计算 y 之前,我需要找到 G=f(G0) 的根:我必须选择返回的根中最小的正值,并将其分配给 G。

现在,前面的代码返回:

Traceback (most recent call last):
  File "/home/djipey/Working/Data_boss/21.py", line 80, in <module>
    result = mod.fit(y, G0=x)
  File "/usr/lib/python3.5/site-packages/lmfit/model.py", line 506, in fit
    output.fit(data=data, weights=weights)
  File "/usr/lib/python3.5/site-packages/lmfit/model.py", line 710, in fit
    self.init_fit    = self.model.eval(params=self.params, **self.userkws)
  File "/usr/lib/python3.5/site-packages/lmfit/model.py", line 372, in eval
    result = self.func(**self.make_funcargs(params, kwargs))
  File "/home/djipey/Working/Data_boss/21.py", line 38, in binding21
    roots = np.roots([A, B, C, -D])
  File "/usr/lib/python3.5/site-packages/numpy/lib/polynomial.py", line 207, in roots
    p = atleast_1d(p)
  File "/usr/lib/python3.5/site-packages/numpy/core/shape_base.py", line 50, in atleast_1d
    ary = asanyarray(ary)
  File "/usr/lib/python3.5/site-packages/numpy/core/numeric.py", line 525, in asanyarray
    return array(a, dtype, copy=False, order=order, subok=True)
ValueError: setting an array element with a sequence.

因为我正在尝试使用 G0 查找根,所以它不是单个值,而是一个数组。

你能帮我解决这个问题吗?

编辑:

我基本上是在尝试拟合这个等式:

与:

Epsilon_HG、Epsilon_HG2、K1 和 K2 是参数。 H0 是一个已知常数。 G 是该模型中的变量。而 G 取决于 G0,这是我给模型的“x”值。

我有几个 Y=f(G0) 的实验数据点。但我需要拟合 Y=f(G)。 G只能通过求解上面的三次方程得到。

【问题讨论】:

  • 哪一行抛出异常?
  • 我添加了完整的回溯。
  • 我不完全理解您要计算的内容,但参考 numpy.roots 的 documentation 时错误很明显。它计算多项式的根,其中系数以 array_like 形式给出,例如标量列表。您使用具有 3 个标量和一个数组的列表。您希望多项式看起来如何? G0 中的所有元素都是多项式的系数吗?
  • 我添加了我试图求解/拟合的方程。基本上,我需要的是:在评估 Y 函数时访问 G0 的特定值。
  • 你能添加你正在使用的数据吗?!

标签: python scipy


【解决方案1】:

我终于找到了解决办法,其实很简单:

G = []


def binding21(G0, eps1, eps2, K1, K2):

    global G

    G = []

    for value in G0:
        A = K1 * K2
        B = K1 * (2 * K2 * H0 - K2 * value + 1)
        C = K1 * (H0 - value) + 1
        D = value

        roots = np.roots([A, B, C, -D])

        roots = [float(value) for value in roots if np.isreal(value)]

        G.append(max(roots))

    G = np.array(G)

    y = (eps1 * H0 * K1 * G + eps2 * H0 * K1 * K2 * G**2) / \
        (1 + K1 * G + K1 * K2 * G**2)

    return y

我基本上在curve_fit的每次迭代中重新计算G。但是我必须对整个列表都这样做,我不能使用一个特定的值。所以,我只是为整个列表做这件事:)

因为我需要 G 的最终值,所以我不得不使用一个全局变量。我知道这很糟糕,但在这种情况下我找不到更好的解决方案。

对于那里的化学家来说,这个 sn-p 用于拟合结合实验的滴定(模型 1:2)。

【讨论】:

  • 我也不喜欢使用全局变量,所以我要做的就是将 G 的计算外包给另一个函数 def calcG(G0, K1, K2, H0):...。优化后,您可以再次调用该函数以获取G。另一种方法是将您的代码包装到一个以G 作为成员的类中。
  • 是的。如果我的脚本变得更大,我会选择其中一种解决方案。目前,全局变量还没有那么邪恶。
猜你喜欢
  • 2019-01-23
  • 1970-01-01
  • 2021-11-05
  • 2018-11-04
  • 2020-06-08
  • 2012-06-07
  • 2019-02-12
  • 1970-01-01
  • 2018-10-21
相关资源
最近更新 更多