hep-mc  0.8
Classes | Typedefs | Enumerations | Functions
Integrand Functions

Detailed Description

How integrand functions are written.

Functions that can be integrated by the Monte Carlo algorithms must accept a single parameter of the type mc_point and return a value of type T. For example, an integrand of the form \( f(x) := x^2 \) implemented with double precision numbers would look like:

double square(hep::mc_point<double> const& x)
{
return x.point[0] * x.point[0];
}

Some integration algorithms, e.g. vegas, supply additional information that can be accessed by capturing the argument with a different type, e.g. for VEGAS by vegas_point :

double square(hep::vegas_point<double> const& x)
{
return x.point[0] * x.point[0];
}

If additional variables in the integrand are necessary, they can be supplied by global variables or using functors:

class power
{
public:
power(double exponent)
: exponent(exponent)
{
}
double operator()(hep::mc_point<double> const& x)
{
return std::pow(x.point[0], exponent);
}
private:
double exponent;
};

Starting with version 0.5 it is possible to generate differential distributions, which can be generated if a second argument is accepted, e.g.

double square_with_distribution(
) {
double const x = x.point[0];
double const f = x * x;
// add the the tuple `(x, f)` to the zeroeth distribution
projector.add(0, x, f);
return f;
}

Specifying the integrand is not enough for the Monte Carlo integration routines. They also must know the dimensionsionaly of the integrand, or how many random numbers are needed; furthermore, the numeric type with which the operations should be performed must be specified. If distributions should be accumulated during the integration the binning (how many bins, upper and lower boundaries) must be specified as well. Since this is generic for all algorithms the complete integrand information is specified by creating an integrand, which, for the examples above, would be written as follows:

// the integer specifies the dimension of the integrand `square`, `double`
// specifies the numeric type the integration algorithm should use
auto square_integrand = hep::make_integrand<double>(square, 1);
// captures `exponent = 2.0` with an instance of `power` with integrand
// `power::operator()`
auto power_integrand = hep::make_integrand<double>(power(2.0), 1);
// the third argument specifies the distribution parameters: the x-axis ranges
// from -10 to 10 and is subdivided into 100 bins
auto square_distributions = hep::make_integrand<double>(square, 1,
hep::make_dist_params(-10.0, +10.0, 200));

An integrand for a multi channel integrator requires even more information because the user must provide PDFs and CDFs. Both must be calculated in a single function that has the following signature:

T map(
std::size_t channel,
std::vector<T> const& random_numbers,
std::vector<T>& coordinates,
std::vector<std::size_t>& enabled_channels,
std::vector<T>& densities,
);

A multi_channel_integrand is now created as follows:

auto mc_integrand = hep::make_multi_channel_integrand<double>(
function, // the integrand function that we wish to integrate
10, // the integration is ten dimensional
map, // the map function providing PDFs and CDFs
20, // `map` maps the ten random numbers to twenty in `coordinates`
200 // `map` uses two hundred channels
);

Classes

class  hep::integrand< T, F, distributions >
 
class  hep::mc_point< T >
 
class  hep::multi_channel_integrand< T, F, M, distributions >
 
class  hep::multi_channel_point< T >
 
class  hep::multi_channel_point2< T, M >
 
class  hep::vegas_point< T >
 

Typedefs

template<typename T , typename F , bool distributions>
using hep::integrand_type = integrand< T, typename std::decay< F >::type, distributions >
 
template<typename I >
using hep::numeric_type_of = typename std::remove_reference< I >::type::numeric_type
 
template<typename T , typename F , typename M , bool distributions>
using hep::multi_channel_integrand_type = multi_channel_integrand< T, typename std::decay< F >::type, typename std::decay< M >::type, distributions >
 

Enumerations

enum  hep::multi_channel_map { hep::multi_channel_map::calculate_coordinates, hep::multi_channel_map::calculate_densities }
 

Functions

template<typename T , typename F >
integrand_type< T, F, false > hep::make_integrand (F &&function, std::size_t dimensions)
 
template<typename T , typename F , typename... D>
integrand_type< T, F, true > hep::make_integrand (F &&function, std::size_t dimensions, D &&... parameters)
 
template<typename T , typename F , typename M >
multi_channel_integrand_type< T, F, M, false > hep::make_multi_channel_integrand (F &&function, std::size_t dimensions, M &&map, std::size_t map_dimensions, std::size_t channels)
 
template<typename T , typename F , typename M , typename... Ds>
multi_channel_integrand_type< T, F, M, true > hep::make_multi_channel_integrand (F &&function, std::size_t dimensions, M &&map, std::size_t map_dimensions, std::size_t channels, Ds &&... parameters)
 

Typedef Documentation

◆ integrand_type

template<typename T , typename F , bool distributions>
using hep::integrand_type = typedef integrand<T, typename std::decay<F>::type, distributions>

Template alias for an integrand with its type F decayed with std::decay.

◆ multi_channel_integrand_type

template<typename T , typename F , typename M , bool distributions>
using hep::multi_channel_integrand_type = typedef multi_channel_integrand<T, typename std::decay<F>::type, typename std::decay<M>::type, distributions>

Template alias for a multi_channel_integrand with its types F and M decayed with std::decay.

◆ numeric_type_of

template<typename I >
using hep::numeric_type_of = typedef typename std::remove_reference<I>::type::numeric_type

Shortcut for accessing the numeric type of an integrand that is possibly a reference.

Enumeration Type Documentation

◆ multi_channel_map

Enumeration that specifies which parameters of the user specified map should be calculated.

Enumerator
calculate_coordinates 

Signals the map-function that the parameter coordinates should be calculated. The parameter densities can be calculated at time point.

calculate_densities 

Signals that the map function is called with the previously calculated coordinates and that the paramter densities now must be calculated. If the integrand does not contribute, i.e. if the user-defined function returned zero, then this step will be skipped because the densities are not needed.

Function Documentation

◆ make_integrand() [1/2]

template<typename T , typename F >
integrand_type<T, F, false> hep::make_integrand ( F &&  function,
std::size_t  dimensions 
)
inline

PLAIN/VEGAS integrand constructor. This function constructs an integrand using the given function that must accept points from the \( d \)-dimensional hypercube, where \( d \) is given by the parameter dimensions. The type of the point is determined by the integration algorithm later used on the integrand, e.g. for vegas it is vegas_point. For this case the integrand would look like:

T function(hep::vegas_point<T> const& x)
{
// x.point.size() is as large as specified with `dimensions`
return /* calculate the function value from x.point */;
}

◆ make_integrand() [2/2]

template<typename T , typename F , typename... D>
integrand_type<T, F, true> hep::make_integrand ( F &&  function,
std::size_t  dimensions,
D &&...  parameters 
)
inline

PLAIN/VEGAS distributions constructor. This function constructs an integrand using the given function that must accept points from the \( d \)-dimensional hypercube and a reference to a projector that generates the distributions. The dimension \( d \) is given by the parameter dimension, and parameters define the number and parameters of the distribution(s). For the VEGAS algorithm the function would look like:

T function(hep::vegas_point<T> const& x, hep::projector<T>& projector)
{
T const x0 = /* calculate the position of `x` for the distribution 0 */;
T const f = /* calculate the function value from x.point */;
// add the function value `f` to the zeroeth distribution at `x0`
projector.add(0, x0, f);
// return the value of the function for the integrator
return f;
}

◆ make_multi_channel_integrand() [1/2]

template<typename T , typename F , typename M >
multi_channel_integrand_type<T, F, M, false> hep::make_multi_channel_integrand ( F &&  function,
std::size_t  dimensions,
M &&  map,
std::size_t  map_dimensions,
std::size_t  channels 
)
inline

Multi channel integrand constructor. For a description of the parameters see make_integrand. In addition, Multi Channel integrators need an additonal function map that computes the PDFs and the CDFs for a randomly selected channel. This function should look like:

T map(
std::size_t channel,
std::vector<T> const& random_numbers,
std::vector<T>& coordinates,
std::vector<T>& densities,
);

This function is called by the multi channel integrator, first with the parameter action set to multi_channel_map::calculate_coordinates, which signals that the vector coordinates must be filled using the CDFs. The return value is ignored for this function call. If the integrand returns a non-zero value map is called again with action set to multi_channel_map::calculate_densities, which means that the vector densities must be populated with all PDFs for the given channel and random_numbers. The return value is the jacobian for the given channel.

◆ make_multi_channel_integrand() [2/2]

template<typename T , typename F , typename M , typename... Ds>
multi_channel_integrand_type<T, F, M, true> hep::make_multi_channel_integrand ( F &&  function,
std::size_t  dimensions,
M &&  map,
std::size_t  map_dimensions,
std::size_t  channels,
Ds &&...  parameters 
)
inline

Multi channel integrand constructor for distributions.