Repository: scipy/scipy

Issue:
linprog(method='revised simplex') doctest bug
`linprog` `method='revised simplex'` (in the 1.3 branch) doesn't solve the example problem in the docstring. The example was supposed to be a doctest, but all the outputs were marked "# may vary", so the problem wasn't caught. 

I think a small bug in the phase 1 problem formulation was introduced at some point. Strangely, the issue didn't surface in any of the other tests (or the much more difficult benchmark problems). I can fix it before 1.3 and add the example as a regular test before 1.3 is released. @tylerjereddy Do I submit a PR to the "maintenance/1.3.x" branch?

### Reproducing code example:
```
c = [-1, 4]
A = [[-3, 1], [1, 2]]
b = [6, 4]
x0_bounds = (None, None)
x1_bounds = (-3, None)
from scipy.optimize import linprog
res = linprog(c, A_ub=A, b_ub=b, bounds=(x0_bounds, x1_bounds), method="revised simplex",
              options={"disp": True})
print(res)
```
The status is 4 (algorithm reported success, but solution was infeasible).



Discussion:
We are at RC phase to catch these post branch issues. If needed, which seems so, Tyler would backport it
If you open a PR also mark it backport candidate and remove it here maybe? 
Will try to do this weekend. Still scheduled to release 5/20?

Resolving patch:
diff --git a/scipy/optimize/_linprog_ip.py b/scipy/optimize/_linprog_ip.py
--- a/scipy/optimize/_linprog_ip.py
+++ b/scipy/optimize/_linprog_ip.py
@@ -22,6 +22,7 @@
 import numpy as np
 import scipy as sp
 import scipy.sparse as sps
+import numbers
 from warnings import warn
 from scipy.linalg import LinAlgError
 from .optimize import OptimizeWarning, OptimizeResult, _check_unknown_options
@@ -557,12 +558,12 @@ def _display_iter(rho_p, rho_d, rho_g, alpha, rho_mu, obj, header=False):
     # no clue why this works
     fmt = '{0:<20.13}{1:<20.13}{2:<20.13}{3:<17.13}{4:<20.13}{5:<20.13}'
     print(fmt.format(
-        rho_p,
-        rho_d,
-        rho_g,
-        alpha,
-        rho_mu,
-        obj))
+        float(rho_p),
+        float(rho_d),
+        float(rho_g),
+        float(alpha) if isinstance(alpha, numbers.Number) else alpha,
+        float(rho_mu),
+        float(obj)))
 
 
 def _ip_hsd(A, b, c, c0, alpha0, beta, maxiter, disp, tol, sparse, lstsq,
@@ -722,6 +723,14 @@ def _ip_hsd(A, b, c, c0, alpha0, beta, maxiter, disp, tol, sparse, lstsq,
 
     if disp:
         _display_iter(rho_p, rho_d, rho_g, "-", rho_mu, obj, header=True)
+    if callback is not None:
+        x_o, fun, slack, con, _, _ = _postsolve(x/tau, *_T_o,
+                                                tol=tol)
+        res = OptimizeResult({'x': x_o, 'fun': fun, 'slack': slack,
+                              'con': con, 'nit': iteration, 'phase': 1,
+                              'complete': False, 'status': 0,
+                              'message': "", 'success': False})
+        callback(res)
 
     status = 0
     message = "Optimization terminated successfully."
@@ -794,7 +803,7 @@ def eta(g=gamma):
         go = rho_p > tol or rho_d > tol or rho_A > tol
 
         if disp:
-            _display_iter(rho_p, rho_d, rho_g, alpha, float(rho_mu), obj)
+            _display_iter(rho_p, rho_d, rho_g, alpha, rho_mu, obj)
         if callback is not None:
             x_o, fun, slack, con, _, _ = _postsolve(x/tau, *_T_o,
                                                     tol=tol)
diff --git a/scipy/optimize/_linprog_rs.py b/scipy/optimize/_linprog_rs.py
--- a/scipy/optimize/_linprog_rs.py
+++ b/scipy/optimize/_linprog_rs.py
@@ -93,7 +93,6 @@ def _phase_one(A, b, x0, maxiter, tol, maxupdate, mast, pivot, callback=None,
     basis = basis[keep_rows]
     x = x[:n]
     m = A.shape[0]
-
     return x, basis, A, b, residual, status, iter_k
 
 
@@ -342,7 +341,7 @@ def _phase_two(c, A, x, b, maxiter, tol, maxupdate, mast, pivot, iteration=0,
                 phase = 2
                 x_postsolve = x
             x_o, fun, slack, con, _, _ = _postsolve(x_postsolve, *_T_o,
-                                                    tol=tol)
+                                                    tol=tol, copy=True)
 
             if callback is not None:
                 res = OptimizeResult({'x': x_o, 'fun': fun, 'slack': slack,
diff --git a/scipy/optimize/_linprog_util.py b/scipy/optimize/_linprog_util.py
--- a/scipy/optimize/_linprog_util.py
+++ b/scipy/optimize/_linprog_util.py
@@ -1114,7 +1114,7 @@ def _display_summary(message, status, fun, iteration):
 
 
 def _postsolve(x, c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=None,
-               complete=False, undo=[], tol=1e-8):
+               complete=False, undo=[], tol=1e-8, copy=False):
     """
     Given solution x to presolved, standard form linear program x, add
     fixed variables back into the problem and undo the variable substitutions
@@ -1187,7 +1187,9 @@ def _postsolve(x, c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=None,
         x = x.tolist()
         for i, val in zip(undo[0], undo[1]):
             x.insert(i, val)
-        x = np.array(x)
+        copy = True
+    if copy:
+        x = np.array(x, copy=True)
 
     # now undo variable substitutions
     # if "complete", problem was solved in presolve; don't do anything here


Test patch:
diff --git a/scipy/optimize/tests/test_linprog.py b/scipy/optimize/tests/test_linprog.py
--- a/scipy/optimize/tests/test_linprog.py
+++ b/scipy/optimize/tests/test_linprog.py
@@ -1301,6 +1301,25 @@ def test_bug_8973_2(self):
                       method=self.method, options=self.options)
         _assert_success(res, desired_x=[-2], desired_fun=0)
 
+    def test_bug_10124(self):
+        """
+        Test for linprog docstring problem
+        'disp'=True caused revised simplex failure
+        """
+        c = np.zeros(1)
+        A_ub = np.array([[1]])
+        b_ub = np.array([-2])
+        bounds = (None, None)
+        c = [-1, 4]
+        A_ub = [[-3, 1], [1, 2]]
+        b_ub = [6, 4]
+        bounds = [(None, None), (-3, None)]
+        o = {"disp": True}
+        o.update(self.options)
+        res = linprog(c, A_ub, b_ub, A_eq, b_eq, bounds,
+                      method=self.method, options=self.options)
+        _assert_success(res, desired_x=[10, -3], desired_fun=-22)
+
 #########################
 # Method-specific Tests #
 #########################