34 #include "gsl/gsl_integration.h"
56 GSLIntegrator::GSLIntegrator(
const Integration::Type type ,
const Integration::GKRule rule,
double absTol,
double relTol,
size_t size) :
63 fResult(0),fError(0),fStatus(-1),fNEval(-1),
69 if (type != Integration::kNONADAPTIVE)
70 fWorkspace =
new GSLIntegrationWorkspace( fSize);
77 GSLIntegrator::GSLIntegrator(
double absTol,
double relTol,
size_t size) :
78 fType(Integration::kADAPTIVESINGULAR),
79 fRule(Integration::kGAUSS31),
84 fResult(0),fError(0),fStatus(-1),fNEval(-1),
89 fWorkspace =
new GSLIntegrationWorkspace( fSize);
95 GSLIntegrator::GSLIntegrator(
const Integration::Type type ,
double absTol,
double relTol,
size_t size) :
97 fRule(Integration::kGAUSS31),
102 fResult(0),fError(0),fStatus(-1),fNEval(-1),
109 if (type != Integration::kNONADAPTIVE)
110 fWorkspace =
new GSLIntegrationWorkspace( fSize);
114 GSLIntegrator::GSLIntegrator(
const char * type ,
int rule,
double absTol,
double relTol,
size_t size) :
115 fRule(Integration::kGAUSS31),
120 fResult(0),fError(0),fStatus(-1),fNEval(-1),
126 fType = Integration::kADAPTIVESINGULAR;
128 std::string typeName(type);
129 std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );
130 if (typeName ==
"NONADAPTIVE")
131 fType = Integration::kNONADAPTIVE;
132 else if (typeName ==
"ADAPTIVE")
133 fType = Integration::kADAPTIVE;
135 if (typeName !=
"ADAPTIVESINGULAR")
136 MATH_WARN_MSG(
"GSLIntegrator",
"Use default type: AdaptiveSingular");
143 if (fType != Integration::kNONADAPTIVE)
144 fWorkspace =
new GSLIntegrationWorkspace( fSize);
146 if (rule >= Integration::kGAUSS15 && rule <= Integration::kGAUSS61) SetIntegrationRule((Integration::GKRule) rule);
151 GSLIntegrator::~GSLIntegrator()
154 if (fFunction)
delete fFunction;
155 if (fWorkspace)
delete fWorkspace;
158 GSLIntegrator::GSLIntegrator(
const GSLIntegrator &) :
159 VirtualIntegratorOneDim()
164 GSLIntegrator & GSLIntegrator::operator = (
const GSLIntegrator &rhs)
167 if (
this == &rhs)
return *
this;
175 void GSLIntegrator::SetFunction( GSLFuncPointer fp,
void * p) {
177 if (fFunction ==0) fFunction =
new GSLFunctionWrapper();
178 fFunction->SetFuncPointer( fp );
179 fFunction->SetParams ( p );
182 void GSLIntegrator::SetFunction(
const IGenFunction &f ) {
184 if (fFunction ==0) fFunction =
new GSLFunctionWrapper();
185 fFunction->SetFunction(f);
190 double GSLIntegrator::Integral(
double a,
double b) {
195 if (!CheckFunction())
return 0;
197 if ( fType == Integration::kNONADAPTIVE) {
199 fStatus = gsl_integration_qng( fFunction->GetFunc(), a, b , fAbsTol, fRelTol, &fResult, &fError, &neval);
202 else if (fType == Integration::kADAPTIVE) {
203 fStatus = gsl_integration_qag( fFunction->GetFunc(), a, b , fAbsTol, fRelTol, fMaxIntervals, fRule, fWorkspace->GetWS(), &fResult, &fError);
204 const int npts[6] = {15,21,31,41,51,61};
205 assert(fRule>=1 && fRule <=6);
206 fNEval = (fWorkspace->GetWS()->size)*npts[fRule-1];
208 else if (fType == Integration::kADAPTIVESINGULAR) {
213 fStatus = gsl_integration_qags( fFunction->GetFunc(), a, b , fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
214 fNEval = (fWorkspace->GetWS()->size) * 21;
221 std::cerr <<
"GSLIntegrator - Error: Unknown integration type" << std::endl;
222 throw std::exception();
230 double GSLIntegrator::IntegralCauchy(
double a,
double b,
double c) {
232 if (!CheckFunction())
return 0;
234 fStatus = gsl_integration_qawc( fFunction->GetFunc(), a, b , c, fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
235 fNEval = (fWorkspace->GetWS()->size) * 15;
241 double GSLIntegrator::IntegralCauchy(
const IGenFunction & f,
double a,
double b,
double c) {
244 if (!CheckFunction())
return 0;
246 return IntegralCauchy(a, b, c);
252 double GSLIntegrator::Integral(
const std::vector<double> & pts) {
255 if (!CheckFunction())
return 0;
257 if (fType == Integration::kADAPTIVESINGULAR && pts.size() >= 2 ) {
259 double * p =
const_cast<double *
>(&pts.front() );
260 fStatus = gsl_integration_qagp( fFunction->GetFunc(), p, pts.size() , fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
261 fNEval = (fWorkspace->GetWS()->size) * 15;
267 std::cerr <<
"GSLIntegrator - Error: Unknown integration type or not enough singular points defined" << std::endl;
274 double GSLIntegrator::Integral( ) {
278 if (!CheckFunction())
return 0;
280 if (!fWorkspace) fWorkspace =
new GSLIntegrationWorkspace( fSize);
282 fStatus = gsl_integration_qagi( fFunction->GetFunc(), fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
283 fNEval = (fWorkspace->GetWS()->size) * 15;
290 double GSLIntegrator::IntegralUp(
double a ) {
294 if (!CheckFunction())
return 0;
296 if (!fWorkspace) fWorkspace =
new GSLIntegrationWorkspace( fSize);
298 fStatus = gsl_integration_qagiu( fFunction->GetFunc(), a, fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
299 fNEval = (fWorkspace->GetWS()->size) * 21;
306 double GSLIntegrator::IntegralLow(
double b ) {
310 if (!CheckFunction())
return 0;
312 if (!fWorkspace) fWorkspace =
new GSLIntegrationWorkspace( fSize);
314 fStatus = gsl_integration_qagil( fFunction->GetFunc(), b, fAbsTol, fRelTol, fMaxIntervals, fWorkspace->GetWS(), &fResult, &fError);
315 fNEval = (fWorkspace->GetWS()->size) * 21;
323 double GSLIntegrator::Integral(
const IGenFunction & f,
double a,
double b) {
326 return Integral(a,b);
329 double GSLIntegrator::Integral(
const IGenFunction & f ) {
335 double GSLIntegrator::IntegralUp(
const IGenFunction & f,
double a) {
338 return IntegralUp(a);
341 double GSLIntegrator::IntegralLow(
const IGenFunction & f,
double b) {
344 return IntegralLow(b);
347 double GSLIntegrator::Integral(
const IGenFunction & f,
const std::vector<double> & pts) {
350 return Integral(pts);
356 double GSLIntegrator::Integral( GSLFuncPointer f ,
void * p,
double a,
double b) {
359 return Integral(a,b);
362 double GSLIntegrator::Integral( GSLFuncPointer f,
void * p ) {
368 double GSLIntegrator::IntegralUp( GSLFuncPointer f,
void * p,
double a ) {
371 return IntegralUp(a);
374 double GSLIntegrator::IntegralLow( GSLFuncPointer f,
void * p,
double b ) {
377 return IntegralLow(b);
380 double GSLIntegrator::Integral( GSLFuncPointer f,
void * p,
const std::vector<double> & pts ) {
383 return Integral(pts);
388 double GSLIntegrator::Result()
const {
return fResult; }
390 double GSLIntegrator::Error()
const {
return fError; }
392 int GSLIntegrator::Status()
const {
return fStatus; }
399 void GSLIntegrator::SetAbsTolerance(
double absTol){ this->fAbsTol = absTol; }
403 void GSLIntegrator::SetRelTolerance(
double relTol){ this->fRelTol = relTol; }
406 void GSLIntegrator::SetIntegrationRule(Integration::GKRule rule){ this->fRule = rule; }
408 bool GSLIntegrator::CheckFunction() {
410 if (fFunction && fFunction->IsValid())
return true;
411 fStatus = -1; fResult = 0; fError = 0;
412 std::cerr <<
"GSLIntegrator - Error : Function has not been specified " << std::endl;
416 void GSLIntegrator::SetOptions(
const ROOT::Math::IntegratorOneDimOptions & opt)
419 fType = opt.IntegratorType();
420 if (fType == IntegrationOneDim::kDEFAULT) fType = IntegrationOneDim::kADAPTIVESINGULAR;
421 if (fType != IntegrationOneDim::kADAPTIVE &&
422 fType != IntegrationOneDim::kADAPTIVESINGULAR &&
423 fType != IntegrationOneDim::kNONADAPTIVE ) {
424 MATH_WARN_MSG(
"GSLIntegrator::SetOptions",
"Invalid rule options - use default ADAPTIVESINGULAR");
425 fType = IntegrationOneDim::kADAPTIVESINGULAR;
427 SetAbsTolerance( opt.AbsTolerance() );
428 SetRelTolerance( opt.RelTolerance() );
429 fSize = opt.WKSize();
430 fMaxIntervals = fSize;
431 if (fType == Integration::kADAPTIVE) {
432 int npts = opt.NPoints();
433 if ( npts >= Integration::kGAUSS15 && npts <= Integration::kGAUSS61)
434 fRule = (Integration::GKRule) npts;
436 MATH_WARN_MSG(
"GSLIntegrator::SetOptions",
"Invalid rule options - use default GAUSS31");
437 fRule = Integration::kGAUSS31;
442 ROOT::Math::IntegratorOneDimOptions GSLIntegrator::Options()
const {
443 ROOT::Math::IntegratorOneDimOptions opt;
444 opt.SetAbsTolerance(fAbsTol);
445 opt.SetRelTolerance(fRelTol);
446 opt.SetWKSize(fSize);
447 opt.SetIntegrator(GetTypeName() );
449 if (fType == IntegrationOneDim::kADAPTIVE)
450 opt.SetNPoints(fRule);
451 else if (fType == IntegrationOneDim::kADAPTIVESINGULAR)
452 opt.SetNPoints( Integration::kGAUSS31 );
459 const char * GSLIntegrator::GetTypeName()
const {
460 if (fType == IntegrationOneDim::kADAPTIVE)
return "Adaptive";
461 if (fType == IntegrationOneDim::kADAPTIVESINGULAR)
return "AdaptiveSingular";
462 if (fType == IntegrationOneDim::kNONADAPTIVE)
return "NonAdaptive";