Beispiel #1
0
void Test::test_PolyMult_works() {
  srand(time(0));

  int n = 4;

  int randMin = -100, randMax = 100;

  Vector<Complex> P(n), Q(n);

  for(int i = 0; i < n; ++i) {

    double real = rand()%(randMax-randMin)+randMin;
    double imaginary = rand()%(randMax-randMin)+randMin;

    P[i] = Complex(real, imaginary);
    Q[i] = Complex(real, imaginary);
  }

  FFT fft;

  fft.preComputeOmega(n);
  Vector<Complex> resultsR = fft.polyMultR(P, Q, n);
  fft.preComputeRBS(n);
  Vector<Complex> resultsD = fft.polyMultD(P, Q, n);

  for(int i = 0; i < n; ++i) {
    if(resultsD[i] != resultsR[i])
      std::cout << "*** Failed ***" << std::endl;

    std::cout << resultsR[i] << " " << resultsD[i] << std::endl;
  }
}
Beispiel #2
0
void Test::test_PolyMult_dynamic() {
  int n = 2;
  Vector<Complex> P(n),Q(n);

  P[0] = Complex(2,0);
  P[1] = Complex(2,0);

  Q[0] = Complex(2,0);
  Q[1] = Complex(2,0);

  FFT fft;

  fft.preComputeOmega(n);
  fft.preComputeRBS(n);
  Vector<Complex> results = fft.polyMultD(P, Q, n);

  for(Complex c : results) {
    std::cout << c << std::endl;
  }
}
Beispiel #3
0
void Test::test_FFT_works() {
  srand(time(0));

  int n = 4;
  Vector<Complex> P(n);

  int randMin = -100, randMax = 100;

  for(int i = 0; i < n; ++i) {

    double real = rand()%(randMax-randMin)+randMin;
    double imaginary = rand()%(randMax-randMin)+randMin;

    P[i] = Complex(real, imaginary);
  }

  // P[0] = Complex(2,0);
  // P[1] = Complex(2,0);
  // P[2] = Complex(2,0);
  // P[3] = Complex(2,0);

  Vector<Complex> x = Vector<Complex> (n);

  for(int i = 0; i < n; i++) {
    x[i] = Complex(cos(2*PI/n * i), sin(2*PI/n * i));
  }

  FFT fft;
  fft.preComputeRBS(n);

  Vector<Complex> algebraic = fft.algebraic(P, n, x);
  Vector<Complex> recursive = fft.recursive(P, n, x, 1);
  Vector<Complex> dynamic = fft.dynamic(P, n, x);

  for(int i = 0; i < n; ++i) {
    std::cout << "A(" << i << "): " << algebraic[i] << std::endl;
    std::cout << "R(" << i << "): " << recursive[i] << std::endl;
    std::cout << "D(" << i << "): " << dynamic[i] << std::endl;
    std::cout << std::endl;
  }
}
Beispiel #4
0
void Test::run_FFT_dynamic() {
  int minN = 32, maxN = 20000000;

  std::cout << "FFT dynamic" << std::endl
            << "N" << '\t' << "Time" << std::endl;

  for(int n = minN; n <= maxN; n*=2) {

    FFT fft;
    fft.preComputeRBS(n);
    fft.preComputeOmega(n);

    int runTime = averageRuntime([&](){

      Vector<Complex> P = fft.makeRandomVector(n, -1, 1);
      Vector<Complex> Q = fft.makeRandomVector(n, -1, 1);

      Vector<Complex> result = fft.polyMultD(P, Q, n);

    }, RUNS);

    std::cout << n << '\t' << runTime << std::endl;
  }
}
Beispiel #5
0
void Test::test_FFT_vs_previous_approaches() {
  std::cout << "Simple Test" << std::endl;

  {
    int n = 2;
    double p[] = {3,5};
    double q[] = {2,1};

    Vector<double> P(p, p+n);
    Vector<double> Q(q, q+n);

    Vector<Complex> PFFT (P.begin(), P.end());
    Vector<Complex> QFFT (Q.begin(), Q.end());

    PolyMult polyMultSB;
    Vector<double> pqActualSB = polyMultSB.schoolBook(n, P, Q);

    PolyMult polyMultDnC4;
    std::vector<double> pqActualDnC4 = polyMultDnC4.divideAndConquer4(n, P, Q);

    PolyMult polyMultDnC3;
    std::vector<double> pqActualDnC3 = polyMultDnC3.divideAndConquer3(n, P, Q);

    FFT fft;
    fft.preComputeOmega(n);
    Vector<Complex> pqActualFFTR = fft.polyMultR(PFFT, QFFT, n);
    fft.preComputeRBS(n);
    Vector<Complex> pqActualFFTD = fft.polyMultD(PFFT, QFFT, n);

    double pqExpected[] = {6,13,5};

    int w1 = 10;

    std::cout << std::setw(w1) << "Expected"
              << std::setw(w1) << "SB"
              << std::setw(w1) << "DnC 4"
              << std::setw(w1) << "DnC 3"
              << std::setw(w1) << "FFT R"
              << std::setw(w1) << "FFT D"
              << std::endl;

    std::cout << std::right;

    for(int index = 0; index < 2*n-1; ++index) {
      std::cout << std::setw(w1) << pqExpected[index]
                << std::setw(w1) << pqActualSB[index]
                << std::setw(w1) << pqActualDnC4[index]
                << std::setw(w1) << pqActualDnC3[index]
                << std::setw(w1) << pqActualFFTR[index].real()
                << std::setw(w1) << pqActualFFTD[index].real()
                << std::endl;
    }
  }

  std::cout << std::endl
            << "Random Test" << std::endl;

  {
    srand(time(0));

    int n = 8;
    int randMin = 0, randMax = 100;

    Vector<double> P(n), Q(n);

    Vector<Complex> PFFT(n), QFFT(n);

    for(int i = 0; i < n; ++i) {
      double randomP = rand()%(randMax-randMin)+randMin;
      double randomQ = rand()%(randMax-randMin)+randMin;

      P[i] = randomP;
      Q[i] = randomQ;

      PFFT[i] = Complex(randomP, 0);
      QFFT[i] = Complex(randomQ, 0);
    }

    PolyMult polyMultSB;
    Vector<double> pqActualSB = polyMultSB.schoolBook(n, P, Q);

    PolyMult polyMultDnC4;
    std::vector<double> pqActualDnC4 = polyMultDnC4.divideAndConquer4(n, P, Q);

    PolyMult polyMultDnC3;
    std::vector<double> pqActualDnC3 = polyMultDnC3.divideAndConquer3(n, P, Q);

    FFT fft;
    fft.preComputeOmega(n);
    Vector<Complex> pqActualFFTR = fft.polyMultR(PFFT, QFFT, n);
    fft.preComputeRBS(n);
    Vector<Complex> pqActualFFTD = fft.polyMultD(PFFT, QFFT, n);

    int w1 = 10;

    std::cout << std::setw(w1) << "SB"
              << std::setw(w1) << "DnC 4"
              << std::setw(w1) << "DnC 3"
              << std::setw(w1) << "FFT R"
              << std::setw(w1) << "FFT D"
              << std::endl;

    std::cout << std::right << std::fixed;

    for(int index = 0; index < 2*n-1; ++index) {
      std::cout << std::setprecision(0) << std::setw(w1) << pqActualSB[index]
                << std::setprecision(0) << std::setw(w1) << pqActualDnC4[index]
                << std::setprecision(0) << std::setw(w1) << pqActualDnC3[index]
                << std::setprecision(0) << std::setw(w1) << pqActualFFTR[index].real()
                << std::setprecision(0) << std::setw(w1) << pqActualFFTD[index].real()
                << std::endl;
    }
  }
}