Repository: scipy/scipy
Pull request: DOC: clarify usage of options param in scipy.optimize.linprog
<!-- 
Thanks for contributing a pull request! Please ensure that
your PR satisfies the checklist before submitting:
http://scipy.github.io/devdocs/dev/contributor/development_workflow.html#checklist-before-submitting-a-pr

Also, please name and describe your PR as you would write a
commit message:
https://docs.scipy.org/doc/numpy/dev/development_workflow.html#writing-the-commit-message

Note that we are a team of volunteers; we appreciate your
patience during the review process.

Again, thanks for contributing!
-->

#### Reference issue
Closes gh-14514.

#### What does this implement/fix?
Clarify how to use the `options` param in `scipy.optimize.linprog`.

#### Additional information
I added an example of how to use the `options` param (e.g. to print convergence messages) in the docs of `scipy.optimize.linprog`.

Problem statement:
linprog kwargs not recognised
`scipy.optimize.linprog` is supposed to accept keywords `rr_method` and `autoscale`, but they are not recognised (c.1.7.0 at least), raising a TypeError

#### Reproducing code example:

```
result = linprog(np.array([1,1]), A_eq=np.array([[1,0]]), b_eq=1, A_ub=np.array([[0,1]]), b_ub=np.array([2]), rr_method="SVD")
# ERROR

result = linprog(np.array([1,1]), A_eq=np.array([[1,0]]), b_eq=1, A_ub=np.array([[0,1]]), b_ub=np.array([2]), autoscale=True)
# ERROR

```

#### Error message:

```
Traceback (most recent call last):
  File <REDACTED>, line 7, in <module>
    result = linprog(np.array([1,1]), A_eq=np.array([[1,0]]), b_eq=1, A_ub=np.array([[0,1]]), b_ub=np.array([2]), rr_method="SVD")
TypeError: linprog() got an unexpected keyword argument 'rr_method'

```
similarly for autoscale


#### Scipy/Numpy/Python version information:
```
1.7.0 1.20.1 sys.version_info(major=3, minor=8, micro=6, releaselevel='final', serial=0)
```

Also doesn't work on 1.6

Hints from issue discussion:
They are not keywords; they need to be part of the `options` dictionary, e.g.
```
result = linprog(np.array([1,1]), A_eq=np.array([[1,0]]), b_eq=1, 
                 A_ub=np.array([[0,1]]), b_ub=np.array([2]),
                 options={'rr_method':'SVD'})
```

This is documented:
![image](https://user-images.githubusercontent.com/6570539/127787424-e4b38183-19c4-4d29-9c0d-9d20b903569d.png)

But I'll leave this open as the documentation would benefit from an example that uses `'options'`.

For new code, I'd recommend one of the HiGHS methods, which do not use these options.
```
result = linprog(np.array([1,1]), A_eq=np.array([[1,0]]), b_eq=1, 
                 A_ub=np.array([[0,1]]), b_ub=np.array([2]),
                 method='highs')
```
(or `'highs-ds'` for dual simplex, which is what `method='highs'` uses right now, or `'highs-ipm'` for interior-point method)
Oh, I see, I didn't notice that they were subheadings of the option keyword documentation, not the documentation for the keywords themselves.
Hi! In case no one else is already on this, I would be down to adding an example for how to use `'options'` to the docs.

Commit message: DOC: removing trailing whitespace

Patch to review:
diff --git a/scipy/optimize/_linprog.py b/scipy/optimize/_linprog.py
index 71ea32faa26c..9ff866ac136c 100644
--- a/scipy/optimize/_linprog.py
+++ b/scipy/optimize/_linprog.py
@@ -575,6 +575,26 @@ def linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None,
      success: True
            x: array([10., -3.]) # may vary
 
+    You can use the ``options`` parameter, e.g.,
+    to restrict the maximum number of iterations.
+
+    >>> res = linprog(
+            c,
+            A_ub=A,
+            b_ub=b,
+            bounds=[x0_bounds, x1_bounds],
+            options={'maxiter': 4}
+        )
+    >>> print(res)
+        con: array([], dtype=float64)
+        fun: -21.35207150630408
+    message: 'The iteration limit was reached before the algorithm converged.'
+        nit: 4
+      slack: array([37.19406046,  0.5727398 ])
+     status: 1
+    success: False
+          x: array([ 9.4021973 , -2.98746855])
+
     """
 
     meth = method.lower()


Code review comments:
diff_hunk: @@ -575,6 +575,26 @@ def linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None,
      success: True
            x: array([10., -3.]) # may vary
 
+    You can use the ``options`` parameter, e.g.,
+    to restrict the maximum number of iterations.
+
+    >>> res = linprog(
+            c,
+            A_ub=A,
+            b_ub=b,
+            bounds=[x0_bounds, x1_bounds],
+            options={'maxiter': 4}
+        )
path: scipy/optimize/_linprog.py
text: @user1:
```suggestion
    You can use the ``options`` parameter, e.g.,
    to restrict the maximum number of iterations.

    >>> res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds],
    ...               options={'maxiter': 4})
```
The `...` is needed to indicate line continuation in doctests.