Reputation: 45
I am still learning the optimize function in scipy so as a test I wanted to optimize
def f(x):
return (x-2)**2+2
This should give a minimum of (2, 2). Then I set x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
. When I ran res = minimize(f, x0, method='BFGS', options={'disp': True})
, I got the following error
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/optimize.py in _minimize_bfgs(fun, x0, args, jac, callback, gtol, norm, eps, maxiter, disp, return_all, finite_diff_rel_step, **unknown_options)
1211 try:
-> 1212 old_fval = old_fval.item()
1213 except (ValueError, AttributeError) as e:
ValueError: can only convert an array of size 1 to a Python scalar
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-16-a687d5eaf37f> in <module>
----> 1 res = minimize(f, x0, method='BFGS', options={'disp': True})
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
616 return _minimize_cg(fun, x0, args, jac, callback, **options)
617 elif meth == 'bfgs':
--> 618 return _minimize_bfgs(fun, x0, args, jac, callback, **options)
619 elif meth == 'newton-cg':
620 return _minimize_newtoncg(fun, x0, args, jac, hess, hessp, callback,
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/optimize.py in _minimize_bfgs(fun, x0, args, jac, callback, gtol, norm, eps, maxiter, disp, return_all, finite_diff_rel_step, **unknown_options)
1212 old_fval = old_fval.item()
1213 except (ValueError, AttributeError) as e:
-> 1214 raise ValueError("The user-provided "
1215 "objective function must "
1216 "return a scalar value.") from e
ValueError: The user-provided objective function must return a scalar value.
Could someone help me understand what is happening?
Upvotes: 1
Views: 929
Reputation: 7353
You were copying the x0
used for scipy.optimize.rosen
: Rosenbrock objective function in the example of scipy.optimize.minimize
. The Rosenbrock function applies a sum()
on the various x0
values you provide and hence evaluates to a scalar.
Note that BFGS
is essentially going to use the function and it's derivatives at a point (x
). The x0
is only the starting point (a trial solution), where the algorithm starts to look for the solution from. If your objective function provides you with only a scalar, you cannot pass multiple x0
values to it.
# This should work for you
from scipy.optimize import minimize
x0 = 1.3 # an initial value for f(x)
res = minimize(f, x0, method='BFGS', options={'disp': True})
x0
values?Say, your objective function has the following form. This will require you to provide an array of 5 initial values to x0
.
def f(x):
return 10.0 * (x[0]**3 - 0.5 * x[1]**2 + 7.0 * x[2]**(-1.5)) - 6.0 * (x[3] - 2*x[4])**2
Upvotes: 1