45 #ifndef _NonLinearBrent_H 46 #define _NonLinearBrent_H 1
50 #include <lifev/core/LifeV.hpp> 73 template <
class Function>
78 if ( leftExtremeBase == rightExtremeBase )
80 return leftExtremeBase;
84 Real leftExtreme ( leftExtremeBase ), rightExtreme ( rightExtremeBase );
86 if ( leftExtreme > rightExtreme )
88 std::swap ( leftExtreme, rightExtreme );
92 UInt numIter (
static_cast<
UInt> (0) );
95 Real midpoint ( ( leftExtreme + rightExtreme ) /
static_cast<
Real> (2.) );
98 Real gold (
static_cast<Real> ( (3. - std::sqrt (5.) ) / 2. ) );
101 Real p (0), q (0), r (0);
102 Real x ( leftExtreme + gold * ( rightExtreme - leftExtreme ) );
103 Real u (0), e (0), w (0), v (0), d (0);
104 Real fx ( f (x) ), fv ( fx ), fw ( fx ), fu (0);
107 Real tollRelative ( std::numeric_limits<Real>::epsilon() * std::fabs ( x ) + toll );
110 while ( std::fabs ( x - midpoint) > (
static_cast<Real> (2.) * tollRelative - ( rightExtreme - leftExtreme ) /
static_cast<Real> (2.) ) && numIter < maxIter )
114 p = q = r =
static_cast<Real> (0);
116 if ( std::fabs ( e ) > tollRelative )
118 r = ( x - w ) * ( fx - fv );
119 q = ( x - v ) * ( fx - fw );
120 p = ( x - v ) * q - ( x - w ) * r;
121 q =
static_cast<Real> (2.) * ( q - r );
123 if ( q >
static_cast<Real> (0.) )
137 if ( std::fabs ( p ) < std::fabs ( q * r /
static_cast<Real> (2.) ) && p > q * ( leftExtreme - x ) && p < q * ( rightExtreme - x ) )
142 if ( ( u - leftExtreme) <
static_cast<Real> (2.) * tollRelative || ( rightExtreme - u ) <
static_cast<Real> (2.) * tollRelative )
158 e = rightExtreme - x;
168 if ( std::fabs ( d ) >= tollRelative )
174 if ( d >
static_cast<Real> (0.) )
176 u = x + tollRelative;
180 u = x - tollRelative;
216 if ( fu <= fw || x == w )
225 if ( fu <= fv || v == x || v == w )
234 midpoint = ( leftExtreme + rightExtreme ) /
static_cast<Real> (2.);
237 tollRelative = std::numeric_limits<Real>::epsilon() * std::fabs ( x ) + toll;
243 std::ostringstream os;
244 os <<
"Attention the brent scheme does not reach the convergence in " 245 << numIter <<
", with tollerance " 246 << tollRelative << std::endl;
249 ASSERT ( maxIter > numIter, os.str().c_str() );
Real NonLinearBrent(const Function &f, const Real &leftExtremeBase, const Real &rightExtremeBase, const Real &toll, const UInt &maxIter)
Implementation of Brent's method for root finding.
double Real
Generic real data.
uint32_type UInt
generic unsigned integer (used mainly for addressing)