/* L-6 MCS 572 Mon 23 Jan 2012 : sprng_estpi_mpi.c
 * The program uses SPRNG and MPI in a simple 
 * Monte Carlo simulation to estimate Pi. */

#include <stdio.h>
#include <math.h>
#define SIMPLE_SPRNG
#include "sprng.h"
#define PI 3.14159265358979
#include <mpi.h>

double estimate_pi ( int i, int n );
/* Estimation of pi by process i,
 * using n samples. */

int main ( int argc, char *argv[] )
{
   int id,np;

   MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD,&np);
   MPI_Comm_rank(MPI_COMM_WORLD,&id);

   int n;

   if(id == 0)
   {
      printf("Reading the number of samples...\n");
      scanf("%d",&n);
   }
   MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
   double est4pi = estimate_pi(id,n);
   double sum = 0.0;
   MPI_Reduce(&est4pi,&sum,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);

   if(id == 0)
   {
      est4pi = sum/np;
      printf("Estimate for Pi : %.15lf",est4pi);
      printf("  error : %.3e\n",fabs(est4pi-PI));
   }
   MPI_Finalize();

   return 0;
}

double estimate_pi ( int i, int n )
{
   int seed = make_sprng_seed();  
   init_sprng(0,seed,SPRNG_DEFAULT); 

   int j,cnt=0;
   for(j=0; j<n; j++)
   {
      double x = sprng();
      double y = sprng();
      double z = x*x + y*y;
      if(z <= 1.0) cnt++;
   }
   double estimate = (4.0*cnt)/n;
   printf("Node %d estimate for Pi : %.15f",i,estimate);
   printf("  error : %.3e\n",fabs(estimate-PI));

   return estimate;
}

