test_cobyla.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from __future__ import division, print_function, absolute_import
  2. import math
  3. import numpy as np
  4. from numpy.testing import assert_allclose, assert_
  5. from scipy.optimize import fmin_cobyla, minimize
  6. class TestCobyla(object):
  7. def setup_method(self):
  8. self.x0 = [4.95, 0.66]
  9. self.solution = [math.sqrt(25 - (2.0/3)**2), 2.0/3]
  10. self.opts = {'disp': False, 'rhobeg': 1, 'tol': 1e-5,
  11. 'maxiter': 100}
  12. def fun(self, x):
  13. return x[0]**2 + abs(x[1])**3
  14. def con1(self, x):
  15. return x[0]**2 + x[1]**2 - 25
  16. def con2(self, x):
  17. return -self.con1(x)
  18. def test_simple(self):
  19. # use disp=True as smoke test for gh-8118
  20. x = fmin_cobyla(self.fun, self.x0, [self.con1, self.con2], rhobeg=1,
  21. rhoend=1e-5, maxfun=100, disp=True)
  22. assert_allclose(x, self.solution, atol=1e-4)
  23. def test_minimize_simple(self):
  24. # Minimize with method='COBYLA'
  25. cons = ({'type': 'ineq', 'fun': self.con1},
  26. {'type': 'ineq', 'fun': self.con2})
  27. sol = minimize(self.fun, self.x0, method='cobyla', constraints=cons,
  28. options=self.opts)
  29. assert_allclose(sol.x, self.solution, atol=1e-4)
  30. assert_(sol.success, sol.message)
  31. assert_(sol.maxcv < 1e-5, sol)
  32. assert_(sol.nfev < 70, sol)
  33. assert_(sol.fun < self.fun(self.solution) + 1e-3, sol)
  34. def test_minimize_constraint_violation(self):
  35. np.random.seed(1234)
  36. pb = np.random.rand(10, 10)
  37. spread = np.random.rand(10)
  38. def p(w):
  39. return pb.dot(w)
  40. def f(w):
  41. return -(w * spread).sum()
  42. def c1(w):
  43. return 500 - abs(p(w)).sum()
  44. def c2(w):
  45. return 5 - abs(p(w).sum())
  46. def c3(w):
  47. return 5 - abs(p(w)).max()
  48. cons = ({'type': 'ineq', 'fun': c1},
  49. {'type': 'ineq', 'fun': c2},
  50. {'type': 'ineq', 'fun': c3})
  51. w0 = np.zeros((10, 1))
  52. sol = minimize(f, w0, method='cobyla', constraints=cons,
  53. options={'catol': 1e-6})
  54. assert_(sol.maxcv > 1e-6)
  55. assert_(not sol.success)
  56. def test_vector_constraints():
  57. # test that fmin_cobyla and minimize can take a combination
  58. # of constraints, some returning a number and others an array
  59. def fun(x):
  60. return (x[0] - 1)**2 + (x[1] - 2.5)**2
  61. def fmin(x):
  62. return fun(x) - 1
  63. def cons1(x):
  64. a = np.array([[1, -2, 2], [-1, -2, 6], [-1, 2, 2]])
  65. return np.array([a[i, 0] * x[0] + a[i, 1] * x[1] +
  66. a[i, 2] for i in range(len(a))])
  67. def cons2(x):
  68. return x # identity, acts as bounds x > 0
  69. x0 = np.array([2, 0])
  70. cons_list = [fun, cons1, cons2]
  71. xsol = [1.4, 1.7]
  72. fsol = 0.8
  73. # testing fmin_cobyla
  74. sol = fmin_cobyla(fun, x0, cons_list, rhoend=1e-5)
  75. assert_allclose(sol, xsol, atol=1e-4)
  76. sol = fmin_cobyla(fun, x0, fmin, rhoend=1e-5)
  77. assert_allclose(fun(sol), 1, atol=1e-4)
  78. # testing minimize
  79. constraints = [{'type': 'ineq', 'fun': cons} for cons in cons_list]
  80. sol = minimize(fun, x0, constraints=constraints, tol=1e-5)
  81. assert_allclose(sol.x, xsol, atol=1e-4)
  82. assert_(sol.success, sol.message)
  83. assert_allclose(sol.fun, fsol, atol=1e-4)
  84. constraints = {'type': 'ineq', 'fun': fmin}
  85. sol = minimize(fun, x0, constraints=constraints, tol=1e-5)
  86. assert_allclose(sol.fun, 1, atol=1e-4)