int dconvolve(const double *data, int ndata, const double *syn, int nsyn, double *conv) { int nextpow2(); void cfft(); int ncorr,n_max,i; dcomplex *cdata,*csyn,*ccorr; if (ndata <=0 || nsyn <=0) { fprintf(stderr,"No data or syn is read in ...\n"); return -1; } ncorr = ndata+nsyn-1; // length of correlation time series n_max = nextpow2(ncorr); // closest 2 power // dynamic allocate array to avoid defining upper limit of the length cdata = (dcomplex *) malloc(n_max * sizeof(dcomplex)); csyn = (dcomplex *) malloc(n_max * sizeof(dcomplex)); ccorr = (dcomplex *) malloc(n_max * sizeof(dcomplex)); // set complex data and syn array for (i=0; i<ndata; i++) {cdata[i].re = data[i]; cdata[i].im = 0.;} for (i=ndata; i<n_max; i++) cdata[i].re = cdata[i].im = 0.; for (i=0; i<nsyn; i++) {csyn[i].re = syn[i]; csyn[i].im = 0.;} for (i=nsyn; i<n_max; i++) csyn[i].re = csyn[i].im = 0.; // fft both complex data and syn array cfft(cdata,n_max,1); cfft(csyn,n_max,1); // in frequency domain, calculate the fft of correlation for (i=0;i<n_max;i++) ccorr[i] = dcmult(cdata[i],csyn[i]); // fft back to get the correlation time series cfft(ccorr,n_max,-1); for (i=0;i<ncorr;i++) conv[i] = ccorr[i].re/n_max; free(cdata); free(csyn); free(ccorr); return ncorr; }
void psdcmean(float *rsbuf, float *cpsd, int lblock, int nblocks) { float *pinput; int i, j; float tmpinbuf[2048]; float result[512]; /* check space */ if (lblock > 1024) { printf("not enough temp space\b"); exit(EXIT_FAILURE); } /* clear array result before accumulating new data */ for (i = 0; i < (lblock / 2); i++) { result[i] = 0.0; } /* loop over all blocks taking care to keep track of ptr in input */ pinput = rsbuf; for (j = 0; j < nblocks; j++) { /* Now fill tmpinbuf with converted data from input */ for (i = 0; i < lblock; i++) { tmpinbuf[i * 2] = pinput[2 * i]; tmpinbuf[i * 2 + 1] = pinput[2 * i + 1]; } cfft(tmpinbuf, lblock / 2, 1); for (i = 1; i < lblock / 2; ++i) { result[i] += sqrt(tmpinbuf[i * 2] * tmpinbuf[i * 2] + tmpinbuf[i * 2 + 1] * tmpinbuf[i * 2 + 1]); } pinput += 2 * lblock; /* update pointer in input data */ } for (i = 0; i < lblock / 2; i++) { result[i] = (float) (10.0 * log(result[i] + 1.0e-8) / 2.305 - 14.0); } /* interchange halfs of cpsd buffer as in matlab code from plot_input_spectrum in diorama */ for (i = 1; i < lblock / 4; i++) { cpsd[i] = result[lblock / 4 + i]; cpsd[i + lblock / 4 - 1] = result[i]; } }
LVAL xsfft(V) { LVAL data, result, x, work; int n, isign; data = xlgaseq(); isign = (moreargs() && xlgetarg() != NIL) ? -1.0 : 1.0; xllastarg(); /* check and convert the data */ n = seqlen(data); if (n <= 0) xlfail("not enough data"); xlstkcheck(2); xlsave(x); xlsave(work); x = gen2linalg(data, n, 1, s_c_dcomplex, FALSE); work = mktvec(4 * n + 15, s_c_double); cfft(n, REDAT(x), REDAT(work), isign); result = listp(x) ? coerce_to_list(x) : coerce_to_tvec(x, s_true); xlpopn(2); return result; }
void ifft(dcomplex *v, int n, dcomplex *tmp) { for (int i = 0; i < n; i++) { v[i] = conj(v[i]); } cfft(v, n, tmp); for (int i = 0; i < n; i++) { dcomplex t = conj(v[i]) / ((double) n); v[i] = t; } return; }
int main(void) { std::size_t i; scitbx::fftpack::complex_to_complex<double> cfft(10); std::vector<std::complex<double> > vc(cfft.n()); for(i=0;i<cfft.n();i++) { vc[i] = std::complex<double>(2.*i, 2.*i+1.); } cfft.forward(vc.begin()); for(i=0;i<cfft.n();i++) { std::cout << vc[i].real() << " " << vc[i].imag() << std::endl; } cfft.backward(vc.begin()); for(i=0;i<cfft.n();i++) { std::cout << vc[i].real() << " " << vc[i].imag() << std::endl; } scitbx::fftpack::real_to_complex<double> rfft(10); std::vector<double> vr(2 * rfft.n_complex()); for(i=0;i<rfft.n_real();i++) { vr[i] = 1.*i; } rfft.forward(vr.begin()); for(i=0;i<2*rfft.n_complex();i++) { std::cout << vr[i] << std::endl; } rfft.backward(vr.begin()); for(i=0;i<rfft.n_real();i++) { std::cout << vr[i] << std::endl; } scitbx::fftpack::complex_to_complex_3d<double> cfft3d(2, 3, 5); scitbx::af::versa<std::complex<double>, scitbx::af::c_grid<3> > c3dmap(scitbx::af::c_grid<3>(cfft3d.n())); cfft3d.forward(c3dmap.ref()); cfft3d.backward(c3dmap.ref()); scitbx::fftpack::real_to_complex_3d<double> rfft3d(3, 4, 5); scitbx::af::versa<double, scitbx::af::c_grid<3> > r3dmap(scitbx::af::c_grid<3>(rfft3d.m_real())); rfft3d.forward(r3dmap.ref()); rfft3d.backward(r3dmap.ref()); #ifdef NEVER_DEFINED #endif return 0; }
//----------------------------------------------------------------------------- // name: rfft() // desc: real value fft // // these routines from the CARL software, spect.c // check out the CARL CMusic distribution for more source code // // if forward is true, rfft replaces 2*N real data points in x with N complex // values representing the positive frequency half of their Fourier spectrum, // with x[1] replaced with the real part of the Nyquist frequency value. // // if forward is false, rfft expects x to contain a positive frequency // spectrum arranged as before, and replaces it with 2*N real values. // // N MUST be a power of 2. // //----------------------------------------------------------------------------- void rfft( float * x, long N, unsigned int forward ) { static int first = 1 ; float c1, c2, h1r, h1i, h2r, h2i, wr, wi, wpr, wpi, temp, theta ; float xr, xi ; long i, i1, i2, i3, i4, N2p1 ; if( first ) { PI = (float) (4.*atan( 1. )) ; TWOPI = (float) (8.*atan( 1. )) ; first = 0 ; } theta = PI/N ; wr = 1. ; wi = 0. ; c1 = 0.5 ; if( forward ) { c2 = -0.5 ; cfft( x, N, forward ) ; xr = x[0] ; xi = x[1] ; } else { c2 = 0.5 ; theta = -theta ; xr = x[1] ; xi = 0. ; x[1] = 0. ; } wpr = (float) (-2.*pow( sin( 0.5*theta ), 2. )) ; wpi = (float) sin( theta ) ; N2p1 = (N<<1) + 1 ; for( i = 0 ; i <= N>>1 ; i++ ) { i1 = i<<1 ; i2 = i1 + 1 ; i3 = N2p1 - i2 ; i4 = i3 + 1 ; if( i == 0 ) { h1r = c1*(x[i1] + xr ) ; h1i = c1*(x[i2] - xi ) ; h2r = -c2*(x[i2] + xi ) ; h2i = c2*(x[i1] - xr ) ; x[i1] = h1r + wr*h2r - wi*h2i ; x[i2] = h1i + wr*h2i + wi*h2r ; xr = h1r - wr*h2r + wi*h2i ; xi = -h1i + wr*h2i + wi*h2r ; } else { h1r = c1*(x[i1] + x[i3] ) ; h1i = c1*(x[i2] - x[i4] ) ; h2r = -c2*(x[i2] + x[i4] ) ; h2i = c2*(x[i1] - x[i3] ) ; x[i1] = h1r + wr*h2r - wi*h2i ; x[i2] = h1i + wr*h2i + wi*h2r ; x[i3] = h1r - wr*h2r + wi*h2i ; x[i4] = -h1i + wr*h2i + wi*h2r ; } wr = (temp = wr)*wpr - wi*wpi + wr ; wi = wi*wpr + temp*wpi + wi ; } if( forward ) x[1] = xr ; else cfft( x, N, forward ) ; }
void rfft(float x[], int N, int forward) { float c1,c2, h1r,h1i, h2r,h2i, wr,wi, wpr,wpi, temp, theta; float xr,xi; int i, i1,i2,i3,i4, N2p1; // static int first = 1; theta = PI/N; wr = 1.; wi = 0.; c1 = 0.5; if ( forward ) { c2 = -0.5; cfft( x, N, forward ); xr = x[0]; xi = x[1]; } else { c2 = 0.5; theta = -theta; xr = x[1]; xi = 0.; x[1] = 0.; } wpr = -2.*powf( sinf( 0.5*theta ), 2. ); wpi = sinf( theta ); N2p1 = (N<<1) + 1; for ( i = 0; i <= N>>1; i++ ) { i1 = i<<1; i2 = i1 + 1; i3 = N2p1 - i2; i4 = i3 + 1; if ( i == 0 ) { h1r = c1*(x[i1] + xr ); h1i = c1*(x[i2] - xi ); h2r = -c2*(x[i2] + xi ); h2i = c2*(x[i1] - xr ); x[i1] = h1r + wr*h2r - wi*h2i; x[i2] = h1i + wr*h2i + wi*h2r; xr = h1r - wr*h2r + wi*h2i; xi = -h1i + wr*h2i + wi*h2r; } else { h1r = c1*(x[i1] + x[i3] ); h1i = c1*(x[i2] - x[i4] ); h2r = -c2*(x[i2] + x[i4] ); h2i = c2*(x[i1] - x[i3] ); x[i1] = h1r + wr*h2r - wi*h2i; x[i2] = h1i + wr*h2i + wi*h2r; x[i3] = h1r - wr*h2r + wi*h2i; x[i4] = -h1i + wr*h2i + wi*h2r; } wr = (temp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + temp*wpi + wi; } if ( forward ) x[1] = xr; else cfft( x, N, forward ); }
void vspectra(void) { int i, j, k, kk, num, numm, i4, maxi, r; int m, mm, blsiz, blsiz2, nsam, n_read; double avsig, av, max, min, noise, wid; uint8_t *bufferRead = malloc((NSAM) * sizeof(uint8_t)); static double vspec[NSPEC]; static int wtt[NSPEC]; static double re[NSPEC * 2], am[NSPEC * 2]; double smax; fftwf_plan p0; float *reamin0, *reamout0; blsiz = NSPEC * 2; blsiz2 = blsiz / 2; d1.bw = 2.4; // fixed 2.4 for TV dongle 10 MHz for ADC card if (d1.fbw == 0.0) d1.fbw = 2.0; // use bandwidth default if not set in srt.cat d1.f1 = 0.5 - (d1.fbw / d1.bw) * 0.5; d1.f2 = 0.5 + (d1.fbw / d1.bw) * 0.5; d1.fc = (d1.f1 + d1.f2) * 0.5; d1.lofreq = 0; // not used but needs to be set to zero to flag the use of the dongle d1.efflofreq = d1.freq - d1.bw * 0.5; if (!d1.fftsim) { fft_init(blsiz2, &p0, &reamin0, &reamout0); } num = d1.nblk; //was 20 // was 100 nsam = NSAM; d1.nsam = NSAM * num; avsig = 0; numm = 0; smax = 0; max = -1e99; min = 1e99; for (i = 0; i < blsiz2; i++) vspec[i] = 0.0; for (k = 0; k < num; k++) { if (!d1.radiosim) // Read the raw data from the RTL Dongle r = rtlsdr_read_sync(dev, bufferRead, nsam, &n_read); else { av = 5.0; if (d1.elnow < 5.0) av = av * (d1.tsys + d1.tcal) / d1.tsys; if (strstr(soutrack, "Sun")) { av = sqrt(d1.eloff * d1.eloff + d1.azoff * d1.azoff * cos(d1.elnow * PI / 180.0) * cos(d1.elnow * PI / 180.0) + 1e-6); if (av > d1.beamw) av = d1.beamw; av = 5.0 + 25.0 * cos(av * PI * 0.5 / d1.beamw) * cos(av * PI * 0.5 / d1.beamw); } for (i = 0; i < nsam; i++) bufferRead[i] = (uint8_t) (sqrt(av) * gauss() + 127.397 + 0.5 + 0 * sin(2.0 * PI * 0.5 * (i / 2) / d1.bw)); // simulate data } // for(i=0;i<nsam;i+=0x10000) printf("%d %f\n",i,(double)(bufferRead[i]-127.397)); for (kk = 0; kk < nsam / blsiz; kk++) { if (d1.fftsim) for (i = 0; i < blsiz2; i++) { re[i] = (double) (bufferRead[2 * i + kk * blsiz] - 127.397); am[i] = (double) (bufferRead[2 * i + 1 + kk * blsiz] - 127.397); if (re[i] > smax) smax = re[i]; } else for (i = 0; i < blsiz2; i++) { reamin0[2 * i] = (float) (bufferRead[2 * i + kk * blsiz] - 127.397); reamin0[2 * i + 1] = (float) (bufferRead[2 * i + 1 + kk * blsiz] - 127.397); if (reamin0[2 * i] > smax) smax = reamin0[2 * i]; } if (d1.fftsim) Four(re, am, blsiz2); else { cfft(&p0); for (i = 0; i < blsiz2; i++) { re[i] = reamout0[2 * i]; am[i] = reamout0[2 * i + 1]; } } // for(i = 0; i < blsiz2; i++) if(re[i] > max) max=re[i]; // for(i = 0; i < blsiz2; i++) if(re[i] < min) min=re[i]; for (i = 0; i < blsiz2; i++) { if (i < blsiz2 / 2) j = i + blsiz2 / 2; else j = i - blsiz2 / 2; vspec[j] += re[i] * re[i] + am[i] * am[i]; numm++; } } } // printf("max %f min %f\n",max,min); max = av = 0; maxi = 0; for (i = 0; i < blsiz2; i++) wtt[i] = 1; if (numm > 0) { if (d1.nfreq == blsiz2) { for (i = 0; i < blsiz2; i++) { if (i > 10) spec[i] = vspec[i] / (double) numm; else spec[i] = 0; } } else { m = blsiz2 / d1.nfreq; for (i = 0; i < d1.nrfi; i++) { i4 = (d1.rfi[i] - d1.freq + d1.bw * 0.5) * blsiz2 / d1.bw + 0.5; // index of rfi MHz wid = 0.5 * d1.rfiwid[i] / (d1.bw / NSPEC); for (j = -wid; j <= wid; j++) if ((i4 + j) >= 0 && (i4 + j) < blsiz2) wtt[i4 + j] = 0; } for (j = 0; j < d1.nfreq; j++) { av = mm = 0; for (i = j * m - m / 2; i <= j * m + m / 2; i++) { if (i > 10 && i < blsiz2 && wtt[i]) { // wtt=0 removal of spurs av += vspec[i] / (double) numm; if (vspec[i] > max) { max = vspec[i]; maxi = i; } mm++; } } if (mm > 0) spec[j] = av / mm; else { spec[j] = 0; if (j > 10) printf("check RFI settings in srt.cat data deleted at %8.3f\n", j * d1.bw / d1.nfreq + d1.freq - d1.bw * 0.5); } } max = max / (double) numm; noise = spec[maxi / m] * sqrt(2.0 * blsiz2 / (double) d1.nsam); if (max > spec[maxi / m] + d1.rfisigma * noise && d1.printout) // rfisigma sigma printf("check for RFI at %8.4f MHz max %5.0e av %5.0e smax %5.0f %3.0f sigma\n", maxi * d1.bw / blsiz2 + d1.freq - d1.bw * 0.5, max, spec[maxi / m], smax, (max - spec[maxi / m]) / noise); } } d1.smax = smax; if (!d1.fftsim) fft_free(&p0, &reamin0, &reamout0); free(bufferRead); }
void vspectra(void) { int i, j, size, sizep, kk, kkk, num, numm, i4; int k, m, mm, blsiz, blsiz2, nsam, info, maxi; double avsig, av, wid, noise, max; static double vspec[NSPEC]; static int wtt[NSPEC]; static float ream[NSPEC * 4]; static double re[NSPEC * 2], am[NSPEC * 2]; double smax, aam, rre, aam2, rre2; double *comm; d1.bw = 10.0; // 10 MHz d1.lofreq = 1416.0; // Luff 1416 MHz d1.efflofreq = d1.lofreq; d1.f1 = (d1.freq - d1.lofreq) / d1.bw - (d1.fbw / d1.bw) * 0.5; d1.f2 = (d1.freq - d1.lofreq) / d1.bw + (d1.fbw / d1.bw) * 0.5; d1.fc = (d1.f1 + d1.f2) * 0.5; blsiz = NSPEC * 2; info = 0; comm = 0; if (!d1.fftsim) { comm = (double *) malloc((5 * blsiz + 100) * sizeof(double)); fft_init(blsiz, ream, comm, &info); } // printf("comm %x\n",comm); nsam = 0x100000; blsiz2 = blsiz / 2; num = 20; // was 100 d1.nsam = nsam * num; avsig = 0; size = 0; numm = 0; smax = 0; av = 0; for (i = 0; i < blsiz2; i++) vspec[i] = 0.0; size = -1; if (!d1.radiosim) while (size != nsam) size = get_pci(buffer1, nsam); // wait for transfer to complete else { av = 5.0; if (d1.elnow < 5.0) av = av * (d1.tsys + d1.tcal) / d1.tsys; if (strstr(soutrack, "Sun")) { av = sqrt(d1.eloff * d1.eloff + d1.azoff * d1.azoff * cos(d1.elnow * PI / 180.0) * cos(d1.elnow * PI / 180.0) + 1e-6); if (av > d1.beamw) av = d1.beamw; av = 5.0 + 25.0 * cos(av * PI * 0.5 / d1.beamw) * cos(av * PI * 0.5 / d1.beamw); } for (i = 0; i < nsam; i++) buffer1[i] = 2048 + sqrt(av) * gauss(); size = nsam; } // simulate transfer sizep = size; for (k = 0; k < num; k++) { if (k < num - 1) { if (!d1.radiosim) size = get_pci(buffer1, nsam); // start new transfer else { for (i = 0; i < nsam; i++) buffer1[i] = 2048 + sqrt(av) * gauss(); size = nsam; } // simulate transfer } if (sizep == nsam) { // work on previous buffer for (kk = 0; kk < sizep / blsiz; kk++) { avsig = 2048; // should be 2048 // avsig = 2300; kkk = kk * blsiz; for (j = 0; j < blsiz; j++) { // if(j==0 && kkk==0) printf("sam %f\n",(buffer1[j + kkk] & 0xfff) - avsig); if (kk % 2 == 0) ream[2 * j] = ((double) (buffer1[j + kkk] & 0xfff) - avsig); else ream[2 * j + 1] = ((double) (buffer1[j + kkk] & 0xfff) - avsig); if (j && ream[2 * j] > smax) smax = ream[2 * j]; } if (kk % 2 == 1) { if (d1.fftsim) { for (i = 0; i < blsiz2; i++) { re[i] = ream[2 * i]; am[i] = ream[2 * i + 1]; } Four(re, am, blsiz2); } else cfft(blsiz, ream, comm, &info); for (i = 0; i < blsiz2; i++) { if (i >= 1) { rre = ream[2 * i] + ream[2 * (blsiz - i)]; aam = ream[2 * i + 1] - ream[2 * (blsiz - i) + 1]; aam2 = -ream[2 * i] + ream[2 * (blsiz - i)]; rre2 = ream[2 * i + 1] + ream[2 * (blsiz - i) + 1]; } else { rre = ream[2 * i] + ream[0]; aam = ream[2 * i + 1] - ream[1]; aam2 = -ream[2 * i] + ream[0]; rre2 = ream[2 * i + 1] + ream[1]; } vspec[i] += rre * rre + aam * aam + rre2 * rre2 + aam2 * aam2; } } } numm++; } while (size != nsam) if (!d1.radiosim) size = get_pci(buffer1, nsam); // wait for transfer to complete else { for (i = 0; i < nsam; i++) buffer1[i] = 2048 + 10.0 * gauss(); size = nsam; } // simulate transfer sizep = size; } av = max = 0; maxi = 0; for (i = 0; i < blsiz2; i++) wtt[i] = 1; if (numm > 0) { if (d1.nfreq == blsiz2) { for (i = 0; i < blsiz2; i++) { if (i > 10) spec[i] = vspec[i] / (double) numm; else spec[i] = 0; } } else { m = blsiz2 / d1.nfreq; for (i = 0; i < d1.nrfi; i++) { i4 = (d1.rfi[i] - d1.lofreq) * blsiz2 / d1.bw + 0.5; // index of rfi MHz wid = 0.5 * d1.rfiwid[i] / (d1.bw / NSPEC); for (j = -wid; j <= wid; j++) if ((i4 + j) >= 0 && (i4 + j) < blsiz2) wtt[i4 + j] = 0; } for (j = 0; j < d1.nfreq; j++) { av = mm = 0; for (i = j * m - m / 2; i <= j * m + m / 2; i++) { if (i > 10 && i < blsiz2 && wtt[i]) { // wtt=0 removal of spurs av += vspec[i] / (double) numm; if (vspec[i] > max) { max = vspec[i]; maxi = i; } mm++; } } if (mm > 0) spec[j] = av / mm; else { spec[j] = 0; if (j > 10) printf("check RFI settings in srt.cat data deleted at %8.3f\n", j * d1.bw / d1.nfreq + d1.lofreq); } } max = max / (double) numm; noise = spec[maxi / m] * sqrt(2.0 * blsiz2 / (double) d1.nsam); if (max > spec[maxi / m] + d1.rfisigma * noise && d1.printout) // rfisigma sigma printf("check for RFI at %8.4f MHz max %5.0e av %5.0e smax %5.0f %3.0f sigma\n", maxi * d1.bw / blsiz2 + d1.lofreq, max, spec[maxi / m], smax, (max - spec[maxi / m]) / noise); } } d1.smax = smax; if (!d1.fftsim) free(comm); }
int hilbert(int numsamp,const double *f,double *fhilb) { void cfft(); int find_length(); void detrend(); int i, j,npts_max; double bpfilt; dcomplex imag; dcomplex *x; if(numsamp<=0) { fprintf(stderr,"%s\n","No data points read ...."); return (1); } npts_max = find_length(numsamp); if (npts_max == 0) { fprintf(stderr,"Too long input time series \n"); return (2); } x = (dcomplex *) malloc(npts_max * sizeof(dcomplex)); if ( x == NULL ) { fprintf(stderr,"Incorrect allocation\n"); return (3); } imag.re = 0.; imag.im = 1.0; for( i=0; i<numsamp; i++) { x[i].re = f[i]; x[i].im = 0.; } for(i=numsamp; i<npts_max; i++) x[i].re = x[i].im = 0.; cfft( x,npts_max,-1 ); for (i=1; i<=npts_max/2; ++i) { x[i] = dcmult(x[i],imag); } x[0].re = 0.; x[0].im = 0.; for( i=(npts_max/2)+1; i<npts_max; i++ ) x[i] = dconj(x[npts_max-i]); cfft( x,npts_max,1 ); for( i=0; i<numsamp; i++) fhilb[i] = x[i].re/npts_max; detrend(fhilb, numsamp); free(x); return (0); }