test_trustregion_krylov.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. """
  2. Unit tests for Krylov space trust-region subproblem solver.
  3. To run it in its simplest form::
  4. nosetests test_optimize.py
  5. """
  6. from __future__ import division, print_function, absolute_import
  7. import numpy as np
  8. from scipy.optimize._trlib import (get_trlib_quadratic_subproblem)
  9. from numpy.testing import (assert_, assert_array_equal,
  10. assert_almost_equal,
  11. assert_equal, assert_array_almost_equal,
  12. assert_array_less)
  13. KrylovQP = get_trlib_quadratic_subproblem(tol_rel_i=1e-8, tol_rel_b=1e-6)
  14. KrylovQP_disp = get_trlib_quadratic_subproblem(tol_rel_i=1e-8, tol_rel_b=1e-6, disp=True)
  15. class TestKrylovQuadraticSubproblem(object):
  16. def test_for_the_easy_case(self):
  17. # `H` is chosen such that `g` is not orthogonal to the
  18. # eigenvector associated with the smallest eigenvalue.
  19. H = np.array([[1.0, 0.0, 4.0],
  20. [0.0, 2.0, 0.0],
  21. [4.0, 0.0, 3.0]])
  22. g = np.array([5.0, 0.0, 4.0])
  23. # Trust Radius
  24. trust_radius = 1.0
  25. # Solve Subproblem
  26. subprob = KrylovQP(x=0,
  27. fun=lambda x: 0,
  28. jac=lambda x: g,
  29. hess=lambda x: None,
  30. hessp=lambda x, y: H.dot(y))
  31. p, hits_boundary = subprob.solve(trust_radius)
  32. assert_array_almost_equal(p, np.array([-1.0, 0.0, 0.0]))
  33. assert_equal(hits_boundary, True)
  34. # check kkt satisfaction
  35. assert_almost_equal(
  36. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  37. 0.0)
  38. # check trust region constraint
  39. assert_almost_equal(np.linalg.norm(p), trust_radius)
  40. trust_radius = 0.5
  41. p, hits_boundary = subprob.solve(trust_radius)
  42. assert_array_almost_equal(p,
  43. np.array([-0.46125446, 0., -0.19298788]))
  44. assert_equal(hits_boundary, True)
  45. # check kkt satisfaction
  46. assert_almost_equal(
  47. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  48. 0.0)
  49. # check trust region constraint
  50. assert_almost_equal(np.linalg.norm(p), trust_radius)
  51. def test_for_the_hard_case(self):
  52. # `H` is chosen such that `g` is orthogonal to the
  53. # eigenvector associated with the smallest eigenvalue.
  54. H = np.array([[1.0, 0.0, 4.0],
  55. [0.0, 2.0, 0.0],
  56. [4.0, 0.0, 3.0]])
  57. g = np.array([0.0, 2.0, 0.0])
  58. # Trust Radius
  59. trust_radius = 1.0
  60. # Solve Subproblem
  61. subprob = KrylovQP(x=0,
  62. fun=lambda x: 0,
  63. jac=lambda x: g,
  64. hess=lambda x: None,
  65. hessp=lambda x, y: H.dot(y))
  66. p, hits_boundary = subprob.solve(trust_radius)
  67. assert_array_almost_equal(p, np.array([0.0, -1.0, 0.0]))
  68. # check kkt satisfaction
  69. assert_almost_equal(
  70. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  71. 0.0)
  72. # check trust region constraint
  73. assert_almost_equal(np.linalg.norm(p), trust_radius)
  74. trust_radius = 0.5
  75. p, hits_boundary = subprob.solve(trust_radius)
  76. assert_array_almost_equal(p, np.array([0.0, -0.5, 0.0]))
  77. # check kkt satisfaction
  78. assert_almost_equal(
  79. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  80. 0.0)
  81. # check trust region constraint
  82. assert_almost_equal(np.linalg.norm(p), trust_radius)
  83. def test_for_interior_convergence(self):
  84. H = np.array([[1.812159, 0.82687265, 0.21838879, -0.52487006, 0.25436988],
  85. [0.82687265, 2.66380283, 0.31508988, -0.40144163, 0.08811588],
  86. [0.21838879, 0.31508988, 2.38020726, -0.3166346, 0.27363867],
  87. [-0.52487006, -0.40144163, -0.3166346, 1.61927182, -0.42140166],
  88. [0.25436988, 0.08811588, 0.27363867, -0.42140166, 1.33243101]])
  89. g = np.array([0.75798952, 0.01421945, 0.33847612, 0.83725004, -0.47909534])
  90. trust_radius = 1.1
  91. # Solve Subproblem
  92. subprob = KrylovQP(x=0,
  93. fun=lambda x: 0,
  94. jac=lambda x: g,
  95. hess=lambda x: None,
  96. hessp=lambda x, y: H.dot(y))
  97. p, hits_boundary = subprob.solve(trust_radius)
  98. # check kkt satisfaction
  99. assert_almost_equal(
  100. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  101. 0.0)
  102. assert_array_almost_equal(p, [-0.68585435, 0.1222621, -0.22090999,
  103. -0.67005053, 0.31586769])
  104. assert_array_almost_equal(hits_boundary, False)
  105. def test_for_very_close_to_zero(self):
  106. H = np.array([[0.88547534, 2.90692271, 0.98440885, -0.78911503, -0.28035809],
  107. [2.90692271, -0.04618819, 0.32867263, -0.83737945, 0.17116396],
  108. [0.98440885, 0.32867263, -0.87355957, -0.06521957, -1.43030957],
  109. [-0.78911503, -0.83737945, -0.06521957, -1.645709, -0.33887298],
  110. [-0.28035809, 0.17116396, -1.43030957, -0.33887298, -1.68586978]])
  111. g = np.array([0, 0, 0, 0, 1e-6])
  112. trust_radius = 1.1
  113. # Solve Subproblem
  114. subprob = KrylovQP(x=0,
  115. fun=lambda x: 0,
  116. jac=lambda x: g,
  117. hess=lambda x: None,
  118. hessp=lambda x, y: H.dot(y))
  119. p, hits_boundary = subprob.solve(trust_radius)
  120. # check kkt satisfaction
  121. assert_almost_equal(
  122. np.linalg.norm(H.dot(p) + subprob.lam * p + g),
  123. 0.0)
  124. # check trust region constraint
  125. assert_almost_equal(np.linalg.norm(p), trust_radius)
  126. assert_array_almost_equal(p, [0.06910534, -0.01432721,
  127. -0.65311947, -0.23815972,
  128. -0.84954934])
  129. assert_array_almost_equal(hits_boundary, True)
  130. def test_disp(self, capsys):
  131. H = -np.eye(5)
  132. g = np.array([0, 0, 0, 0, 1e-6])
  133. trust_radius = 1.1
  134. subprob = KrylovQP_disp(x=0,
  135. fun=lambda x: 0,
  136. jac=lambda x: g,
  137. hess=lambda x: None,
  138. hessp=lambda x, y: H.dot(y))
  139. p, hits_boundary = subprob.solve(trust_radius)
  140. out, err = capsys.readouterr()
  141. assert_(out.startswith(' TR Solving trust region problem'), repr(out))