error message when trying to minimize a function with scipy using jacobian

青春壹個敷衍的年華 提交于 2020-01-02 09:10:58

问题


Using Python 3.6, I am trying to minimize a function using scipy.optimize.minimize. My minimization problem as two constraints, and I can find a solution. So far, I have the following:

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)

I am now trying to get my optimizer to run faster as this is only a simplified problem. In the end, my arrays and matrices are way bigger. In a previous question, somebody came up with the idea of defining the jacobian of my function to optimize, so I added the following:

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']

Problem is I get the following error message when trying to run:

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

Any ideas on what the problem could be? The link to my previous answer is here: What is the fastest way to minimize a function in python?


回答1:


Your function to minimize takes a 3 vector as input, so your Jacobian should correspondingly be a 3 vector as well, each component being the partial derivative with regard to the corresponding input component. SciPy is complaining about not knowing what to do with the single value you are giving it.

In your case, I think this is what you want:

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

Also, if speed is a concern you probably want to use np.sum, not sum, in fct1.




回答2:


I think I finally found the answer, and will post here so people can use it or correct me:

In an optimization problem of the form y = x^2, the solution can be found by differentiating y with respect to x, and solving by setting the derivative equal to 0. Therefore, the solution can be found with 2x = 0.0 (solving for x=0.0). Therefore, I have the feeling that passing the Jacobian (first derivative) of a function to optimize helps the optimizer in finding a solution.

In the problem I am trying to optimize, my function is of the form y = x. This function can't be optimize (besides giving it constraints) by differentiating y with respect to x. That would lead to the following equation : 1.0 = 0.0. Therefore giving the Jacobian of my function to my optimizer is probably causing the problem because of the above.



来源:https://stackoverflow.com/questions/43793204/error-message-when-trying-to-minimize-a-function-with-scipy-using-jacobian

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!