/*  Class CPUPower .. Test performances CPU en Java     */
/*  Compilation: javac cpupower.java                    */
/*  Execution: java CPUPower Ope Size                   */ 
/*  R. Ansari - LAL/UPS - Mai 2004                      */

import java.lang.*;

class CPUPower {
 
  public static void main(String[] args) throws java.io.IOException {
    if (args.length < 1) { 
	System.out.println("Java CPUPower.main() Usage: java CPUPower Ope=1/2/3/4/5 [Size=20000]");
      return;
    }
    Integer aOp = new Integer(args[0]);
    Integer N;
    if (args.length > 1) N  = new Integer(args[1]);
    else N = new Integer("20000");
    int sz = N.intValue();
    if (sz < 10) sz = 20000;
    int ope = aOp.intValue();
    System.out.println("Java CPUPower: OPE= " + ope + " SZ= " + sz);    
    CPUPower cpup = new CPUPower(sz);
    cpup.Compute(ope);    
  }

  double x[];
  double y[];
  double z[];
  int SZ;
  int OPE;
  long N_OP;
  long tml,tm,dtm;
 
  CPUPower(int sz) {   
    tml = System.currentTimeMillis();
    SZ = sz;
    x = new double[SZ];
    y = new double[SZ];
    z = new double[SZ];
    int k;
    for(k=0; k<SZ; k++) {
      double xx = (k%340);
      x[k] = Math.PI*Math.exp(-xx/160.);
      y[k] = Math.sin(x[k]);
      z[k] = 0.;
    }
    N_OP = 0;
    tm = System.currentTimeMillis();
    dtm = tm-tml;
    tml = tm;
    System.out.println("CPUPower.CPUPower  Time= " + dtm + "  ms ..."); 

  }

  public void Compute(int ope) { 
    OPE = ope;
    System.out.println("CPUPower.Compute() OPE= " + OPE );
    tml = System.currentTimeMillis();
    if (OPE == 5)  fop5();
    else if (OPE == 4)  fop4();
    else if (OPE == 3)  fop3();
    else if (OPE == 2)  fop2();
    else fop1();
    tm = System.currentTimeMillis();
    dtm = tm-tml;
    tml = tm;
    double mflops = N_OP;
    mflops = mflops/dtm*1.e-3;
    System.out.println("CPUPower.Compute() N_OP= " + N_OP + " Time= " + dtm + "  ms ");
    System.out.println("CPUPower.Compute()  Time= " + dtm + "  ms  -> MFLOPS= " + mflops); 
  }

  public void fop1() {
    System.out.println("CPUPower.fop1(): Double Loop: z[k] = Somme_i(x[k]*y[i]) --");
    int i,j,k;
    double s = 0.;
    for(k=0; k<SZ; k++) {
      for(i=0; i<SZ; i++)  s += x[k]*y[i];
      z[k] = s;
      N_OP += 2*SZ;
    }    
    return;
  }
 
  public void fop2() {
    System.out.println("CPUPower.fop2() Double Loop: z[k] = Somme_i(x[k]*y[i]+x[i]*y[k] --");
    double s = 0.;
    int i,j,k;
    for(k=0; k<SZ; k++) {
      for(i=0; i<SZ; i++)  s += x[k]*y[i]+x[i]*y[k];
      z[k] = s;
      N_OP += 4*SZ;
    }

  return;
  }

  public void fop3() {
    System.out.println("CPUPower.fop3() Double Loop: z[k] = Somme_i(x[k]*y[i]+x[i]*y[k]-0.85*(y[k]+x[k])) --");
    double s = 0.;
    int i,j,k;
    for(k=0; k<SZ; k++) {
      for(i=0; i<SZ; i++)  s += x[k]*y[i]+x[i]*y[k]-0.85*(y[k]+x[k]);
      z[k] = s;
      N_OP += 7*SZ;
    }
  return;
  }
  public void fop4() {
    System.out.println("CPUPower.fop4() Double Loop: z[k] = Somme_i(x[k]*sin(y[i])+y[k]*cos(x[i])) --");
    double s = 0.;
    int i,j,k;
    for(k=0; k<SZ; k++) {
      for(i=0; i<SZ; i++)  s += x[k]*Math.sin(y[i])+y[k]*Math.cos(x[i]);
      z[k] = s;
      N_OP += 70*SZ;  // le facteur 70 est approximatif
    }
  }
  public void fop5() {
    System.out.println("CPUPower.fop5() Double Loop: z[k] = Somme_i(x[k]*sin(y[i])+log(abs(x[i])+0.1)+y[k]) --");
    double s = 0.;
    int i,j,k;
    for(k=0; k<SZ; k++) {
      for(i=0; i<SZ; i++)  s += x[k]*Math.sin(y[i])+Math.log(Math.abs(x[i])+0.1)+y[k];
      z[k] = s;
      N_OP += 100*SZ;  // le facteur 100 est approximatif
    }
  }

}






