1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
// @(#)root/mathmore:$Id$
// Author: L. Moneta Wed Dec 20 14:36:31 2006
/**********************************************************************
* *
* Copyright (c) 2006 LCG ROOT Math Team, 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. *
* *
**********************************************************************/
// implementation file for class MultiNumGradFunction
#include "Math/MultiNumGradFunction.h"
#include <limits>
#include <cmath>
#include <algorithm> // needed for std::max on Solaris
#include "Math/Derivator.h"
namespace ROOT {
namespace Math {
double MultiNumGradFunction::fgEps = 0.001;
double MultiNumGradFunction::DoDerivative (const double * x, unsigned int icoord ) const {
// calculate derivative using mathcore derivator class
// step size can be changes using SetDerivPrecision()
static double kPrecision = std::sqrt ( std::numeric_limits<double>::epsilon() );
double x0 = std::abs(x[icoord]);
//double step = (x0 > 0) ? kPrecision * x0 : kPrecision;
// this seems to work better than above
double step = (x0>0) ? std::max( fgEps* x0, 8.0*kPrecision*(x0 + kPrecision) ) : kPrecision;
return ROOT::Math::Derivator::Eval(*fFunc, x, icoord, step);
}
void MultiNumGradFunction::SetDerivPrecision(double eps) { fgEps = eps; }
double MultiNumGradFunction::GetDerivPrecision( ) { return fgEps; }
} // end namespace Math
} // end namespace ROOT
|