Olivier Marty 8 éve
szülő
commit
fc138a4481
3 módosított fájl, 56 hozzáadás és 136 törlés
  1. 54 0
      code/FFT.cpp
  2. 0 134
      code/FFT_new.cc
  3. 2 2
      main.tex

+ 54 - 0
code/FFT.cpp

@@ -0,0 +1,54 @@
+struct cpx{
+  cpx(){}
+  cpx(double aa):a(aa) {}
+  cpx(double aa, double bb):a(aa),b(bb) {}
+  double a;
+  double b;
+  double modsq(void) const {
+    return a * a + b * b;
+  }
+  cpx bar(void) const {
+    return cpx(a, -b);
+  }
+};
+cpx operator +(cpx a, cpx b) {
+  return cpx(a.a + b.a, a.b + b.b);
+}
+cpx operator *(cpx a, cpx b) {
+  return cpx(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a);
+}
+cpx operator /(cpx a, cpx b) {
+  cpx r = a * b.bar();
+  return cpx(r.a / b.modsq(), r.b / b.modsq());
+}
+cpx EXP(double theta) {
+  return cpx(cos(theta),sin(theta));
+}
+const double two_pi = 4 * acos(0);
+// in:     input array
+// out:    output array
+// step:   {SET TO 1} (used internally)
+// size:   length of the input/output {MUST BE A POWER OF 2} (use nextPowerOf2)
+// dir:    either plus or minus one (direction of the FFT)
+// RESULT: out[k] = \sum_{j=0}^{size - 1} in[j] * exp(dir * 2pi * i * j * k / size)
+void FFT(cpx *in, cpx *out, int step, int size, int dir) {
+  if(size < 1) return;
+  if(size == 1) {
+    out[0] = in[0];
+    return;
+  }
+  FFT(in, out, step * 2, size / 2, dir);
+  FFT(in + step, out + size / 2, step * 2, size / 2, dir);
+  for(int i = 0 ; i < size / 2 ; i++) {
+    cpx even = out[i];
+    cpx odd = out[i + size / 2];
+    out[i] = even + EXP(dir * two_pi * i / size) * odd;
+    out[i + size / 2] = even + EXP(dir * two_pi * (i + size / 2) / size) * odd;
+  }
+}
+unsigned int nextPowerOf2(unsigned int n) {
+    unsigned int p = 1;
+    if (n && !(n & (n - 1))) return n;
+    while (p < n) p <<= 1;
+    return p;
+}

+ 0 - 134
code/FFT_new.cc

@@ -1,134 +0,0 @@
-#include <cassert>
-#include <cstdio>
-#include <cmath>
-
-struct cpx
-{
-  cpx(){}
-  cpx(double aa):a(aa){}
-  cpx(double aa, double bb):a(aa),b(bb){}
-  double a;
-  double b;
-  double modsq(void) const
-  {
-    return a * a + b * b;
-  }
-  cpx bar(void) const
-  {
-    return cpx(a, -b);
-  }
-};
-
-cpx operator +(cpx a, cpx b)
-{
-  return cpx(a.a + b.a, a.b + b.b);
-}
-
-cpx operator *(cpx a, cpx b)
-{
-  return cpx(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a);
-}
-
-cpx operator /(cpx a, cpx b)
-{
-  cpx r = a * b.bar();
-  return cpx(r.a / b.modsq(), r.b / b.modsq());
-}
-
-cpx EXP(double theta)
-{
-  return cpx(cos(theta),sin(theta));
-}
-
-const double two_pi = 4 * acos(0);
-
-// in:     input array
-// out:    output array
-// step:   {SET TO 1} (used internally)
-// size:   length of the input/output {MUST BE A POWER OF 2}
-// dir:    either plus or minus one (direction of the FFT)
-// RESULT: out[k] = \sum_{j=0}^{size - 1} in[j] * exp(dir * 2pi * i * j * k / size)
-void FFT(cpx *in, cpx *out, int step, int size, int dir)
-{
-  if(size < 1) return;
-  if(size == 1)
-  {
-    out[0] = in[0];
-    return;
-  }
-  FFT(in, out, step * 2, size / 2, dir);
-  FFT(in + step, out + size / 2, step * 2, size / 2, dir);
-  for(int i = 0 ; i < size / 2 ; i++)
-  {
-    cpx even = out[i];
-    cpx odd = out[i + size / 2];
-    out[i] = even + EXP(dir * two_pi * i / size) * odd;
-    out[i + size / 2] = even + EXP(dir * two_pi * (i + size / 2) / size) * odd;
-  }
-}
-
-// Usage:
-// f[0...N-1] and g[0..N-1] are numbers
-// Want to compute the convolution h, defined by
-// h[n] = sum of f[k]g[n-k] (k = 0, ..., N-1).
-// Here, the index is cyclic; f[-1] = f[N-1], f[-2] = f[N-2], etc.
-// Let F[0...N-1] be FFT(f), and similarly, define G and H.
-// The convolution theorem says H[n] = F[n]G[n] (element-wise product).
-// To compute h[] in O(N log N) time, do the following:
-//   1. Compute F and G (pass dir = 1 as the argument).
-//   2. Get H by element-wise multiplying F and G.
-//   3. Get h by taking the inverse FFT (use dir = -1 as the argument)
-//      and *dividing by N*. DO NOT FORGET THIS SCALING FACTOR.
-
-int main(void)
-{
-  printf("If rows come in identical pairs, then everything works.\n");
-  
-  cpx a[8] = {0, 1, cpx(1,3), cpx(0,5), 1, 0, 2, 0};
-  cpx b[8] = {1, cpx(0,-2), cpx(0,1), 3, -1, -3, 1, -2};
-  cpx A[8];
-  cpx B[8];
-  FFT(a, A, 1, 8, 1);
-  FFT(b, B, 1, 8, 1);
-  
-  for(int i = 0 ; i < 8 ; i++)
-  {
-    printf("%7.2lf%7.2lf", A[i].a, A[i].b);
-  }
-  printf("\n");
-  for(int i = 0 ; i < 8 ; i++)
-  {
-    cpx Ai(0,0);
-    for(int j = 0 ; j < 8 ; j++)
-    {
-      Ai = Ai + a[j] * EXP(j * i * two_pi / 8);
-    }
-    printf("%7.2lf%7.2lf", Ai.a, Ai.b);
-  }
-  printf("\n");
-  
-  cpx AB[8];
-  for(int i = 0 ; i < 8 ; i++)
-    AB[i] = A[i] * B[i];
-  cpx aconvb[8];
-  FFT(AB, aconvb, 1, 8, -1);
-  for(int i = 0 ; i < 8 ; i++)
-    aconvb[i] = aconvb[i] / 8;
-  for(int i = 0 ; i < 8 ; i++)
-  {
-    printf("%7.2lf%7.2lf", aconvb[i].a, aconvb[i].b);
-  }
-  printf("\n");
-  for(int i = 0 ; i < 8 ; i++)
-  {
-    cpx aconvbi(0,0);
-    for(int j = 0 ; j < 8 ; j++)
-    {
-      aconvbi = aconvbi + a[j] * b[(8 + i - j) % 8];
-    }
-    printf("%7.2lf%7.2lf", aconvbi.a, aconvbi.b);
-  }
-  printf("\n");
-  
-  return 0;
-}

+ 2 - 2
main.tex

@@ -85,7 +85,7 @@ Temps de cuisson : $O(n)$
 {\scriptsize\lstinputlisting{code/Geometry.cc}}
 
 \subsection{Slow Delaunay triangulation}
-{\scriptsize\lstinputlisting{code/Delaunay.cc}}
+{\scriptsize\lstinputlisting{code/Delaunay.cc}} % TODO chercher algo en N (incremental flip)
 
 \section{Algorithmes numériques}
 
@@ -99,7 +99,7 @@ Temps de cuisson : $O(n)$
 {\scriptsize\lstinputlisting{code/ReducedRowEchelonForm.cc}}
 
 \subsection{Fast Fourier transform}
-{\scriptsize\lstinputlisting{code/FFT_new.cc}}
+{\scriptsize\lstinputlisting{code/FFT.cpp}} % OK
 
 \subsection{Simplex algorithm}
 {\scriptsize\lstinputlisting{code/Simplex.cc}}