Repository: fitbenchmarking/fitbenchmarking

Issue:
scipy Hessian solvers
The minimizer docs for scipy (https://fitbenchmarking.readthedocs.io/en/latest/users/options/minimizer_option.html) currently say:

![image](https://user-images.githubusercontent.com/13645545/148751059-d10e48e2-ac0d-4c73-aa67-35d2c59e9777.png)

We now have support for Hessians, so should add support for: 
- [ ] ‘COBYLA’ (which doesn't actually need Hessian information)
- [ ] ‘trust-constr’
- [ ] ‘dogleg’ 
- [ ] ‘trust-ncg’ 
- [ ] ‘trust-exact’
- [ ] ‘trust-krylov’


Discussion:
github-actions[bot]: ## Unit & System Test Results
    4 files  ±0      4 suites  ±0   11m 14s [:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "duration of all tests") + 3m 28s
360 tests ±0  348 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests")  - 2    8 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") ±0  4 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") +2 
688 runs  ±0  632 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests")  - 4  50 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") ±0  6 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") +4 

For more details on these failures, see [this check](https://github.com/fitbenchmarking/fitbenchmarking/runs/10281004955).

Results for commit cffb15e0. ± Comparison against base commit 88ed6de9.

[test-results]:data:application/gzip;base64,H4sIAJ4npmMC/02Myw6DIBQFf8Ww7gJQbml/puGZkKo0PFam/95LFO1y5pzMRnyYXSbPYboNJNdQTrA1qRLiigj3JnAqbRyBdnrlakxTk7zUO3xQXcKrMB/NXbiUYkLTMqmurQlSHtCTMPLT7EXR/70Inf+DJi5LKAjEeK+ZcJSBklorJyTSSK2wXBhQjFOvHwCefH+pywU7BgEAAA==


Patch:
diff --git a/docs/source/users/options/minimizer_option.rst b/docs/source/users/options/minimizer_option.rst
index 2a48debb..12f52da4 100644
--- a/docs/source/users/options/minimizer_option.rst
+++ b/docs/source/users/options/minimizer_option.rst
@@ -569,6 +569,12 @@ Hessian information as inputs.
 * `L-BFGS-B algorithm <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-lbfgsb.html>`__ (:code:`L-BFGS-B`)
 * `Truncated Newton (TNC) algorithm <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-tnc.html>`__ (:code:`TNC`)
 * `Sequential Least SQuares Programming <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-slsqp.html>`__ (:code:`SLSQP`)
+* `Constrained Optimization BY Linear Approximations <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-cobyla.html>`__ (:code:`COBYLA`)
+* `Newton-CG trust-region <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-trustncg.html>`__  (:code:`trust-ncg`)
+* `Nearly exact trust-region <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-trustexact.html>`__  (:code:`trust-exact`)
+* `Newton Generalized Lanczos Trust Region <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-trustkrylov.html>`__  (:code:`trust-krylov`)
+* `Trust-region for constrained optimization <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-trustconstr.html>`__  (:code:`trust-constr`)
+* `Dog-leg trust-region <https://docs.scipy.org/doc/scipy/reference/optimize.minimize-dogleg.html>`__ (:code:`dogleg`)
 
 **Links** `Github - SciPy minimize <https://github.com/scipy/scipy/blob/master/scipy/optimize/_minimize.py>`__
 
@@ -587,6 +593,12 @@ The SciPy minimizers are set as follows:
            L-BFGS-B
            TNC
            SLSQP
+           COBYLA
+           trust-ncg
+           trust-exact
+           trust-krylov
+           trust-constr
+           dogleg
 
 .. _scipy-ls:
 
diff --git a/fitbenchmarking/controllers/scipy_controller.py b/fitbenchmarking/controllers/scipy_controller.py
index a845d5f4..4e4009fd 100644
--- a/fitbenchmarking/controllers/scipy_controller.py
+++ b/fitbenchmarking/controllers/scipy_controller.py
@@ -15,14 +15,30 @@ class ScipyController(Controller):
     """
 
     algorithm_check = {
-            'all': ['Nelder-Mead', 'Powell', 'CG', 'BFGS', 'Newton-CG',
-                    'L-BFGS-B', 'TNC', 'SLSQP'],
+            'all': ['Nelder-Mead',
+                    'Powell',
+                    'CG',
+                    'BFGS',
+                    'Newton-CG',
+                    'L-BFGS-B',
+                    'TNC',
+                    'SLSQP',
+                    'COBYLA',
+                    'trust-ncg',
+                    'trust-exact',
+                    'trust-krylov',
+                    'trust-constr',
+                    'dogleg'],
             'ls': [None],
-            'deriv_free': ['Nelder-Mead', 'Powell'],
+            'deriv_free': ['Nelder-Mead', 'Powell', 'COBYLA'],
             'general': ['Nelder-Mead', 'Powell', 'CG', 'BFGS',
                         'Newton-CG', 'L-BFGS-B', 'TNC', 'SLSQP'],
             'simplex': ['Nelder-Mead'],
-            'trust_region': [],
+            'trust_region': ['trust-ncg',
+                             'trust-exact',
+                             'trust-krylov',
+                             'trust-constr',
+                             'dogleg'],
             'levenberg-marquardt': [],
             'gauss_newton': [],
             'bfgs': ['BFGS', 'L-BFGS-B'],
@@ -30,10 +46,24 @@ class ScipyController(Controller):
             'steepest_descent': [],
             'global_optimization': []}
 
-    jacobian_enabled_solvers = ['CG', 'BFGS', 'Newton-CG',
-                                'L-BFGS-B', 'TNC', 'SLSQP']
-
-    hessian_enabled_solvers = ['Newton-CG']
+    jacobian_enabled_solvers = ['CG',
+                                'BFGS',
+                                'Newton-CG',
+                                'L-BFGS-B',
+                                'TNC',
+                                'SLSQP',
+                                'trust-ncg',
+                                'trust-exact',
+                                'trust-krylov',
+                                'trust-constr',
+                                'dogleg']
+
+    hessian_enabled_solvers = ['Newton-CG',
+                               'trust-ncg',
+                               'trust-exact',
+                               'trust-krylov',
+                               'trust-constr',
+                               'dogleg']
 
     def __init__(self, cost_func):
         """
diff --git a/fitbenchmarking/utils/options.py b/fitbenchmarking/utils/options.py
index 1732aff2..9abe7d78 100644
--- a/fitbenchmarking/utils/options.py
+++ b/fitbenchmarking/utils/options.py
@@ -52,8 +52,20 @@ class Options:
          'matlab_stats': ['Levenberg-Marquardt'],
          'minuit': ['minuit'],
          'ralfit': ['gn', 'gn_reg', 'hybrid', 'hybrid_reg'],
-         'scipy': ['Nelder-Mead', 'Powell', 'CG', 'BFGS',
-                   'Newton-CG', 'L-BFGS-B', 'TNC', 'SLSQP'],
+         'scipy': ['Nelder-Mead',
+                   'Powell',
+                   'CG',
+                   'BFGS',
+                   'Newton-CG',
+                   'L-BFGS-B',
+                   'TNC',
+                   'SLSQP',
+                   'COBYLA',
+                   'trust-ncg',
+                   'trust-exact',
+                   'trust-krylov',
+                   'trust-constr',
+                   'dogleg'],
          'scipy_ls': ['lm-scipy', 'trf', 'dogbox'],
          'scipy_go': ['differential_evolution', 'shgo', 'dual_annealing']}
     VALID_FITTING = \
@@ -140,8 +152,20 @@ class Options:
          'matlab_stats': ['Levenberg-Marquardt'],
          'minuit': ['minuit'],
          'ralfit': ['gn', 'gn_reg', 'hybrid', 'hybrid_reg'],
-         'scipy': ['Nelder-Mead', 'Powell', 'CG', 'BFGS',
-                   'Newton-CG', 'L-BFGS-B', 'TNC', 'SLSQP'],
+         'scipy': ['Nelder-Mead',
+                   'Powell',
+                   'CG',
+                   'BFGS',
+                   'Newton-CG',
+                   'L-BFGS-B',
+                   'TNC',
+                   'SLSQP',
+                   'COBYLA',
+                   'trust-ncg',
+                   'trust-exact',
+                   'trust-krylov',
+                   'trust-constr',
+                   'dogleg'],
          'scipy_ls': ['lm-scipy', 'trf', 'dogbox'],
          'scipy_go': ['differential_evolution', 'dual_annealing']}
     DEFAULT_FITTING = \


Test patch:
diff --git a/fitbenchmarking/core/tests/test_fitting_benchmarking_software.py b/fitbenchmarking/core/tests/test_fitting_benchmarking_software.py
index ecefc632..4b4fa7be 100644
--- a/fitbenchmarking/core/tests/test_fitting_benchmarking_software.py
+++ b/fitbenchmarking/core/tests/test_fitting_benchmarking_software.py
@@ -191,7 +191,7 @@ class LoopOverSoftwareTests(unittest.TestCase):
                                 [fitbm_result.FittingResult(**self.result_args)
                                  for i in range(self.scipy_ls_len)]]
         loop_over_minimizers.side_effect = self.mock_func_call
-        expected_list_len = 13
+        expected_list_len = 19
         expected_minimizer_failed = self.minimizer_failed
         self.shared_test(expected_list_len, expected_minimizer_failed)
 
diff --git a/fitbenchmarking/utils/tests/test_options_minimizers.py b/fitbenchmarking/utils/tests/test_options_minimizers.py
index 3261bc77..7f7d7654 100644
--- a/fitbenchmarking/utils/tests/test_options_minimizers.py
+++ b/fitbenchmarking/utils/tests/test_options_minimizers.py
@@ -83,8 +83,20 @@ class MininimizerOptionTests(unittest.TestCase):
         """
         Checks valid scipy minimizers are set correctly
         """
-        expected = ['Nelder-Mead', 'Powell', 'CG', 'BFGS',
-                    'Newton-CG', 'L-BFGS-B', 'TNC', 'SLSQP']
+        expected = ['Nelder-Mead',
+                    'Powell',
+                    'CG',
+                    'BFGS',
+                    'Newton-CG',
+                    'L-BFGS-B',
+                    'TNC',
+                    'SLSQP',
+                    'COBYLA',
+                    'trust-ncg',
+                    'trust-exact',
+                    'trust-krylov',
+                    'trust-constr',
+                    'dogleg']
         actual = self.options.minimizers['scipy']
         self.assertEqual(expected, actual)