Programmierpraktikum




Claudius Gros, SS2012

Institut für theoretische Physik
Goethe-University Frankfurt a.M.

Monte Carlo & Metropolis Sampling

statistical evaluation of integrals


Monte Carlo sampling


Metropolis algorithm

integration as averaging



$\hspace{10ex} \displaystyle I \ =\ \int_a^b \, f(x)\, dx \ =\ \sum_{i=1}^N f(x_i)\,\Delta x $ $\hspace{10ex} \displaystyle I \ =\ (a-b) \left(\frac{1}{N} \sum_i\, f(x_i) \right) \ =\ (a-b)\, \langle f\rangle $
$$ I\ =\ V\, \langle f\rangle$$

area integration



$\hspace{10ex} \displaystyle I\ = \ \int_{-a}^a f(x,y)\,dx\,dy $

with

$\hspace{10ex} \displaystyle f(x,y)\ =\ \left\{ \begin{array}{ccl} 1 && \mbox{inside}\\ 0 && \mbox{outside} \end{array} \right. $

/** Evaluating \pi with simple Monte Carlo evaluation.
  */
public class MonteCarlo {
  static final double x0 = 0.0, x1 = 1.0;    // x-bounds
  static final double y0 = 0.0, y1 = 1.0;    // y-bounds

public static void main(String[] args) {
  int N = 1000000;                           // number of draws
  int deltaN = N/10;                         // printout intervals
  double x, y, sum = 0;

// --- loop over all random evaluations 
  for (int i=0; i<N; i++)
    {
    x = Math.random();     // random draws
    y = Math.random();
    sum += MonteCarlo.myFunction(x,y);
    if ((i+1)%deltaN==0)
      System.out.printf("%8d %8.4f\n",i+1,4.0*sum/(i+1.0));
    }  // end of loop over all Monte Carlo draws
}  // end of MonteCarlo.main()

/** The function to be evaluated.
  * Here the circle.
  */
public static double myFunction(double x, double y) {
  if ( (x<MonteCarlo.x0)||(x>MonteCarlo.x1)||
       (y<MonteCarlo.y0)||(y>MonteCarlo.y1) )
    {
    System.out.println("x or y value out of range");
    return 0.0;
    }
  if (y*y<=1.0-x*x)     // x*x+y*y=1 is the circle equation
     return 1.0;
  else
     return 0.0;
  } // end of MonteCarlo.myFunction()

} // end of class MonteCarlo

basic statistics

statistics

Monte Carlo - convergence

data binning


law of large numbers

Monte Carlo with error estimation

/** Evaluating \pi with simple Monte Carlo evaluation,
  * calculating variance and standard deviation (error).
  * On input: number of measurements N.
  */
public class MonteCarloVariance {
  static final double x0 = 0.0, x1 = 1.0;          // x-bounds
  static final double y0 = 0.0, y1 = 1.0;          // y-bounds

public static void main(String[] args) {

// --- determine the number of draws from input
  int N = 0;                                 
  if (args.length==1)
    N = Integer.parseInt(args[0]);      
  else
    {
    System.out.println("Wrong number of input parameters");
    return;
    }

// --- other parameters and variables
  int K = 20;                                      // number of bins
  int nK = N/K;                                    // number of data per bin
  double[] data = new double[N];                   // storing all measurements
  double[] meanBin = new double[K];                // means of bins
  double mean = 0.0, sigma = 0.0;                  // result: mean and error
  double x, y;                                     // variables

// --- loop over all random evaluations 
  for (int i=0; i<N; i++)
    {
    x = Math.random();                             // random draws
    y = Math.random();
    data[i] = MonteCarloVariance.myFunction(x,y);  // storing measurement
    }  // end of loop over all Monte Carlo draws

// --- evaluate the overall mean and the mean of the bins
    for (int i=0; i<N; i++) 
      mean += data[i];
    mean = mean/N;

    for (int k=0; k<K; k++)
      {
      meanBin[k] = 0.0;       
      for (int n=0; n<nK; n++)                     // nK data points in each bin
        meanBin[k] += data[k*nK+n];
      meanBin[k] = meanBin[k]/nK;
      }  // end of loop over all bins

// --- evaluate the error: variance of means of bins
    for (int k=0; k<K; k++)
      sigma += (meanBin[k]-mean)*(meanBin[k]-mean);
    sigma = Math.sqrt(sigma/K);

// --- printout of result
    System.out.printf(" number of measurements : %d\n",N);
    System.out.printf(" number of bins         : %d\n",K);
    System.out.printf(" data points per bin    : %d\n",nK);
    System.out.printf(" estimate for pi        : %8.4f\n",4.0*mean);
    System.out.printf(" estimate for accuracy  : %8.4f\n",4.0*sigma);

}  // end of MonteCarloVariance.main()

/** The function to be evaluated.
  * Here the circle.
  */
public static double myFunction(double x, double y) {
  if ( (x<MonteCarloVariance.x0)||(x>MonteCarloVariance.x1)||
       (y<MonteCarloVariance.y0)||(y>MonteCarloVariance.y1) )
    {
    System.out.println("x or y value out of range");
    return 0.0;
    }
  if (y*y<=1.0-x*x)
     return 1.0;
  else
     return 0.0;
  } // end of MonteCarloVariance.myFunction()

} // end of class MonteCarloVariance

integrals over distribution functions


importance sampling

$\hspace{6ex}\displaystyle \rho(x) \ =\ \frac{1}{y_n}\frac{x^n}{x+a}, \quad\quad y_n\ =\ \int_0^1\, \frac{x^n}{x+a}\, dx $

random walk through configuration space

Metropolis algorithm


transition rules

detailed balance


detailed balance

evaluation of relative properties

/** Evaluating y_{n+1}/y_n, with y_n = \int_0^1 x^n/(a+x) dx
  * with Monte Carlo (Metropolis) algorithm.
  * On input: number of Monte Carlo steps N.
  */
public class Metropolis {
  static final double aPar = 10.0;                 // parameter 
  static final double nPow = 3.0;                  // power

public static void main(String[] args) {

// --- determine the number of draws from input
  int N = 0;                                 
  if (args.length==1)
    N = Integer.parseInt(args[0]);      
  else
    {
    System.out.println("Wrong number of input parameters");
    return;
    }

// --- other parameters and variables
  int K = 20;                                      // number of bins
  int nK = N/K;                                    // number of data per bin
  double[] data = new double[N];                   // storing all measurements
  double[] meanBin = new double[nK];               // means of bins
  double mean = 0.0, sigma = 0.0;                  // result: mean and error
  double x = Math.random();                        // random starting value
  double y, ratio;                                 // variables
  data[0] = x;                                     // first measurment

// --- loop over all Monte Carlo steps
  for (int i=1; i<N; i++)
    {
    y = Math.random();                             // random candiate
    ratio = Metropolis.myDensity(y)/Metropolis.myDensity(x);
    if (ratio>Math.random())
      x = y;                                       // accept candidate
    data[i] = x;                                   // storing measurement
    }  // end of loop over all Monte Carlo draws

// --- evaluate the overall mean and the mean of the bins
    for (int i=0; i<N; i++) 
      mean += data[i];
    mean = mean/N;

    for (int k=0; k<K; k++)
      {
      meanBin[k] = 0.0;       
      for (int n=0; n<nK; n++)                     // nK data points in each bin
        meanBin[k] += data[k*nK+n];
      meanBin[k] = meanBin[k]/nK;
      }  // end of loop over all bins

// --- evaluate the error: variance of means of bins
    for (int k=0; k<K; k++)
      sigma += (meanBin[k]-mean)*(meanBin[k]-mean);
    sigma = Math.sqrt(sigma/K);

// --- printout of result
    System.out.printf(" a  in  y^n/(x+a)       : %8.4f\n",aPar);
    System.out.printf(" n  in  y^n/(x+a)       : %8.4f\n",nPow);
    System.out.printf(" number of measurements : %d\n",N);
    System.out.printf(" number of bins         : %d\n",K);
    System.out.printf(" data points per bin    : %d\n",nK);
    System.out.printf(" y_{n+1}/y_n  estimate  : %8.4f\n",mean);
    System.out.printf(" estimate for accuracy  : %8.4f\n",sigma);
    System.out.printf("\n");
    System.out.printf(" ratio y_4/y_3 (exact)  : %8.4f\n",0.797490089);

}  // end of Metropolis.main()

/** The proability density.
  */
public static double myDensity(double x) {
 return Math.pow(x,nPow)/(x+aPar);
  } // end of Metropolis.myDensity()

} // end of class Metropolis