【问题标题】:Passing arguments to objective functions in Python optimize.root在 Python optimize.root 中将参数传递给目标函数
【发布时间】:2015-07-20 15:48:31
【问题描述】:

我正在使用optimize.root 来寻找方程组的数值解。我需要将每个条件表示为一个单独的函数,并且我还需要将参数传递给某些条件。然而,optimize.root 似乎只有在目标函数本身而不是在目标函数调用的单独函数中完成计算时才能正确传递参数。

下面的代码复制了这个问题:

# Conditions to be solved
def fSSBj(inp):
    return (0.5*inp[1])/(1+inp[1])-0.9*inp[0]
def fSSBJ(inp):
    return inp[0]-inp[2]*inp[1]

# Objective function with conditions inserted directly
def objFunc1(inp,pM):
    out = empty(2)
    out[0] = (0.5*inp[1])/(1+inp[1])-0.9*inp[0]
    out[1] = inp[0]-pM*inp[1]
    return out

# Objective function that calls the functions with the conditions
def objFunc2(inp,pM):
    out = empty(2)
    out[0] = fSSBj(inp+[pM])
    out[1] = fSSBJ(inp+[pM])
    return out

请注意,两个目标函数使用相同的输入;他们也给出了相同的输出:

print objFunc1([1.0,1.0],0.2)
print objFunc2([1.0,1.0],0.2)

这两个命令都返回

[-0.65  0.8 ]

然而,问题在于以下两个命令给出了截然不同的结果:

Out1 = optimize.root(objFunc1, [1.0,1.0], args = (0.2), method='hybr')
Out2 = optimize.root(objFunc2, [1.0,1.0], args = (0.2), method='hybr')

第一个效果很好;第二个给出错误消息(Index is out of bounds)。 optimize.root 将参数传递给函数的方式会不会有问题?

这对我来说是个问题,因为(1)我有不同的条件要解决; (2) 我需要对雅可比函数求一阶导数。出于这两个原因,我使用 SymPy 的 lambdify 函数来生成函数及其导数,并将它们包含在目标函数中。

【问题讨论】:

  • 它们不相同。 “out[1] = inp[0]-pM*inp[1]”应该是“out[1] = inp[0]-inp[2]*inp[1]”吗?

标签: python optimization lambda scipy


【解决方案1】:

我假设numpy 将您的输入列表转换为ndarray

很遗憾,

>> [1,1] + [0.2]
[1, 1, 0.2]

>> np.array([1,1]) + [0.2]
array([ 1.2,  1.2])

因此,您会得到一个IndexError

【讨论】:

    【解决方案2】:

    这就是我需要的提示!当我使用numpy.concatenate 时,它可以工作。在工作代码下方:

    # Conditions to be solved
    def fSSBj(inp):
        return (0.5*inp[1])/(1+inp[1])-0.9*inp[0]
    def fSSBJ(inp):
        return inp[0]-inp[2]*inp[1]
    
    # Objective function that calls the functions with the conditions
    # Use numpy.concatenate to concatenate the numpy arrays
    def objFunc(inp,pM):
        out = empty(2)
        allInp = concatenate((inp,pM))
        out[0] = fSSBj(allInp)
        out[1] = fSSBJ(allInp)
        return out
    
    # Be sure to give the argument as a list:
    Out = optimize.root(objFunc, [1.0,1.0], args = ([0.2]), method='hybr')
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 2015-01-23
      • 1970-01-01
      相关资源
      最近更新 更多