Esempio n. 1
0
  // compute the linear convolution of x and y
  public static Pair<Var, Var> convolve(Pair<Var, Var> x, Pair<Var, Var> y) {
    Pair<Var, Var> a = Pair.from(x._1.solidCopy(), x._2.solidCopy());
    Pair<Var, Var> b = Pair.from(y._1.solidCopy(), y._2.solidCopy());

    for (int i = 0; i < x._1.rowCount(); i++) {
      a._1.addValue(0.0);
      a._2.addValue(0.0);
      b._1.addValue(0.0);
      b._2.addValue(0.0);
    }
    return cconvolve(a, b);
  }
Esempio n. 2
0
  // compute the inverse FFT of x[], assuming its length is a power of 2
  public static Pair<Var, Var> ifft(Pair<Var, Var> x) {
    int N = x._1.rowCount();

    Var im2 = Numeric.from(N, row -> -x._2.value(row));

    // compute forward FFT
    Pair<Var, Var> y = fft(Pair.from(x._1, im2));

    // take conjugate again and divide by N
    Var re3 = Numeric.from(N, row -> y._1.value(row) / N);
    Var im3 = Numeric.from(N, row -> -y._2.value(row) / N);
    return Pair.from(re3, im3);
  }
Esempio n. 3
0
  // compute the circular convolution of x and y
  public static Pair<Var, Var> cconvolve(Pair<Var, Var> x, Pair<Var, Var> y) {

    int len = x._1.rowCount();

    // should probably pad x and y with 0s so that they have same length
    // and are powers of 2
    if ((x._2.rowCount() != len)) {
      throw new RuntimeException("Dimensions don't agree");
    }

    int N = x._1.rowCount();

    // compute FFT of each sequence
    Pair<Var, Var> a = fft(x);
    Pair<Var, Var> b = fft(y);

    // point-wise multiply
    Pair<Var, Var> c = Pair.from(Numeric.fill(len, 0.0), Numeric.fill(len, 0.0));
    for (int i = 0; i < N; i++) {
      c._1.setValue(i, a._1.value(i) * b._1.value(i) - a._2.value(i) * b._2.value(i));
      c._2.setValue(i, a._1.value(i) * b._2.value(i) + a._1.value(i) * b._2.value(i));
    }

    // compute inverse FFT
    return ifft(c);
  }
Esempio n. 4
0
  // compute the FFT of x[], assuming its length is a power of 2
  public static Pair<Var, Var> fft(Pair<Var, Var> x) {

    int N = x._1.rowCount();

    // base case
    if (N == 1) return x;

    // radix 2 Cooley-Tukey FFT
    if (N % 2 != 0) {
      throw new RuntimeException("N is not a power of 2");
    }

    // fft of even terms
    Mapping evenMap = Mapping.empty();
    for (int k = 0; k < N / 2; k++) {
      evenMap.add(2 * k);
    }
    Pair<Var, Var> even = Pair.from(x._1.mapRows(evenMap), x._2.mapRows(evenMap));
    Pair<Var, Var> q = fft(even);

    // fft of odd terms
    Mapping oddMap = Mapping.empty();
    for (int k = 0; k < N / 2; k++) {
      oddMap.add(2 * k + 1);
    }
    Pair<Var, Var> r = fft(Pair.from(x._1.mapRows(oddMap), x._2.mapRows(oddMap)));

    // combine
    Var rey = Numeric.fill(N, 0.0);
    Var imy = Numeric.fill(N, 0.0);
    for (int k = 0; k < N / 2; k++) {
      double kth = -2 * k * Math.PI / N;
      double coskth = Math.cos(kth);
      double sinkth = Math.sin(kth);

      rey.setValue(k, q._1.value(k) + coskth * r._1.value(k) - sinkth * r._2.value(k));
      imy.setValue(k, q._2.value(k) + coskth * r._2.value(k) + sinkth * r._1.value(k));

      rey.setValue(k + N / 2, q._1.value(k) - coskth * r._1.value(k) + sinkth * r._2.value(k));
      imy.setValue(k + N / 2, q._2.value(k) - coskth * r._2.value(k) - sinkth * r._1.value(k));
    }
    return Pair.from(rey, imy);
  }