Scipy 曲线拟合(优化)- 使用自定义函数矢量化条件以识别阈值

Scipy curve fit (optimization) - vectorizing a conditional to identify threshold using a custom function

我正在尝试使用 scipy curve_fit 来捕获 a0 参数的值。截至目前,它没有变化(始终显示为 1):

X = [[1,2,3],[4,5,6]]
def func(X, a0, c):
     x1 = X[0]; x2 = X[1]
     a = x1*x2
     result = np.where(a(a<a0), -c*(a + np.sqrt(x2)), -c*x1)
     return result

Popt, Cov = scipy.curve_fit(func, X, y) 
a0, c = Popt
Predicted = func(X, a0, c) # a0 and c are constants

我得到了 c 的值,它是一个标量,没有任何问题。我无法解释为什么 a0(也是标量)始终为 1,而且我不确定如何修复它。我确实在 SO 上看到 elsewhere 可以像我在这里使用的那样使用 np.where,但显然不适用于 curve_fit 函数。也许我需要使用不同的优化方法,我想要一些使用 scipy 方法来做到这一点的指示。

编辑:我尝试了 Brad 建议的构造,但不是这样。

已更新!

这应该有效。请注意,a 变量在此示例中是长度为 3 的向量,因为它是通过 X(2x3 矩阵)的第一个和第二个元素的逐元素乘法计算得出的。因此 a0 可以是标量或长度为 3 的向量,c 也可以是标量或长度为 3 的向量。

import numpy as np


X = np.array([[1, 2, 3], [4, 5, 6]])

a0 = np.array([8,25,400])
# a0 = 2


# Code works whether C is scalar or a matrix since it can be broadcast to matrix a below.
# c = 3 # Uncomment this for scalar
c = np.array([8, 12, 2000])  # Element wise


def func(X, a0, c):
    x = X[0]
    y = X[1]
    a = x * y
    print(a.shape)
    result = np.where(a < a0, c * (a + np.sqrt(y)), c * x)
    return result


func(X, a0, c)

这是最低限度的有效代码。请注意,我删除了 y>0 并将 a 定义为与 c 相同的大小。现在您得到了正确的插入,因为 np.where 的第一个参数现在与第二个和第三个参数的大小相同。在 (x<a) & (y>0) 之前总是评估为 TrueFalse 并且在这种情况下这是一个标量。如果 a 是一个 N 维数组,你会收到一个 ValueError 因为操作数不能一起广播

import numpy as np


c = np.array([[22,34],[33,480]])


def func(X, a):
     x = X[0]; y = X[1]
     return np.where(c[(x<a)], -c*(a + np.sqrt(y)), -c*x)


X = [25, 600]
a = np.array([[2,14],[33,22]])

func(X,a)

如果 c 是常量并且 a 是您想要操作的数组,这也适用

import numpy as np


c = 2


def func(X, a):
     x = X[0]; y = X[1]
     return np.where(a[(x<a)], -c*(a + np.sqrt(y)), -c*x)


X = [25, 600]
a = np.array([[2,14],[33,22]])

func(X,a)