/*----------------------------------------------------------------*/
 Brought To You By CToHTML 
http://www.cs.washington.edu/homes/zahorjan/homepage/Tools/index.htm
 
/*----------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <sprng.h>
#include <mpi.h>
#define USE_MPI   
#define SEED 35791246
main(int argc, char *argv[])
{
    int niter=0,count=0,i,mycount,mpi_error;
    double x,y,z,pi;
    int streamnum, nstreams, seed, *stream, myid, numprocs,proc;
    int gtype=1;  /*--- type of psudo random number generator. using lcg  */
    MPI_Status status;
    int master =0;
    int tag = 123;
    int *stream_id;             /* stream id generated by SPRNGS */

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    streamnum = myid;
    nstreams = numprocs;      /* one stream per processor                */
    seed = make_sprng_seed(); /* make new seed each time program is run  */
    if (myid==0) {
        printf("How may iterations?\n");
        scanf("%d",&niter); /* 1st argument is the number of iterations*/       
    }
    MPI_Bcast(&niter,1,MPI_INT,0,MPI_COMM_WORLD );
    /* initialize random numbers */
    stream_id = init_sprng(gtype,streamnum,nstreams,seed,SPRNG_DEFAULT); /*initialize stream  "1" is the generator type*/
    mycount=0;
    for ( i=0; i<niter; i++) {
        x = (double)sprng(stream_id);
        y = (double)sprng(stream_id);
        z = x*x+y*y;
        if (z<=1) mycount++;
    }
    if (myid ==0) { /* if I am the master process gather results from others */
        count = mycount;
        for (proc=1; proc<numprocs; proc++) {
            MPI_Recv(&mycount,1,MPI_REAL,proc,tag,MPI_COMM_WORLD,&status);
     printf("Processor %d sending results= %d to master process  \n",proc,mycount);
            count +=mycount;        
        }
        pi=(double)count/(niter*numprocs)*4;
        printf("\n # of trials= %d , estimate of pi is %.16f \n",niter*numprocs,pi);
    } else { /* for all the slave processes send results to the master */
       
        MPI_Send(&mycount,1,MPI_REAL,master,tag,MPI_COMM_WORLD);
    }

    mpi_error=MPI_Finalize();
    if (MPI_SUCCESS!=mpi_error)
        return mpi_error;
    else
        return 0;
}