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
00030 #include "Math/BrentMinimizer1D.h"
00031 #include "Math/BrentMethods.h"
00032 #include "Math/IFunction.h"
00033
00034 #ifndef ROOT_Math_Error
00035 #include "Math/Error.h"
00036 #endif
00037
00038 namespace ROOT {
00039 namespace Math {
00040
00041 static int gDefaultNpx = 100;
00042 static int gDefaultNSearch = 10;
00043
00044
00045 BrentMinimizer1D::BrentMinimizer1D(): IMinimizer1D(),
00046 fFunction(0),
00047 fLogScan(false), fNIter(0),
00048 fNpx(0), fStatus(-1),
00049 fXMin(0), fXMax(0), fXMinimum(0)
00050 {
00051
00052 fNpx = gDefaultNpx;
00053 }
00054
00055 void BrentMinimizer1D::SetDefaultNpx(int n) { gDefaultNpx = n; }
00056
00057 void BrentMinimizer1D::SetDefaultNSearch(int n) { gDefaultNSearch = n; }
00058
00059
00060 void BrentMinimizer1D::SetFunction(const ROOT::Math::IGenFunction& f, double xlow, double xup)
00061 {
00062
00063
00064 fFunction = &f;
00065 fStatus = -1;
00066
00067 if (xlow >= xup)
00068 {
00069 double tmp = xlow;
00070 xlow = xup;
00071 xup = tmp;
00072 }
00073 fXMin = xlow;
00074 fXMax = xup;
00075 }
00076
00077
00078
00079 double BrentMinimizer1D::FValMinimum() const
00080 { return (*fFunction)(fXMinimum); }
00081
00082 double BrentMinimizer1D::FValLower() const
00083 { return (*fFunction)(fXMin); }
00084
00085 double BrentMinimizer1D::FValUpper() const
00086 { return (*fFunction)(fXMax); }
00087
00088 bool BrentMinimizer1D::Minimize( int maxIter, double absTol , double relTol)
00089 {
00090
00091
00092
00093
00094
00095
00096 if (!fFunction) {
00097 MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "Function has not been set");
00098 return false;
00099 }
00100
00101 if (fLogScan && fXMin <= 0) {
00102 MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "xmin is < 0 and log scan is set - disable it");
00103 fLogScan = false;
00104 }
00105
00106 fNIter = 0;
00107 fStatus = -1;
00108
00109 double xmin = fXMin;
00110 double xmax = fXMax;
00111
00112 int maxIter1 = gDefaultNSearch;
00113 int maxIter2 = maxIter;
00114
00115 int niter1 = 0;
00116 int niter2 = 0;
00117 bool ok = false;
00118 while (!ok){
00119 if (niter1 > maxIter1){
00120 MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "Search didn't converge");
00121 fStatus = -2;
00122 return false;
00123 }
00124 double x = BrentMethods::MinimStep(fFunction, 0, xmin, xmax, 0, fNpx,fLogScan);
00125 x = BrentMethods::MinimBrent(fFunction, 0, xmin, xmax, x, 0, ok, niter2, absTol, relTol, maxIter2 );
00126 fNIter += niter2;
00127 niter1++;
00128 fXMinimum = x;
00129 }
00130
00131 fStatus = 0;
00132 return true;
00133 }
00134
00135
00136 const char * BrentMinimizer1D::Name() const
00137 { return "BrentMinimizer1D"; }
00138
00139 }
00140
00141 }