Below we list two codes, one for the brute force integration and the other employing importance sampling with a gaussian distribution.
#include <iostream>
#include <fstream>
#include <iomanip>
#include "lib.h"
using namespace std;
double brute_force_MC(double *);
// Main function begins here
int main()
{
int n;
double x[6], y, fx;
double int_mc = 0.; double variance = 0.;
double sum_sigma= 0. ; long idum=-1 ;
double length = 5.; // we fix the max size of the box to L=5
double jacobidet = pow((2*length),6);
cout << "Read in the number of Monte-Carlo samples" << endl;
cin >> n;
// evaluate the integral with importance sampling
for ( int i = 1; i <= n; i++){
// x[] contains the random numbers for all dimensions
for (int j = 0; j< 6; j++) {
x[j]=-length+2*length*ran0(&idum);
}
fx=brute_force_MC(x);
int_mc += fx;
sum_sigma += fx*fx;
}
int_mc = int_mc/((double) n );
sum_sigma = sum_sigma/((double) n );
variance=sum_sigma-int_mc*int_mc;
// final output
cout << setiosflags(ios::showpoint | ios::uppercase);
cout << " Monte carlo result= " << setw(10) << setprecision(8) << jacobidet*int_mc;
cout << " Sigma= " << setw(10) << setprecision(8) << volume*sqrt(variance/((double) n )) << endl;
return 0;
} // end of main program
// this function defines the integrand to integrate
double brute_force_MC(double *x)
{
// evaluate the different terms of the exponential
double xx=x[0]*x[0]+x[1]*x[1]+x[2]*x[2];
double yy=x[3]*x[3]+x[4]*x[4]+x[5]*x[5];
double xy=pow((x[0]-x[3]),2)+pow((x[1]-x[4]),2)+pow((x[2]-x[5]),2);
return exp(-xx-yy)*xy;
} // end function for the integrand