Пример #1
0
/* calculates the inverse fast Fourier transform of a complex packed array, and stores
 * it into fft_results. Storage conventions as for complex_fft */
int complex_inverse_fft (size_t N, double *data, double *fft_results) {
  size_t i;
  int retcode;

  /* initialize the data for fft */
  for (i=0; i<2*N; i++) fft_results [i] = data [i];

  /* use the corresponding routine if N is power of 2 */
  if (is_power_of_n (N,2)) {
    /* perform the fft */
    retcode = gsl_fft_complex_radix2_inverse (fft_results, 1, N);
  }
  else {
    /* alloc memory for wavetable and workspace */
    gsl_fft_complex_wavetable * wavetable = gsl_fft_complex_wavetable_alloc (N);
    gsl_fft_complex_workspace * workspace = gsl_fft_complex_workspace_alloc (N);

    /* perform the fft */
    retcode = gsl_fft_complex_inverse (fft_results, 1, N, wavetable, workspace);

    /* free memory */
    gsl_fft_complex_wavetable_free (wavetable);
    gsl_fft_complex_workspace_free (workspace);
  }
  return retcode;
}
Пример #2
0
QuantityType fftgtof(const QuantityType& g, double rstep, double rmin)
{
    if (g.empty())  return g;
    int padrmin = int(round(rmin / rstep));
    int Npad1 = padrmin + g.size();
    // pad to the next power of 2 for fast Fourier transformation
    int Npad2 = (1 << int(ceil(log2(Npad1))));
    // sine transformations needs an odd extension
    // gpadc array has to be doubled for complex coefficients
    int Npad4 = 4 * Npad2;
    valarray<double> gpadc(0.0, Npad4);
    QuantityType::const_iterator gi;
    // copy the original g signal
    int ilo = padrmin;
    for (gi = g.begin(); gi != g.end(); ++gi, ++ilo)
    {
        gpadc[2 * ilo] = *gi;
    }
    // copy the odd part of g skipping the first point,
    // because it is periodic image of gpadc[0]
    int ihi = 2 * Npad2 - 1;
    for (ilo = 1; ilo < Npad2; ++ilo, --ihi)
    {
        gpadc[2 * ihi] = -1 * gpadc[2 * ilo];
    }
    int status;
    status = gsl_fft_complex_radix2_inverse(&(gpadc[0]), 1, 2 * Npad2);
    if (status != GSL_SUCCESS)  throw invalid_argument(EMSGFFT);
    QuantityType f(Npad2);
    for (int i = 0; i < Npad2; ++i)
    {
        f[i] = gpadc[2 * i + 1] * Npad2 * rstep;
    }
    // real components should be all close to zero
    assert(fabs(valarray<double>(gpadc[slice(0, 2 * Npad2, 2)]).min()) <=
            SQRT_DOUBLE_EPS * gpadc.max());
    assert(fabs(valarray<double>(gpadc[slice(0, 2 * Npad2, 2)]).max()) <=
            SQRT_DOUBLE_EPS * gpadc.max());
    return f;
}
Пример #3
0
/*
 * Extracting information from a noisy signal
 */
void extract_noisy_signal(int count, double *values) {
    plot_t p;

    p.outfile = "output5.png";
    p.title = "Noisy signal";
    p.xlabel = "t [s]";
    p.ylabel = "u(t) [m]";
    p.xmin = 0;
    p.xmax = 0;
    init_gnuplot(&p);

    gsl_complex_packed_array data = calloc(2*count, sizeof(double));

    // Noisy signal
    BEGIN_SCATTER(p, "u(t)");

    double t = 0;

    for (int i = 0; i < count; i++) {
        PLOT(p, t, values[i]);
        data[2*i] = values[i];
        t += 1.0/count;
    }

    END_PLOT(p);

    p.outfile = "output6.png";
    p.title = "FFT of noisy signal";
    p.xlabel = "f [Hz]";
    p.ylabel = "U(f) [m]";
    p.xmin = -1500;
    p.xmax = 1500;
    init_gnuplot(&p);

    gsl_fft_complex_radix2_forward(data, 1, count);

    // FFT of noisy signal
    BEGIN_SCATTER(p, "U(f)");

    double f = -count/2;

    for (int i = count; i < 2*count; i += 2) {
        double y = data[i];
        data[i] = H(f) * data[i];
        data[i+1] = H(f) * data[i+1];
        PLOT(p, f, y);
        f += 1.0;
    }

    for (int i = 0; i < count; i += 2) {
        double y = data[i];
        data[i] = H(f) * data[i];
        data[i+1] = H(f) * data[i+1];
        PLOT(p, f, y);
        f += 1.0;
    }

    END_PLOT(p);

    gsl_fft_complex_radix2_inverse(data, 1, count);

    p.outfile = "output7.png";
    p.title = "Inverse FFT of data";
    p.xlabel = "t [s]";
    p.ylabel = "u(t) [m]";
    p.xmin = 0;
    p.xmax = 1;
    init_gnuplot(&p);

    // Filtered signal
    BEGIN_PLOT(p, "u(t)");

    t = 0;

    double umax = 0;
    int periods = 0;
    char letter = 0;
    int bits = 0;
    const double plen = 0.0078;

    for (int i = 0; i < 2*count; i += 2) {
        if (t >= plen * (double)periods && t < plen * ((double)periods + 1.0)) {
            if (data[i] > umax) umax = data[i];
        } else {
            if (umax < 1) letter *= 2;
            else letter = letter*2 + 1;
            bits++;
            if (bits % 8 == 0) {
                printf("%c", letter);
                bits = 0;
                letter = 0;
            }
            umax = 0;
            periods++;
        }

        PLOT(p, t, (data[i]));
        t += 1.0/count;
    }
    if (umax < 1) letter *= 2;
    else letter = letter*2 + 1;
    printf("%c\n", letter);

    END_PLOT(p);
}