ArmijoLineSearcher.cpp 2.8 KB

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