Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
IntegratorOptions.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: L. Moneta Fri Aug 15 2008
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2008 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 #include "Math/IntegratorOptions.h"
12 #include "Math/Integrator.h"
14 #include "Math/GenAlgoOptions.h"
15 
16 #include "RConfigure.h"
17 
18 #include <algorithm>
19 #include <functional>
20 #include <ctype.h> // need to use c version of tolower defined here
21 
22 #include <map>
23 
24 namespace ROOT {
25 
26 namespace Math {
27 
28  // eventually could take values from /etc/system.rootrc
29 
30 namespace IntegOneDim {
31 
32 #ifdef R__HAS_MATHMORE
33  static int gDefaultIntegrator = IntegrationOneDim::kADAPTIVESINGULAR;
34 #else
35  static int gDefaultIntegrator = IntegrationOneDim::kGAUSS;
36 #endif
37  static double gDefaultAbsTolerance = 1.E-09;
38  static double gDefaultRelTolerance = 1.E-09;
39  static unsigned int gDefaultWKSize = 1000;
40  static unsigned int gDefaultNPointsLegendre = 10;
41  static unsigned int gDefaultNPointsGSLAdaptive = 3; // corresponds to 31 points
42  static unsigned int gDefaultNPoints = gDefaultNPointsGSLAdaptive;
43 
44 
45 }
46 
47 namespace IntegMultiDim {
48 
49  static int gDefaultIntegrator = IntegrationMultiDim::kADAPTIVE;
50  // by default do not use absolute tolerance in AdaptiveIntegration multidim.
51  // If an absolute tolerance is given integration of shar peaks often failed
52  static double gDefaultAbsTolerance = 0.0;
53  static double gDefaultRelTolerance = 1.E-09;
54  static unsigned int gDefaultWKSize = 100000;
55  static unsigned int gDefaultNCalls = 100000;
56 
57 
58 }
59 
60 
61 // some utility functions
62 
63 namespace IntegOptionsUtil {
64 
65 
66  // traits for the specific methods 1D - ND
67  template<class OptionType>
68  struct OptionTrait {
69  static int N() { return 0; }
70  static int N(const OptionType & ) { return 0; }
71  static const char * DescriptionOfN() {return 0; }
72  };
73  template<>
74  struct OptionTrait<IntegratorOneDimOptions> {
75  typedef IntegratorOneDimOptions OptType;
76  static int N() { return OptType::DefaultNPoints(); }
77  static int N(const OptType & opt) { return opt.NPoints(); }
78  static const char * DescriptionOfN() {return "Rule (Npoints)";}
79  };
80  template<>
81  struct OptionTrait<IntegratorMultiDimOptions> {
82  typedef IntegratorMultiDimOptions OptType;
83  static int N() { return OptType::DefaultNCalls(); }
84  static int N(const OptType & opt) { return opt.NCalls(); }
85  static const char * DescriptionOfN() {return "(max) function calls";}
86  };
87 
88 
89  //print option values (not the default ones)
90  template <class OptionType>
91  void Print(std::ostream & os,const OptionType & opt) {
92  //print all the options
93  os << std::setw(25) << "Integrator Type" << " : " << std::setw(15) << opt.Integrator() << std::endl;
94  os << std::setw(25) << "Absolute tolerance" << " : " << std::setw(15) << opt.AbsTolerance() << std::endl;
95  os << std::setw(25) << "Relative tolerance" << " : " << std::setw(15) << opt.RelTolerance() << std::endl;
96  os << std::setw(25) << "Workspace size" << " : " << std::setw(15) << opt.WKSize() << std::endl;
97  typedef OptionTrait<OptionType> OPT;
98  os << std::setw(25) << OPT::DescriptionOfN() << " : " << std::setw(15) << OPT::N(opt) << std::endl;
99  if (opt.ExtraOptions()) {
100  os << opt.Integrator() << " specific options :" << std::endl;
101  opt.ExtraOptions()->Print(os);
102  }
103  }
104 
105 
106  /// print default options
107  template <class OptionType>
108  void PrintDefault(const char * name, std::ostream & os) {
109  //print default options
110  std::string integName = (name != 0) ? name : OptionType::DefaultIntegrator();
111  os << "Default options for numerical integrator " << integName << " : " << std::endl;
112  os << std::setw(25) << "Absolute tolerance" << " : " << std::setw(15) << OptionType::DefaultAbsTolerance() << std::endl;
113  os << std::setw(25) << "Relative tolerance" << " : " <<std::setw(15) << OptionType::DefaultRelTolerance() << std::endl;
114  os << std::setw(25) << "Workspace size" << " : " << std::setw(15) << OptionType::DefaultWKSize() << std::endl;
115  typedef OptionTrait<OptionType> OPT;
116  os << std::setw(25) << OPT::DescriptionOfN() << " : " << std::setw(15) << OPT::N() << std::endl;
117  IOptions * opts = GenAlgoOptions::FindDefault(integName.c_str());
118  if (opts) opts->Print(os);
119  }
120 
121 }
122 
123 
124 /// constructor (protected) to avoid user creating this class
125 BaseIntegratorOptions::BaseIntegratorOptions() :
126  fIntegType(-1),
127  fWKSize(0), fNCalls(0),
128  fAbsTolerance(0), fRelTolerance(0),
129  fExtraOptions(0)
130 {}
131 
132 BaseIntegratorOptions::BaseIntegratorOptions(const BaseIntegratorOptions & opt) : fExtraOptions(0) {
133  // copy constructor
134  (*this) = opt;
135 }
136 
137 BaseIntegratorOptions & BaseIntegratorOptions::operator=(const BaseIntegratorOptions & opt) {
138  // assignment operator
139  if (this == &opt) return *this; // self assignment
140  fWKSize = opt.fWKSize;
141  fNCalls = opt.fNCalls;
142  fAbsTolerance = opt.fAbsTolerance;
143  fRelTolerance = opt.fRelTolerance;
144  fIntegType = opt.fIntegType;
145 
146 // std::cout << " copy options for " << fIntegName << std::endl;
147 // std::cout << fExtraOptions << std::endl;
148 // if (fExtraOptions) fExtraOptions->Print(std::cout);
149 
150 // std::cout << opt.fExtraOptions << std::endl;
151 // if (opt.fExtraOptions) (opt.fExtraOptions)->Print(std::cout);
152 
153 
154 
155  ClearExtra();
156  if (opt.fExtraOptions) fExtraOptions = (opt.fExtraOptions)->Clone();
157  return *this;
158 }
159 
160 
161 void BaseIntegratorOptions::ClearExtra() {
162  // delete extra options
163  if (fExtraOptions) delete fExtraOptions;
164  fExtraOptions = 0;
165 }
166 
167 void BaseIntegratorOptions::SetExtraOptions(const IOptions & opt) {
168  // delete extra options
169  ClearExtra();
170  fExtraOptions = opt.Clone();
171 }
172 
173 
174 
175 // one dim specific methods
176 
177 // implementation of non-static methods
178 
179 IntegratorOneDimOptions::IntegratorOneDimOptions(IOptions * opts):
180  BaseIntegratorOptions()
181 {
182  fWKSize = IntegOneDim::gDefaultWKSize;
183  fNCalls = IntegOneDim::gDefaultNPoints;
184  fAbsTolerance = IntegOneDim::gDefaultAbsTolerance;
185  fRelTolerance = IntegOneDim::gDefaultRelTolerance;
186  fIntegType = IntegOneDim::gDefaultIntegrator;
187 
188  fExtraOptions = opts; // N.B. ownership of pointer is given to the class !
189 
190  // check the default options if opts = 0
191  if (!fExtraOptions) {
192  std::string igname = DefaultIntegrator();
193  IOptions * gopts = FindDefault( igname.c_str() );
194  if (gopts) fExtraOptions = gopts->Clone();
195  }
196 }
197 
198 void IntegratorOneDimOptions::SetIntegrator(const char * algo ) {
199  // set the default 1D integrator
200  if (!algo) return;
201  fIntegType = (int) IntegratorOneDim::GetType(algo);
202 }
203 
204 std::string IntegratorOneDimOptions::Integrator() const {
205  return IntegratorOneDim::GetName((IntegratorOneDim::Type) fIntegType);
206 }
207 
208 void IntegratorOneDimOptions::Print(std::ostream & os) const {
209  //print all the options
210  IntegOptionsUtil::Print(os, *this);
211 }
212 
213 // one dim integrator options: implementation for static methods
214 
215 /// print default options
216 void IntegratorOneDimOptions::PrintDefault(const char * name, std::ostream & os) {
217  //print default options
218  IntegOptionsUtil::PrintDefault<IntegratorOneDimOptions>(name,os);
219 }
220 
221 
222 
223 void IntegratorOneDimOptions::SetDefaultIntegrator(const char * algo ) {
224  // set the default 1D integrator
225  if (!algo) return;
226  IntegrationOneDim::Type type = IntegratorOneDim::GetType(algo);
227  if (type == IntegrationOneDim::kDEFAULT) return; // this is possible only when invalid name was specified
228  IntegOneDim::gDefaultIntegrator = (int) type;
229  if (IntegOneDim::gDefaultIntegrator == IntegrationOneDim::kLEGENDRE)
230  IntegOneDim::gDefaultNPoints = IntegOneDim::gDefaultNPointsLegendre;
231  if (IntegOneDim::gDefaultIntegrator == IntegrationOneDim::kADAPTIVE)
232  IntegOneDim::gDefaultNPoints = IntegOneDim::gDefaultNPointsGSLAdaptive;
233 }
234 
235 
236 std::string IntegratorOneDimOptions::DefaultIntegrator() {
237  // return default integrator name
238  return IntegratorOneDim::GetName((IntegratorOneDim::Type) IntegOneDim::gDefaultIntegrator);
239 }
240 
241 IntegratorOneDim::Type IntegratorOneDimOptions::DefaultIntegratorType() {
242  // return default integrator type (enum)
243  return (IntegratorOneDim::Type) IntegOneDim::gDefaultIntegrator;
244 }
245 
246 
247 void IntegratorOneDimOptions::SetDefaultAbsTolerance(double tol) {
248  // set the default tolerance
249  IntegOneDim::gDefaultAbsTolerance = tol;
250 }
251 void IntegratorOneDimOptions::SetDefaultRelTolerance(double tol) {
252  // set the default tolerance
253  IntegOneDim::gDefaultRelTolerance = tol;
254 }
255 
256 void IntegratorOneDimOptions::SetDefaultWKSize(unsigned int size) {
257  // set the default workspace size
258  IntegOneDim::gDefaultWKSize = size;
259 }
260 void IntegratorOneDimOptions::SetDefaultNPoints(unsigned int n) {
261  // set the default number of points for the integration rule
262  IntegOneDim::gDefaultNPoints = n;
263 }
264 
265 
266 double IntegratorOneDimOptions::DefaultAbsTolerance() { return IntegOneDim::gDefaultAbsTolerance; }
267 double IntegratorOneDimOptions::DefaultRelTolerance() { return IntegOneDim::gDefaultRelTolerance; }
268 unsigned int IntegratorOneDimOptions::DefaultWKSize() { return IntegOneDim::gDefaultWKSize; }
269 unsigned int IntegratorOneDimOptions::DefaultNPoints() { return IntegOneDim::gDefaultNPoints; }
270 
271 
272 IOptions & IntegratorOneDimOptions::Default(const char * algo) {
273  // create default extra options for the given algorithm type
274  return GenAlgoOptions::Default(algo);
275 }
276 
277 IOptions * IntegratorOneDimOptions::FindDefault(const char * algo) {
278  // find extra options for the given algorithm type
279  return GenAlgoOptions::FindDefault(algo);
280 }
281 
282 //////////////////////////////////////////////////////
283 //Multi-dim integration options implementation
284 /////////////////////////////////////////////////////////
285 
286 IntegratorMultiDimOptions::IntegratorMultiDimOptions(IOptions * opts):
287  BaseIntegratorOptions()
288 {
289  fWKSize = IntegMultiDim::gDefaultWKSize;
290  fNCalls = IntegMultiDim::gDefaultNCalls;
291  fAbsTolerance = IntegMultiDim::gDefaultAbsTolerance;
292  fRelTolerance = IntegMultiDim::gDefaultRelTolerance;
293  fIntegType = IntegMultiDim::gDefaultIntegrator;
294 
295  fExtraOptions = opts; // N.B. ownership of pointer is given to the class !
296 
297  // check the default options if opts = 0
298  if (!fExtraOptions) {
299  IOptions * gopts = FindDefault( DefaultIntegrator().c_str() );
300  if (gopts) fExtraOptions = gopts->Clone();
301  }
302 }
303 
304 void IntegratorMultiDimOptions::SetIntegrator(const char * algo ) {
305  // set the default integrator
306  if (!algo) return;
307  fIntegType = (int) IntegratorMultiDim::GetType(algo);
308 }
309 
310 std::string IntegratorMultiDimOptions::Integrator() const {
311  return IntegratorMultiDim::GetName((IntegratorMultiDim::Type) fIntegType);
312 }
313 
314 void IntegratorMultiDimOptions::Print(std::ostream & os) const {
315  //print all the options
316  IntegOptionsUtil::Print(os, *this);
317 }
318 
319 // multi dim integrator options: implementation for static methods
320 
321 /// print default options
322 void IntegratorMultiDimOptions::PrintDefault(const char * name, std::ostream & os) {
323  //print default options
324  IntegOptionsUtil::PrintDefault<IntegratorMultiDimOptions>(name,os);
325 }
326 
327 
328 void IntegratorMultiDimOptions::SetDefaultIntegrator(const char * algo ) {
329  // set the default integrator
330  if (!algo) return;
331  // check if type is correct
332  IntegrationMultiDim::Type type = IntegratorMultiDim::GetType(algo);
333  if (type == IntegrationMultiDim::kDEFAULT) return; // this is possible only when invalid name was specified
334  IntegMultiDim::gDefaultIntegrator = (int) type;
335 }
336 
337 
338 std::string IntegratorMultiDimOptions::DefaultIntegrator() {
339  // return default integrator name
340  return IntegratorMultiDim::GetName((IntegratorMultiDim::Type) IntegMultiDim::gDefaultIntegrator);
341 }
342 
343 IntegratorMultiDim::Type IntegratorMultiDimOptions::DefaultIntegratorType() {
344  // return default integrator type (enum)
345  return (IntegratorMultiDim::Type) IntegMultiDim::gDefaultIntegrator;
346 }
347 
348 
349 void IntegratorMultiDimOptions::SetDefaultAbsTolerance(double tol) {
350  // set the default tolerance
351  IntegMultiDim::gDefaultAbsTolerance = tol;
352 }
353 
354 void IntegratorMultiDimOptions::SetDefaultRelTolerance(double tol) {
355  // set the default tolerance
356  IntegMultiDim::gDefaultRelTolerance = tol;
357 }
358 
359 void IntegratorMultiDimOptions::SetDefaultWKSize(unsigned int size) {
360  // set the default workspace size
361  IntegMultiDim::gDefaultWKSize = size;
362 }
363 void IntegratorMultiDimOptions::SetDefaultNCalls(unsigned int ncall) {
364  // set the default (max) function calls
365  IntegMultiDim::gDefaultNCalls = ncall;
366 }
367 
368 
369 double IntegratorMultiDimOptions::DefaultAbsTolerance() { return IntegMultiDim::gDefaultAbsTolerance; }
370 double IntegratorMultiDimOptions::DefaultRelTolerance() { return IntegMultiDim::gDefaultRelTolerance; }
371 unsigned int IntegratorMultiDimOptions::DefaultWKSize() { return IntegMultiDim::gDefaultWKSize; }
372 unsigned int IntegratorMultiDimOptions::DefaultNCalls() { return IntegMultiDim::gDefaultNCalls; }
373 
374 
375 IOptions & IntegratorMultiDimOptions::Default(const char * algo) {
376  // create default extra options for the given algorithm type
377  return GenAlgoOptions::Default(algo);
378 }
379 
380 IOptions * IntegratorMultiDimOptions::FindDefault(const char * algo) {
381  // create default extra options for the given algorithm type
382  return GenAlgoOptions::FindDefault(algo);
383 }
384 
385 
386 } // end namespace Math
387 
388 } // end namespace ROOT
389