#include <math.h>
#include <stdlib.h>
#include <mpi.h>

#define f(x) (4.0 /(1.0 + (x)*(x)))
#define PI 3.141592653589793238462643

int main (int argc, char *argv[])
{
   int nproc;
   int iproc;
   int nameLength;
   int intervals;
   double interval_length;
   double pi;
   double local_area = 0.0;
   
   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &nproc);
   MPI_Comm_rank(MPI_COMM_WORLD, &iproc);
   
   if (argc != 2)
      perror("Usage: pi <number of intervals>");
      
   intervals = atoi(argv[1]);
   
   if (intervals % nproc)
      perror("Fatal runtime error: intervals not divisible by nproc\n");
   
   interval_length = 1.0 / ((double) intervals);
   {
      int i;
      int intervals_local;
      double current_x;
      
      intervals_local = intervals /nproc;
      current_x = (((double) (iproc * intervals_local))
         + 0.5 ) * interval_length;
      for (i=0; i < intervals_local; i++)
      {
         local_area += interval_length * f(current_x);
         current_x += interval_length;
      }
   }
   
   MPI_Reduce(&local_area, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
      MPI_COMM_WORLD);
      
   if (iproc ==0)
      printf("Computed pi is %.16f, error is %.16f\n",
         pi, fabs(pi-PI));

   
   MPI_Finalize();
   
   return 0;
}
