dvegas is hosted by Hepforge, IPPP Durham


Chapter 2: Dvegas

2.1: Dvegas interface

namespace HepSource
{
class Dvegas
{
public:
  Dvegas(const int aDim, const int f, Integrand *const i);
  Dvegas(const int cDim, const int cBin, const int f, Integrand *const i,
         const Sampling sampling = IMPORTANCE);
  Dvegas(const int cDim, const int cBin, const vector<int>& dDimSizes, const int f,
         Integrand *const i, const Sampling sampling = IMPORTANCE);
  Dvegas(const int cDim, const int cBin, const int corrDim,
         const vector<int>& dDimSizes, const int aDim, const int f, Integrand *const i,
         const Sampling sampling = IMPORTANCE);
  Dvegas(const int cDim, const int cBin, const vector<int>& corrDim,
         const vector<int>& dDimSizes, const int aDim, const int f, Integrand *const i,
         const Sampling sampling = IMPORTANCE);
  Dvegas();
  virtual ~Dvegas();

  CellAccumulators collectData(const Int64 numberOfShots);

  void info() const;     // print info about best estimate
  const bool isAdaptingContinuousDimensions() const;
  const double chiSquarePerIteration() const;

  void adapt(CellAccumulators& cellAcc);     // adapt weights
  const double getCurvature() const;
  void setCurvature(const double curvature);
  const double getRootAmpl() const;
  void setRootAmpl(const double rootAmpl);

  void disableOptimize(const int setOfCorrelatedWeights);
  
  void reset();          // discard all data
  void resetWeights();
  void resetEstimates();

  void saveStateToFile(const string& filename = "dvegas.state") const;
  void restoreStateFromFile(Integrand *const i, const string& filename = "dvegas.state");
  void restoreWeightsFromFile(Integrand *const i, const string& filename = "dvegas.state");
  void saveStateToStream(ostream& os) const;
  void restoreStateFromStream(Integrand *const i, istream& is);
  void restoreWeightsFromStream(Integrand *const i, istream& is);
  const string saveStateToString() const;
  void restoreStateFromString(Integrand *const i, const string& s);
  void restoreWeightsFromString(Integrand *const i, const string& s);

  void activateCorrelationsDetector();

  void attachOmniComp(OmniComp *const omniComp);
  void detachOmniComp();

  void printVersion() const;
};
}

2.2: Dvegas constructors

2.2.1: Constructor arguments

cDim: int
number of adapted continuous dimensions

cBin: int
resolution of adaptation (number of bins)

corrDim: vector<int>
defines sets of continuous dimensions for which the adaptation fully takes correlations into account
Example: cDim = 8 and corrDim = {3, 5}: set1 = {0, 1, 2}, set2 = {3, 4}, correlations not sampled for 5, 6, 7

dDimSizes: vector<int>
defines discrete dimensions
Example: dDimSizes = {3, 5}: two discrete dimensions with index1 in {0, 1, 2} and index2 in {0, 1, 2, 3, 4}

aDim: int
number of "auxilliary" (i.e. non- adapted) continuous dimensions

f: int
number of integrands to be evaluated (first integrand drives adapation, see below)

i: Integrand*
pointer to function that evaluates the integrand(s)

sampling: enum Sampling {NONE, IMPORTANCE, STRATIFIED}
Importance sampling concentrates sampled points in hypercubes that contribute most to the integral.
Stratified sampling concentrates sampled points in hypercubes that contribute most to the error of the integral.

The integration range for adapted and auxilliary continuous dimensions is (0, 1).

Note that, except for i, all arguments can be zero (or empty vector), thus disabling the particular functionality.

2.2.2: Function that evaluates f integrands

typedef void Integrand(const double x[], const int k[], const double& weight,
                       const double aux[], double f[]);

x: double array (in)
contains cDim random floats in (0, 1) and thus covers the integration volume for the adapted continuous dimensions

k: int array (in)
contains dDimSizes.size() random integers in [0, dDimSizes[j]) with j = 0, ..., dDimSizes.size() - 1
covering all possible index combinations for the discrete dimensions

weight: double (in)
weight of the sampled point, which may, for example, be used to fill histograms
Note that by default the weight is normalized in each iteration to yield the average integrand value--corresponding to the value of the integral (assuming unit volume)--rather than the sum.

aux: double array (in)
contains aDim random numbers in (0, 1) that have no effect on the adaptation

f: double array (out)
passes back f floats obtained by evaluating each integrand at the point specified by the input parameters
Note that the first integrand (i.e. values passed back through f[0]) drives the adaptation.
Depending on how similar the other integrands are to the first the adapted sampling may or may not be well suited for them.

2.2.3: Constructors

Dvegas(const int aDim, const int f, Integrand *const i);
"Crude", unadapted Monte Carlo sampling.

Dvegas(const int cDim, const int cBin, const int f, Integrand *const i,
       const Sampling sampling = IMPORTANCE);
Classic VEGAS case: the sampling is adapted for a number of continuous dimensions that are assumed to be independent.

Dvegas(const int cDim, const int cBin, const vector<int>& dDimSizes, const int f,
       Integrand *const i, const Sampling sampling = IMPORTANCE);
Full adaptation for sums of integrals.

Dvegas(const int cDim, const int cBin, const int corrDim,
       const vector<int>& dDimSizes, const int aDim, const int f, Integrand *const i,
       const Sampling sampling = IMPORTANCE);
Exclude "auxilliary" dimensions from adaptation.

Dvegas(const int cDim, const int cBin, const vector<int>& corrDim,
       const vector<int>& dDimSizes, const int aDim, const int f, Integrand *const i,
       const Sampling sampling = IMPORTANCE);
Relax independence assumption for continuous dimensions and fully sample correlations for selected dimensions.

Dvegas();
Use default constructor to subsequently initialize with restoreStateFromStream() or a similar method.

2.3: 64-bit numeric types

The following type aliases are defined:

#if (defined LONG_IS_INT64) && (!defined LONG_LONG_IS_INT64)
typedef long int Int64;
#elif (defined LONG_LONG_IS_INT64) && (!defined LONG_IS_INT64)
typedef long long int Int64;
#endif
typedef double Float64;

The type alias Int64 corresponds to 64-bit integers, which allow for a maximum of 2^63 - 1 = 9,223,372,036,854,755,807 sampled points. Note that 32-bit integers only allow up to about 2 billion sampled points (2^31 - 1 = 2,147,483,647 to be precise), which in some cases may not suffice to achieve the desired precision. On 32-bit processor hardware including most Intel and AMD processors (i386 architecture), the macro LONG_LONG_IS_INT64 should be defined. On 64-bit processor hardware, on the other hand, like DEC's Alpha, Intel's Itanium or AMD's Sledgehammer processor, the macro LONG_IS_INT64 should be defined (see Makefile).

The type alias Float64 corresponds to 64-bit floating point numbers and is used internally for variables that accumulate a large number of temporary results (of O(numberOfShots)). 32-bit floating point numbers provide only a precision of typically 7 decimal digits, which can be insufficient when adding about 100 million numbers or more. For 64-bit floating point numbers with a precision of typically 15 decimal digits this problem occurs roughly at 10^16 additions. On most platforms the type double corresponds to 64-bit floating point numbers. In rare cases Float64 might correspond to long double. In this case the typedef should be adjusted accordingly. (Note that this issue is also relevant for histogram packages.)

2.4: Dvegas methods

CellAccumulators collectData(const Int64 numberOfShots);
void adapt(CellAccumulators& cellAcc);
Method collectData() samples numberOfShots points in the integration volume, i.e. advances the Monte Carlo integration by one iteration and returns data accumulated for each cell in an object of type CellAccumulators. This object is subsequently passed to method adapt(), which adapts all weights, and thus improves the sampling in the next iteration.

void info() const;
At any time method info() can be used to print out information regarding the currently best estimate for the integral(s).

const double getCurvature() const;
void setCurvature(const double curvature);
const double getRootAmpl() const;
void setRootAmpl(const double rootAmpl);
The parameters curvature and rootAmpl ("root amplification") control the promotion of smaller weights, which damps the adaptation in order to avoid oscillations. See implementation of helper function promoteSmallerWeights() in dvegas.cpp for details.

void disableOptimize(const int setOfCorrelatedWeights);
If correlations are sampled, an optimization is performed before the sampling occurs. In rare cases the optimization step requires more time than is subsequently saved. In such cases the optimization can be turned off with the disableOptimize() method.

void reset();
void resetWeights();
void resetEstimates();
reset() discards all state-related internal data, reverting the object back to the state immediately after construction.

void saveStateToFile(const string& filename = "dvegas.state") const;
void restoreStateFromFile(Integrand *const i, const string& filename = "dvegas.state");
void restoreWeightsFromFile(Integrand *const i, const string& filename = "dvegas.state");
void saveStateToStream(ostream& os) const;
void restoreStateFromStream(Integrand *const i, istream& is);
void restoreWeightsFromStream(Integrand *const i, istream& is);
const string saveStateToString() const;
void restoreStateFromString(Integrand *const i, const string& s);
void restoreWeightsFromString(Integrand *const i, const string& s);
Methods are provided to save Dvegas objects to a stream, file or string and subsequently restore the saved state
(or the most recent weights without the integral estimates of previous iterations).

void activateCorrelationsDetector();
By calling activateCorrelationsDetector() a separate module is activated that, during the following iteration, probes (for the first integrand) to what degree combinations of two dimensions are independent (as assumed by the VEGAS algorithm). If strong correlations are detected, they can then be fully sampled by setting corrDim accordingly. Circular correlations should be properly combined, e.g. the correlations {0, 1} and {1, 2} translate to the set {0, 1, 2}.

void attachOmniComp(OmniComp *const omniComp);
void detachOmniComp();
Before distributed integrand evaluation can be used to accelerate computations, an OmniComp object needs to be attached to the Dvegas object with attachOmniComp (see section 3 for more on OmniComp).

const bool isAdaptingContinuousDimensions() const;
const double chiSquarePerIteration() const;
These getter methods are used in VEGAS() for diagnostic warnings (see section 2.5).

2.5: VEGAS function

namespace HepSource
{
void VEGAS(Dvegas& dvegas, const Int64 numberOfShots, const int numberOfIterations,
           const int init = 0);
}
This function mimics the interface of the original VEGAS program. The parameter init has the following meaning:

init = 0
fresh start--discard all weight and estimate information

init = 1
use current weights, but discard prior estimates

init = 2
use current weights and take into account estimates of previous iterations

2.6: Examples

A comprehensive set of examples can be found in the file dvegas_demo.cpp.