ArmijoLineSearcher.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //////////////////////////////////////////////////////////////////////
  2. //
  3. // ArmijoLineSearcher.cpp: Implementation of the Brent LineSearcher class.
  4. //
  5. // Written by Matthias Wacker
  6. //
  7. // Big parts of code are from numerical recipes in C
  8. //
  9. //////////////////////////////////////////////////////////////////////
  10. #include "optimization/ArmijoLineSearcher.h"
  11. #include <iostream>
  12. using namespace OPTIMIZATION;
  13. ArmijoLineSearcher::ArmijoLineSearcher() : m_dGamma(0.7), m_dL(1.0),m_dSigma(0.33)
  14. {
  15. }
  16. ArmijoLineSearcher::ArmijoLineSearcher(CostFunction *costFunc,OptLogBase* loger) : SuperClass(costFunc,loger),m_dGamma(0.5), m_dL(1.0),m_dSigma(0.33)
  17. {
  18. }
  19. ArmijoLineSearcher::ArmijoLineSearcher(const ArmijoLineSearcher &lin) : SuperClass(lin)
  20. {
  21. m_dGamma = lin.m_dGamma;
  22. m_dL = lin.m_dL;
  23. m_dSigma = lin.m_dSigma;
  24. }
  25. ArmijoLineSearcher & ArmijoLineSearcher::operator =(const ArmijoLineSearcher &lin)
  26. {
  27. /*
  28. avoid self-copy
  29. */
  30. if(this != &lin)
  31. {
  32. /*
  33. =operator of SuperClass
  34. */
  35. SuperClass::operator=(lin);
  36. m_dGamma = lin.m_dGamma;
  37. m_dL = lin.m_dL;
  38. m_dSigma = lin.m_dSigma;
  39. }
  40. return *this;
  41. }
  42. ArmijoLineSearcher::~ArmijoLineSearcher()
  43. {
  44. }
  45. void ArmijoLineSearcher::setGammaLSigma(double gamma, double L, double sigma)
  46. {
  47. m_dGamma=gamma;
  48. m_dL=L;
  49. m_dSigma=sigma;
  50. }
  51. void ArmijoLineSearcher::setXkGkDk(const matrix_type xk, const matrix_type gk, const matrix_type dk)
  52. {
  53. this->setX0(xk);
  54. this->setH0(dk);
  55. m_gk=gk;
  56. m_dk=dk;
  57. }
  58. double ArmijoLineSearcher::optimize()
  59. {
  60. double x=0.0;
  61. double ndk2=m_dk.frobeniusNorm();ndk2*=ndk2;
  62. double fk= evaluateSub(0.0);
  63. double tmp= (!m_gk * m_dk)(0,0);
  64. double sk= - tmp / (m_dL * ndk2 );
  65. x=sk;
  66. int maxIter=30;
  67. int iter=0;
  68. // own rule
  69. double fk_old=fk;
  70. double x_old=0.0;
  71. double fk_new;
  72. bool improved = false;
  73. while( iter < maxIter)
  74. {
  75. fk_new=evaluateSub(x);
  76. if ( fk_new > fk_old)
  77. {
  78. x=x_old;
  79. //cout << "loop 1: end " << endl;
  80. break;
  81. }
  82. //cout << "loop 1: iter "<< iter << " " << x << " " << fk_new<<endl;
  83. fk_old = fk_new;
  84. x_old = x;
  85. x/=m_dGamma;
  86. ++iter;
  87. }
  88. if( iter <= 1 )
  89. {
  90. iter=0;
  91. fk_old=fk;
  92. x_old=0.0;
  93. x=sk;
  94. while( iter < maxIter)
  95. {
  96. fk_new=evaluateSub(x);
  97. // fk_new is worse than old, and we are lower than fk
  98. if( fk_new > fk_old && improved==true)
  99. {
  100. // abort with fk_old which was generated by x_old
  101. x = x_old;
  102. break;
  103. }
  104. //cout << "loop 2: iter "<< iter << " " << x << " " << fk_new<<endl;
  105. fk_old=fk_new;
  106. x_old=x;
  107. x*=m_dGamma;
  108. ++iter;
  109. if( fk_old < fk)
  110. {
  111. improved = true;
  112. }
  113. }
  114. }
  115. // own rule till here
  116. // original implementation
  117. //iter=0.0;
  118. //while( fk - evaluateSub(x) < - m_dSigma * x *tmp && iter < maxIter)
  119. //{
  120. // x*=m_dGamma;
  121. // iter++;
  122. //}
  123. // if(m_pLoger)
  124. // m_pLoger->logWarning("Brent took too many iterations.. Tol threshold was to low for the number of iterations..\n");
  125. return x;
  126. }