% File: cpi_parallel.m
% Purpose: Parallel computation of pi in Matlab with 
%          measurement of the time taken to complete the computation.

MPI_Init;

comm = MPI_COMM_WORLD;
numprocs = MPI_Comm_size(comm);
myid = MPI_Comm_rank(comm);

n = 4800000;
sum = 0.0;

% determine the start and end interval numbers (sp and ep) 
% for the pi computation 
average = fix(n / numprocs);
extra = mod(n, numprocs);
if (myid+1 <= extra)
  n2 = average + 1;
else
  n2 = average;
end
if (myid <= extra)
  sp = myid*(average+1) + 1;
else
  sp = myid*average + 1;
end
ep = sp + n2 - 1;

if (numprocs >= 2)
  synch_start(comm, 0, 5);  % synch_start() imitates MPI_Barrier()
end                         % it is included in MatlabMPI package

tic;  % start a timer for the pi computation
h = 1.0 / n;
for i = sp : ep
  x = h * (i-0.5);
  sum = sum + 4.0/(1.0+x*x);
end
mypi = h * sum;

if (myid ~= 0)
  MPI_Send(0, 101, comm, mypi);
else
  pi = mypi;
  for i = 1 : numprocs-1
    mypi = MPI_Recv(i, 101, comm);
    pi = pi + mypi;
  end
  toc;  % print the elapsed time since tic was used
  fprintf('pi: %.16f\n', pi);
end

MPI_Finalize;

exit;
