pythonscipy-optimize-minimize

in scipy.optimize.minimize - could not be broadcast together data with shapes (2,) (2,5)


I cannot cope with shapes mismatch in scipy.optimize.minimize here in this example:

import numpy as np
from scipy.spatial import distance_matrix
from scipy.optimize import minimize

# Create the matrices
X = np.array([[1,2,3,4,5],[2,1,0,3,4]])
y = np.array([[0,0,0,0,1],[1,1,1,1,0]])

# Display the matrices
print("matrix x:\n", X)
print("matrix y:\n", y)

# compute the distance matrix
dist_mat = distance_matrix(X, y, p=2)

# display distance matrix
print("Distance Matrix:\n", dist_mat)

loss_res = lambda z: 0.5 * z ** 2 * (np.abs(z) <= 1) + (np.abs(z) - 0.5) * (np.abs(z) > 1)
f_to_optMin = lambda w: np.sum(loss_res(X @ w.ravel() - y)) # (2,) 10, (2,5)

res= minimize(f_to_optMin, (10,10,10,10,10,))
print(res.x)

seems, that problem/solution is rather simple, but I don't see how to make it working. Can somebody help me, please?

Traceback (most recent call last):
  File "E:\NEW docs\dist_mat.py", line 33, in <module>
    res= minimize(f_to_optMin, ([1,1,1,1,1,]))
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\_minimize.py", line 618, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\optimize.py", line 1201, in _minimize_bfgs
    sf = _prepare_scalar_function(fun, x0, jac, args=args, epsilon=eps,
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\optimize.py", line 261, in _prepare_scalar_function
    sf = ScalarFunction(fun, x0, args, grad, hess,
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 140, in __init__
    self._update_fun()
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 233, in _update_fun
    self._update_fun_impl()
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 137, in update_fun
    self.f = fun_wrapped(self.x)
  File "C:\Users\adm\AppData\Local\Programs\Python\Python310-32\lib\site-packages\scipy\optimize\_differentiable_functions.py", line 134, in fun_wrapped
    return fun(np.copy(x), *args)
  File "E:\NEW docs\dist_mat.py", line 31, in <lambda>
    f_to_optMin = lambda w: np.sum(loss_res(X @ w.ravel() - y)) # 2, 10, [2,5]
ValueError: operands could not be broadcast together with shapes (2,) (2,5) 

Solution

  • The problem is with

    X @ w.ravel() - y
    

    The left side of the subtraction has shape (2) while the right has shape (2,5). To reconcile that, according to the numpy broadcasting rules, you could replace y by its transpose, and have the subtraction applied by rows. I tested it:

    import numpy as np
    from scipy.spatial import distance_matrix
    from scipy.optimize import minimize
    
    # Create the matrices
    X = np.array([[1,2,3,4,5],[2,1,0,3,4]])
    y = np.array([[0,0,0,0,1],[1,1,1,1,2]])
    
    # Display the matrices
    print("matrix x:\n", X)
    print("matrix y:\n", y)
    
    # compute the distance matrix
    dist_mat = distance_matrix(X, y, p=2)
    
    # display distance matrix
    print("Distance Matrix:\n", dist_mat)
    
    loss_res = lambda z: 0.5 * z ** 2 * (np.abs(z) <= 1) + (np.abs(z) - 0.5) * (np.abs(z) > 1)
    f_to_optMin = lambda w: np.sum(loss_res(X @ w.ravel() - y.T)) # (2,) 10, (2,5)
    
    res= minimize(f_to_optMin, (1,1,1,1,1,))
    print(res.x) # [ 0.91638545  0.41921018 -0.07796579 -0.0237285  -0.2451989 ]
    

    and it seems to work. Not knowing what you are trying to solve, it's impossible to know if this is what you want or need though.