// Pi3.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.
//

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>

#include <math.h>

#include <windows.h>

#include <time.h>

#include <mpi.h>


///////////////////////////////////////////////////////////////////////////
// Konstanten
///////////////////////////////////////////////////////////////////////////

const long COUNT = 100000000; 


long Worker( int worker_id, int anz) {
	int i;			// Laufindex
	long double x, y;  // Interne Variablen der Berechnung
	long summe;  // Interne Variablen der Berechnung
	long double r;
	
		// Thread-ID von Windows
	

		// Zufallszahl initialisieren

	// Sleep( rand()/(unsigned)MPI_Wtime() ); // kurze Wartezeit
	// Diese Anweisung ist wichtig, da sonst alle synchron rechnen
    Sleep(worker_id*100);

	srand( (unsigned)worker_id*100 );  // init

	summe=0;  // Init der lokalen Summe


	for (i=0; i<anz; i++) {
		x= ((long double)rand())/RAND_MAX;  
		y= ((long double)rand())/RAND_MAX;  
		if (i==0) {
			printf("x/y:  %f  %f \n",x,y);
		}
			  // summieren, wenn innerhalb des Kreises
		r = x*x+ y*y;
		if (r<=1.0) {
		    summe +=1;
		}
	} // for
	
    printf("in worker %d   Summe %d \n",  worker_id, summe);
	return summe;
} // Workers


void main(int argc, char *argv[])
{
    int myPid;
    int numprocs;

    long double PI25DT = 3.141592653589793238462643;
    long double PI;
	long double pi;
	long double prozDiff;
    long double sum;
    long double G_sum;
    
	
    MPI_Init(&argc,&argv);

	   // Anzahl der Prozesse
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
   
	   // meine eigene ID
	MPI_Comm_rank(MPI_COMM_WORLD,&myPid);
    
	
	puts("Master und Client rechnen");
	sum = (double) Worker(myPid, COUNT);

    // MPI_Barrier(MPI_COMM_WORLD);


    MPI_Reduce(&sum, &G_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

	
    if (myPid == 0)
	{    
       printf("G_Summe %f \n", G_sum);
		  // nur Master gibt aus
		pi = 4.0*(G_sum / COUNT)/numprocs;

		PI = atan(1.0)*4;
	
		prozDiff = fabs(PI-pi)*100.0; 
		printf("\n\n       Ergebnis Summe : %f \n",G_sum);
		printf("\n\n                Pi    : %f \n",pi);
		printf("\n\n                Delta : %f %% \n",prozDiff);
	}
    MPI_Finalize();
}

