typedef void (*C_Integrand)(double x[], int k[], double* wgt, double aux[], double f[]); void fxn(double x[], int k[], double* wgt, double aux[], double f[]);
The array x[]
contains the random numbers for the continuous dimensions,
the array k[]
contains the random numbers for the discrete dimensions,
the array aux[]
contains the auxilliary random numbers. The VEGAS weight (For
each iteration the sum of the weights is normalized to 1.)
is passed in variable wgt
, so that it can be passed on to functions that
fill histograms, for example. The function *fxn
is expected to fill the
array f[]
with the function values that correspond to the arguments
x[0]
, x[1]
, ..., k[0]
, k[1]
, ... and aux[0]
, aux[1]
, ...
The value of the first function is assigned to f[0]
. The integration is optimized
for this function according to the VEGAS algorithm. Secondary functions can simultaneously be
integrated and their values are expected to be returned as f[1]
, f[2]
, etc.
First this function has to be called:
void dvegas_init_(int* cdim, int* nsdim, int* cnbin, int* ddim, int* adim, int nvals[], int* fn, C_Integrand fxn);which sets the following (internal) variables:
cdim: number of continuous dimensions
nsdim: number of non-separable continuous dimensions (first nsdim dimensions)
cnbin: number of bins for each continuous dimension
ddim: number of discrete dimensions
adim: number of auxilliary dimensions (no adaptation)
nvals[]: number of values for each discrete dimension (see below)
fn: number of functions to integrate
fxn: pointer to integrand function
The default integration/summation range is
Random numbers in (0, 1) are provided to facilitate the addition of auxilliary dimensions that are not VEGAS driven.
The parameters ddim
or adim
can be set to zero if no discrete
or auxilliary dimensions are needed.
Optional initialization calls:
void dvegas_init_parallel_(int* ncpu);specify number of CPUs for multiprocessor machines (see section 5.1)
void dvegas_init_output_();save status (init. parameters and weights) to file dvegas.dat-new after next
dvegas_
call
void dvegas_init_files_(char* outfile_, char* infile_, int outfile_len, int infile_len);restore previously saved status from file inputfile and save new status to file outputfile
outfile_len
and infile_len
are not really necessary in C,
because C strings are NULL terminated. Fortran strings are unfortunately not terminated.
Thus, in a C program it is sufficient that the values passed for outfile_len
and infile_len
are equal or larger than the actual string sizes. The exact values are irrelevant.
After dVegas has been initialized you can make multiple calls to dvegas_
:
void dvegas_(longint* ncall, int* iterats, int* init, double integral[], double error[], double redchi2[]);ncall: type longint, request
ncall
shots per iteration iterats
iterations, init
is explained below The parameter init
has the same meaning as in the original VEGAS program:
init = 0: fresh start (no prior information)
init = 1: use previous adaptation info, but discard shot data
init = 2: use previous adaptation info and build on previous shots data
#include <math.h> #include <stdio.h> #include "c_dvegas.h" void fxn2(double x[], int k[], double* wgt, double aux[], double f[]); int main() { int cdim = 5 ; int nsdim = 0 ; int cnbin = 50 ; int ddim = 1 ; int adim = 0 ; int nvals[1] = { 100 }; int fn = 1 ; longint ncalls = 100000 ; int iterats ; int init ; double integral[1]; double error[1]; double redchi2[1]; char inputfile[21] = "run2.in" ; char outputfile[21] = "run2.out" ; dvegas_init_(&cdim, &nsdim, &cnbin, &ddim, &adim, nvals, &fn, fxn2); /* 2 iterations with init = 0, no initial adaptation */ iterats = 2 ; init = 0 ; dvegas_(&ncalls, &iterats, &init, integral, error, redchi2); /* result is 199.0 */ printf("Result:\n"); printf("integral = %f\n", integral[0]); printf("error = %f\n", error[0]); printf("chi2/itn = %f\n\n", redchi2[0]); fflush(NULL); /* now 1 iteration with init = 1, use previous adaptation */ iterats = 1 ; init = 1 ; /* save grid */ dvegas_init_output_(); dvegas_(&ncalls, &iterats, &init, integral, error, redchi2); /* now another run after restoring adaptation from file */ dvegas_init_files_(outputfile, inputfile, 20, 20); dvegas_(&ncalls, &iterats, &init, integral, error, redchi2); } void fxn2(double x[], int k[], double* wgt, double aux[], double f[]) { if (k[0] < 99) f[0] = 1.0 * x[0]*x[1]*x[2]*x[3]*x[4]*pow(2.0,5.0); else if (k[0] == 99) f[0] = 100.0 * x[0]*x[1]*x[2]*x[3]*x[4]*pow(2.0,5.0); }