Introduzione
Si vuole scrivere un programma che tramite il metodo di Montecarlo calcoli il valore stimato di distribuendo il lavoro su più processi tramite MPI.
L’algoritmo utilizzato per il calcolo è semplice, si consideri un cerchio di raggio unitario, inscritto in un quadrato .

L’area del cerchio, è uguale a , l’area del quadrato è 4. Sia l’insieme di tutti i punti compresi nel cerchio, e sia l’insieme di tutti i punti compresi nel quadrato.
Risulta che il numero di punti nell’area del cerchio stanno all’area , come il numero di punti che stanno nell’area del quadrato stanno a 4.
In realtà, non ha senso considerare la cardinalità o di , in quanto sono insiemi infiniti, supponiamo allora che tali insiemi siano finiti e di cardinalità n, si denotano e , chiaramente . Si ha che:
L’algoritmo consiste nel :
- calcolare un numero
ndi punti casuali - determinare il numero
cdi punti interni al cerchio, (ossia i punti(x,y)tali da rispettare )
Numericamente, approssimerà , con una precisione sempre maggiore all’aumentare di n.
L’algoritmo si renderà parallelo, distribuendo equamente il numero di punti da calcolare a tutti i processi presenti.
Codice
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[]) {
int total_square_points = atoi(argv[1]); //più è alto maggiore è la precisione
int total_circle_points;
double x, y; //point coordinates
int local_square_points, local_circle_points;
int my_rank, comm_size;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
srand(time(NULL));
local_square_points = total_square_points / comm_size;
for (int i=0; i<local_square_points; i++) {
//point generation
x = 2 * (rand() / (double)RAND_MAX) - 1;
y = 2 * (rand() / (double)RAND_MAX) - 1;
if (x*x + y*y <= 1 ) { // controllo se il punto è nel cerchio
local_circle_points++;
}
}
MPI_Reduce(&local_circle_points, &total_circle_points, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (my_rank == 0) {
double pi_estimate = (double)total_circle_points / (double)total_square_points * 4;
printf("Estimate of pi = %f\n", pi_estimate);
}
MPI_Finalize();
return 0;
}