#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
#define NB_VALEURS 4
typedef struct {
          double reel,
          double imag;
        } Complex;
        
void mon_produit(Complex *valeur,Complex *resultat,int *longueur, MPI_Datatype *type);

int main(int argc, char *argv[])
{
int i, rang, commute=0;
Complex valeur[NB_VALEURS]; 
Complex resultat[NB_VALEURS];
MPI_Op mon_operation;
MPI_Datatype type_complexe;

MPI_Init (&argc,&argv);
MPI_Comm_rank ( MPI_COMM_WORLD , &rang);

MPI_Type_contiguous (2, MPI_DOUBLE , &type_complexe);
MPI_Type_commit (&type_complexe);

MPI_Op_create (mon_produit, commute, &mon_operation);

for (i=0; i<NB_VALEURS; i++) {
  valeur[i].reel = (double)(rang+i+1); 
  valeur[i].imag = (double)(rang+i+2);
}

MPI_Reduce(valeur,resultat,NB_VALEURS,type_complexe,mon_operation,0, MPI_COMM_WORLD );
if (rang == 0) {
   printf("Valeur du produit : ");
   for (i=0; i<NB_VALEURS; i++)
       printf("(%.0f,%.0f), ",resultat[i].reel,resultat[i].imag);
}
MPI_Op_free (&mon_operation); 
MPI_Finalize (); 
return(0);
}


/* Definition du produit terme a terme de deux vecteurs de nombres complexes */
void mon_produit(Complex *valeur, Complex *resultat,
                   int *longueur, MPI_Datatype *type);
{
 int i;
 Complex c;

 for (i=0; i< *longueur; ++i) {
 c.reel = resultat->reel*valeur->reel - resultat->imag*valeur->imag;
 c.imag = resultat->reel*valeur->imag + resultat->imag*valeur->reel;
 *resultat = c;
 valeur++;
 resultat++;
 }
}