change doubles to floats in 2DFFT - ecoop submission
authoradash <adash>
Tue, 15 Dec 2009 20:22:10 +0000 (20:22 +0000)
committeradash <adash>
Tue, 15 Dec 2009 20:22:10 +0000 (20:22 +0000)
Robust/src/Benchmarks/Prefetch/2DFFT/dsm/Makefile
Robust/src/Benchmarks/Prefetch/2DFFT/dsm/Matrix.java
Robust/src/Benchmarks/Prefetch/2DFFT/dsm/fft1d.java
Robust/src/Benchmarks/Prefetch/2DFFT/dsm/fft2d.java
Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/MatrixN.java [new file with mode: 0644]
Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft1dN.java [new file with mode: 0644]
Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft2dN.java [new file with mode: 0644]
Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/makefile

index e2a0abffffb3755057ffd709415f5b5acd758d12..c861b00955ec50d1ca3b5229e857500ce84e0f03 100644 (file)
@@ -7,17 +7,27 @@ SRC1=${MAINCLASS}rect.java \
        fft1d.java \
        Matrix1.java \
        ../../../../ClassLibrary/JavaDSM/Barrier.java
-FLAGS =-dsm -dsmcaching -transstats -prefetch -optimize -excprefetch fft2d.main -excprefetch fft2d.twiddle -excprefetch fft1d.factorize -excprefetch fft1d.printFactors -excprefetch Matrix.setValues -excprefetch Matrix.setZeros -excprefetch fft2d.transpose -trueprob 0.95 -mainclass ${MAINCLASS}
-FLAGS1=-dsm -optimize -transstats -mainclass ${MAINCLASS}
+SRC2=${MAINCLASS}N.java \
+       fft1dN.java \
+       MatrixN.java \
+       ../../../../ClassLibrary/JavaDSM/Barrier.java
+
+FLAGS =-dsm -dsmcaching -transstats -builddir tmpbuilddirectory2 -prefetch -optimize -excprefetch fft2d.main -excprefetch fft2d.twiddle -excprefetch fft1d.factorize -excprefetch fft1d.printFactors -excprefetch Matrix.setValues -excprefetch Matrix.setZeros -excprefetch fft2d.transpose -trueprob 0.90 -mainclass ${MAINCLASS}
+FLAGS1=-dsm -optimize -transstats -builddir tmpbuilddirectory1 -mainclass ${MAINCLASS}
 FLAGS2=-dsm -optimize -transstats -dsmcaching -mainclass ${MAINCLASS}
 
+FLAGSP =-dsm -dsmcaching -builddir tmpbuilddirectory2 -prefetch -optimize -excprefetch fft2d.main -excprefetch fft2d.twiddle -excprefetch fft1d.factorize -excprefetch fft1d.printFactors -excprefetch Matrix.setValues -excprefetch Matrix.setZeros -excprefetch fft2d.transpose -trueprob 0.90 -mainclass ${MAINCLASS}
+FLAGSNPNC=-dsm -optimize -builddir tmpbuilddirectory1 -mainclass ${MAINCLASS}
+FLAGSNPC=-dsm -optimize -dsmcaching -mainclass ${MAINCLASS}
+
+
 default:
-#../../../../buildscript ${FLAGS1} ${SRC} -o ${MAINCLASS}NPNC
-#      ../../../../buildscript ${FLAGS2} ${SRC} -o ${MAINCLASS}NPC
-#      ../../../../buildscript ${FLAGS} ${SRC} -o ${MAINCLASS}N
-       ../../../../buildscript ${FLAGS1} ${SRC1} -o ${MAINCLASS}NPNC
-#      ../../../../buildscript ${FLAGS2} ${SRC} -o ${MAINCLASS}NPC
-       ../../../../buildscript ${FLAGS} ${SRC1} -o ${MAINCLASS}N
+       ../../../../buildscript ${FLAGS1} ${SRC} -o ${MAINCLASS}withstatNPNC
+       ../../../../buildscript ${FLAGS2} ${SRC} -o ${MAINCLASS}withstatNPC
+       ../../../../buildscript ${FLAGS} ${SRC} -o ${MAINCLASS}withstatN
+       ../../../../buildscript ${FLAGSNPNC} ${SRC} -o ${MAINCLASS}NPNC
+       ../../../../buildscript ${FLAGSNPC} ${SRC} -o ${MAINCLASS}NPC
+       ../../../../buildscript ${FLAGSP} ${SRC} -o ${MAINCLASS}N
 
 clean:
        rm -rf tmpbuilddirectory
index 3734e0733efa143f055d4e08b03c5fc911d7573f..e06e60c35850d3e6d45405aae641ab754b2979fc 100644 (file)
@@ -1,36 +1,44 @@
 public class Matrix {
   public int M, N; //M = column, N = row
-  public double[][] dataRe;
-  public double[][] dataIm;
+  public float[][][] dataRe;
+  public float[][][] dataIm;
+  public int numMatrix;
 
-  public Matrix(int M, int N) {
+  public Matrix(int M, int N, int numMatrix) {
     this.M = M;
     this.N = N;
-    dataRe = global new double[M][N];
-    dataIm = global new double[M][N];
+    this.numMatrix = numMatrix;
+    dataRe = global new float[numMatrix][M][N];
+    dataIm = global new float[numMatrix][M][N];
   }
 
   public void setValues() {
-    for (int i = 0; i<M; i++) {
-      double dataRei[] = dataRe[i];
-      double dataImi[] = dataIm[i];
-      for(int j = 0; j<N; j++) {
-       dataRei[j] = j + 1;
-       dataImi[j] = j + 1;
+    for(int z=0; z<numMatrix; z++) {
+      for(int i = 0; i<M; i++) {
+        float dataRei[] = global new float[N];
+        float dataImi[] = global new float[N];
+        for(int j = 0; j<N; j++) {
+          dataRei[j] = j + 1;
+          dataImi[j] = j + 1;
+        }
+        dataRe[z][i] = dataRei;
+        dataIm[z][i] = dataImi;
       }
     }
   }
 
+  /*
   public void setZeros() {
     for (int i = 0; i<M; i++) {
-      double dataRei[] = dataRe[i];
-      double dataImi[] = dataIm[i];
+      float dataRei[] = dataRe[i];
+      float dataImi[] = dataIm[i];
       for(int j = 0; j<N; j++) {
        dataRei[j] = 0;
        dataImi[j] = 0;
       }
     }
   }
+  */
 
   //Transpose matrix input.
   private float[][] transpose(float[][] input) {
index fe6dc37e0298b6ca0dd187e56c77162042464e8e..0576f1618ba9aa547d26b491f26d15f480c70627 100644 (file)
@@ -28,7 +28,7 @@
 // still use this program.
 //
 // To save the memory and improve the speed, float data are used
-// instead of double, but I do have a double version transforms.fft.
+// instead of double
 //
 // Factorize() is done in constructor, transforms.fft() is needed to be
 // called to do FFT, this is good for use in fft2d, then
@@ -44,25 +44,25 @@ public class fft1d {
 
   // cos2to3PI = cos(2*pi/3), using for 3 point FFT.
   // cos(2*PI/3) is not -1.5
-  public double cos2to3PI;
+  public float cos2to3PI;
   // sin2to3PI = sin(2*pi/3), using for 3 point FFT.
-  public double sin2to3PI;
+  public float sin2to3PI;
 
   // TwotoFivePI   = 2*pi/5.
   // c51, c52, c53, c54, c55 are used in fft5().
   // c51 =(cos(TwotoFivePI)+cos(2*TwotoFivePI))/2-1.
-  public double c51;
+  public float c51;
   // c52 =(cos(TwotoFivePI)-cos(2*TwotoFivePI))/2.
-  public double c52;
+  public float c52;
   // c53 = -sin(TwotoFivePI).
-  public double c53;
+  public float c53;
   // c54 =-(sin(TwotoFivePI)+sin(2*TwotoFivePI)).
-  public double c54;
+  public float c54;
   // c55 =(sin(TwotoFivePI)-sin(2*TwotoFivePI)).
-  public double c55;
+  public float c55;
 
   // OnetoSqrt2 = 1/sqrt(2), used in fft8().
-  public double OnetoSqrt2;
+  public float OnetoSqrt2;
 
   public int lastRadix;
 
@@ -74,9 +74,9 @@ public class fft1d {
   int sofar[];        // Finished factors before the current stage.
   int remain[];       // Finished factors after the current stage.
 
-  double inputRe[],  inputIm[];   // Input  of FFT.
-  double temRe[],    temIm[];     // Intermediate result of FFT.
-  double outputRe[], outputIm[];  // Output of FFT.
+  float inputRe[],  inputIm[];   // Input  of FFT.
+  float temRe[],    temIm[];     // Intermediate result of FFT.
+  float outputRe[], outputIm[];  // Output of FFT.
   boolean factorsWerePrinted;
 
   // Constructor: FFT of Complex data.
@@ -94,15 +94,15 @@ public class fft1d {
     lastRadix = 0;
     maxFactor = 20;
     factorsWerePrinted = false;
-    outputRe = new double[N];
-    outputIm = new double[N];
+    outputRe = new float[N];
+    outputIm = new float[N];
 
     factorize();
     //printFactors();
 
     // Allocate memory for intermediate result of FFT.
-    temRe = new double[maxFactor]; //Check usage of this
-    temIm = new double[maxFactor];
+    temRe = new float[maxFactor]; //Check usage of this
+    temIm = new float[maxFactor];
   }
 
   public void printFactors() {
index dd6a7116c1bdbd3a2da87e62e34818e2b9a1b4ea..0f34980dd8e7bc87f1575765b34cae088c3c47d8 100644 (file)
@@ -23,28 +23,31 @@ public class fft2d extends Thread {
     fft1d fft1, fft2;
     Barrier barr;
     barr = new Barrier("128.195.136.162");
-    double tempdataRe[][];
-    double tempdataIm[][];
+    float tempdataRe[][];
+    float tempdataIm[][];
     int rowlength, columnlength;
-    int start, end;
+    int start, end, nmatrix;
 
     // Calculate FFT for each row of the data.
     atomic {
       rowlength = data1.M;
       columnlength = data1.N;
-      tempdataRe = data1.dataRe;
-      tempdataIm = data1.dataIm;
+      nmatrix = data1.numMatrix;
       start = x0;
       end = x1;
       fft1 = new fft1d(columnlength);
       fft2 = new fft1d(rowlength);
       int l=8;
-      for (int i = x0; i < x1; i++,l++) {
-       //input of FFT
-       double inputRe[] = tempdataRe[i]; //local array
-       double inputIm[] = tempdataIm[i];
-       fft(fft1, inputRe, inputIm);
-      } //end of for
+      for(int z=0; z<nmatrix; z++) {
+        tempdataRe = data1.dataRe[z];
+        tempdataIm = data1.dataIm[z];
+        for (int i = start; i < end; i++,l++) {
+          //input of FFT
+          float inputRe[] = tempdataRe[i]; //local array //remote reads here for NPNC
+          float inputIm[] = tempdataIm[i];//remote reads here for NPNC
+          fft(fft1, inputRe, inputIm);
+        } //end of for
+      }
     }
 
     //Start Barrier
@@ -53,7 +56,11 @@ public class fft2d extends Thread {
     // Tranpose data.
     if (start == 0) {
       atomic {
-        transpose(tempdataRe, tempdataIm, rowlength, columnlength);
+        for(int z=0; z<nmatrix; z++) {
+          tempdataRe = data1.dataRe[z];
+          tempdataIm = data1.dataIm[z];
+          transpose(tempdataRe, tempdataIm, rowlength, columnlength);
+        }
       }
     }
 
@@ -61,26 +68,28 @@ public class fft2d extends Thread {
     Barrier.enterBarrier(barr);
 
     // Calculate FFT for each column of the data.
-    double transtempRe[][];
-    double transtempIm[][];
+    float transtempRe[][];
+    float transtempIm[][];
     atomic {
-      transtempRe = data1.dataRe;
-      transtempIm = data1.dataIm;
-      int l=8;
-      for (int j = start; j < end; j++,l++) {
-       //input of FFT
-       double inputRe[] = transtempRe[j]; //local array
-       double inputIm[] = transtempIm[j];
-       fft(fft2, inputRe, inputIm);
-      } //end of fft2 for
+      for(int z=0; z<nmatrix; z++) {
+        transtempRe = data1.dataRe[z];
+        transtempIm = data1.dataIm[z];
+        int l=8;
+        for (int j = start; j < end; j++,l++) {
+          //input of FFT
+          float inputRe[] = transtempRe[j]; //local array //Remote reads here
+          float inputIm[] = transtempIm[j]; //remote reads here
+          fft(fft2, inputRe, inputIm);
+        } //end of fft2 for
+      }
     }
   } //end of run
 
-  public void transpose(double[][] tempdataRe, double[][] tempdataIm, int rowlength, int columnlength) {
+  public void transpose(float[][] tempdataRe, float[][] tempdataIm, int rowlength, int columnlength) {
     for(int i = 0; i<rowlength; i++) {
-      double tRe[] = tempdataRe[i];
-      double tIm[] = tempdataIm[i];
-      double a;
+      float tRe[] = tempdataRe[i];
+      float tIm[] = tempdataIm[i];
+      float a;
 
       for(int j = 0; j<i; j++) {
        a=tempdataRe[j][i];
@@ -95,15 +104,19 @@ public class fft2d extends Thread {
 
   public static void main(String[] args) {
     int NUM_THREADS = 1;
+    int NUM_MATRIX = 1;
     int SIZE = 800;
     int inputWidth = 10;
     if(args.length>0) {
       NUM_THREADS=Integer.parseInt(args[0]);
-      if(args.length > 1)
+      if(args.length > 1){
        SIZE = Integer.parseInt(args[1]);
+    if(args.length > 2)
+      NUM_MATRIX = Integer.parseInt(args[2]);
+      }
     }
 
-    System.printString("Num threads = " + NUM_THREADS + " SIZE= " + SIZE + "\n");
+    System.printString("Num threads = " + NUM_THREADS + " SIZE= " + SIZE + " NUM_MATRIX= " + NUM_MATRIX +"\n");
 
     int[] mid = new int[8];
     mid[0] = (128<<24)|(195<<16)|(136<<8)|162; //dw-10
@@ -129,7 +142,7 @@ public class fft2d extends Thread {
     fft2d[] myfft2d;
     atomic {
       // Set up data for FFT transform
-      data1 = global new Matrix(SIZE, SIZE);
+      data1 = global new Matrix(SIZE, SIZE, NUM_MATRIX);
       data1.setValues(); //Input Matrix
       myfft2d = global new fft2d[NUM_THREADS];
       int increment = SIZE/NUM_THREADS;
@@ -171,21 +184,19 @@ public class fft2d extends Thread {
     System.printString("2DFFT done! \n");
   }
 
-  public static void fft(fft1d myfft, double inputRe[], double inputIm[]) {
+  public static void fft(fft1d myfft, float inputRe[], float inputIm[]) {
     //output of FFT
-    double outputRe[] = myfft.outputRe;
-    double outputIm[] = myfft.outputIm;
+    float outputRe[] = myfft.outputRe;
+    float outputIm[] = myfft.outputIm;
     // intermediate results
-    double temRe[] = myfft.temRe;
-    double temIm[] = myfft.temIm;
+    float temRe[] = myfft.temRe;
+    float temIm[] = myfft.temIm;
     //Permute() operation
     permute(myfft, outputRe, outputIm, inputRe, inputIm);
 
-    //System.printString("ready to twiddle");
     for (int factorIndex = 0; factorIndex < myfft.NumofFactors; factorIndex++)
       twiddle(factorIndex, myfft, temRe, temIm, outputRe, outputIm);
 
-    //System.printString("ready to copy");
     // Copy the output[] data to input[], so the output can be
     // returned in the input array.
     for (int i = 0; i < myfft.N; i++) {
@@ -194,7 +205,7 @@ public class fft2d extends Thread {
     }
   }
 
-  private static void permute(fft1d myfft, double[] outputRe, double[] outputIm, double[] inputRe, double[] inputIm) {
+  private static void permute(fft1d myfft, float[] outputRe, float[] outputIm, float[] inputRe, float[] inputIm) {
     int count[] = new int[myfft.MaxFactorsNumber];
     int j;
     int k = 0;
@@ -221,28 +232,27 @@ public class fft2d extends Thread {
     outputIm[myfft.N - 1] = inputIm[myfft.N - 1];
   }   // End of function permute().
 
-  private static void twiddle(int factorIndex, fft1d myfft, double[] temRe, double[] temIm,
-                              double[] outputRe, double[] outputIm) {
+  private static void twiddle(int factorIndex, fft1d myfft, float[] temRe, float[] temIm,
+                              float[] outputRe, float[] outputIm) {
     // Get factor data.
     int sofarRadix = myfft.sofar[factorIndex];
     int radix = myfft.factors[factorIndex];
     int remainRadix = myfft.remain[factorIndex];
 
-    double tem;   // Temporary variable to do data exchange.
+    float tem;   // Temporary variable to do data exchange.
 
-    double W = 2 * (double) Math.setPI() / (sofarRadix * radix);
-    double cosW = (double) Math.cos(W);
-    double sinW = -(double) Math.sin(W);
+    float W = 2 * (float) Math.setPI() / (sofarRadix * radix);
+    float cosW = (float) Math.cos(W);
+    float sinW = -(float) Math.sin(W);
 
-    double twiddleRe[] = new double[radix];
-    double twiddleIm[] = new double[radix];
-    double twRe = 1.0f, twIm = 0f;
+    float twiddleRe[] = new float[radix];
+    float twiddleIm[] = new float[radix];
+    float twRe = 1.0f, twIm = 0f;
 
     //Initialize twiddle addBk.address variables.
     int dataOffset = 0, groupOffset = 0, address = 0;
 
     for (int dataNo = 0; dataNo < sofarRadix; dataNo++) {
-      //System.printString("datano="+dataNo);
       if (sofarRadix > 1) {
        twiddleRe[0] = 1.0f;
        twiddleIm[0] = 0.0f;
@@ -257,7 +267,6 @@ public class fft2d extends Thread {
        twRe = tem;
       }
       for (int groupNo = 0; groupNo < remainRadix; groupNo++) {
-       //System.printString("groupNo="+groupNo);
        if ((sofarRadix > 1) && (dataNo > 0)) {
          temRe[0] = outputRe[address];
          temIm[0] = outputIm[address];
@@ -272,14 +281,11 @@ public class fft2d extends Thread {
          } while (blockIndex < radix);
        } else {
          for (int i = 0; i < radix; i++) {
-           //System.printString("temRe.length="+temRe.length);
-           //System.printString("i = "+i);
            temRe[i] = outputRe[address];
            temIm[i] = outputIm[address];
            address += sofarRadix;
          }
        }
-       //System.printString("radix="+radix);
        if(radix == 2) {
          tem = temRe[0] + temRe[1];
          temRe[1] = temRe[0] - temRe[1];
@@ -288,17 +294,17 @@ public class fft2d extends Thread {
          temIm[1] = temIm[0] - temIm[1];
          temIm[0] = tem;
        } else if( radix == 3) {
-         double t1Re = temRe[1] + temRe[2];
-         double t1Im = temIm[1] + temIm[2];
+         float t1Re = temRe[1] + temRe[2];
+         float t1Im = temIm[1] + temIm[2];
          temRe[0] = temRe[0] + t1Re;
          temIm[0] = temIm[0] + t1Im;
 
-         double m1Re = myfft.cos2to3PI * t1Re;
-         double m1Im = myfft.cos2to3PI * t1Im;
-         double m2Re = myfft.sin2to3PI * (temIm[1] - temIm[2]);
-         double m2Im = myfft.sin2to3PI * (temRe[2] - temRe[1]);
-         double s1Re = temRe[0] + m1Re;
-         double s1Im = temIm[0] + m1Im;
+         float m1Re = myfft.cos2to3PI * t1Re;
+         float m1Im = myfft.cos2to3PI * t1Im;
+         float m2Re = myfft.sin2to3PI * (temIm[1] - temIm[2]);
+         float m2Im = myfft.sin2to3PI * (temRe[2] - temRe[1]);
+         float s1Re = temRe[0] + m1Re;
+         float s1Im = temIm[0] + m1Im;
 
          temRe[1] = s1Re + m2Re;
          temIm[1] = s1Im + m2Im;
@@ -330,9 +336,9 @@ public class fft2d extends Thread {
   } //twiddle operation
 
   // The two arguments dataRe[], dataIm[] are mainly for using in fft8();
-  private static void fft4(double dataRe[], double dataIm[]) {
-    double t1Re,t1Im, t2Re,t2Im;
-    double m2Re,m2Im, m3Re,m3Im;
+  private static void fft4(float dataRe[], float dataIm[]) {
+    float t1Re,t1Im, t2Re,t2Im;
+    float m2Re,m2Im, m3Re,m3Im;
 
     t1Re = dataRe[0] + dataRe[2];
     t1Im = dataIm[0] + dataIm[2];
@@ -355,10 +361,10 @@ public class fft2d extends Thread {
   }   // End of function fft4().
 
   // The two arguments dataRe[], dataIm[] are mainly for using in fft10();
-  private static void fft5(fft1d myfft, double dataRe[], double dataIm[]) {
-    double t1Re,t1Im, t2Re,t2Im, t3Re,t3Im, t4Re,t4Im, t5Re,t5Im;
-    double m1Re,m1Im, m2Re,m2Im, m3Re,m3Im, m4Re,m4Im, m5Re,m5Im;
-    double s1Re,s1Im, s2Re,s2Im, s3Re,s3Im, s4Re,s4Im, s5Re,s5Im;
+  private static void fft5(fft1d myfft, float dataRe[], float dataIm[]) {
+    float t1Re,t1Im, t2Re,t2Im, t3Re,t3Im, t4Re,t4Im, t5Re,t5Im;
+    float m1Re,m1Im, m2Re,m2Im, m3Re,m3Im, m4Re,m4Im, m5Re,m5Im;
+    float s1Re,s1Im, s2Re,s2Im, s3Re,s3Im, s4Re,s4Im, s5Re,s5Im;
 
     t1Re = dataRe[1] + dataRe[4];
     t1Im = dataIm[1] + dataIm[4];
@@ -406,12 +412,12 @@ public class fft2d extends Thread {
     dataIm[4] = s2Im - s3Im;
   }   // End of function fft5().
 
-  private static void fft8(fft1d myfft, double[] temRe, double[] temIm) {
-    double data1Re[] = new double[4];
-    double data1Im[] = new double[4];
-    double data2Re[] = new double[4];
-    double data2Im[] = new double[4];
-    double tem;
+  private static void fft8(fft1d myfft, float[] temRe, float[] temIm) {
+    float data1Re[] = new float[4];
+    float data1Im[] = new float[4];
+    float data2Re[] = new float[4];
+    float data2Im[] = new float[4];
+    float tem;
 
     // To improve the speed, use direct assaignment instead for loop here.
     data1Re[0] = temRe[0];
@@ -464,11 +470,11 @@ public class fft2d extends Thread {
     temIm[7] = data1Im[3] - data2Im[3];
   }   // End of function fft8().
 
-  private static void fft10(fft1d myfft, double[] temRe, double[] temIm) {
-    double data1Re[] = new double[5];
-    double data1Im[] = new double[5];
-    double data2Re[] = new double[5];
-    double data2Im[] = new double[5];
+  private static void fft10(fft1d myfft, float[] temRe, float[] temIm) {
+    float data1Re[] = new float[5];
+    float data1Im[] = new float[5];
+    float data2Re[] = new float[5];
+    float data2Im[] = new float[5];
 
     // To improve the speed, use direct assaignment instead for loop here.
     data1Re[0] = temRe[0];
@@ -519,13 +525,13 @@ public class fft2d extends Thread {
     temIm[9] = data1Im[4] - data2Im[4];
   }   // End of function fft10().
 
-  private static void fftPrime(int radix, double[] temRe, double[] temIm) {
+  private static void fftPrime(int radix, float[] temRe, float[] temIm) {
     // Initial WRe, WIm.
-    double W = 2 * (double) Math.setPI() / radix;
-    double cosW = (double) Math.cos(W);
-    double sinW = -(double) Math.sin(W);
-    double WRe[] = new double[radix];
-    double WIm[] = new double[radix];
+    float W = 2 * (float) Math.setPI() / radix;
+    float cosW = (float) Math.cos(W);
+    float sinW = -(float) Math.sin(W);
+    float WRe[] = new float[radix];
+    float WIm[] = new float[radix];
 
     WRe[0] = 1;
     WIm[0] = 0;
@@ -538,14 +544,14 @@ public class fft2d extends Thread {
     }
 
     // FFT of prime length data, using DFT, can be improved in the future.
-    double rere, reim, imre, imim;
+    float rere, reim, imre, imim;
     int j, k;
     int max = (radix + 1) / 2;
 
-    double tem1Re[] = new double[max];
-    double tem1Im[] = new double[max];
-    double tem2Re[] = new double[max];
-    double tem2Im[] = new double[max];
+    float tem1Re[] = new float[max];
+    float tem1Im[] = new float[max];
+    float tem2Re[] = new float[max];
+    float tem2Im[] = new float[max];
 
     for (j = 1; j < max; j++) {
       tem1Re[j] = temRe[j] + temRe[radix - j];
diff --git a/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/MatrixN.java b/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/MatrixN.java
new file mode 100644 (file)
index 0000000..442b008
--- /dev/null
@@ -0,0 +1,40 @@
+public class Matrix {
+  public int M, N; //M = column, N = row
+  public float[][][] dataRe;
+  public float[][][] dataIm;
+  public int numMatrix;
+
+  public Matrix(int M, int N, int numMatrix) {
+    this.M = M;
+    this.N = N;
+    this.numMatrix = numMatrix;
+    dataRe = new float[numMatrix][M][N];
+    dataIm = new float[numMatrix][M][N];
+  }
+
+  public void setValues() {
+    for(int z=0; z<numMatrix; z++) {
+      for(int i = 0; i<M; i++) {
+        float dataRei[] = new float[N];
+        float dataImi[] = new float[N];
+        for(int j = 0; j<N; j++) {
+          dataRei[j] = j + 1;
+          dataImi[j] = j + 1;
+        }
+        dataRe[z][i] = dataRei;
+        dataIm[z][i] = dataImi;
+      }
+    }
+  }
+
+  //Transpose matrix input.
+  private float[][] transpose(float[][] input) {
+    float[][] output = new float[N][M];
+
+    for (int j = 0; j < N; j++)
+      for (int i = 0; i < M; i++)
+       output[j][i] = input[i][j];
+
+    return output;
+  } // End of function transpose().
+}
diff --git a/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft1dN.java b/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft1dN.java
new file mode 100644 (file)
index 0000000..9173030
--- /dev/null
@@ -0,0 +1,192 @@
+
+//Title:        1-d mixed radix FFT.
+//Version:
+//Copyright:    Copyright (c) 1998
+//Author:       Dongyan Wang
+//Company:      University of Wisconsin-Milwaukee.
+//Description:
+//  The number of DFT is factorized.
+//
+// Some short FFTs, such as length 2, 3, 4, 5, 8, 10, are used
+// to improve the speed.
+//
+// Prime factors are processed using DFT. In the future, we can
+// improve this part.
+// Note: there is no limit how large the prime factor can be,
+// because for a set of data of an image, the length can be
+// random, ie. an image can have size 263 x 300, where 263 is
+// a large prime factor.
+//
+// A permute() function is used to make sure FFT can be calculated
+// in place.
+//
+// A triddle() function is used to perform the FFT.
+//
+// This program is for FFT of complex data, if the input is real,
+// the program can be further improved. Because I want to use the
+// same program to do IFFT, whose input is often complex, so I
+// still use this program.
+//
+// To save the memory and improve the speed, float data are used
+// instead of float, but I do have a float version transforms.fft.
+//
+// Factorize() is done in constructor, transforms.fft() is needed to be
+// called to do FFT, this is good for use in fft2d, then
+// factorize() is not needed for each row/column of data, since
+// each row/column of a matrix has the same length.
+//
+
+
+public class fft1d {
+  // Maximum numbers of factors allowed.
+  //private int MaxFactorsNumber = 30;
+  public int MaxFactorsNumber;
+
+  // cos2to3PI = cos(2*pi/3), using for 3 point FFT.
+  // cos(2*PI/3) is not -1.5
+  public float cos2to3PI;
+  // sin2to3PI = sin(2*pi/3), using for 3 point FFT.
+  public float sin2to3PI;
+
+  // TwotoFivePI   = 2*pi/5.
+  // c51, c52, c53, c54, c55 are used in fft5().
+  // c51 =(cos(TwotoFivePI)+cos(2*TwotoFivePI))/2-1.
+  public float c51;
+  // c52 =(cos(TwotoFivePI)-cos(2*TwotoFivePI))/2.
+  public float c52;
+  // c53 = -sin(TwotoFivePI).
+  public float c53;
+  // c54 =-(sin(TwotoFivePI)+sin(2*TwotoFivePI)).
+  public float c54;
+  // c55 =(sin(TwotoFivePI)-sin(2*TwotoFivePI)).
+  public float c55;
+
+  // OnetoSqrt2 = 1/sqrt(2), used in fft8().
+  public float OnetoSqrt2;
+
+  public int lastRadix;
+
+  int N;              // length of N point FFT.
+  int NumofFactors;   // Number of factors of N.
+  int maxFactor;      // Maximum factor of N.
+
+  int factors[];      // Factors of N processed in the current stage.
+  int sofar[];        // Finished factors before the current stage.
+  int remain[];       // Finished factors after the current stage.
+
+  float inputRe[],  inputIm[];   // Input  of FFT.
+  float temRe[],    temIm[];     // Intermediate result of FFT.
+  float outputRe[], outputIm[];  // Output of FFT.
+  boolean factorsWerePrinted;
+
+  // Constructor: FFT of Complex data.
+  public fft1d(int N) {
+    this.N = N;
+    MaxFactorsNumber = 37;
+    cos2to3PI = -1.5000f;
+    sin2to3PI = 8.6602540378444E-01f;
+    c51 = -1.25f;
+    c52 = 5.5901699437495E-01f;
+    c53 = -9.5105651629515E-01f;
+    c54 = -1.5388417685876E+00f;
+    c55 = 3.6327126400268E-01f;
+    OnetoSqrt2 = 7.0710678118655E-01f;
+    lastRadix = 0;
+    maxFactor = 20;
+    factorsWerePrinted = false;
+    outputRe = new float[N];
+    outputIm = new float[N];
+
+    factorize();
+    //printFactors();
+
+    // Allocate memory for intermediate result of FFT.
+    temRe = new float[maxFactor]; //Check usage of this
+    temIm = new float[maxFactor];
+  }
+
+  public void printFactors() {
+    if (factorsWerePrinted) return;
+    factorsWerePrinted = true;
+    System.printString("factors.length = " + factors.length + "\n");
+    for (int i = 0; i < factors.length; i++)
+      System.printString("factors[i] = " + factors[i] + "\n");
+  }
+
+  public void factorize() {
+    int radices[] = new int[6];
+    radices[0] = 2;
+    radices[1] = 3;
+    radices[2] = 4;
+    radices[3] = 5;
+    radices[4] = 8;
+    radices[5] = 10;
+    int temFactors[] = new int[MaxFactorsNumber];
+
+    // 1 - point FFT, no need to factorize N.
+    if (N == 1) {
+      temFactors[0] = 1;
+      NumofFactors = 1;
+    }
+
+    // N - point FFT, N is needed to be factorized.
+    int n = N;
+    int index = 0;    // index of temFactors.
+    int i = radices.length - 1;
+
+    while ((n > 1) && (i >= 0)) {
+      if ((n % radices[i]) == 0) {
+       n /= radices[i];
+       temFactors[index++] = radices[i];
+      } else
+       i--;
+    }
+
+    // Substitute 2x8 with 4x4.
+    // index>0, in the case only one prime factor, such as N=263.
+    if ((index > 0) && (temFactors[index - 1] == 2)) {
+      int test = 0;
+      for (i = index - 2; (i >= 0) && (test == 0); i--) {
+       if (temFactors[i] == 8) {
+         temFactors[index - 1] = temFactors[i] = 4;
+         // break out of for loop, because only one '2' will exist in
+         // temFactors, so only one substitutation is needed.
+         test = 1;
+       }
+      }
+    }
+
+    if (n > 1) {
+      for (int k = 2; k < Math.sqrt(n) + 1; k++)
+       while ((n % k) == 0) {
+         n /= k;
+         temFactors[index++] = k;
+       }
+      if (n > 1) {
+       temFactors[index++] = n;
+      }
+    }
+    NumofFactors = index;
+
+    // Inverse temFactors and store factors into factors[].
+    factors = new int[NumofFactors];
+    for (i = 0; i < NumofFactors; i++) {
+      factors[i] = temFactors[NumofFactors - i - 1];
+    }
+
+    // Calculate sofar[], remain[].
+    // sofar[]  : finished factors before the current stage.
+    // factors[]: factors of N processed in the current stage.
+    // remain[] : finished factors after the current stage.
+
+    sofar = new int[NumofFactors];
+    remain = new int[NumofFactors];
+
+    remain[0] = N / factors[0];
+    sofar[0] = 1;
+    for (i = 1; i < NumofFactors; i++) {
+      sofar[i] = sofar[i - 1] * factors[i - 1];
+      remain[i] = remain[i - 1] / factors[i];
+    }
+  }   // End of function factorize().
+} // End of class FFT1d
diff --git a/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft2dN.java b/Robust/src/Benchmarks/Prefetch/2DFFT/javasingle/fft2dN.java
new file mode 100644 (file)
index 0000000..07758c0
--- /dev/null
@@ -0,0 +1,545 @@
+public class fft2d extends Thread {
+  //Title:        2-d mixed radix FFT.
+  //Version:
+  //Copyright:    Copyright (c) 1998
+  //Author:       Dongyan Wang
+  //Company:      University of Wisconsin-Milwaukee.
+  //Description:
+  //              . Use fft1d to perform fft2d.
+  //
+  // Code borrowed from :Java Digital Signal Processing book by Lyon and Rao
+
+  public Matrix data1;
+  public int x0, x1;
+
+  // Constructor: 2-d FFT of Complex data.
+  public fft2d(Matrix data1, int x0, int x1) {
+    this.data1 = data1;
+    this.x0 = x0;
+    this.x1 = x1;
+  }
+
+  public void run() {
+    fft1d fft1, fft2;
+    float tempdataRe[][];
+    float tempdataIm[][];
+    int rowlength, columnlength;
+    int start, end, nmatrix;
+
+    // Calculate FFT for each row of the data.
+    rowlength = data1.M;
+    columnlength = data1.N;
+    //tempdataRe = data1.dataRe;
+    //tempdataIm = data1.dataIm;
+    nmatrix = data1.numMatrix;
+    start = x0;
+    end = x1;
+    fft1 = new fft1d(columnlength);
+    fft2 = new fft1d(rowlength);
+    for(int z=0; z<nmatrix; z++) {
+      tempdataRe = data1.dataRe[z];
+      tempdataIm = data1.dataIm[z];
+      for (int i = start; i < end; i++) {
+        //input of FFT
+        float inputRe[] = tempdataRe[i]; //local array
+        float inputIm[] = tempdataIm[i];
+        fft(fft1, inputRe, inputIm);
+      } //end of for
+    }
+
+    // Tranpose data.
+    if (start == 0) {
+      for(int z=0; z<nmatrix; z++) {
+        tempdataRe = data1.dataRe[z];
+        tempdataIm = data1.dataIm[z];
+        transpose(tempdataRe, tempdataIm, rowlength, columnlength);
+      }
+    }
+
+    // Calculate FFT for each column of the data.
+    float transtempRe[][];
+    float transtempIm[][];
+    for(int z=0; z<nmatrix; z++) {
+      transtempRe = data1.dataRe[z];
+      transtempIm = data1.dataIm[z];
+      for (int j = start; j < end; j++) {
+        //input of FFT
+        float inputRe[] = transtempRe[j]; //local array
+        float inputIm[] = transtempIm[j];
+        fft(fft2, inputRe, inputIm);
+      } //end of fft2 for
+    }
+  } //end of run
+
+  public void transpose(float[][] tempdataRe, float[][] tempdataIm, int rowlength, int columnlength) {
+    for(int i = 0; i<rowlength; i++) {
+      float tRe[] = tempdataRe[i];
+      float tIm[] = tempdataIm[i];
+      float a;
+
+      for(int j = 0; j<i; j++) {
+        a=tempdataRe[j][i];
+        tempdataRe[j][i] = tRe[j];
+        tRe[j]=a;
+        a=tempdataIm[j][i];
+        tempdataIm[j][i] = tIm[j];
+        tIm[j]=a;
+      }
+    }
+  }
+
+  public static void main(String[] args) {
+    int NUM_THREADS = 1;
+    int NUM_MATRIX = 1;
+    int SIZE = 800;
+    int inputWidth = 10;
+    if(args.length>0) {
+      NUM_THREADS=Integer.parseInt(args[0]);
+      if(args.length > 1){
+        SIZE = Integer.parseInt(args[1]);
+        if(args.length > 2)
+          NUM_MATRIX = Integer.parseInt(args[2]);
+      }
+    }
+
+    System.printString("Num threads = " + NUM_THREADS + " SIZE= " + SIZE + " NUM_MATRIX= " + NUM_MATRIX +"\n");
+
+    Matrix data1;
+
+    // Create threads to do FFT
+    fft2d[] myfft2d;
+      // Set up data for FFT transform
+      data1 = new Matrix(SIZE, SIZE, NUM_MATRIX);
+      data1.setValues(); //Input Matrix
+      myfft2d = new fft2d[NUM_THREADS];
+      int increment = SIZE/NUM_THREADS;
+      int base = 0;
+      for(int i =0 ; i<NUM_THREADS; i++) {
+       if((i+1)==NUM_THREADS)
+         myfft2d[i] = new fft2d(data1, base, SIZE);
+       else
+         myfft2d[i] = new fft2d(data1, base, base+increment);
+       base+=increment;
+      }
+
+    fft2d tmp;
+    //Start a thread to compute each c[l,n]
+    for(int i = 0; i<NUM_THREADS; i++) {
+      tmp = myfft2d[i];
+      tmp.run();
+    }
+
+    System.printString("2DFFT done! \n");
+  }
+
+  public static void fft(fft1d myfft, float inputRe[], float inputIm[]) {
+    //output of FFT
+    float outputRe[] = myfft.outputRe;
+    float outputIm[] = myfft.outputIm;
+    // intermediate results
+    float temRe[] = myfft.temRe;
+    float temIm[] = myfft.temIm;
+    //Permute() operation
+    permute(myfft, outputRe, outputIm, inputRe, inputIm);
+
+    //System.printString("ready to twiddle");
+    for (int factorIndex = 0; factorIndex < myfft.NumofFactors; factorIndex++)
+      twiddle(factorIndex, myfft, temRe, temIm, outputRe, outputIm);
+
+    //System.printString("ready to copy");
+    // Copy the output[] data to input[], so the output can be
+    // returned in the input array.
+    for (int i = 0; i < myfft.N; i++) {
+      inputRe[i] = outputRe[i];
+      inputIm[i] = outputIm[i];
+    }
+  }
+
+  private static void permute(fft1d myfft, float[] outputRe, float[] outputIm, float[] inputRe, float[] inputIm) {
+    int count[] = new int[myfft.MaxFactorsNumber];
+    int j;
+    int k = 0;
+
+    for (int i = 0; i < myfft.N - 1; i++) {
+      outputRe[i] = inputRe[k];
+      outputIm[i] = inputIm[k];
+      j = 0;
+      k = k + myfft.remain[j];
+      count[0] = count[0] + 1;
+      while (count[j] >= myfft.factors[j]) {
+       count[j] = 0;
+       int tmp;
+       if(j == 0)
+         tmp = myfft.N;
+       else
+         tmp = myfft.remain[j - 1];
+       k = k - tmp + myfft.remain[j + 1];
+       j++;
+       count[j] = count[j] + 1;
+      }
+    }
+    outputRe[myfft.N - 1] = inputRe[myfft.N - 1];
+    outputIm[myfft.N - 1] = inputIm[myfft.N - 1];
+  }   // End of function permute().
+
+  private static void twiddle(int factorIndex, fft1d myfft, float[] temRe, float[] temIm,
+                              float[] outputRe, float[] outputIm) {
+    // Get factor data.
+    int sofarRadix = myfft.sofar[factorIndex];
+    int radix = myfft.factors[factorIndex];
+    int remainRadix = myfft.remain[factorIndex];
+
+    float tem;   // Temporary variable to do data exchange.
+
+    float W = 2 * (float) Math.setPI() / (sofarRadix * radix);
+    float cosW = (float) Math.cos(W);
+    float sinW = -(float) Math.sin(W);
+
+    float twiddleRe[] = new float[radix];
+    float twiddleIm[] = new float[radix];
+    float twRe = 1.0f, twIm = 0f;
+
+    //Initialize twiddle addBk.address variables.
+    int dataOffset = 0, groupOffset = 0, address = 0;
+
+    for (int dataNo = 0; dataNo < sofarRadix; dataNo++) {
+      //System.printString("datano="+dataNo);
+      if (sofarRadix > 1) {
+       twiddleRe[0] = 1.0f;
+       twiddleIm[0] = 0.0f;
+       twiddleRe[1] = twRe;
+       twiddleIm[1] = twIm;
+       for (int i = 2; i < radix; i++) {
+         twiddleRe[i] = twRe * twiddleRe[i - 1] - twIm * twiddleIm[i - 1];
+         twiddleIm[i] = twIm * twiddleRe[i - 1] + twRe * twiddleIm[i - 1];
+       }
+       tem = cosW * twRe - sinW * twIm;
+       twIm = sinW * twRe + cosW * twIm;
+       twRe = tem;
+      }
+      for (int groupNo = 0; groupNo < remainRadix; groupNo++) {
+       //System.printString("groupNo="+groupNo);
+       if ((sofarRadix > 1) && (dataNo > 0)) {
+         temRe[0] = outputRe[address];
+         temIm[0] = outputIm[address];
+         int blockIndex = 1;
+         do {
+           address = address + sofarRadix;
+           temRe[blockIndex] = twiddleRe[blockIndex] * outputRe[address] -
+                               twiddleIm[blockIndex] * outputIm[address];
+           temIm[blockIndex] = twiddleRe[blockIndex] * outputIm[address] +
+                               twiddleIm[blockIndex] * outputRe[address];
+           blockIndex++;
+         } while (blockIndex < radix);
+       } else {
+         for (int i = 0; i < radix; i++) {
+           //System.printString("temRe.length="+temRe.length);
+           //System.printString("i = "+i);
+           temRe[i] = outputRe[address];
+           temIm[i] = outputIm[address];
+           address += sofarRadix;
+         }
+       }
+       //System.printString("radix="+radix);
+       if(radix == 2) {
+         tem = temRe[0] + temRe[1];
+         temRe[1] = temRe[0] - temRe[1];
+         temRe[0] = tem;
+         tem = temIm[0] + temIm[1];
+         temIm[1] = temIm[0] - temIm[1];
+         temIm[0] = tem;
+       } else if( radix == 3) {
+         float t1Re = temRe[1] + temRe[2];
+         float t1Im = temIm[1] + temIm[2];
+         temRe[0] = temRe[0] + t1Re;
+         temIm[0] = temIm[0] + t1Im;
+
+         float m1Re = myfft.cos2to3PI * t1Re;
+         float m1Im = myfft.cos2to3PI * t1Im;
+         float m2Re = myfft.sin2to3PI * (temIm[1] - temIm[2]);
+         float m2Im = myfft.sin2to3PI * (temRe[2] - temRe[1]);
+         float s1Re = temRe[0] + m1Re;
+         float s1Im = temIm[0] + m1Im;
+
+         temRe[1] = s1Re + m2Re;
+         temIm[1] = s1Im + m2Im;
+         temRe[2] = s1Re - m2Re;
+         temIm[2] = s1Im - m2Im;
+       } else if(radix == 4) {
+         fft4(temRe, temIm);
+       } else if(radix == 5) {
+         fft5(myfft, temRe, temIm);
+       } else if(radix == 8) {
+         fft8(myfft, temRe, temIm);
+       } else if(radix == 10) {
+         fft10(myfft, temRe, temIm);
+       } else {
+         fftPrime(radix, temRe, temIm);
+       }
+       address = groupOffset;
+       for (int i = 0; i < radix; i++) {
+         outputRe[address] = temRe[i];
+         outputIm[address] = temIm[i];
+         address += sofarRadix;
+       }
+       groupOffset += sofarRadix * radix;
+       address = groupOffset;
+      }
+      groupOffset = ++dataOffset;
+      address = groupOffset;
+    }
+  } //twiddle operation
+
+  // The two arguments dataRe[], dataIm[] are mainly for using in fft8();
+  private static void fft4(float dataRe[], float dataIm[]) {
+    float t1Re,t1Im, t2Re,t2Im;
+    float m2Re,m2Im, m3Re,m3Im;
+
+    t1Re = dataRe[0] + dataRe[2];
+    t1Im = dataIm[0] + dataIm[2];
+    t2Re = dataRe[1] + dataRe[3];
+    t2Im = dataIm[1] + dataIm[3];
+
+    m2Re = dataRe[0] - dataRe[2];
+    m2Im = dataIm[0] - dataIm[2];
+    m3Re = dataIm[1] - dataIm[3];
+    m3Im = dataRe[3] - dataRe[1];
+
+    dataRe[0] = t1Re + t2Re;
+    dataIm[0] = t1Im + t2Im;
+    dataRe[2] = t1Re - t2Re;
+    dataIm[2] = t1Im - t2Im;
+    dataRe[1] = m2Re + m3Re;
+    dataIm[1] = m2Im + m3Im;
+    dataRe[3] = m2Re - m3Re;
+    dataIm[3] = m2Im - m3Im;
+  }   // End of function fft4().
+
+  // The two arguments dataRe[], dataIm[] are mainly for using in fft10();
+  private static void fft5(fft1d myfft, float dataRe[], float dataIm[]) {
+    float t1Re,t1Im, t2Re,t2Im, t3Re,t3Im, t4Re,t4Im, t5Re,t5Im;
+    float m1Re,m1Im, m2Re,m2Im, m3Re,m3Im, m4Re,m4Im, m5Re,m5Im;
+    float s1Re,s1Im, s2Re,s2Im, s3Re,s3Im, s4Re,s4Im, s5Re,s5Im;
+
+    t1Re = dataRe[1] + dataRe[4];
+    t1Im = dataIm[1] + dataIm[4];
+    t2Re = dataRe[2] + dataRe[3];
+    t2Im = dataIm[2] + dataIm[3];
+    t3Re = dataRe[1] - dataRe[4];
+    t3Im = dataIm[1] - dataIm[4];
+    t4Re = dataRe[3] - dataRe[2];
+    t4Im = dataIm[3] - dataIm[2];
+    t5Re = t1Re + t2Re;
+    t5Im = t1Im + t2Im;
+
+    dataRe[0] = dataRe[0] + t5Re;
+    dataIm[0] = dataIm[0] + t5Im;
+
+    m1Re = myfft.c51 * t5Re;
+    m1Im = myfft.c51 * t5Im;
+    m2Re = myfft.c52 * (t1Re - t2Re);
+    m2Im = myfft.c52 * (t1Im - t2Im);
+    m3Re = -(myfft.c53) * (t3Im + t4Im);
+    m3Im = myfft.c53 * (t3Re + t4Re);
+    m4Re = -(myfft.c54) * t4Im;
+    m4Im = myfft.c54 * t4Re;
+    m5Re = -(myfft.c55) * t3Im;
+    m5Im = myfft.c55 * t3Re;
+
+    s3Re = m3Re - m4Re;
+    s3Im = m3Im - m4Im;
+    s5Re = m3Re + m5Re;
+    s5Im = m3Im + m5Im;
+    s1Re = dataRe[0] + m1Re;
+    s1Im = dataIm[0] + m1Im;
+    s2Re = s1Re + m2Re;
+    s2Im = s1Im + m2Im;
+    s4Re = s1Re - m2Re;
+    s4Im = s1Im - m2Im;
+
+    dataRe[1] = s2Re + s3Re;
+    dataIm[1] = s2Im + s3Im;
+    dataRe[2] = s4Re + s5Re;
+    dataIm[2] = s4Im + s5Im;
+    dataRe[3] = s4Re - s5Re;
+    dataIm[3] = s4Im - s5Im;
+    dataRe[4] = s2Re - s3Re;
+    dataIm[4] = s2Im - s3Im;
+  }   // End of function fft5().
+
+  private static void fft8(fft1d myfft, float[] temRe, float[] temIm) {
+    float data1Re[] = new float[4];
+    float data1Im[] = new float[4];
+    float data2Re[] = new float[4];
+    float data2Im[] = new float[4];
+    float tem;
+
+    // To improve the speed, use direct assaignment instead for loop here.
+    data1Re[0] = temRe[0];
+    data2Re[0] = temRe[1];
+    data1Re[1] = temRe[2];
+    data2Re[1] = temRe[3];
+    data1Re[2] = temRe[4];
+    data2Re[2] = temRe[5];
+    data1Re[3] = temRe[6];
+    data2Re[3] = temRe[7];
+
+    data1Im[0] = temIm[0];
+    data2Im[0] = temIm[1];
+    data1Im[1] = temIm[2];
+    data2Im[1] = temIm[3];
+    data1Im[2] = temIm[4];
+    data2Im[2] = temIm[5];
+    data1Im[3] = temIm[6];
+    data2Im[3] = temIm[7];
+
+    fft4(data1Re, data1Im);
+    fft4(data2Re, data2Im);
+
+    tem = myfft.OnetoSqrt2 * (data2Re[1] + data2Im[1]);
+    data2Im[1] = myfft.OnetoSqrt2 * (data2Im[1] - data2Re[1]);
+    data2Re[1] = tem;
+    tem = data2Im[2];
+    data2Im[2] = -data2Re[2];
+    data2Re[2] = tem;
+    tem = myfft.OnetoSqrt2 * (data2Im[3] - data2Re[3]);
+    data2Im[3] = -(myfft.OnetoSqrt2) * (data2Re[3] + data2Im[3]);
+    data2Re[3] = tem;
+
+    temRe[0] = data1Re[0] + data2Re[0];
+    temRe[4] = data1Re[0] - data2Re[0];
+    temRe[1] = data1Re[1] + data2Re[1];
+    temRe[5] = data1Re[1] - data2Re[1];
+    temRe[2] = data1Re[2] + data2Re[2];
+    temRe[6] = data1Re[2] - data2Re[2];
+    temRe[3] = data1Re[3] + data2Re[3];
+    temRe[7] = data1Re[3] - data2Re[3];
+
+    temIm[0] = data1Im[0] + data2Im[0];
+    temIm[4] = data1Im[0] - data2Im[0];
+    temIm[1] = data1Im[1] + data2Im[1];
+    temIm[5] = data1Im[1] - data2Im[1];
+    temIm[2] = data1Im[2] + data2Im[2];
+    temIm[6] = data1Im[2] - data2Im[2];
+    temIm[3] = data1Im[3] + data2Im[3];
+    temIm[7] = data1Im[3] - data2Im[3];
+  }   // End of function fft8().
+
+  private static void fft10(fft1d myfft, float[] temRe, float[] temIm) {
+    float data1Re[] = new float[5];
+    float data1Im[] = new float[5];
+    float data2Re[] = new float[5];
+    float data2Im[] = new float[5];
+
+    // To improve the speed, use direct assaignment instead for loop here.
+    data1Re[0] = temRe[0];
+    data2Re[0] = temRe[5];
+    data1Re[1] = temRe[2];
+    data2Re[1] = temRe[7];
+    data1Re[2] = temRe[4];
+    data2Re[2] = temRe[9];
+    data1Re[3] = temRe[6];
+    data2Re[3] = temRe[1];
+    data1Re[4] = temRe[8];
+    data2Re[4] = temRe[3];
+
+    data1Im[0] = temIm[0];
+    data2Im[0] = temIm[5];
+    data1Im[1] = temIm[2];
+    data2Im[1] = temIm[7];
+    data1Im[2] = temIm[4];
+    data2Im[2] = temIm[9];
+    data1Im[3] = temIm[6];
+    data2Im[3] = temIm[1];
+    data1Im[4] = temIm[8];
+    data2Im[4] = temIm[3];
+
+    fft5(myfft, data1Re, data1Im);
+    fft5(myfft, data2Re, data2Im);
+
+    temRe[0] = data1Re[0] + data2Re[0];
+    temRe[5] = data1Re[0] - data2Re[0];
+    temRe[6] = data1Re[1] + data2Re[1];
+    temRe[1] = data1Re[1] - data2Re[1];
+    temRe[2] = data1Re[2] + data2Re[2];
+    temRe[7] = data1Re[2] - data2Re[2];
+    temRe[8] = data1Re[3] + data2Re[3];
+    temRe[3] = data1Re[3] - data2Re[3];
+    temRe[4] = data1Re[4] + data2Re[4];
+    temRe[9] = data1Re[4] - data2Re[4];
+
+    temIm[0] = data1Im[0] + data2Im[0];
+    temIm[5] = data1Im[0] - data2Im[0];
+    temIm[6] = data1Im[1] + data2Im[1];
+    temIm[1] = data1Im[1] - data2Im[1];
+    temIm[2] = data1Im[2] + data2Im[2];
+    temIm[7] = data1Im[2] - data2Im[2];
+    temIm[8] = data1Im[3] + data2Im[3];
+    temIm[3] = data1Im[3] - data2Im[3];
+    temIm[4] = data1Im[4] + data2Im[4];
+    temIm[9] = data1Im[4] - data2Im[4];
+  }   // End of function fft10().
+
+  private static void fftPrime(int radix, float[] temRe, float[] temIm) {
+    // Initial WRe, WIm.
+    float W = 2 * (float) Math.setPI() / radix;
+    float cosW = (float) Math.cos(W);
+    float sinW = -(float) Math.sin(W);
+    float WRe[] = new float[radix];
+    float WIm[] = new float[radix];
+
+    WRe[0] = 1;
+    WIm[0] = 0;
+    WRe[1] = cosW;
+    WIm[1] = sinW;
+
+    for (int i = 2; i < radix; i++) {
+      WRe[i] = cosW * WRe[i - 1] - sinW * WIm[i - 1];
+      WIm[i] = sinW * WRe[i - 1] + cosW * WIm[i - 1];
+    }
+
+    // FFT of prime length data, using DFT, can be improved in the future.
+    float rere, reim, imre, imim;
+    int j, k;
+    int max = (radix + 1) / 2;
+
+    float tem1Re[] = new float[max];
+    float tem1Im[] = new float[max];
+    float tem2Re[] = new float[max];
+    float tem2Im[] = new float[max];
+
+    for (j = 1; j < max; j++) {
+      tem1Re[j] = temRe[j] + temRe[radix - j];
+      tem1Im[j] = temIm[j] - temIm[radix - j];
+      tem2Re[j] = temRe[j] - temRe[radix - j];
+      tem2Im[j] = temIm[j] + temIm[radix - j];
+    }
+
+    for (j = 1; j < max; j++) {
+      temRe[j] = temRe[0];
+      temIm[j] = temIm[0];
+      temRe[radix - j] = temRe[0];
+      temIm[radix - j] = temIm[0];
+      k = j;
+      for (int i = 1; i < max; i++) {
+       rere = WRe[k] * tem1Re[i];
+       imim = WIm[k] * tem1Im[i];
+       reim = WRe[k] * tem2Im[i];
+       imre = WIm[k] * tem2Re[i];
+
+       temRe[radix - j] += rere + imim;
+       temIm[radix - j] += reim - imre;
+       temRe[j] += rere - imim;
+       temIm[j] += reim + imre;
+
+       k = k + j;
+       if (k >= radix)
+         k = k - radix;
+      }
+    }
+    for (j = 1; j < max; j++) {
+      temRe[0] = temRe[0] + tem1Re[j];
+      temIm[0] = temIm[0] + tem2Im[j];
+    }
+  }   // End of function fftPrime().
+}
index 2d2e90cc48d41cbea43ee19f5bc114e0bbc9e8a9..4a52304ccb09d69917d517b80da337be932466d0 100644 (file)
@@ -5,9 +5,11 @@ SRC=${MAINCLASS}.java \
 SRC1=${MAINCLASS}rect.java \
        fft1d.java \
        Matrix1.java
+SRC2=${MAINCLASS}N.java \
+       fft1dN.java \
+       MatrixN.java
 default:
-#      ../../../../buildscript -thread -optimize -mainclass ${MAINCLASS} ${SRC} -o ${MAINCLASS}
-       ../../../../buildscript -thread -optimize -mainclass ${MAINCLASS} ${SRC1} -o ${MAINCLASS}
+       ../../../../buildscript -thread -optimize -mainclass ${MAINCLASS} ${SRC2} -o ${MAINCLASS}
 
 clean:
        rm -rf tmpbuilddirectory