尝试使用jacobian使用scipy最小化函数时出现错误消息

时间:2017-05-04 21:40:20

标签: python optimization scipy

使用Python 3.6,我试图使用scipy.optimize.minimize最小化函数。我的最小化问题是两个约束,我可以找到解决方案。到目前为止,我有以下内容:

import numpy as np
from scipy.optimize import minimize

array = np.array([[3.0, 0.25, 0.75],
                  [0.1, 0.65, 2.50],
                  [0.80, 2.5, 1.20],
                  [0.0, 0.25, 0.15],
                  [1.2, 2.40, 3.60]])

matrix = np.array([[1.0, 1.5, -2.],
                   [0.5, 3.0, 2.5],
                   [1.0, 0.25, 0.75]])


def fct1(x):
    return -sum(x.dot(array.T))


def fct2(x):
    return x.dot(matrix).dot(x)

x0 = np.ones(3) / 3
cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1.0},
        {'type': 'eq', 'fun': lambda x: fct2(x) - tgt})

tgt = 0.15

w = minimize(fct1, x0, method='SLSQP', constraints=cons)['x']
res1 = fct1(w)
res2 = fct2(w)

我现在正试图让我的优化器运行得更快,因为这只是一个简化的问题。最后,我的数组和矩阵更大。在上一个问题中,有人提出了定义我的函数的jacobian以进行优化的想法,所以我添加了以下内容:

def fct1_deriv(x):
    return -sum(np.ones_like(x).dot(array.T))

w = minimize(fct1, x0, method='SLSQP', jac=fct1_deriv, constraints=cons)['x']

问题是我在尝试运行时收到以下错误消息:

0-th dimension must be fixed to 4 but got 2
Traceback (most recent call last):
  File "C:\Anaconda2\envs\py36\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-111-d1b854178c13>", line 1, in <module>
    w = minimize(fct1, x0, method='SLSQP', jac=fct1_deriv, constraints=cons)['x']
  File "C:\Anaconda2\envs\py36\lib\site-packages\scipy\optimize\_minimize.py", line 458, in minimize
    constraints, callback=callback, **options)
  File "C:\Anaconda2\envs\py36\lib\site-packages\scipy\optimize\slsqp.py", line 410, in _minimize_slsqp
    slsqp(m, meq, x, xl, xu, fx, c, g, a, acc, majiter, mode, w, jw)
_slsqp.error: failed in converting 8th argument `g' of _slsqp.slsqp to C/Fortran array

关于问题可能是什么的任何想法?我之前回答的链接在这里: What is the fastest way to minimize a function in python?

2 个答案:

答案 0 :(得分:0)

你的最小化函数需要一个3向量作为输入,因此你的雅可比行列式也应该相应地是一个3向量,每个组件都是相应输入组件的偏导数。 SciPy抱怨不知道如何处理你给它的单一值。

在你的情况下,我认为这就是你想要的:

def fct1_deriv(x):
    return -np.sum(array, axis=1)

此外,如果速度是一个问题,您可能希望在np.sum中使用sum,而不是fct1

答案 1 :(得分:0)

我想我终于找到了答案,并会发布在这里,以便人们可以使用它或纠正我:

y = x^2形式的优化问题中,可以通过将y相对于x进行微分来求解,并通过将导数设置为等于0来求解。因此,可以找到{{1 (解决2x = 0.0)。因此,我觉得将函数的雅可比(一阶导数)传递给优化有助于优化器找到解决方案。

在我尝试优化的问题中,我的功能是x=0.0形式。通过将y = xy区分开来,无法优化此功能(除了给出约束)。这将导致以下等式:x。因此,将我的函数的雅可比行列式赋予我的优化器可能会因此而导致问题。