// @(#)root/mathcore:$Id$ // Author: David Gonzalez Maline 2/2008 /********************************************************************** * * * Copyright (c) 2004 Maline, CERN/PH-SFT * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this library (see file COPYING); if not, write * * to the Free Software Foundation, Inc., 59 Temple Place, Suite * * 330, Boston, MA 02111-1307 USA, or contact the author. * * * **********************************************************************/ // Header file for class BrentMinimizer1D // // Created by: Maline at Mon Feb 4 09:32:36 2008 // // #include "Math/BrentMinimizer1D.h" #include "Math/BrentMethods.h" #include "Math/IFunction.h" #ifndef ROOT_Math_Error #include "Math/Error.h" #endif namespace ROOT { namespace Math { static int gDefaultNpx = 100; // default nunmber of points used in the grid to bracked the minimum static int gDefaultNSearch = 10; // nnumber of time the iteration (bracketing -Brent ) is repeted BrentMinimizer1D::BrentMinimizer1D(): IMinimizer1D(), fFunction(0), fLogScan(false), fNIter(0), fNpx(0), fStatus(-1), fXMin(0), fXMax(0), fXMinimum(0) { // Default Constructor. fNpx = gDefaultNpx; } void BrentMinimizer1D::SetDefaultNpx(int n) { gDefaultNpx = n; } void BrentMinimizer1D::SetDefaultNSearch(int n) { gDefaultNSearch = n; } void BrentMinimizer1D::SetFunction(const ROOT::Math::IGenFunction& f, double xlow, double xup) { // Sets function to be minimized. fFunction = &f; fStatus = -1; // reset the status if (xlow >= xup) { double tmp = xlow; xlow = xup; xup = tmp; } fXMin = xlow; fXMax = xup; } double BrentMinimizer1D::FValMinimum() const { return (*fFunction)(fXMinimum); } double BrentMinimizer1D::FValLower() const { return (*fFunction)(fXMin); } double BrentMinimizer1D::FValUpper() const { return (*fFunction)(fXMax); } bool BrentMinimizer1D::Minimize( int maxIter, double absTol , double relTol) { // Find minimum position iterating until convergence specified by the // absolute and relative tolerance or the maximum number of iteration // is reached. // repet search (Bracketing + Brent) until max number of search is reached (default is 10) // maxITer refers to the iterations inside the Brent algorithm if (!fFunction) { MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "Function has not been set"); return false; } if (fLogScan && fXMin <= 0) { MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "xmin is < 0 and log scan is set - disable it"); fLogScan = false; } fNIter = 0; fStatus = -1; double xmin = fXMin; double xmax = fXMax; int maxIter1 = gDefaultNSearch; // external loop (number of search ) int maxIter2 = maxIter; // internal loop inside the Brent algorithm int niter1 = 0; int niter2 = 0; bool ok = false; while (!ok){ if (niter1 > maxIter1){ MATH_ERROR_MSG("BrentMinimizer1D::Minimize", "Search didn't converge"); fStatus = -2; return false; } double x = BrentMethods::MinimStep(fFunction, 0, xmin, xmax, 0, fNpx,fLogScan); x = BrentMethods::MinimBrent(fFunction, 0, xmin, xmax, x, 0, ok, niter2, absTol, relTol, maxIter2 ); fNIter += niter2; // count the total number of iterations niter1++; fXMinimum = x; } fStatus = 0; return true; } const char * BrentMinimizer1D::Name() const { return "BrentMinimizer1D"; } } // Namespace Math } // Namespace ROOT