/***************************************************************************/
/* AUTHOR : Hasan Timucin OZDEMIR                                          */
/* DATE   : October, 1995                                                  */
/* PROGRAM : ASSIGN11.M                                                    */
/* ALGORITHM :                                                             */
/*             1. Get number of processor array dimension                  */
/*             2. Get number of iteration per processor n                  */
/*             3. set value of each processor to 0(zero)                   */
/*             4. each processor finds the value of function where         */ 
/*                x is set to the value calculated according to its        */ 
/*                coordinate in the processor array.                       */
/*             5. each processor updates its value by using new calculated */
/*                value.                                                   */ 
/*             6. Mesh Collapse algorithm to sum the results coming from   */
/*                each processor.                                          */
/***************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<reduce.h>
#include<mpl.h>
#include<ctype.h>
#include<math.h>

#define DimenX   10
#define DimenY   10
#define MAX_DIMEN (DimenX*DimenY)
#define square(x) ((x)*(x))
#define func(n,x) (((n)*4.0)/(square(n)+square(x+0.5)))

double when() /* time function */
{ struct timeval tp;
  struct timezone tzp;
  gettimeofday(&tp, &tzp);
  return( (double) tp.tv_sec + (double) tp.tv_usec * 1e-6 ) ;
}/* end of when() */

double Find_Total(int processor_num_x, int processor_num_y, double n, 
                  double base,long iteration_num)
{ plural double value;
  plural double x;
  plural long i;
  double dimen2; 
  int k,l;

  dimen2 = (double) processor_num_x * processor_num_y ;
  value = (double) 0;
  printf("\n X=%d, Y=%d, Base=%f, Itera=%d, n=%f",processor_num_x, processor_num_y,base,iteration_num,n);

  if((ixproc<processor_num_x) && (iyproc<processor_num_y))
  {  for(i=0;i<iteration_num;i++)
     { x = dimen2 * i + (double) processor_num_x * iyproc + base + ixproc ; 
       value = value + func(n,x);
     }/* end of for() */
  }/* end of if */

  /* Mesh Collapse  */
  for(l=1;l<processor_num_x;l++)
    if((iyproc<processor_num_y) && (ixproc==l)) 
								value = value + xnetW[1].value;

  for(l=1;l<processor_num_y;l++)
    if((ixproc==processor_num_x-1) && (iyproc==l)) 
								value = value + xnetN[1].value;

  return(proc[processor_num_y-1][processor_num_x-1].value);
}/* end of Find_Total() */

void main(void)
{  double TotalValue;
   int i,l,dimen;
   long iteration_num;
   long k;
   double n;
   double original_n;
   double start,finish;
   double dimen2;
   double base;
   char intvariable[20];
 
   Ask = FALSE;
   continue = TRUE;
   
   /* Read Number of Iterations */
   printf("\n Enter number of iteration =");
   scanf("%s",&intvariable);
   iteration_num = atol(intvariable);

   start = when();

   n = (double) iteration_num; /* find the number of total iteration */
   original_n = n;
   base = 1.0; 
   TotalValue = (double) 0.0;

   if(n>MAX_DIMEN) 
   { k = (long) ( n / MAX_DIMEN )  ; /* k times do calculation */
     TotalValue = TotalValue + Find_Total(DimenX,DimenY,original_n,base,k);
     n = n - k * MAX_DIMEN;
     base = k * MAX_DIMEN + base;
   }/* end of if */

   while(n>3)
   { k = (long) sqrt(n);
     TotalValue = TotalValue + Find_Total(k,k,original_n,base,(long)1);
     n = n - (long) k * k ;
     base = k * k + base;
   }/* end of while */

   if(n)
   { for(i=0;i<n;i++) 
       { TotalValue = TotalValue + func(original_n,base); base++; }
   }/* end of if */

   finish = when();

   printf("\n After %ld iteration, the approximated value is %f ",iteration_num,TotalValue);
   printf("\n Total Elapsed time is %f seconds. \n",finish-start);

}/* end of main */

