00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef ROOTSOLVER_H
00030 #define ROOTSOLVER_H
00031
00032 #include "QGpCoreToolsDLLExport.h"
00033 #include "CoreApplication.h"
00034
00035 namespace QGpCoreTools {
00036
00037 #define ROOTSOLVER_MAX_ITERATIONS 500
00038
00039 template <class RealType, class FunctionClass>
00040 class QGPCORETOOLS_EXPORT RootSolverTemplate
00041 {
00042 public:
00043 RootSolverTemplate(FunctionClass * values);
00044
00045 FunctionClass * values() {return _values;}
00046
00047 RealType searchStep() const {return _dx;}
00048 void setAbsoluteStep(RealType step) {_dx=fabs(step); _dxType=Absolute;}
00049 void setRelativeStep(RealType step) {_dx=fabs(step); _dxType=Relative;}
00050
00051 void setPolarity(RealType x0);
00052 void inversePolarity() {_polarity=-_polarity;}
00053
00054 RealType precision() const {return _precision;}
00055 void setPrecision(RealType prec) {_precision=prec;}
00056
00057 inline bool searchUp(RealType from, RealType to);
00058 inline bool searchDown(RealType from, RealType to);
00059
00060 inline bool searchUp(RealType from, RealType min, RealType max);
00061 inline bool searchDown(RealType from, RealType min, RealType max);
00062
00063 inline bool searchUpSlope(RealType from, RealType min, RealType max);
00064 inline bool searchDownSlope(RealType from, RealType min, RealType max);
00065
00066 bool setInterval(RealType min, RealType max);
00067
00068 void halving();
00069 void newtonRaphson();
00070 void neville();
00071
00072 RealType lower() const {return _x1<_x2 ? _x1 : _x2;}
00073 RealType upper() const {return _x1<_x2 ? _x2 : _x1;}
00074 private:
00075 FunctionClass * _values;
00076 RealType _x1, _x2, _y1, _y2;
00077
00078 enum StepType {Absolute, Relative};
00079 StepType _dxType;
00080 RealType _dx;
00081 RealType _polarity;
00082 RealType _precision;
00083
00084 template <class Iterator>
00085 bool search(RealType from, RealType to, const Iterator& it);
00086 template <class Iterator>
00087 bool search(RealType from, RealType min, RealType max, const Iterator& it);
00088 template <class Iterator>
00089 bool searchSlope(RealType from, RealType min, RealType max, const Iterator& it);
00090 static inline bool isFound(RealType y1, RealType y2);
00091
00092 class AbsoluteUpIterator
00093 {
00094 public:
00095 AbsoluteUpIterator(RealType dx) {_dx=dx;}
00096 RealType next(RealType x) const {return x+_dx;}
00097 static bool atEnd(RealType x, RealType to) {return x >= to;}
00098 static bool atEnd(RealType x, RealType , RealType max) {return x >= max;}
00099 static RealType begin(RealType min, RealType ) {return min;}
00100 static RealType end(RealType , RealType max) {return max;}
00101 private:
00102 RealType _dx;
00103 };
00104
00105 class AbsoluteDownIterator
00106 {
00107 public:
00108 AbsoluteDownIterator(RealType dx) {_dx=dx;}
00109 RealType next(RealType x) const {return x-_dx;}
00110 static bool atEnd(RealType x, RealType to) {return x <= to;}
00111 static bool atEnd(RealType x, RealType min, RealType ) {return x <= min;}
00112 static RealType begin(RealType , RealType max) {return max;}
00113 static RealType end(RealType min, RealType ) {return min;}
00114 private:
00115 RealType _dx;
00116 };
00117
00118 class RelativeUpIterator
00119 {
00120 public:
00121 RelativeUpIterator(RealType dx) {_dx=1.0+dx;}
00122 RealType next(RealType x) const {return x*_dx;}
00123 static bool atEnd(RealType x, RealType to) {return x >= to;}
00124 static bool atEnd(RealType x, RealType , RealType max) {return x >= max;}
00125 static RealType begin(RealType min, RealType ) {return min;}
00126 static RealType end(RealType , RealType max) {return max;}
00127 private:
00128 RealType _dx;
00129 };
00130
00131 class RelativeDownIterator
00132 {
00133 public:
00134 RelativeDownIterator(RealType dx) {_dx=1.0-dx;}
00135 RealType next(RealType x) const {return x*_dx;}
00136 static bool atEnd(RealType x, RealType to) {return x <= to;}
00137 static bool atEnd(RealType x, RealType min, RealType ) {return x <= min;}
00138 static RealType begin(RealType , RealType max) {return max;}
00139 static RealType end(RealType min, RealType ) {return min;}
00140 private:
00141 RealType _dx;
00142 };
00143 };
00144
00145 template <class RealType, class FunctionClass>
00146 inline bool RootSolverTemplate<RealType, FunctionClass>
00147 ::searchDown(RealType from, RealType min, RealType max)
00148 {
00149 if(_dxType==Absolute) {
00150 AbsoluteDownIterator it(_dx);
00151 return search(from, min, max, it);
00152 } else {
00153 RelativeDownIterator it(_dx);
00154 return search(from, min, max, it);
00155 }
00156 }
00157
00158 template <class RealType, class FunctionClass>
00159 inline bool RootSolverTemplate<RealType, FunctionClass>
00160 ::searchUp(RealType from, RealType min, RealType max)
00161 {
00162 if(_dxType==Absolute) {
00163 AbsoluteUpIterator it(_dx);
00164 return search(from, min, max, it);
00165 } else {
00166 RelativeUpIterator it(_dx);
00167 return search(from, min, max, it);
00168 }
00169 }
00170
00171 template <class RealType, class FunctionClass>
00172 inline bool RootSolverTemplate<RealType, FunctionClass>
00173 ::searchDownSlope(RealType from, RealType min, RealType max)
00174 {
00175 if(_dxType==Absolute) {
00176 AbsoluteDownIterator it(_dx);
00177 return searchSlope(from, min, max, it);
00178 } else {
00179 RelativeDownIterator it(_dx);
00180 return searchSlope(from, min, max, it);
00181 }
00182 }
00183
00184 template <class RealType, class FunctionClass>
00185 inline bool RootSolverTemplate<RealType, FunctionClass>
00186 ::searchUpSlope(RealType from, RealType min, RealType max)
00187 {
00188 if(_dxType==Absolute) {
00189 AbsoluteUpIterator it(_dx);
00190 return searchSlope(from, min, max, it);
00191 } else {
00192 RelativeUpIterator it(_dx);
00193 return searchSlope(from, min, max, it);
00194 }
00195 }
00196
00197 template <class RealType, class FunctionClass>
00198 inline bool RootSolverTemplate<RealType, FunctionClass>
00199 ::searchUp(RealType from, RealType to)
00200 {
00201 if(from>to) return false;
00202 if(_dxType==Absolute) {
00203 AbsoluteUpIterator it(_dx);
00204 return search(from, to, it);
00205 } else {
00206 RelativeUpIterator it(_dx);
00207 return search(from, to, it);
00208 }
00209 }
00210
00211 template <class RealType, class FunctionClass>
00212 inline bool RootSolverTemplate<RealType, FunctionClass>
00213 ::searchDown(RealType from, RealType to)
00214 {
00215 if(from>to) return false;
00216 if(_dxType==Absolute) {
00217 AbsoluteDownIterator it(_dx);
00218 return search(from, to, it);
00219 } else {
00220 RelativeDownIterator it(_dx);
00221 return search(from, to, it);
00222 }
00223 }
00224
00225 template <class RealType, class FunctionClass>
00226 inline bool RootSolverTemplate<RealType, FunctionClass>::isFound(RealType y1, RealType y2)
00227 {
00228 return (y1<0.0 && y2>0.0) || (y1>0.0 && y2<0.0);
00229 }
00230
00231
00232 template <class FunctionClass>
00233 class QGPCORETOOLS_EXPORT RootSolver: public RootSolverTemplate<double, FunctionClass>
00234 {
00235 public:
00236 RootSolver(FunctionClass * values) :
00237 RootSolverTemplate<double, FunctionClass>(values) {}
00238 };
00239
00240 #ifdef BIGNUM
00241
00242 template <class FunctionClass>
00243 class QGPCORETOOLS_EXPORT RootSolverBigNum: public RootSolverTemplate<mp_real, FunctionClass>
00244 {
00245 public:
00246 RootSolverBigNum(FunctionClass * values) :
00247 RootSolverTemplate<mp_real, FunctionClass>(values) {}
00248 };
00249 #endif
00250
00251 template <class RealType, class FunctionClass>
00252 RootSolverTemplate<RealType, FunctionClass>::
00253 RootSolverTemplate(FunctionClass * values)
00254 {
00255 _values=values;
00256 _dxType=Relative;
00257 _dx=0.1;
00258 _polarity=1.0;
00259 _precision=1e-7;
00260 }
00261
00262 template <class RealType, class FunctionClass>
00263 void RootSolverTemplate<RealType, FunctionClass>::
00264 setPolarity(RealType x0)
00265 {
00266 _polarity=_values->y(x0);
00267 }
00268
00269 template <class RealType, class FunctionClass> template <class Iterator>
00270 bool RootSolverTemplate<RealType, FunctionClass>::
00271 search(RealType from, RealType to, const Iterator& it)
00272 {
00273
00274 #ifdef searchFromTo
00275 printf( "RootSolverTemplate::searchFromTo\n" );
00276 #endif
00277 _x1=from;
00278 _y1=_values->y(_x1);
00279 _x2=it.next(_x1);
00280 while( ! it.atEnd(_x2, to)) {
00281 _y2=_values->y(_x2);
00282 #ifdef searchFromTo
00283 printSearchDebug();
00284 #endif
00285 if(isFound(_y1, _y2)) {
00286 return true;
00287 } else {
00288 _x1=_x2;
00289 _y1=_y2;
00290 _x2=it.next(_x1);
00291 }
00292 }
00293
00294
00295 #ifdef searchFromTo
00296 printSearchDebug();
00297 #endif
00298 if( ! it.atEnd(_x1, to)) {
00299 _x2=to;
00300 _y2=_values->y(_x2);
00301 if(isFound(_y1, _y2)) {
00302 return true;
00303 }
00304 }
00305 return false;
00306 }
00307
00308 template <class RealType, class FunctionClass> template <class Iterator>
00309 bool RootSolverTemplate<RealType, FunctionClass>::
00310 search(RealType from, RealType min, RealType max, const Iterator& it)
00311 {
00312
00313 #ifdef searchMinMax
00314 printf( "RootSolverTemplate::searchMinMax\n" );
00315 printf( "Current polarity %lg\n", ::toDouble(_polarity));
00316 #endif
00317
00318 _x1=from;
00319 _y1=_values->y(_x1);
00320 _y2=_polarity;
00321
00322 if(isFound(_y1, _y2)) {
00323
00324 #ifdef searchMinMax
00325
00326 printf( "Root above _x1=%.8lf _y1=%lg _x2=%.8lf _y2=%lg\n", _x1, _y1, _x2, _y2);
00327 #endif
00328 if(it.atEnd(from, min, max)) {
00329
00330
00331
00332
00333
00334 App::stream() << "** Warning ** : directly at the end" << endl;
00335 return false;
00336 } else {
00337 _x2=_x1;
00338 _y2=_y1;
00339 _x1=it.begin(min, max);
00340 _y1=_polarity;
00341 return true;
00342 }
00343 } else {
00344
00345 _x2=it.next(_x1);
00346 while( ! it.atEnd(_x2, min, max)) {
00347 _y2=_values->y(_x2);
00348 #ifdef searchMinMax
00349 printSearchDebug()
00350 #endif
00351 if(isFound(_y1, _y2)) {
00352 return true;
00353 } else {
00354 _x1=_x2;
00355 _y1=_y2;
00356 _x2=it.next(_x1);
00357 }
00358 }
00359 }
00360
00361 if( ! it.atEnd(_x1, min, max)) {
00362 _x2=it.end(min, max);
00363 _y2=_values->y(_x2);
00364 if(isFound(_y1, _y2)) {
00365 return true;
00366 }
00367 }
00368 #ifdef searchMinMax
00369 printf( "*** no root\n" );
00370 #endif
00371
00372
00373
00374
00375
00376 return false;
00377 }
00378
00379 template <class RealType, class FunctionClass> template <class Iterator>
00380 bool RootSolverTemplate<RealType, FunctionClass>
00381 ::searchSlope(RealType from, RealType min, RealType max, const Iterator& it)
00382 {
00383 _x1=from;
00384 _y1=_values->y(_x1);
00385 _x2=it.next(_x1);
00386 RealType maxDiff;
00387 if(_dxType==Absolute) {
00388 maxDiff=1e-7*_dx;
00389 } else {
00390 maxDiff=0.5e-7*fabs(_x1 + _x2) * _dx;
00391 }
00392 while( ! it.atEnd(_x2, min, max)) {
00393 _y2=_values->y(_x2);
00394 if(isFound(_y1, _y2)) {
00395 return true;
00396 }
00397
00398 RealType x3=0.5 * (_x1 + _x2);
00399 RealType y3=_values->y(x3);
00400 if(y3 < _y1 && y3 < _y2) {
00401
00402 RealType x1=_x1;
00403 RealType y1=_y1;
00404 RealType x2=_x2;
00405 RealType y2=_y2;
00406 RealType x13, y13, x32, y32;
00407 while(fabs(x2 - x1) > maxDiff) {
00408 x13=0.5 * (x1 + x3);
00409 y13=_values->y(x13);
00410 x32=0.5 * (x3 + x2);
00411 y32=_values->y(x32);
00412 if(y3 < y13 && y3 < y32) {
00413 x1=x13;
00414 y1=y13;
00415 x2=x32;
00416 y2=y32;
00417 } else if(y13 < y32) {
00418 x2=x3;
00419 y2=y3;
00420 x3=x13;
00421 y3=y13;
00422 } else {
00423 x1=x13;
00424 y1=y13;
00425 x3=x32;
00426 y3=y32;
00427 }
00428 }
00429 if(isFound(y3, _y2)) {
00430
00431 _x2=x3;
00432 _y2=y3;
00433 return true;
00434 }
00435
00436 } else if(y3 > _y1 && y3 > _y2) {
00437
00438 RealType x1=_x1;
00439 RealType y1=_y1;
00440 RealType x2=_x2;
00441 RealType y2=_y2;
00442 RealType x13, y13, x32, y32;
00443 while(fabs(x1 - x2) > maxDiff) {
00444 x13=0.5 * (x1 + x3);
00445 y13=_values->y(x13);
00446 x32=0.5 * (x3 + x2);
00447 y32=_values->y(x32);
00448 if(y3 > y13 && y3 > y32) {
00449 x1=x13;
00450 y1=y13;
00451 x2=x32;
00452 y2=y32;
00453 } else if(y13 > y32) {
00454 x2=x3;
00455 y2=y3;
00456 x3=x13;
00457 y3=y13;
00458 } else {
00459 x1=x13;
00460 y1=y13;
00461 x3=x32;
00462 y3=y32;
00463 }
00464 }
00465 if(isFound(y3, _y2)) {
00466
00467 _x2=x3;
00468 _y2=y3;
00469 return true;
00470 }
00471
00472 }
00473 _x1=_x2;
00474 _y1=_y2;
00475 _x2=it.next(_x1);
00476 }
00477
00478 if( ! it.atEnd(_x1, min, max)) {
00479 _x2=it.end(min, max);
00480 _y2=_values->y(_x2);
00481 if(isFound(_y1, _y2)) {
00482 return true;
00483 }
00484 }
00485 return false;
00486 }
00487
00488 template <class RealType, class FunctionClass>
00489 bool RootSolverTemplate<RealType, FunctionClass>::setInterval(RealType min, RealType max)
00490 {
00491 _x1=min;
00492 _y1=_values->y(_x1);
00493 _x2=max;
00494 _y2=_values->y(_x2);
00495 return isFound(_y1, _y2);
00496 }
00497
00498 template <class RealType, class FunctionClass>
00499 void RootSolverTemplate<RealType, FunctionClass>::halving()
00500 {
00501
00502 RealType x3=0.5 * (_x1 + _x2);
00503 RealType y3=_values->y(x3);
00504
00505 RealType tmpAbs1;
00506 tmpAbs1=_x1 + _x2;
00507 if(tmpAbs1 < 0) tmpAbs1=-tmpAbs1;
00508 RealType maxDiff=tmpAbs1 * _precision;
00509 RealType minDiff=-maxDiff;
00510 for(register int i=1;i < ROOTSOLVER_MAX_ITERATIONS;i++ ) {
00511 if(y3==0.0) {
00512
00513 x3 -= (_x2 - _x1) * 0.1;
00514
00515 y3=_values->y(x3);
00516 }
00517 if(isFound(_y1, y3)) {
00518 _x2=x3;
00519 _y2=y3;
00520 } else {
00521 _x1=x3;
00522 _y1=y3;
00523 }
00524
00525 RealType diff=_x1 - _x2;
00526 if(minDiff <= diff && diff <= maxDiff) {
00527 return;
00528 }
00529 x3=0.5 * (_x1 + _x2);
00530 y3=_values->y(x3);
00531 }
00532 App::stream() << "Halving maximum iteration reached" << endl;
00533 }
00534
00535 template <class RealType, class FunctionClass>
00536 void RootSolverTemplate<RealType, FunctionClass>::neville()
00537 {
00538
00539
00540 #if defined(neville_DEBUG) || defined(neville_STAT)
00541 printf("RootSolverTemplate::neville() @ precision=%lg\n", _precision);
00542 #endif
00543
00544 int m=0;
00545 RealType p[ 20 ], nevY[ 20 ];
00546
00547 RealType x3=0.5 * (_x1 + _x2);
00548 RealType y3=_values->y(x3);
00549
00550 RealType maxDiff=fabs(x3)*_precision;
00551 for (register int i=1; i<ROOTSOLVER_MAX_ITERATIONS; i++) {
00552
00553
00554
00555
00556
00557
00558
00559 #ifdef neville_DEBUG
00560
00561 printf("_x1=%.20lf _y1=%.20lg _x2=%.20lf _y2=%.20lg x3=%.20lf y3=%.20lg diff=%.20lg\n", _x1, _y1, _x2, _y2, x3, y3, fabs(_x1-_x2));
00562 #endif
00563 if(y3==0.0) {
00564
00565 if(fabs(_x1-x3)>fabs(_x2-x3)) {
00566 x3=0.5*(_x1+x3);
00567 } else {
00568 x3=0.5*(_x2+x3);
00569 }
00570
00571 y3=_values->y(x3);
00572 #ifdef neville_DEBUG
00573 printf("y3 is null: x3=%.20lf y3=%.20lg\n", x3, y3);
00574 #endif
00575 }
00576 if(isFound(_y1, y3)) {
00577 _x2=x3;
00578 _y2=y3;
00579 } else {
00580 _x1=x3;
00581 _y1=y3;
00582 }
00583
00584 if(fabs(_x1-_x2)<=maxDiff) {
00585 #if defined(neville_DEBUG) || defined(neville_STAT)
00586 printf( "Number of iterations=%i \n", i);
00587 printf( "Neville poly m=%i \n", m);
00588 printf( "Convergence achieved\n" );
00589 #endif
00590 return;
00591 }
00592
00593
00594
00595 if(isFound(_y1 - y3, y3 - _y2)) {
00596 #if defined(neville_DEBUG) || defined(neville_STAT)
00597 printf( "Neville poly m=%i \n", m);
00598 printf( "Inverse slopes: " );
00599 #endif
00600 x3=0.5* (_x1 + _x2);
00601 y3=_values->y(x3);
00602 m=0;
00603 } else {
00604
00605
00606
00607
00608 #if 0
00609 RealType ay1=_y1;
00610 if(ay1 < 0) ay1=-ay1;
00611 RealType ay2=_y2;
00612 if(ay2 < 0) ay2=-ay2;
00613 if(ay1 > 100 * ay2 || ay2 > 100 * ay1) {
00614 #if defined(neville_DEBUG) || defined(neville_STAT)
00615 printf( "Neville poly m=%i \n", m);
00616 printf( "Factor of more than 100: " );
00617 #endif
00618 x3=0.5* (x1 + x2);
00619 y3=_values->y(x3);
00620 m=0;
00621 } else {
00622 #endif
00623 #ifdef neville_DEBUG
00624 printf( "Neville poly m=%i \n", m);
00625 #endif
00626
00627 if(m>0) {
00628 p[ m + 1 ]=x3;
00629 nevY[ m + 1 ]=y3;
00630 } else {
00631 p[ 0 ]=_x1;
00632 nevY[ 0 ]=_y1;
00633 p[ 1 ]=_x2;
00634 nevY[ 1 ]=_y2;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644 for(int j=m;j >= 0;j-- ) {
00645 RealType denom=nevY[ m + 1 ] - nevY[ j ];
00646 RealType tmpAbs1=nevY[ m + 1 ];
00647 if(tmpAbs1 < 0) tmpAbs1=-tmpAbs1;
00648 RealType tmpAbs2=denom;
00649 if(tmpAbs2 < 0) tmpAbs2=-tmpAbs2;
00650 if(tmpAbs2 < 1.0e-10 * tmpAbs1) {
00651 #if defined(neville_DEBUG) || defined(neville_STAT)
00652 printf( "Neville poly m=%i \n", m);
00653 printf( "Denom too small (%lf), halving\n", denom);
00654 #endif
00655 p[ 0 ]=0.5 * (_x1 + _x2);
00656 m=0;
00657 break;
00658 } else p[ j ]=(nevY[ m + 1 ] * p[ j ] - nevY[ j ] * p[ j + 1 ] )/denom;
00659 }
00660 x3=p[ 0 ];
00661
00662 RealType tmpAbs1=_y1<0 ? -_y1 : _y1;
00663 RealType tmpAbs2=_y2<0 ? -_y2 : _y2;
00664 if(tmpAbs1 > tmpAbs2)
00665 x3 -= 0.1 * (x3 - _x1);
00666 else
00667 x3 -= 0.1 * (x3 - _x2);
00668
00669 m++;
00670 if(m > 18) m=1;
00671
00672
00673 if(_x1 <= _x2) {
00674 if(x3 < _x1 || x3 > _x2) {
00675 #if defined(neville_DEBUG) || defined(neville_STAT)
00676 printf( "Neville poly m=%i \n", m);
00677 printf( "New estimate out of range, halving\n" );
00678 #endif
00679 x3=0.5* (_x1 + _x2);
00680 m=1;
00681 }
00682 } else {
00683 if(x3 < _x2 || x3 > _x1) {
00684 #if defined(neville_DEBUG) || defined(neville_STAT)
00685 printf( "Neville poly m=%i \n", m);
00686 printf( "New estimate out of range, halving\n" );
00687 #endif
00688 x3=0.5* (_x1 + _x2);
00689 m=1;
00690 }
00691 }
00692 y3=_values->y(x3);
00693 }
00694 }
00695 App::stream() << "Neville maximum iteration reached" << endl;
00696 }
00697
00698 template <class RealType, class FunctionClass>
00699 void RootSolverTemplate<RealType, FunctionClass>::newtonRaphson()
00700 {
00701
00702 RealType x3=0.5 * (_x1 + _x2);
00703 RealType y3=_values->y(x3);
00704
00705 RealType tmpAbs1;
00706 tmpAbs1=_x1 + _x2;
00707 if(tmpAbs1 < 0) tmpAbs1=-tmpAbs1;
00708 RealType maxDiff=tmpAbs1 * _precision;
00709 RealType minDiff=-maxDiff;
00710 for(register int i=1;i < ROOTSOLVER_MAX_ITERATIONS;i++ ) {
00711 if(y3==0.0) {
00712
00713 x3 -= (_x2 - _x1) * 0.1;
00714
00715 y3=_values->y(x3);
00716 }
00717 if(isFound(_y1, y3)) {
00718 _x2=x3;
00719 _y2=y3;
00720 } else {
00721 _x1=x3;
00722 _y1=y3;
00723 }
00724
00725 RealType diff=_x1 - _x2;
00726 if(minDiff <= diff && diff <= maxDiff) {
00727 return;
00728 }
00729
00730
00731 RealType tmpAbs1=_y1<0 ? -_y1 : _y1;
00732 RealType tmpAbs2=_y2<0 ? -_y2 : _y2;
00733 if(tmpAbs1 > tmpAbs2) {
00734 x3=_x2 - _y2/_values->derivative(_x2);
00735 x3 -= 0.1 * (x3 - _x1);
00736 } else {
00737 x3=_x1 - _y1/_values->derivative(_x1);
00738 x3 -= 0.1 * (x3 - _x2);
00739 }
00740
00741
00742 if(_x1 <= _x2) {
00743 if(x3 < _x1 || x3 > _x2) {
00744 x3=0.5* (_x1 + _x2);
00745 }
00746 } else {
00747 if(x3 < _x2 || x3 > _x1) {
00748 x3=0.5* (_x1 + _x2);
00749 }
00750 }
00751 y3=_values->y(x3);
00752 }
00753 App::stream() << "Newton-Raphson maximum iteration reached" << endl;
00754 }
00755
00756 }
00757
00758 #endif // ROOTSOLVER_H