Repository: scipy/scipy

Issue:
Minimize with trust-constr method leads to TypeError if option verbose is set to 2 or 3 
When I changed the minimize method to "trust-constr" I got the TypeError. TypeError does not appear if verbose is set to 0 or 1.

#### Reproducing code example:
```python
cons = ({'type':'ineq','fun': lambda params: params[31]},\
        {'type':'ineq','fun': lambda params: params[-1]})  

opts = {'maxiter': 1000, 'verbose': 3, 'factorization_method': 'SVDFactorization'} 

result = scipy.optimize.minimize(func_value,params,args=(func_args), method='trust-constr', \
                      options=opts,constraints=cons)
```

#### Error message:
```python
   File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py", line 628, in minimize return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\minimize_trustregion_constr.py", line 509, in _minimize_trustregion_constr
    _, result = tr_interior_point(

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\tr_interior_point.py", line 321, in tr_interior_point
    z, state = equality_constrained_sqp(

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\equality_constrained_sqp.py", line 93, in equality_constrained_sqp
    while not stop_criteria(state, x, last_iteration_failed,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\tr_interior_point.py", line 251, in stop_criteria
    if self.global_stop_criteria(state, x,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\minimize_trustregion_constr.py", line 449, in stop_criteria
    BasicReport.print_iteration(state.nit,

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_trustregion_constr\report.py", line 28, in print_iteration
    print(fmt.format(*args))

TypeError: unsupported format string passed to numpy.ndarray.__format__
```

#### Scipy/Numpy/Python version information:
```
1.5.0 1.19.1 sys.version_info(major=3, minor=8, micro=3, releaselevel='final', serial=0)
```



Discussion:
This looks like a duplicate of https://github.com/scipy/scipy/issues/10880.  But that problem was fixed in SciPy 1.4.0 by https://github.com/scipy/scipy/pull/10946, and you say you are using SciPy 1.5.0.

Can you provide a minimal but complete code example that demonstrates the problem?  It would be helpful to have code that we can simply copy and run to produce the problem.
Also, can you add the lines

    import scipy
    print("SciPy version", scipy.__version__)

to your code to verify that you are, in fact, running the code with SciPy 1.5.0?
> Also, can you add the lines
> 
> ```
> import scipy
> print("SciPy version", scipy.__version__)
> ```
> 
> to your code to verify that you are, in fact, running the code with SciPy 1.5.0?

I use this code to check my SciPy version. It is for sure 1.5.0. 

When it comes to providing the full code it could be problematic, because it is currently rather developed with a lot of nested stuff, however I will try to provide simplified version soon. 
Thanks @JacekB104.  It turns out I was able to create a small example that reproduces the problem in both SciPy 1.5.0 and in the latest development version (`'1.6.0.dev0+02563b2'`).  To reproduce the problem, I had to return a 1-d array from the objective function (instead of a scalar), and try different values for the length of the state vector.   Here's a script that reproduces the error `TypeError: unsupported format string passed to numpy.ndarray.__format__`.  I only get the error for some values of `n`.  I don't get an error for `n` equal to 2, 3, 6,  or 7, but I get it for 4, 5, and 8. Other values that for `n` that I've tried:

    no error: 24, 27, 29
       error: 23, 25, 26, 28, 30
```
import numpy as np
from scipy.optimize import minimize


def objective(x):
    return np.array([(np.sum((x + 1)**2))])


cons = {'type': 'ineq', 'fun': lambda x: x[0]}
opts = {'maxiter': 1000, 'verbose': 3}

n = 25
x0 = np.linspace(-5, 5, n)

result = minimize(objective, x0=x0, method='trust-constr',
                  constraints=cons, options=opts)
```
Thank you for your answer! That can be a case, because my state vector has 58 variables, which is relatively a lot.  My objective function returns a 1-d array. Do you think that changing my objective function to return a scalar will solve the problem? 
I edited my previous comment to fix a false conclusion that I jumped to too quickly.  The failure does not seem to occur only for `n` sufficiently large.  I updated the comment to show that there isn't an obvious pattern for which values of `n` will generate the error.

@JacekB104, I think ensuring that your objective function returns a scalar should fix the problem.  In the script shown above, when I fixed `objective`  to return a scalar and ran it with `n` ranging from 2 up to 60, the error did not occur.
Ok, so it looks that the objective function return type is a source of an error. I will work with this setting and if I find the error again, I will let you know. Thank you for your help!
To any devs who follow up on this: the error occurs because `args[4]` (which is the `'tr radius'` value) in the `args` passed to the method `print_iteration` of the report class ends up as a 1-d array of length 1 instead of a scalar.  I haven't dug any deeper than that.

Resolving patch:
diff --git a/scipy/optimize/_trustregion_constr/report.py b/scipy/optimize/_trustregion_constr/report.py
--- a/scipy/optimize/_trustregion_constr/report.py
+++ b/scipy/optimize/_trustregion_constr/report.py
@@ -19,11 +19,13 @@ def print_header(cls):
 
     @classmethod
     def print_iteration(cls, *args):
-        # args[3] is obj func. It should really be a float. However,
-        # trust-constr typically provides a length 1 array. We have to coerce
-        # it to a float, otherwise the string format doesn't work.
+        # args[3] is obj func, and args[4] is tr-radius. They should really be
+        # floats. However, trust-constr typically provides a ndarray for these
+        # values. We have to coerce them to floats, otherwise the string
+        # formatting doesn't work.
         args = list(args)
         args[3] = float(args[3])
+        args[4] = float(args[4])
 
         iteration_format = ["{{:{}}}".format(x) for x in cls.ITERATION_FORMATS]
         fmt = "|" + "|".join(iteration_format) + "|"


Test patch:
diff --git a/scipy/optimize/_trustregion_constr/tests/test_report.py b/scipy/optimize/_trustregion_constr/tests/test_report.py
--- a/scipy/optimize/_trustregion_constr/tests/test_report.py
+++ b/scipy/optimize/_trustregion_constr/tests/test_report.py
@@ -1,10 +1,32 @@
+import numpy as np
 from scipy.optimize import minimize, Bounds
 
 def test_gh10880():
-    # checks that verbose reporting works with trust-constr
+    # checks that verbose reporting works with trust-constr for
+    # bound-contrained problems
     bnds = Bounds(1, 2)
     opts = {'maxiter': 1000, 'verbose': 2}
-    minimize(lambda x: x**2, x0=2., method='trust-constr', bounds=bnds, options=opts)
+    minimize(lambda x: x**2, x0=2., method='trust-constr',
+             bounds=bnds, options=opts)
 
     opts = {'maxiter': 1000, 'verbose': 3}
-    minimize(lambda x: x**2, x0=2., method='trust-constr', bounds=bnds, options=opts)
+    minimize(lambda x: x**2, x0=2., method='trust-constr',
+             bounds=bnds, options=opts)
+
+def test_gh12922():
+    # checks that verbose reporting works with trust-constr for
+    # general constraints
+    def objective(x):
+        return np.array([(np.sum((x+1)**2))])
+
+    cons = {'type': 'ineq', 'fun': lambda x: -x[0]**2}
+    n = 25
+    x0 = np.linspace(-5, 5, n)
+
+    opts = {'maxiter': 1000, 'verbose': 2}
+    result = minimize(objective, x0=x0, method='trust-constr',
+                      constraints=cons, options=opts)
+
+    opts = {'maxiter': 1000, 'verbose': 3}
+    result = minimize(objective, x0=x0, method='trust-constr',
+                      constraints=cons, options=opts)