test_trustregion.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. """
  2. Unit tests for trust-region optimization routines.
  3. """
  4. import pytest
  5. import numpy as np
  6. from numpy.testing import assert_, assert_equal, assert_allclose
  7. from scipy.optimize import (minimize, rosen, rosen_der, rosen_hess,
  8. rosen_hess_prod)
  9. class Accumulator:
  10. """ This is for testing callbacks."""
  11. def __init__(self):
  12. self.count = 0
  13. self.accum = None
  14. def __call__(self, x):
  15. self.count += 1
  16. if self.accum is None:
  17. self.accum = np.array(x)
  18. else:
  19. self.accum += x
  20. class TestTrustRegionSolvers:
  21. def setup_method(self):
  22. self.x_opt = [1.0, 1.0]
  23. self.easy_guess = [2.0, 2.0]
  24. self.hard_guess = [-1.2, 1.0]
  25. def test_dogleg_accuracy(self):
  26. # test the accuracy and the return_all option
  27. x0 = self.hard_guess
  28. r = minimize(rosen, x0, jac=rosen_der, hess=rosen_hess, tol=1e-8,
  29. method='dogleg', options={'return_all': True},)
  30. assert_allclose(x0, r['allvecs'][0])
  31. assert_allclose(r['x'], r['allvecs'][-1])
  32. assert_allclose(r['x'], self.x_opt)
  33. def test_dogleg_callback(self):
  34. # test the callback mechanism and the maxiter and return_all options
  35. accumulator = Accumulator()
  36. maxiter = 5
  37. r = minimize(rosen, self.hard_guess, jac=rosen_der, hess=rosen_hess,
  38. callback=accumulator, method='dogleg',
  39. options={'return_all': True, 'maxiter': maxiter},)
  40. assert_equal(accumulator.count, maxiter)
  41. assert_equal(len(r['allvecs']), maxiter+1)
  42. assert_allclose(r['x'], r['allvecs'][-1])
  43. assert_allclose(sum(r['allvecs'][1:]), accumulator.accum)
  44. def test_dogleg_user_warning(self):
  45. with pytest.warns(RuntimeWarning,
  46. match=r'Maximum number of iterations'):
  47. minimize(rosen, self.hard_guess, jac=rosen_der,
  48. hess=rosen_hess, method='dogleg',
  49. options={'disp': True, 'maxiter': 1}, )
  50. def test_solver_concordance(self):
  51. # Assert that dogleg uses fewer iterations than ncg on the Rosenbrock
  52. # test function, although this does not necessarily mean
  53. # that dogleg is faster or better than ncg even for this function
  54. # and especially not for other test functions.
  55. f = rosen
  56. g = rosen_der
  57. h = rosen_hess
  58. for x0 in (self.easy_guess, self.hard_guess):
  59. r_dogleg = minimize(f, x0, jac=g, hess=h, tol=1e-8,
  60. method='dogleg', options={'return_all': True})
  61. r_trust_ncg = minimize(f, x0, jac=g, hess=h, tol=1e-8,
  62. method='trust-ncg',
  63. options={'return_all': True})
  64. r_trust_krylov = minimize(f, x0, jac=g, hess=h, tol=1e-8,
  65. method='trust-krylov',
  66. options={'return_all': True})
  67. r_ncg = minimize(f, x0, jac=g, hess=h, tol=1e-8,
  68. method='newton-cg', options={'return_all': True})
  69. r_iterative = minimize(f, x0, jac=g, hess=h, tol=1e-8,
  70. method='trust-exact',
  71. options={'return_all': True})
  72. assert_allclose(self.x_opt, r_dogleg['x'])
  73. assert_allclose(self.x_opt, r_trust_ncg['x'])
  74. assert_allclose(self.x_opt, r_trust_krylov['x'])
  75. assert_allclose(self.x_opt, r_ncg['x'])
  76. assert_allclose(self.x_opt, r_iterative['x'])
  77. assert_(len(r_dogleg['allvecs']) < len(r_ncg['allvecs']))
  78. def test_trust_ncg_hessp(self):
  79. for x0 in (self.easy_guess, self.hard_guess, self.x_opt):
  80. r = minimize(rosen, x0, jac=rosen_der, hessp=rosen_hess_prod,
  81. tol=1e-8, method='trust-ncg')
  82. assert_allclose(self.x_opt, r['x'])
  83. def test_trust_ncg_start_in_optimum(self):
  84. r = minimize(rosen, x0=self.x_opt, jac=rosen_der, hess=rosen_hess,
  85. tol=1e-8, method='trust-ncg')
  86. assert_allclose(self.x_opt, r['x'])
  87. def test_trust_krylov_start_in_optimum(self):
  88. r = minimize(rosen, x0=self.x_opt, jac=rosen_der, hess=rosen_hess,
  89. tol=1e-8, method='trust-krylov')
  90. assert_allclose(self.x_opt, r['x'])
  91. def test_trust_exact_start_in_optimum(self):
  92. r = minimize(rosen, x0=self.x_opt, jac=rosen_der, hess=rosen_hess,
  93. tol=1e-8, method='trust-exact')
  94. assert_allclose(self.x_opt, r['x'])