TestTrustRegion.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * NICE-Core - efficient algebra and computer vision methods
  3. * - liboptimization - An optimization/template for new NICE libraries
  4. * See file License for license information.
  5. */
  6. #ifdef NICE_USELIB_CPPUNIT
  7. #include "TestTrustRegion.h"
  8. #include <string>
  9. #include <exception>
  10. #include <core/basics/cppunitex.h>
  11. #include <core/optimization/gradientBased/FirstOrderTrustRegion.h>
  12. #include <core/optimization/gradientBased/FirstOrderRasmussen.h>
  13. #include <core/optimization/gradientBased/SecondOrderTrustRegion.h>
  14. using namespace NICE;
  15. CPPUNIT_TEST_SUITE_REGISTRATION( TestTrustRegion );
  16. void TestTrustRegion::setUp() {
  17. }
  18. void TestTrustRegion::tearDown() {
  19. }
  20. /** a simple quadratic optimization problem */
  21. class MyProblem : public OptimizationProblemFirst {
  22. public:
  23. inline MyProblem() : OptimizationProblemFirst(2) {
  24. parameters()[0] = 1.0;
  25. }
  26. protected:
  27. virtual void computeGradient(Vector& newGradient);
  28. virtual double computeObjective();
  29. };
  30. double MyProblem::computeObjective() {
  31. return 0.7 * square(parameters()[0] + 0.6)
  32. + 0.4 * square(parameters()[1] - 0.3);
  33. }
  34. void MyProblem::computeGradient(Vector& newGradient) {
  35. newGradient[0] = 1.4 * (parameters()[0] + 0.6);
  36. newGradient[1] = 0.8 * (parameters()[1] - 0.3);
  37. }
  38. /** a simple quadratic optimization problem with hessian */
  39. class MyProblem2 : public OptimizationProblemSecond {
  40. public:
  41. inline MyProblem2() : OptimizationProblemSecond(2) {
  42. parameters()[0] = 1.0;
  43. parameters()[1] = 1.0;
  44. }
  45. protected:
  46. virtual void computeGradientAndHessian(Vector& newGradient,
  47. Matrix& newHessian);
  48. virtual double computeObjective();
  49. };
  50. double MyProblem2::computeObjective() {
  51. return 0.7 * square(parameters()[0] + 0.6)
  52. + 0.4 * square(parameters()[1] - 0.3);
  53. }
  54. void MyProblem2::computeGradientAndHessian(Vector& newGradient,
  55. Matrix& newHessian) {
  56. newGradient[0] = 1.4 * (parameters()[0] + 0.6);
  57. newGradient[1] = 0.8 * (parameters()[1] - 0.3);
  58. newHessian(0,0) = 1.4;
  59. newHessian(0,1) = 0.0;
  60. newHessian(1,0) = 0.0;
  61. newHessian(1,1) = 0.8;
  62. }
  63. /** a large scale optimization problem */
  64. class MyProblem3 : public OptimizationProblemFirst
  65. {
  66. public:
  67. MyProblem3 (uint n) : OptimizationProblemFirst(n) {}
  68. double computeObjective()
  69. {
  70. double sum = 0.0;
  71. for ( uint i = 0 ; i < parameters().size() ; i++ )
  72. sum += pow(parameters()[i] - 1,2);
  73. for ( uint i = 1; i < parameters().size(); i++ )
  74. sum -= parameters()[i] * parameters()[i-1];
  75. return sum;
  76. }
  77. void computeGradient ( NICE::Vector &newGradient )
  78. {
  79. newGradient.resize(parameters().size());
  80. for ( uint i = 0 ; i < parameters().size() ; i++ )
  81. {
  82. newGradient[i] = 2*(parameters()[i]-1);
  83. if ( i > 0 )
  84. newGradient[i] -= parameters()[i-1];
  85. if ( i < parameters().size()-1 )
  86. newGradient[i] -= parameters()[i+1];
  87. }
  88. }
  89. Vector groundtruth () {
  90. Vector gt ( parameters().size() );
  91. for ( uint i = 0 ; i < gt.size() ; i++ )
  92. gt[i] = (i+1)*(gt.size()-i);
  93. return gt;
  94. }
  95. };
  96. void TestTrustRegion::testOptimization1() {
  97. {
  98. MyProblem problem;
  99. FirstOrderTrustRegion optimizer;
  100. optimizer.setEpsilonG(1E-4);
  101. optimizer.optimizeFirst(problem);
  102. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem.objective(), 1E-8);
  103. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem.position()[0], 2E-5);
  104. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem.position()[1], 5E-5);
  105. }
  106. {
  107. MyProblem2 problem2;
  108. FirstOrderTrustRegion optimizer;
  109. optimizer.setEpsilonG(1E-4);
  110. optimizer.optimizeFirst(problem2);
  111. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-8);
  112. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 5E-5);
  113. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 2E-6);
  114. }
  115. }
  116. void TestTrustRegion::testOptimization1Ras () {
  117. {
  118. MyProblem problem;
  119. FirstOrderRasmussen optimizer ( false /*verbose*/ );
  120. optimizer.setEpsilonG(1E-4);
  121. optimizer.optimizeFirst(problem);
  122. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem.objective(), 1E-8);
  123. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem.position()[0], 2E-5);
  124. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem.position()[1], 5E-5);
  125. }
  126. {
  127. MyProblem2 problem2;
  128. FirstOrderRasmussen optimizer (false);
  129. optimizer.setEpsilonG(1E-4);
  130. optimizer.optimizeFirst(problem2);
  131. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-8);
  132. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 5E-5);
  133. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 2E-6);
  134. }
  135. {
  136. uint size = 100;
  137. MyProblem3 problem3 (size);
  138. FirstOrderRasmussen optimizer (false);
  139. optimizer.setEpsilonG(1E-9);
  140. optimizer.setMaxIterations ( -1000 );
  141. optimizer.optimizeFirst(problem3);
  142. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, (problem3.position() - problem3.groundtruth()).normL2() / size, 4E-3);
  143. }
  144. }
  145. void TestTrustRegion::testOptimization2() {
  146. MyProblem2 problem2;
  147. SecondOrderTrustRegion optimizer;
  148. optimizer.setEpsilonG(1E-4);
  149. optimizer.optimize(problem2);
  150. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-30);
  151. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 1E-14);
  152. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 1E-16);
  153. }
  154. #endif