123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*
- * NICE-Core - efficient algebra and computer vision methods
- * - liboptimization - An optimization/template for new NICE libraries
- * See file License for license information.
- */
- #ifdef NICE_USELIB_CPPUNIT
- #include "TestTrustRegion.h"
- #include <string>
- #include <exception>
- #include <core/basics/cppunitex.h>
- #include <core/optimization/gradientBased/FirstOrderTrustRegion.h>
- #include <core/optimization/gradientBased/FirstOrderRasmussen.h>
- #include <core/optimization/gradientBased/SecondOrderTrustRegion.h>
- using namespace NICE;
- CPPUNIT_TEST_SUITE_REGISTRATION( TestTrustRegion );
- void TestTrustRegion::setUp() {
- }
- void TestTrustRegion::tearDown() {
- }
- /** a simple quadratic optimization problem */
- class MyProblem : public OptimizationProblemFirst {
- public:
- inline MyProblem() : OptimizationProblemFirst(2) {
- parameters()[0] = 1.0;
- }
- protected:
- virtual void computeGradient(Vector& newGradient);
- virtual double computeObjective();
- };
- double MyProblem::computeObjective() {
- return 0.7 * square(parameters()[0] + 0.6)
- + 0.4 * square(parameters()[1] - 0.3);
- }
-
- void MyProblem::computeGradient(Vector& newGradient) {
- newGradient[0] = 1.4 * (parameters()[0] + 0.6);
- newGradient[1] = 0.8 * (parameters()[1] - 0.3);
- }
- /** a simple quadratic optimization problem with hessian */
- class MyProblem2 : public OptimizationProblemSecond {
- public:
- inline MyProblem2() : OptimizationProblemSecond(2) {
- parameters()[0] = 1.0;
- parameters()[1] = 1.0;
- }
- protected:
- virtual void computeGradientAndHessian(Vector& newGradient,
- Matrix& newHessian);
- virtual double computeObjective();
- };
- double MyProblem2::computeObjective() {
- return 0.7 * square(parameters()[0] + 0.6)
- + 0.4 * square(parameters()[1] - 0.3);
- }
-
- void MyProblem2::computeGradientAndHessian(Vector& newGradient,
- Matrix& newHessian) {
- newGradient[0] = 1.4 * (parameters()[0] + 0.6);
- newGradient[1] = 0.8 * (parameters()[1] - 0.3);
- newHessian(0,0) = 1.4;
- newHessian(0,1) = 0.0;
- newHessian(1,0) = 0.0;
- newHessian(1,1) = 0.8;
- }
- /** a large scale optimization problem */
- class MyProblem3 : public OptimizationProblemFirst
- {
- public:
- MyProblem3 (uint n) : OptimizationProblemFirst(n) {}
- double computeObjective()
- {
- double sum = 0.0;
- for ( uint i = 0 ; i < parameters().size() ; i++ )
- sum += pow(parameters()[i] - 1,2);
- for ( uint i = 1; i < parameters().size(); i++ )
- sum -= parameters()[i] * parameters()[i-1];
- return sum;
- }
- void computeGradient ( NICE::Vector &newGradient )
- {
- newGradient.resize(parameters().size());
- for ( uint i = 0 ; i < parameters().size() ; i++ )
- {
- newGradient[i] = 2*(parameters()[i]-1);
- if ( i > 0 )
- newGradient[i] -= parameters()[i-1];
- if ( i < parameters().size()-1 )
- newGradient[i] -= parameters()[i+1];
- }
- }
- Vector groundtruth () {
- Vector gt ( parameters().size() );
- for ( uint i = 0 ; i < gt.size() ; i++ )
- gt[i] = (i+1)*(gt.size()-i);
- return gt;
- }
- };
- void TestTrustRegion::testOptimization1() {
- {
- MyProblem problem;
- FirstOrderTrustRegion optimizer;
- optimizer.setEpsilonG(1E-4);
- optimizer.optimizeFirst(problem);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem.objective(), 1E-8);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem.position()[0], 2E-5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem.position()[1], 5E-5);
- }
- {
- MyProblem2 problem2;
- FirstOrderTrustRegion optimizer;
- optimizer.setEpsilonG(1E-4);
- optimizer.optimizeFirst(problem2);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-8);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 5E-5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 2E-6);
- }
- }
- void TestTrustRegion::testOptimization1Ras () {
- {
- MyProblem problem;
- FirstOrderRasmussen optimizer ( false /*verbose*/ );
- optimizer.setEpsilonG(1E-4);
- optimizer.optimizeFirst(problem);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem.objective(), 1E-8);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem.position()[0], 2E-5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem.position()[1], 5E-5);
- }
- {
- MyProblem2 problem2;
- FirstOrderRasmussen optimizer (false);
- optimizer.setEpsilonG(1E-4);
- optimizer.optimizeFirst(problem2);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-8);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 5E-5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 2E-6);
- }
- {
- uint size = 100;
- MyProblem3 problem3 (size);
- FirstOrderRasmussen optimizer (false);
- optimizer.setEpsilonG(1E-9);
- optimizer.setMaxIterations ( -1000 );
- optimizer.optimizeFirst(problem3);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, (problem3.position() - problem3.groundtruth()).normL2() / size, 4E-3);
- }
- }
- void TestTrustRegion::testOptimization2() {
- MyProblem2 problem2;
- SecondOrderTrustRegion optimizer;
- optimizer.setEpsilonG(1E-4);
- optimizer.optimize(problem2);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, problem2.objective(), 1E-30);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(-0.6, problem2.position()[0], 1E-14);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.3, problem2.position()[1], 1E-16);
- }
- #endif
|