/* calculates the inverse Fourier transform of signal data (half-complex), * and stores it into fft_results */ int inverse_fft (size_t N, double *data, double *fft_results) { size_t i; int retcode; double *fft_data = (double *) calloc (N, sizeof (double)); /* initialize the data for fft */ for (i=0; i<N; i++) fft_data [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_halfcomplex_radix2_inverse (fft_results, 1, N); gsl_fft_halfcomplex_radix2_unpack (fft_data, fft_results, 1, N); } else { /* alloc memory for real and half-complex wavetables, and workspace */ gsl_fft_halfcomplex_wavetable *hc_wavetable = gsl_fft_halfcomplex_wavetable_alloc (N); gsl_fft_real_workspace *ws = gsl_fft_real_workspace_alloc (N); /* perform the fft */ retcode = gsl_fft_halfcomplex_inverse (fft_data, 1, N, hc_wavetable, ws); gsl_fft_halfcomplex_unpack (fft_data, fft_results, 1, N); /* free memory */ gsl_fft_halfcomplex_wavetable_free (hc_wavetable); gsl_fft_real_workspace_free (ws); } free (fft_data); return retcode; }
static VALUE rb_gsl_fft_halfcomplex_wavetable_new(VALUE klass, VALUE n) { CHECK_FIXNUM(n); return Data_Wrap_Struct(klass, 0, gsl_fft_halfcomplex_wavetable_free, gsl_fft_halfcomplex_wavetable_alloc(FIX2INT(n))); }
/** * The default constructor creates a new workspace of size n. * @param n The size of the workspace. */ explicit wavetable( size_t const n ){ ccgsl_pointer = gsl_fft_halfcomplex_wavetable_alloc( n ); // just plausibly we could allocate wavetable but not count try { count = new size_t; } catch( std::bad_alloc& e ){ // try to tidy up before rethrowing gsl_fft_halfcomplex_wavetable_free( ccgsl_pointer ); throw e; } *count = 1; // initially there is just one reference to ccgsl_pointer }
void ODEfilter(double *data, int nsample, int nfft, ODEparams * pa) { int i, k; gsl_fft_real_wavetable *real; gsl_fft_halfcomplex_wavetable *hc; gsl_fft_real_workspace *work; work = gsl_fft_real_workspace_alloc(nfft); real = gsl_fft_real_wavetable_alloc(nfft); hc = gsl_fft_halfcomplex_wavetable_alloc(nfft); double *filter = (double *) calloc(nfft, sizeof(double)); double *vdata = (double *) calloc(nsample + nfft / 2, sizeof(double)); memcpy(vdata, data, nsample * sizeof(double)); for (i = 0; i < nfft; i++) { double ff = i * 44100.0 / nfft / 2; double fil = gsl_spline_eval(pa->f_spline, ff, pa->f_acc); if (ff > 8000.) fil = 0.0; filter[i] = fil; //printf("%e %e\n", ff, fil); } for (i = 0; i < nsample; i += nfft) { for (k = 0; k < nfft; k++) { (data + i)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); /* hamming window */ (vdata + i + nfft / 2)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); } gsl_fft_real_transform(data + i, 1, nfft, real, work); gsl_fft_real_transform(vdata + i + nfft / 2, 1, nfft, real, work); for (k = 0; k < nfft; k++) { (data + i)[k] = (data + i)[k] * filter[k]; (vdata + i + nfft / 2)[k] = (vdata + i + nfft / 2)[k] * filter[k]; } gsl_fft_halfcomplex_inverse(data + i, 1, nfft, hc, work); gsl_fft_halfcomplex_inverse(vdata + i + nfft / 2, 1, nfft, hc, work); for (k = 0; k < nfft; k++) (data + i)[k] = ((data + i)[k] + (vdata + i)[k]) / 2; } gsl_fft_real_workspace_free(work); gsl_fft_real_wavetable_free(real); gsl_fft_halfcomplex_wavetable_free(hc); }
// Parse argc, argv. obj must be GSL::Vector of halfcomplex data static int gsl_fft_get_argv_halfcomplex(int argc, VALUE *argv, VALUE obj, double **ptr, size_t *stride, size_t *n, gsl_fft_halfcomplex_wavetable **table, gsl_fft_real_workspace **space, int *naflag) { int flag = NONE_OF_TWO, flagtmp, i, itmp = argc, itmp2 = 0, ccc; int flagw = 0; *ptr = get_ptr_double3(obj, n, stride, naflag); ccc = argc; flagtmp = 0; flagw = 0; for (i = argc-1; i >= itmp2; i--) { if (rb_obj_is_kind_of(argv[i], cgsl_fft_real_workspace)) { Data_Get_Struct(argv[i], gsl_fft_real_workspace, *space); flagtmp = 1; flagw = 1; itmp = i; ccc--; break; } } flagtmp = 0; for (i = itmp-1; i >= itmp2; i--) { if (rb_obj_is_kind_of(argv[i], cgsl_fft_halfcomplex_wavetable)) { Data_Get_Struct(argv[i], gsl_fft_halfcomplex_wavetable, *table); flagtmp = 1; ccc--; break; } } if (flagw == 0) { *space = gsl_fft_real_workspace_alloc(*n); flag += ALLOC_SPACE; } if (flagtmp == 0) { *table = gsl_fft_halfcomplex_wavetable_alloc(*n); flag += ALLOC_TABLE; } if (*table == NULL) { rb_raise(rb_eRuntimeError, "something wrong with wavetable"); } if (*space == NULL) { rb_raise(rb_eRuntimeError, "something wrong with workspace"); } return flag; }
int FFTRealTransform::Main() { switch(params.dir) { case FORWARD: work = gsl_fft_real_workspace_alloc (n); real = gsl_fft_real_wavetable_alloc (n); status=gsl_fft_real_transform (y, 1, n, real, work); break; case BACKWARD: work = gsl_fft_real_workspace_alloc (n); hc = gsl_fft_halfcomplex_wavetable_alloc (n); status=gsl_fft_halfcomplex_inverse (y, 1, n, hc, work); break; default: return GSL_FAILURE; } return status; }
void SLIfilter(double *data, int nfft, double * filter) { int i, k; gsl_fft_real_wavetable *real; gsl_fft_halfcomplex_wavetable *hc; gsl_fft_real_workspace *work; work = gsl_fft_real_workspace_alloc(nfft); real = gsl_fft_real_wavetable_alloc(nfft); hc = gsl_fft_halfcomplex_wavetable_alloc(nfft); double *vdata = (double *) calloc(2*nfft+nfft/2, sizeof(double)); memcpy(vdata, data, 2* nfft * sizeof(double)); for (i = 0; i < 2; i ++) { for (k = 0; k < nfft; k++) { (data + i*nfft)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); /* hamming window */ (vdata + i*nfft + nfft / 2)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); } gsl_fft_real_transform(data + i*nfft, 1, nfft, real, work); gsl_fft_real_transform(vdata + i*nfft + nfft / 2, 1, nfft, real, work); for (k = 0; k < nfft; k++) { (data + i*nfft)[k] = (data + i)[k] * filter[k]; (vdata + i*nfft + nfft / 2)[k] = (vdata + i + nfft / 2)[k] * filter[k]; } gsl_fft_halfcomplex_inverse(data + i*nfft, 1, nfft, hc, work); gsl_fft_halfcomplex_inverse(vdata + i*nfft + nfft / 2, 1, nfft, hc, work); for (k = 0; k < nfft; k++) (data + i*nfft)[k] = ((data + i*nfft)[k] + (vdata + i*nfft)[k]) / 2; } gsl_fft_real_workspace_free(work); gsl_fft_real_wavetable_free(real); gsl_fft_halfcomplex_wavetable_free(hc); }
void SmoothFilter::smoothFFT(double *x, double *y) { gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform (y, 1, d_n, real, work);//FFT forward gsl_fft_real_wavetable_free (real); double df = 1.0/(double)(x[1] - x[0]); double lf = df/(double)d_smooth_points;//frequency cutoff df = 0.5*df/(double)d_n; for (int i = 0; i < d_n; i++){ x[i] = d_x[i]; y[i] = i*df > lf ? 0 : y[i];//filtering frequencies } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc (d_n); gsl_fft_halfcomplex_inverse (y, 1, d_n, hc, work);//FFT inverse gsl_fft_halfcomplex_wavetable_free (hc); gsl_fft_real_workspace_free (work); }
static PyObject* PyGSL_transform_space_init(PyObject *self, PyObject *args, const enum pygsl_transform_space_type type) { PyGSL_transform_space *o=NULL; size_t n; FUNC_MESS_BEGIN(); o = (PyGSL_transform_space *) PyObject_NEW(PyGSL_transform_space, &PyGSL_transform_space_pytype); if(o == NULL){ return NULL; } if (0==PyArg_ParseTuple(args,"l", &n)) return NULL; if (n<=0) { pygsl_error("dimension must be >0", filename, __LINE__, GSL_EINVAL); return NULL; } o->type = type; switch(type){ case COMPLEX_WORKSPACE: o->space.cws = gsl_fft_complex_workspace_alloc(n); break; case COMPLEX_WAVETABLE: o->space.cwt = gsl_fft_complex_wavetable_alloc(n); break; case REAL_WORKSPACE: o->space.rws = gsl_fft_real_workspace_alloc(n); break; case REAL_WAVETABLE: o->space.rwt = gsl_fft_real_wavetable_alloc(n); break; case HALFCOMPLEX_WAVETABLE: o->space.hcwt = gsl_fft_halfcomplex_wavetable_alloc(n); break; case COMPLEX_WORKSPACE_FLOAT: o->space.cwsf = gsl_fft_complex_workspace_float_alloc(n); break; case COMPLEX_WAVETABLE_FLOAT: o->space.cwtf = gsl_fft_complex_wavetable_float_alloc(n); break; case REAL_WORKSPACE_FLOAT: o->space.rwsf = gsl_fft_real_workspace_float_alloc(n); break; case REAL_WAVETABLE_FLOAT: o->space.rwtf = gsl_fft_real_wavetable_float_alloc(n); break; case HALFCOMPLEX_WAVETABLE_FLOAT: o->space.hcwtf = gsl_fft_halfcomplex_wavetable_float_alloc(n); break; #ifdef _PYGSL_GSL_HAS_WAVELET case WAVELET_WORKSPACE : o->space.wws = gsl_wavelet_workspace_alloc(n); break; #endif default: pygsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); return NULL; break; } assert(o->space.v); FUNC_MESS_END(); return (PyObject *) o; }
void FFTFilter::calculateOutputData(double *x, double *y) { // interpolate y to even spacing double delta=(d_x[d_n-1]-d_x[0])/d_n; double xi=d_x[0]; for (int i=0, j=0; j<d_n && xi<=d_x[d_n-1]; j++) { x[j]=xi; if (i<d_n-1) y[j]=((d_x[i+1]-xi)*d_y[i] + (xi-d_x[i])*d_y[i+1])/(d_x[i+1]-d_x[i]); else y[j]=d_y[d_n-1]; xi+=delta; while (i<d_n && xi>d_x[i]) i++; } double df = 1.0/(x[d_n-1]-x[0]); gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform (y, 1, d_n, real, work); gsl_fft_real_wavetable_free (real); d_explanation = QLocale().toString(d_low_freq) + " "; if (d_filter_type > 2) d_explanation += tr("to") + " " + QLocale().toString(d_high_freq) + " "; d_explanation += tr("Hz") + " "; switch ((int)d_filter_type) { case 1://low pass d_explanation += tr("Low Pass FFT Filter"); for (int i = d_n-1; i >= 0 && ((i+1)/2)*df > d_low_freq; i--) y[i] = 0; break; case 2://high pass d_explanation += tr("High Pass FFT Filter"); for (int i = 0; i < d_n && ((i+1)/2)*df < d_low_freq; i++) y[i] = 0; break; case 3://band pass d_explanation += tr("Band Pass FFT Filter"); for (int i = d_offset ? 1 : 0; i < d_n; i++) if ((((i+1)/2)*df <= d_low_freq ) || (((i+1)/2)*df >= d_high_freq )) y[i] = 0; break; case 4://band block d_explanation += tr("Band Block FFT Filter"); if(!d_offset) y[0] = 0;//substract DC offset for (int i = 1; i < d_n; i++) if ((((i+1)/2)*df > d_low_freq ) && (((i+1)/2)*df < d_high_freq )) y[i] = 0; break; } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc (d_n); gsl_fft_halfcomplex_inverse (y, 1, d_n, hc, work); gsl_fft_halfcomplex_wavetable_free (hc); gsl_fft_real_workspace_free (work); }
void FFTFilter::calculateOutputData(double *x, double *y) { for (int i = 0; i < d_points; i++) { x[i] = d_x[i]; y[i] = d_y[i]; } double df = 0.5 / (double)(d_n * (x[1] - x[0])); // half frequency sampling due to GSL storing gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform(y, 1, d_n, real, work); gsl_fft_real_wavetable_free(real); ApplicationWindow *app = dynamic_cast<ApplicationWindow *>(parent()); QLocale locale = app->locale(); d_explanation = locale.toString(d_low_freq) + " "; if (d_filter_type > 2) d_explanation += tr("to") + " " + locale.toString(d_high_freq) + " "; d_explanation += tr("Hz") + " "; switch ((int)d_filter_type) { case 1: // low pass d_explanation += tr("Low Pass FFT Filter"); for (int i = 0; i < d_n; i++) y[i] = i * df > d_low_freq ? 0 : y[i]; break; case 2: // high pass d_explanation += tr("High Pass FFT Filter"); for (int i = 0; i < d_n; i++) y[i] = i * df < d_low_freq ? 0 : y[i]; break; case 3: // band pass d_explanation += tr("Band Pass FFT Filter"); if (d_offset) { // keep DC offset for (int i = 1; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? y[i] : 0; } else { for (int i = 0; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? y[i] : 0; } break; case 4: // band block d_explanation += tr("Band Block FFT Filter"); if (!d_offset) y[0] = 0; // substract DC offset for (int i = 1; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? 0 : y[i]; break; } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc(d_n); gsl_fft_halfcomplex_inverse(y, 1, d_n, hc, work); gsl_fft_halfcomplex_wavetable_free(hc); gsl_fft_real_workspace_free(work); }