void wlanframesync_debug_print(wlanframesync _q, const char * _filename) { #if DEBUG_WLANFRAMESYNC if (_q->agc_rx == NULL || _q->debug_x == NULL || _q->debug_rssi == NULL || _q->debug_framesyms == NULL) { fprintf(stderr,"error: wlanframe_debug_print(), debugging objects don't exist; enable debugging first\n"); return; } FILE * fid = fopen(_filename,"w"); if (!fid) { fprintf(stderr,"error: wlanframe_debug_print(), could not open '%s' for writing\n", _filename); return; } fprintf(fid,"%% %s : auto-generated file\n", _filename); fprintf(fid,"close all;\n"); fprintf(fid,"clear all;\n"); fprintf(fid,"n = %u;\n", DEBUG_WLANFRAMESYNC_BUFFER_LEN); unsigned int i; float complex * rc; float * r; fprintf(fid,"x = zeros(1,n);\n"); windowcf_read(_q->debug_x, &rc); for (i=0; i<DEBUG_WLANFRAMESYNC_BUFFER_LEN; i++) fprintf(fid,"x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(rc[i]), cimagf(rc[i])); fprintf(fid,"figure;\n"); fprintf(fid,"plot(0:(n-1),real(x),0:(n-1),imag(x));\n"); fprintf(fid,"xlabel('sample index');\n"); fprintf(fid,"ylabel('received signal, x');\n"); // write agc_rssi fprintf(fid,"\n\n"); fprintf(fid,"agc_rssi = zeros(1,%u);\n", DEBUG_WLANFRAMESYNC_BUFFER_LEN); windowf_read(_q->debug_rssi, &r); for (i=0; i<DEBUG_WLANFRAMESYNC_BUFFER_LEN; i++) fprintf(fid,"agc_rssi(%4u) = %12.4e;\n", i+1, r[i]); fprintf(fid,"figure;\n"); fprintf(fid,"plot(agc_rssi)\n"); fprintf(fid,"ylabel('RSSI [dB]');\n"); // write frame symbols fprintf(fid,"framesyms = zeros(1,n);\n"); windowcf_read(_q->debug_framesyms, &rc); for (i=0; i<DEBUG_WLANFRAMESYNC_BUFFER_LEN; i++) fprintf(fid,"framesyms(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(rc[i]), cimagf(rc[i])); fprintf(fid,"figure;\n"); fprintf(fid,"plot(real(framesyms),imag(framesyms),'x','MarkerSize',2);\n"); fprintf(fid,"axis([-1 1 -1 1]*1.5);\n"); fprintf(fid,"axis square;\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"xlabel('real');\n"); fprintf(fid,"ylabel('imag');\n"); // write gain arrays fprintf(fid,"\n\n"); fprintf(fid,"G0a = zeros(1,64);\n"); fprintf(fid,"G0b = zeros(1,64);\n"); fprintf(fid,"G1a = zeros(1,64);\n"); fprintf(fid,"G1b = zeros(1,64);\n"); fprintf(fid,"G = zeros(1,64);\n"); for (i=0; i<64; i++) { unsigned int k = (i + 32) % 64; fprintf(fid,"G0a(%3u) = %12.8f + j*%12.8f;\n", k+1, crealf(_q->G0a[i]), cimagf(_q->G0a[i])); fprintf(fid,"G0b(%3u) = %12.8f + j*%12.8f;\n", k+1, crealf(_q->G0b[i]), cimagf(_q->G0b[i])); fprintf(fid,"G1a(%3u) = %12.8f + j*%12.8f;\n", k+1, crealf(_q->G1a[i]), cimagf(_q->G1a[i])); fprintf(fid,"G1b(%3u) = %12.8f + j*%12.8f;\n", k+1, crealf(_q->G1b[i]), cimagf(_q->G1b[i])); fprintf(fid,"G(%3u) = %12.8f + j*%12.8f;\n", k+1, crealf(_q->G[i]), cimagf(_q->G[i])); } fprintf(fid,"%% apply timing offset (backoff) phase shift\n"); fprintf(fid,"f = -32:31;\n"); fprintf(fid,"b = 2;\n"); fprintf(fid,"G0a = G0a.*exp(j*b*2*pi*f/64);\n"); fprintf(fid,"G0b = G0b.*exp(j*b*2*pi*f/64);\n"); fprintf(fid,"G1a = G1a.*exp(j*b*2*pi*f/64);\n"); fprintf(fid,"G1b = G1b.*exp(j*b*2*pi*f/64);\n"); fprintf(fid,"G = G.*exp(j*b*2*pi*f/64);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(f,abs(G1a),'x', f,abs(G1b),'x', f,abs(G),'-k','LineWidth',2);\n"); fprintf(fid," ylabel('G (mag)');\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(f,arg(G1a),'x', f,arg(G1b),'x', f,arg(G),'-k','LineWidth',2);\n"); fprintf(fid," ylabel('G (phase)');\n"); fclose(fid); printf("wlanframesync/debug: results written to '%s'\n", _filename); #else fprintf(stderr,"wlanframesync_debug_print(): compile-time debugging disabled\n"); #endif }
int main(int argc, char* argv[]) { bool verb,complx; int it,iz,im,ik,ix,i,j; /* index variables */ int nt,nz,nx, m2, nk, nzx, nz2, nx2, nzx2, n2, pad1; sf_complex c; float *rr; /* I/O arrays*/ sf_complex *ww, *cwave, *cwavem; sf_complex **wave,**wave2, *curr, *currm; float *rcurr=NULL; sf_file Fw,Fr,Fo; /* I/O files */ sf_axis at,az,ax; /* cube axes */ sf_complex **lt, **rt; sf_file left, right; sf_init(argc,argv); if(!sf_getbool("verb",&verb)) verb=false; /* verbosity */ if(!sf_getbool("cmplx",&complx)) complx=true; /* outputs complex wavefield */ /* setup I/O files */ Fw = sf_input ("in" ); Fo = sf_output("out"); Fr = sf_input ("ref"); if (SF_COMPLEX != sf_gettype(Fw)) sf_error("Need complex input"); if (SF_FLOAT != sf_gettype(Fr)) sf_error("Need float ref"); if(complx) sf_settype(Fo,SF_COMPLEX); else sf_settype(Fo,SF_FLOAT); /* Read/Write axes */ at = sf_iaxa(Fw,1); nt = sf_n(at); az = sf_iaxa(Fr,1); nz = sf_n(az); ax = sf_iaxa(Fr,2); nx = sf_n(ax); sf_oaxa(Fo,az,1); sf_oaxa(Fo,ax,2); sf_oaxa(Fo,at,3); if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */ nk = cfft2_init(pad1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; /* propagator matrices */ left = sf_input("left"); right = sf_input("right"); if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx); if (!sf_histint(left,"n2",&m2)) sf_error("Need n2= in left"); if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2); if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk); lt = sf_complexalloc2(nzx,m2); rt = sf_complexalloc2(m2,nk); sf_complexread(lt[0],nzx*m2,left); sf_complexread(rt[0],m2*nk,right); sf_fileclose(left); sf_fileclose(right); /* read wavelet & reflectivity */ ww=sf_complexalloc(nt); sf_complexread(ww,nt ,Fw); rr=sf_floatalloc(nzx); sf_floatread(rr,nzx,Fr); curr = sf_complexalloc(nzx2); currm = sf_complexalloc(nzx2); if(!complx) rcurr = sf_floatalloc(nzx2); cwave = sf_complexalloc(nk); cwavem = sf_complexalloc(nk); wave = sf_complexalloc2(nk,m2); wave2 = sf_complexalloc2(nzx2,m2); for (iz=0; iz < nzx2; iz++) { curr[iz] = sf_cmplx(0.,0.); if(!complx) rcurr[iz]= 0.; } /* MAIN LOOP */ for (it=0; it<nt; it++) { if(verb) sf_warning("it=%d;",it); /* matrix multiplication */ for (im = 0; im < m2; im++) { for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H currm[j] = lt[im][i]*curr[j]; #else currm[j] = sf_cmul(lt[im][i], curr[j]); #endif } } cfft2(currm,wave[im]); } /* approach no.2 */ for (ik = 0; ik < nk; ik++) { c = sf_cmplx(0.,0.); for (im = 0; im < m2; im++) { #ifdef SF_HAS_COMPLEX_H c += wave[im][ik]*rt[ik][im]; #else c = sf_cadd(c,sf_cmul(wave[im][ik],rt[ik][im])); /* complex multiplies complex */ #endif } cwave[ik] = c; } for (im = 0; im < m2; im++) { for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*rt[ik][im]; #else cwavem[ik] = sf_cmul(cwave[ik],rt[ik][im]); /* complex multiplies complex */ #endif } icfft2(wave2[im],cwavem); } /* for (im = 0; im < m2; im++) { for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwave[ik] = wave[im][ik]*rt[ik][im]*rt[ik][im]; #else cwave[ik] = sf_cmul(sf_cmul(wave[im][ik],rt[ik][im]),rt[ik][im]); #endif } icfft2(wave2[im],cwave); } */ for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H c = ww[it] * rr[i]; // source term #else c = sf_crmul(ww[it], rr[i]); // source term #endif for (im = 0; im < m2; im++) { #ifdef SF_HAS_COMPLEX_H c += lt[im][i]*wave2[im][j]; #else c = sf_cadd(c,sf_cmul(lt[im][i], wave2[im][j])); #endif } curr[j] = c; if (!complx) rcurr[j] = crealf(c); } /* write wavefield to output */ if (complx) sf_complexwrite(curr+ix*nz2,nz,Fo); else sf_floatwrite(rcurr+ix*nz2,nz,Fo); } } if(verb) sf_warning("."); exit (0); }
int main(int argc, char*argv[]) { srand(time(NULL)); // options unsigned int k=2; // samples/symbol (input) unsigned int k_out=2; // samples/symbol (output) unsigned int m=3; // filter delay (symbols) float beta=0.5f; // filter excess bandwidth factor unsigned int num_filters=32; // number of filters in the bank unsigned int num_symbols=200; // number of data symbols float SNRdB = 30.0f; // signal-to-noise ratio liquid_rnyquist_type ftype_tx = LIQUID_RNYQUIST_RRC; liquid_rnyquist_type ftype_rx = LIQUID_RNYQUIST_RRC; float bt=0.02f; // loop filter bandwidth float tau=-0.2f; // fractional symbol offset float r = 1.00f; // resampled rate // use random data or 101010 phasing pattern int random_data=1; int dopt; while ((dopt = getopt(argc,argv,"uhT:k:K:m:b:B:s:w:n:t:r:")) != EOF) { switch (dopt) { case 'u': case 'h': usage(); return 0; case 'T': if (strcmp(optarg,"rrcos")==0) { ftype_tx = LIQUID_RNYQUIST_RRC; ftype_rx = LIQUID_RNYQUIST_RRC; } else if (strcmp(optarg,"rkaiser")==0) { ftype_tx = LIQUID_RNYQUIST_RKAISER; ftype_rx = LIQUID_RNYQUIST_RKAISER; } else if (strcmp(optarg,"arkaiser")==0) { ftype_tx = LIQUID_RNYQUIST_ARKAISER; ftype_rx = LIQUID_RNYQUIST_ARKAISER; } else if (strcmp(optarg,"hM3")==0) { ftype_tx = LIQUID_RNYQUIST_hM3; ftype_rx = LIQUID_RNYQUIST_hM3; } else if (strcmp(optarg,"gmsk")==0) { ftype_tx = LIQUID_RNYQUIST_GMSKTX; ftype_rx = LIQUID_RNYQUIST_GMSKRX; } else { fprintf(stderr,"error: %s, unknown filter type '%s'\n", argv[0], optarg); exit(1); } break; case 'k': k = atoi(optarg); break; case 'K': k_out = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 'B': num_filters = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'w': bt = atof(optarg); break; case 'n': num_symbols = atoi(optarg); break; case 't': tau = atof(optarg); break; case 'r': r = atof(optarg); break; default: exit(1); } } // validate input if (k < 2) { fprintf(stderr,"error: k (samples/symbol) must be at least 2\n"); exit(1); } else if (m < 1) { fprintf(stderr,"error: m (filter delay) must be greater than 0\n"); exit(1); } else if (beta <= 0.0f || beta > 1.0f) { fprintf(stderr,"error: beta (excess bandwidth factor) must be in (0,1]\n"); exit(1); } else if (num_filters == 0) { fprintf(stderr,"error: number of polyphase filters must be greater than 0\n"); exit(1); } else if (bt <= 0.0f) { fprintf(stderr,"error: timing PLL bandwidth must be greater than 0\n"); exit(1); } else if (num_symbols == 0) { fprintf(stderr,"error: number of symbols must be greater than 0\n"); exit(1); } else if (tau < -1.0f || tau > 1.0f) { fprintf(stderr,"error: timing phase offset must be in [-1,1]\n"); exit(1); } else if (r < 0.5f || r > 2.0f) { fprintf(stderr,"error: timing frequency offset must be in [0.5,2]\n"); exit(1); } // compute delay while (tau < 0) tau += 1.0f; // ensure positive tau float g = k*tau; // number of samples offset int ds=floorf(g); // additional symbol delay float dt = (g - (float)ds); // fractional sample offset if (dt > 0.5f) { // force dt to be in [0.5,0.5] dt -= 1.0f; ds++; } unsigned int i, n=0; unsigned int num_samples = k*num_symbols; unsigned int num_samples_resamp = (unsigned int) ceilf(num_samples*r*1.1f) + 4; float complex s[num_symbols]; // data symbols float complex x[num_samples]; // interpolated samples float complex y[num_samples_resamp]; // resampled data (resamp_crcf) float complex z[k_out*num_symbols + 64];// synchronized samples float complex sym_out[num_symbols + 64];// synchronized symbols for (i=0; i<num_symbols; i++) { if (random_data) { // random signal (QPSK) s[i] = cexpf(_Complex_I*0.5f*M_PI*((rand() % 4) + 0.5f)); } else { s[i] = (i%2) ? 1.0f : -1.0f; // 101010 phasing pattern } } // // create and run interpolator // // design interpolating filter unsigned int h_len = 2*k*m+1; float h[h_len]; liquid_firdes_rnyquist(ftype_tx,k,m,beta,dt,h); interp_crcf q = interp_crcf_create(k,h,h_len); for (i=0; i<num_symbols; i++) { interp_crcf_execute(q, s[i], &x[n]); n+=k; } assert(n == num_samples); interp_crcf_destroy(q); // // run resampler // unsigned int resamp_len = 10*k; // resampling filter semi-length (filter delay) float resamp_bw = 0.45f; // resampling filter bandwidth float resamp_As = 60.0f; // resampling filter stop-band attenuation unsigned int resamp_npfb = 64; // number of filters in bank resamp_crcf f = resamp_crcf_create(r, resamp_len, resamp_bw, resamp_As, resamp_npfb); unsigned int num_samples_resampled = 0; unsigned int num_written; for (i=0; i<num_samples; i++) { #if 0 // bypass arbitrary resampler y[i] = x[i]; num_samples_resampled = num_samples; #else // TODO : compensate for resampler filter delay resamp_crcf_execute(f, x[i], &y[num_samples_resampled], &num_written); num_samples_resampled += num_written; #endif } resamp_crcf_destroy(f); // // add noise // float nstd = powf(10.0f, -SNRdB/20.0f); for (i=0; i<num_samples_resampled; i++) y[i] += nstd*(randnf() + _Complex_I*randnf()); // // create and run symbol synchronizer // symsync_crcf d = symsync_crcf_create_rnyquist(ftype_rx, k, m, beta, num_filters); symsync_crcf_set_lf_bw(d,bt); symsync_crcf_set_output_rate(d,k_out); unsigned int num_samples_sync=0; unsigned int nn; unsigned int num_symbols_sync = 0; float tau_hat[num_samples]; for (i=ds; i<num_samples_resampled; i++) { tau_hat[num_samples_sync] = symsync_crcf_get_tau(d); symsync_crcf_execute(d, &y[i], 1, &z[num_samples_sync], &nn); // decimate unsigned int j; for (j=0; j<nn; j++) { if ( (num_samples_sync%k_out)==0 ) sym_out[num_symbols_sync++] = z[num_samples_sync]; num_samples_sync++; } } symsync_crcf_destroy(d); // print last several symbols to screen printf("output symbols:\n"); for (i=num_symbols_sync-10; i<num_symbols_sync; i++) printf(" sym_out(%2u) = %8.4f + j*%8.4f;\n", i+1, crealf(sym_out[i]), cimagf(sym_out[i])); // // export output file // FILE* fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s, auto-generated file\n\n", OUTPUT_FILENAME); fprintf(fid,"close all;\nclear all;\n\n"); fprintf(fid,"k=%u;\n",k); fprintf(fid,"m=%u;\n",m); fprintf(fid,"beta=%12.8f;\n",beta); fprintf(fid,"k_out=%u;\n",k_out); fprintf(fid,"num_filters=%u;\n",num_filters); fprintf(fid,"num_symbols=%u;\n",num_symbols); for (i=0; i<h_len; i++) fprintf(fid,"h(%3u) = %12.5f;\n", i+1, h[i]); for (i=0; i<num_symbols; i++) fprintf(fid,"s(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(s[i]), cimagf(s[i])); for (i=0; i<num_samples; i++) fprintf(fid,"x(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i])); for (i=0; i<num_samples_resampled; i++) fprintf(fid,"y(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i])); for (i=0; i<num_samples_sync; i++) fprintf(fid,"z(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(z[i]), cimagf(z[i])); for (i=0; i<num_symbols_sync; i++) fprintf(fid,"sym_out(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(sym_out[i]), cimagf(sym_out[i])); for (i=0; i<num_samples_sync; i++) fprintf(fid,"tau_hat(%3u) = %12.8f;\n", i+1, tau_hat[i]); fprintf(fid,"\n\n"); fprintf(fid,"%% scale QPSK in-phase by sqrt(2)\n"); fprintf(fid,"z = z*sqrt(2);\n"); fprintf(fid,"\n\n"); fprintf(fid,"tz = [0:length(z)-1]/k_out;\n"); fprintf(fid,"iz = 1:k_out:length(z);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(tz, real(z), '-',...\n"); fprintf(fid," tz(iz), real(z(iz)),'or');\n"); fprintf(fid,"xlabel('Time');\n"); fprintf(fid,"ylabel('Output Signal (real)');\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"legend('output time series','optimim timing',1);\n"); fprintf(fid,"iz0 = iz( 1:round(length(iz)*0.5) );\n"); fprintf(fid,"iz1 = iz( round(length(iz)*0.5):length(iz) );\n"); fprintf(fid,"figure;\n"); fprintf(fid,"hold on;\n"); fprintf(fid,"plot(real(z(iz0)),imag(z(iz0)),'x','MarkerSize',4,'Color',[0.6 0.6 0.6]);\n"); fprintf(fid,"plot(real(z(iz1)),imag(z(iz1)),'o','MarkerSize',4,'Color',[0 0.25 0.5]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"axis square;\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([-1 1 -1 1]*1.6);\n"); fprintf(fid,"xlabel('In-phase');\n"); fprintf(fid,"ylabel('Quadrature');\n"); fprintf(fid,"legend(['first 50%%'],['last 50%%'],1);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"tt = 0:(length(tau_hat)-1);\n"); fprintf(fid,"b = floor(num_filters*tau_hat + 0.5);\n"); fprintf(fid,"stairs(tt,tau_hat*num_filters);\n"); fprintf(fid,"hold on;\n"); fprintf(fid,"plot(tt,b,'-k','Color',[0 0 0]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"xlabel('time');\n"); fprintf(fid,"ylabel('filterbank index');\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([0 length(tau_hat) -1 num_filters]);\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); // clean it up printf("done.\n"); return 0; }
int main(int argc, char*argv[]) { srand( time(NULL) ); // parameters float phase_offset = M_PI/10; float frequency_offset = 0.001f; float SNRdB = 30.0f; float pll_bandwidth = 0.02f; modulation_scheme ms = LIQUID_MODEM_QPSK; unsigned int n=256; // number of iterations int dopt; while ((dopt = getopt(argc,argv,"uhs:b:n:P:F:m:")) != EOF) { switch (dopt) { case 'u': case 'h': usage(); return 0; case 's': SNRdB = atof(optarg); break; case 'b': pll_bandwidth = atof(optarg); break; case 'n': n = atoi(optarg); break; case 'P': phase_offset = atof(optarg); break; case 'F': frequency_offset= atof(optarg); break; case 'm': ms = liquid_getopt_str2mod(optarg); if (ms == LIQUID_MODEM_UNKNOWN) { fprintf(stderr,"error: %s, unknown/unsupported modulation scheme \"%s\"\n", argv[0], optarg); return 1; } break; default: exit(1); } } unsigned int d=n/32; // print every "d" lines FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid, "%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid, "clear all;\n"); fprintf(fid, "phi=zeros(1,%u);\n",n); fprintf(fid, "r=zeros(1,%u);\n",n); // objects nco_crcf nco_tx = nco_crcf_create(LIQUID_VCO); nco_crcf nco_rx = nco_crcf_create(LIQUID_VCO); modem mod = modem_create(ms); modem demod = modem_create(ms); unsigned int bps = modem_get_bps(mod); // initialize objects nco_crcf_set_phase(nco_tx, phase_offset); nco_crcf_set_frequency(nco_tx, frequency_offset); nco_crcf_pll_set_bandwidth(nco_rx, pll_bandwidth); float noise_power = powf(10.0f, -SNRdB/20.0f); // print parameters printf("PLL example :\n"); printf("modem : %u-%s\n", 1<<bps, modulation_types[ms].name); printf("frequency offset: %6.3f, phase offset: %6.3f, SNR: %6.2fdB, pll b/w: %6.3f\n", frequency_offset, phase_offset, SNRdB, pll_bandwidth); // run loop unsigned int i, M=1<<bps, sym_in, sym_out, num_errors=0; float phase_error; float complex x, r, v, noise; for (i=0; i<n; i++) { // generate random symbol sym_in = rand() % M; // modulate modem_modulate(mod, sym_in, &x); // channel //r = nco_crcf_cexpf(nco_tx); nco_crcf_mix_up(nco_tx, x, &r); // add complex white noise crandnf(&noise); r += noise * noise_power; // //v = nco_crcf_cexpf(nco_rx); nco_crcf_mix_down(nco_rx, r, &v); // demodulate modem_demodulate(demod, v, &sym_out); num_errors += count_bit_errors(sym_in, sym_out); // error estimation //phase_error = cargf(r*conjf(v)); phase_error = modem_get_demodulator_phase_error(demod); // perfect error estimation //phase_error = nco_tx->theta - nco_rx->theta; // print every line in a format that octave can read fprintf(fid, "phi(%u) = %10.6E;\n", i+1, phase_error); fprintf(fid, "r(%u) = %10.6E + j*%10.6E;\n", i+1, crealf(v), cimagf(v)); if ((i+1)%d == 0 || i==n-1) { printf(" %4u: e_hat : %6.3f, phase error : %6.3f, freq error : %6.3f\n", i+1, // iteration phase_error, // estimated phase error nco_crcf_get_phase(nco_tx) - nco_crcf_get_phase(nco_rx),// true phase error nco_crcf_get_frequency(nco_tx) - nco_crcf_get_frequency(nco_rx)// true frequency error ); } // update tx nco object nco_crcf_step(nco_tx); // update pll nco_crcf_pll_step(nco_rx, phase_error); // update rx nco object nco_crcf_step(nco_rx); } fprintf(fid, "figure;\n"); fprintf(fid, "plot(1:length(phi),phi,'LineWidth',2,'Color',[0 0.25 0.5]);\n"); fprintf(fid, "xlabel('Symbol Index');\n"); fprintf(fid, "ylabel('Phase Error [radians]');\n"); fprintf(fid, "grid on;\n"); fprintf(fid, "t0 = round(0.25*length(r));\n"); fprintf(fid, "figure;\n"); fprintf(fid, "plot(r(1:t0),'x','Color',[0.6 0.6 0.6],r(t0:end),'x','Color',[0 0.25 0.5]);\n"); fprintf(fid, "grid on;\n"); fprintf(fid, "axis([-1.5 1.5 -1.5 1.5]);\n"); fprintf(fid, "axis('square');\n"); fprintf(fid, "xlabel('In-Phase');\n"); fprintf(fid, "ylabel('Quadrature');\n"); fprintf(fid, "legend(['first 25%%'],['last 75%%'],1);\n"); fclose(fid); printf("results written to %s.\n",OUTPUT_FILENAME); nco_crcf_destroy(nco_tx); nco_crcf_destroy(nco_rx); modem_destroy(mod); modem_destroy(demod); printf("bit errors: %u / %u\n", num_errors, bps*n); printf("done.\n"); return 0; }
// ellip_azpkf() // // Compute analog zeros, poles, gain of low-pass elliptic // filter, grouping complex conjugates together. If // the filter order is odd, the single real pole is at the // end of the array. // _n : filter order // _ep : epsilon_p, related to pass-band ripple // _es : epsilon_s, related to stop-band ripple // _za : output analog zeros [length: floor(_n/2)] // _pa : output analog poles [length: _n] // _ka : output analog gain void ellip_azpkf(unsigned int _n, float _ep, float _es, float complex * _za, float complex * _pa, float complex * _ka) { // filter specifications float fp = 1.0f / (2.0f * M_PI); // pass-band cutoff float fs = 1.1*fp; // stop-band cutoff //float Gp = 1/sqrtf(1 + _ep*_ep); // pass-band gain //float Gs = 1/sqrtf(1 + _es*_es); // stop-band gain // number of iterations for elliptic integral // approximations unsigned int n=7; float Wp = 2*M_PI*fp; float Ws = 2*M_PI*fs; // ripples passband, stopband float ep = _ep; float es = _es; #if LIQUID_DEBUG_ELLIP_PRINT printf("ep, es : %12.8f, %12.8f\n", _ep, _es); #endif float k = Wp/Ws; // 0.8889f; float k1 = ep/es; // 0.0165f; #if LIQUID_DEBUG_ELLIP_PRINT printf("k : %12.4e\n", k); printf("k1 : %12.4e\n", k1); #endif float K, Kp; float K1, K1p; ellipkf(k, n, &K, &Kp); // K = 2.23533416, Kp = 1.66463780 ellipkf(k1,n, &K1, &K1p); // K1 = 1.57090271, K1p = 5.49361753 #if LIQUID_DEBUG_ELLIP_PRINT printf("K, Kp : %12.8f, %12.8f\n", K, Kp); printf("K1, K1p : %12.8f, %12.8f\n", K1, K1p); #endif float N = (float)_n; // ceilf(Nexact) = 5 #if LIQUID_DEBUG_ELLIP_PRINT float Nexact = (K1p/K1)/(Kp/K); // 4.69604063 printf("N (exact) : %12.8f\n", Nexact); printf("N : %12.8f\n", N); #endif k = ellipdegf(N,k1,n); // 0.91427171 #if LIQUID_DEBUG_ELLIP_PRINT printf("k : %12.4e\n", k); #endif #if LIQUID_DEBUG_ELLIP_PRINT float fs_new = fp/k; // 4.37506723 printf("fs_new : %12.8f\n", fs_new); #endif unsigned int L = (unsigned int)(floorf(N/2.0f)); // 2 unsigned int r = ((unsigned int)N) % 2; float u[L]; unsigned int i; for (i=0; i<L; i++) { float t = (float)i + 1.0f; u[i] = (2.0f*t - 1.0f)/N; #if LIQUID_DEBUG_ELLIP_PRINT printf("u[%3u] : %12.8f\n", i, u[i]); #endif } float complex zeta[L]; for (i=0; i<L; i++) { zeta[i] = ellip_cdf(u[i],k,n); #if LIQUID_DEBUG_ELLIP_PRINT printf("zeta[%3u] : %12.8f + j*%12.8f\n", i, crealf(zeta[i]), cimagf(zeta[i])); #endif } // compute filter zeros float complex za[L]; for (i=0; i<L; i++) { za[i] = _Complex_I * Wp / (k*zeta[i]); #if LIQUID_DEBUG_ELLIP_PRINT printf("za[%3u] : %12.8f + j*%12.8f\n", i, crealf(za[i]), cimagf(za[i])); #endif } float complex v0 = -_Complex_I*ellip_asnf(_Complex_I/ep, k1, n)/N; #if LIQUID_DEBUG_ELLIP_PRINT printf("v0 : %12.8f + j*%12.8f\n", crealf(v0), cimagf(v0)); #endif float complex pa[L]; for (i=0; i<L; i++) { pa[i] = Wp*_Complex_I*ellip_cdf(u[i]-_Complex_I*v0, k, n); #if LIQUID_DEBUG_ELLIP_PRINT printf("pa[%3u] : %12.8f + j*%12.8f\n", i, crealf(pa[i]), cimagf(pa[i])); #endif } float complex pa0 = Wp * _Complex_I*ellip_snf(_Complex_I*v0, k, n); #if LIQUID_DEBUG_ELLIP_PRINT printf("pa0 : %12.8f + j*%12.8f\n", crealf(pa0), cimagf(pa0)); #endif // compute poles unsigned int t=0; for (i=0; i<L; i++) { _pa[t++] = pa[i]; _pa[t++] = conjf(pa[i]); } if (r) _pa[t++] = pa0; assert(t==_n); t=0; for (i=0; i<L; i++) { _za[t++] = za[i]; _za[t++] = conjf(za[i]); } assert(t==2*L); // compute gain *_ka = r ? 1.0f : 1.0f / sqrtf(1.0f + _ep*_ep); for (i=0; i<_n; i++) *_ka *= _pa[i]; for (i=0; i<2*L; i++) *_ka /= _za[i]; }
/* Actually, we don't need it -- JTW struct tagRealFFTPlan { INT4 sign; UINT4 size; void* junk; }; */ int main( int argc, char *argv[] ) { static LALStatus status; UINT4 i; REAL8 f; const REAL4 testInputDataData[SZEROPADANDFFTTESTC_LENGTH] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; COMPLEX8 expectedOutputDataData[SZEROPADANDFFTTESTC_LENGTH] = {crectf(+3.600000000000000e+01, 0.0), crectf(-1.094039137097177e+01, -2.279368601990178e+01), crectf(+3.693524635113721e-01, +9.326003289238411e+00), crectf(-8.090169943749448e-01, -7.918722831227928e+00), crectf(+3.502214272222959e-01, +5.268737078678177e+00), crectf(+5.329070518200751e-15, -5.196152422706625e+00), crectf(+3.090169943749475e-01, +4.306254604896173e+00), crectf(+2.208174802380956e-01, -4.325962305777781e+00)}; REAL4TimeSeries goodInput; COMPLEX8FrequencySeries goodOutput; int result; LALUnit expectedUnit; CHAR unitString[LALUnitTextSize]; SZeroPadAndFFTParameters goodParams; goodParams.window = NULL; goodParams.fftPlan = NULL; goodParams.length = SZEROPADANDFFTTESTC_FULLLENGTH; /* build window */ goodParams.window = XLALCreateRectangularREAL4Window(SZEROPADANDFFTTESTC_LENGTH); #ifndef LAL_NDEBUG SZeroPadAndFFTParameters badParams = goodParams; #endif /* Fill in expected output */ for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { expectedOutputDataData[i] *= SZEROPADANDFFTTESTC_DELTAT; } ParseOptions( argc, argv ); /* TEST INVALID DATA HERE ------------------------------------------- */ /* define valid parameters */ goodInput.f0 = 0.0; goodInput.deltaT = SZEROPADANDFFTTESTC_DELTAT; goodInput.epoch.gpsSeconds = SZEROPADANDFFTTESTC_EPOCHSEC; goodInput.epoch.gpsNanoSeconds = SZEROPADANDFFTTESTC_EPOCHNS; goodInput.data = NULL; goodOutput.data = NULL; #ifndef LAL_NDEBUG REAL4TimeSeries badInput = goodInput; COMPLEX8FrequencySeries badOutput = goodOutput; #endif /* construct plan */ LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan), SZEROPADANDFFTTESTC_FULLLENGTH, SZEROPADANDFFTTESTC_FALSE); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } /* allocate input and output vectors */ LALSCreateVector(&status, &(goodInput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } LALCCreateVector(&status, &(goodOutput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* test behavior for null pointer to output series */ LALSZeroPadAndFFT(&status, NULL, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to input series */ LALSZeroPadAndFFT(&status, &goodOutput, NULL, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to parameter structure */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, NULL); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to parameter structure results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to FFT plan */ badParams.fftPlan = NULL; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &badParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to FFT plan results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badParams.fftPlan = goodParams.fftPlan; /* test behavior for null pointer to data member of output series */ LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to data member of input series */ LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to data member of data member of output series */ LALCCreateVector(&status, &(badOutput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } COMPLEX8 *cPtr; cPtr = badOutput.data->data; badOutput.data->data = NULL; LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of data member of output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badOutput.data->data = cPtr; LALCDestroyVector(&status, &(badOutput.data)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* test behavior for null pointer to data member of data member of output series */ LALSCreateVector(&status, &(badInput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } REAL4 *sPtr; sPtr = badInput.data->data; badInput.data->data = NULL; LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of data member of input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badInput.data->data = sPtr; LALSDestroyVector(&status, &(badInput.data)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* test behavior for zero length */ goodInput.data->length = goodOutput.data->length = 0; /* plan->size = -1; */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EZEROLEN, STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero length results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN); /* reassign valid length */ goodInput.data->length = goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH; /* plan->size = SZEROPADANDFFTTESTC_FULLLENGTH; */ /* test behavior for negative time spacing */ goodInput.deltaT = -SZEROPADANDFFTTESTC_DELTAT; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative time spacing results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT); /* test behavior for zero time spacing */ goodInput.deltaT = 0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero time spacing results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT); /* reassign valid time spacing */ goodInput.deltaT = SZEROPADANDFFTTESTC_DELTAT; } /* if ( ! lalNoDebug ) */ #endif /* NDEBUG */ /* test behavior for negative heterodyning frequency */ goodInput.f0 = -100.0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO, STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative heterodyning frequency results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO); /* test behavior for positive heterodyning frequency */ goodInput.f0 = 100.0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO, STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: positive heterodyning frequency results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO); goodInput.f0 = 0.0; /* test behavior for length mismatch between input series and output series */ goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH + 1; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EMMLEN, STOCHASTICCROSSCORRELATIONH_MSGEMMLEN, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: length mismatch between input series and output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEMMLEN); goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH; /* TEST VALID DATA HERE --------------------------------------------- */ /* fill input time-series parameters */ strncpy(goodInput.name,"Dummy test data",LALNameLength); goodInput.sampleUnits = lalDimensionlessUnit; goodInput.sampleUnits.unitNumerator[LALUnitIndexADCCount] = 1; /* fill input time-series data */ for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { goodInput.data->data[i] = testInputDataData[i]; } /* zero-pad and FFT */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* check output f0 */ if (optVerbose) { printf("f0=%g, should be 0\n", goodOutput.f0); } if (goodOutput.f0) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output deltaF */ if (optVerbose) { printf("deltaF=%g, should be %g\n", goodOutput.deltaF, SZEROPADANDFFTTESTC_DELTAF); } if ( fabs(goodOutput.deltaF-SZEROPADANDFFTTESTC_DELTAF) / SZEROPADANDFFTTESTC_DELTAF > SZEROPADANDFFTTESTC_TOL ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output epoch */ if (optVerbose) { printf("epoch=%d seconds, %d nanoseconds; should be %d seconds, %d nanoseconds\n", goodOutput.epoch.gpsSeconds, goodOutput.epoch.gpsNanoSeconds, SZEROPADANDFFTTESTC_EPOCHSEC, SZEROPADANDFFTTESTC_EPOCHNS); } if ( goodOutput.epoch.gpsSeconds != SZEROPADANDFFTTESTC_EPOCHSEC || goodOutput.epoch.gpsNanoSeconds != SZEROPADANDFFTTESTC_EPOCHNS ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output units */ expectedUnit = lalDimensionlessUnit; expectedUnit.unitNumerator[LALUnitIndexADCCount] = 1; expectedUnit.unitNumerator[LALUnitIndexSecond] = 1; result = XLALUnitCompare(&expectedUnit, &(goodOutput.sampleUnits)); if (optVerbose) { if ( XLALUnitAsString( unitString, LALUnitTextSize, &(goodOutput.sampleUnits)) == NULL ) { return SZEROPADANDFFTTESTC_EFLS; } printf( "Units are \"%s\", ", unitString ); if ( XLALUnitAsString( unitString, LALUnitTextSize, &expectedUnit) == NULL ) { return SZEROPADANDFFTTESTC_EFLS; } printf( "should be \"%s\"\n", unitString ); } if (result != 0) { printf(" FAIL: Valid data test #1\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output values */ if (optVerbose) { printf("hBarTilde(0)=%g + %g i, should be %g\n", crealf(goodOutput.data->data[0]), cimagf(goodOutput.data->data[0]), crealf(expectedOutputDataData[0])); } if ( fabsf(crealf(goodOutput.data->data[0]) - crealf(expectedOutputDataData[0])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL || fabsf(cimagf(goodOutput.data->data[0])) > SZEROPADANDFFTTESTC_TOL ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } for (i=1; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { f = i * SZEROPADANDFFTTESTC_DELTAF; if (optVerbose) { printf("hBarTilde(%f Hz)=%g + %g i, should be %g + %g i\n", f, crealf(goodOutput.data->data[i]), cimagf(goodOutput.data->data[i]), crealf(expectedOutputDataData[i]), cimagf(expectedOutputDataData[i])); } if (fabsf(crealf(goodOutput.data->data[i]) - crealf(expectedOutputDataData[i])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL || fabsf(cimagf(goodOutput.data->data[i]) - cimagf(expectedOutputDataData[i])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } } /* write results to output file LALSPrintTimeSeries(&input, "zeropadgoodInput.dat"); LALCPrintFrequencySeries(&output, "zeropadgoodOutput.dat");*/ /* clean up valid data */ LALSDestroyVector(&status, &goodInput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCDestroyVector(&status, &goodOutput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } XLALDestroyREAL4Window(goodParams.window); LALCheckMemoryLeaks(); printf("PASS: all tests\n"); /**************** Process User-Entered Data, If Any **************/ /* ::TODO:: Fix this with length and window type to be specified */ if (optInputFile[0] && optOutputFile[0]){ /* construct plan*/ LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan), 2*optLength - 1, optMeasurePlan); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } goodInput.data = NULL; goodOutput.data = NULL; LALSCreateVector(&status, &goodInput.data, optLength); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EUSE, SZEROPADANDFFTTESTC_MSGEUSE) ) ) { return code; } LALCCreateVector(&status, &goodOutput.data, optLength); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* Read input file */ LALSReadTimeSeries(&status, &goodInput, optInputFile); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* calculate zero-pad and FFT */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCPrintFrequencySeries(&goodOutput, optOutputFile); printf("===== FFT of Zero-Padded User-Specified Data Written to File %s =====\n", optOutputFile); /* clean up valid data */ LALSDestroyVector(&status, &goodInput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCDestroyVector(&status, &goodOutput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCheckMemoryLeaks(); } return SZEROPADANDFFTTESTC_ENOM; }
float (crealf)(float complex z) { return crealf(z); }
float my_float_real(float complex c) { return crealf(c); }
int main(int argc, char *argv[]) { bool wantwf, verb; int ix, iz, is, it, wfit, im, ik, i, j, itau; int ns, nx, nz, nt, wfnt, rnx, rnz, nzx, rnzx, vnx, ntau, htau, nds; int scalet, snap, snapshot, fnx, fnz, fnzx, nk, nb; int rectx, rectz, repeat, gpz, n, m, pad1, trunc, spx, spz; float dt, t0, z0, dz, x0, dx, s0, ds, wfdt, srctrunc; float dtau, tau0, tau; int nr, ndr, nr0; char *path1, *path2, number[5], *left, *right; double tstart, tend; struct timeval tim; /*wavenumber domain tapering*/ int taper; float *ktp; float ktmp,kx_trs,kz_trs,thresh; float dkx,dkz,kx0,kz0; float kx,kz; int nkz; sf_complex c, **lt, **rt; sf_complex *ww, **dd, ***dd3; float ***img1, **img2, ***mig1, **mig2; float *rr, **ccr, **sill, ***fwf, ***bwf; sf_complex *cwave, *cwavem, **wave, *curr; sf_axis at, ax, az, atau; sf_file Fdat, Fsrc, Fimg1, Fimg2; sf_file Ffwf, Fbwf, Fvel; sf_file Fleft, Fright; int cpuid, numprocs, nth, nspad, iturn; float *sendbuf, *recvbuf; sf_complex *sendbufc, *recvbufc; MPI_Comm comm=MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &cpuid); MPI_Comm_size(comm, &numprocs); sf_init(argc, argv); #ifdef _OPENMP #pragma omp parallel { nth=omp_get_num_threads(); } sf_warning(">>> Using %d threads <<<", nth); #endif gettimeofday(&tim, NULL); tstart=tim.tv_sec+(tim.tv_usec/1000000.0); if (!sf_getint("taper",&taper)) taper=0; /* tapering in the frequency domain */ if (!sf_getfloat("thresh",&thresh)) thresh=0.92; /* tapering threshold */ if(!sf_getbool("wantwf", &wantwf)) wantwf=false; if(!sf_getbool("verb", &verb)) verb=false; if(!sf_getint("pad1", &pad1)) pad1=1; /* padding factor on the first axis */ if(!sf_getint("nb", &nb)) sf_error("Need nb= "); if(!sf_getfloat("srctrunc", &srctrunc)) srctrunc=0.4; if(!sf_getint("rectx", &rectx)) rectx=2; if(!sf_getint("rectz", &rectz)) rectz=2; if(!sf_getint("repeat", &repeat)) repeat=2; if(!sf_getint("scalet", &scalet)) scalet=1; if(!sf_getint("snap", &snap)) snap=100; /* interval of the output wavefield */ if(!sf_getint("snapshot", &snapshot)) snapshot=0; /* print out the wavefield snapshots of this shot */ if(!sf_getint("nds", &nds)) sf_error("Need nds=!"); /* source and receiver positions */ if(!sf_getint("gpz", &gpz)) sf_error("Need gpz="); if(!sf_getint("spx", &spx)) sf_error("Need spx="); if(!sf_getint("spz", &spz)) sf_error("Need spz="); /* tau parameters */ if(!sf_getint("ntau", &ntau)) sf_error("Need ntau="); if(!sf_getfloat("dtau", &dtau)) sf_error("Need dtau="); if(!sf_getfloat("tau0", &tau0)) sf_error("Need tau0="); /* geometry parameters */ if(!sf_getint("rnx", &rnx)) sf_error("Need rnx="); if(!sf_getint("ndr", &ndr)) ndr=1; if(!sf_getint("nr0", &nr0)) nr0=0; /* input/output files */ Fdat=sf_input("--input"); Fimg1=sf_output("--output"); Fimg2=sf_output("Fimg2"); Fsrc=sf_input("Fsrc"); Fvel=sf_input("Fpadvel"); if(wantwf){ Ffwf=sf_output("Ffwf"); Fbwf=sf_output("Fbwf"); } at=sf_iaxa(Fsrc, 1); nt=sf_n(at); dt=sf_d(at); t0=sf_o(at); ax=sf_iaxa(Fvel, 2); vnx=sf_n(ax); dx=sf_d(ax); x0=sf_o(ax); az=sf_iaxa(Fvel, 1); rnz=sf_n(az); dz=sf_d(az); z0=sf_o(az); if(!sf_histint(Fdat, "n2", &nr)) sf_error("Need n2= in input!"); if(!sf_histint(Fdat, "n3", &ns)) sf_error("Need n3= in input!"); if(!sf_histfloat(Fdat, "d3", &ds)) sf_error("Need d3= in input!"); if(!sf_histfloat(Fdat, "o3", &s0)) sf_error("Need o3= in input!"); wfnt=(nt-1)/scalet+1; wfdt=dt*scalet; /* double check the geometry parameters */ if(nds != (int)(ds/dx)) sf_error("Need ds/dx= %d", nds); //sf_warning("s0=%g, x0+(rnx-1)*dx/2=%g", s0, x0+(rnx-1)*dx/2); //if(s0 != x0+(rnx-1)*dx/2) sf_error("Wrong origin information!"); if(vnx != nds*(ns-1)+rnx) sf_error("Wrong dimension in x axis!"); /* set up the output files */ atau=sf_iaxa(Fsrc, 1); sf_setn(atau, ntau); sf_setd(atau, dtau); sf_seto(atau, tau0); sf_setlabel(atau, "Tau"); sf_setunit(atau, "s"); sf_oaxa(Fimg1, az, 1); sf_oaxa(Fimg1, ax, 2); sf_oaxa(Fimg1, atau, 3); sf_oaxa(Fimg2, az, 1); sf_oaxa(Fimg2, ax, 2); sf_putint(Fimg2, "n3", 1); sf_settype(Fimg1, SF_FLOAT); sf_settype(Fimg2, SF_FLOAT); if(wantwf){ sf_setn(ax, rnx); sf_seto(ax, -(rnx-1)*dx/2.0); sf_oaxa(Ffwf, az, 1); sf_oaxa(Ffwf, ax, 2); sf_putint(Ffwf, "n3", (wfnt-1)/snap+1); sf_putfloat(Ffwf, "d3", snap*wfdt); sf_putfloat(Ffwf, "o3", t0); sf_putstring(Ffwf, "label3", "Time"); sf_putstring(Ffwf, "unit3", "s"); sf_settype(Ffwf, SF_FLOAT); sf_oaxa(Fbwf, az, 1); sf_oaxa(Fbwf, ax, 2); sf_putint(Fbwf, "n3", (wfnt-1)/snap+1); sf_putfloat(Fbwf, "d3", -snap*wfdt); sf_putfloat(Fbwf, "o3", (wfnt-1)*wfdt); sf_putstring(Fbwf, "label3", "Time"); sf_putstring(Fbwf, "unit3", "s"); sf_settype(Fbwf, SF_FLOAT); } nx=rnx+2*nb; nz=rnz+2*nb; nzx=nx*nz; rnzx=rnz*rnx; nk=cfft2_init(pad1, nz, nx, &fnz, &fnx); fnzx=fnz*fnx; if(ns%numprocs==0) nspad=ns; else nspad=(ns/numprocs+1)*numprocs; /* print axies parameters for double check */ sf_warning("cpuid=%d, numprocs=%d, nspad=%d", cpuid, numprocs, nspad); sf_warning("nt=%d, dt=%g, scalet=%d, wfnt=%d, wfdt=%g",nt, dt, scalet, wfnt, wfdt); sf_warning("vnx=%d, nx=%d, dx=%g, nb=%d, rnx=%d", vnx, nx, dx, nb, rnx); sf_warning("nr=%d, ndr=%d, nr0=%g", nr, ndr, nr0); sf_warning("nz=%d, rnz=%d, dz=%g, z0=%g", nz, rnz, dz, z0); sf_warning("spx=%d, spz=%d, gpz=%d", spx, spz, gpz); sf_warning("ns=%d, ds=%g, s0=%g", ns, ds, s0); sf_warning("ntau=%d, dtau=%g, tau0=%g", ntau, dtau, tau0); sf_warning("nzx=%d, fnzx=%d, nk=%d", nzx, fnzx, nk); /* allocate storage and read data */ ww=sf_complexalloc(nt); sf_complexread(ww, nt, Fsrc); sf_fileclose(Fsrc); gpz=gpz+nb; spz=spz+nb; spx=spx+nb; nr0=nr0+nb; trunc=srctrunc/dt+0.5; dd=sf_complexalloc2(nt, nr); if(cpuid==0) dd3=sf_complexalloc3(nt, nr, numprocs); rr=sf_floatalloc(nzx); reflgen(nz, nx, spz, spx, rectz, rectx, repeat, rr); fwf=sf_floatalloc3(rnz, rnx, wfnt); bwf=sf_floatalloc3(rnz, rnx, wfnt); img1=sf_floatalloc3(rnz, vnx, ntau); img2=sf_floatalloc2(rnz, vnx); mig1=sf_floatalloc3(rnz, rnx, ntau); mig2=sf_floatalloc2(rnz, rnx); ccr=sf_floatalloc2(rnz, rnx); sill=sf_floatalloc2(rnz, rnx); curr=sf_complexalloc(fnzx); cwave=sf_complexalloc(nk); cwavem=sf_complexalloc(nk); icfft2_allocate(cwavem); if (taper!=0) { dkz = 1./(fnz*dz); kz0 = -0.5/dz; dkx = 1./(fnx*dx); kx0 = -0.5/dx; nkz = fnz; sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0); sf_warning("nk=%d,nkz=%d,nkx=%d",nk,nkz,fnx); kx_trs = thresh*fabs(0.5/dx); kz_trs = thresh*fabs(0.5/dz); sf_warning("Applying kz tapering below %f",kz_trs); sf_warning("Applying kx tapering below %f",kx_trs); ktp = sf_floatalloc(nk); /* constructing the tapering op */ for (ix=0; ix < fnx; ix++) { kx = kx0+ix*dkx; for (iz=0; iz < nkz; iz++) { kz = kz0+iz*dkz; ktmp = 1.; if (fabs(kx) > kx_trs) ktmp *= powf((2*kx_trs - fabs(kx))/(kx_trs),2); if (fabs(kz) > kz_trs) ktmp *= powf((2*kz_trs - fabs(kz))/(kz_trs),2); ktp[iz+ix*nkz] = ktmp; } } } /* initialize image tables that would be used for summing images */ #ifdef _OPENMP #pragma omp parallel for private(ix, iz, itau) #endif for(ix=0; ix<vnx; ix++){ for(iz=0; iz<rnz; iz++){ img2[ix][iz]=0.; for(itau=0; itau<ntau; itau++){ img1[itau][ix][iz]=0.; } } } path1=sf_getstring("path1"); path2=sf_getstring("path2"); if(path1==NULL) path1="./mat/left"; if(path2==NULL) path2="./mat/right"; /* shot loop */ for (iturn=0; iturn*numprocs<nspad; iturn++){ is=iturn*numprocs+cpuid; /* read data */ if(cpuid==0){ sf_seek(Fdat, ((off_t) is)*((off_t) nr)*((off_t) nt)*sizeof(float complex), SEEK_SET); if((iturn+1)*numprocs<=ns){ sf_complexread(dd3[0][0], nr*nt*numprocs, Fdat); }else{ sf_complexread(dd3[0][0], nr*nt*(ns-iturn*numprocs), Fdat); for(is=ns; is<nspad; is++) for(ix=0; ix<nr; ix++) for(it=0; it<nt; it++) dd3[is-iturn*numprocs][ix][it]=sf_cmplx(0.,0.); is=iturn*numprocs; } sendbufc=dd3[0][0]; recvbufc=dd[0]; }else{ sendbufc=NULL; recvbufc=dd[0]; } MPI_Scatter(sendbufc, nt*nr, MPI_COMPLEX, recvbufc, nt*nr, MPI_COMPLEX, 0, comm); if(is<ns){ /* effective shot loop */ /* construct the names of left and right matrices */ left=sf_charalloc(strlen(path1)); right=sf_charalloc(strlen(path2)); strcpy(left, path1); strcpy(right, path2); sprintf(number, "%d", is+1); strcat(left, number); strcat(right, number); Fleft=sf_input(left); Fright=sf_input(right); if(!sf_histint(Fleft, "n1", &n) || n != nzx) sf_error("Need n1=%d in Fleft", nzx); if(!sf_histint(Fleft, "n2", &m)) sf_error("No n2 in Fleft"); if(!sf_histint(Fright, "n1", &n) || n != m) sf_error("Need n1=%d in Fright", m); if(!sf_histint(Fright, "n2", &n) || n != nk) sf_error("Need n2=%d in Fright", nk); /* allocate storage for each shot migration */ lt=sf_complexalloc2(nzx, m); rt=sf_complexalloc2(m, nk); sf_complexread(lt[0], nzx*m, Fleft); sf_complexread(rt[0], m*nk, Fright); sf_fileclose(Fleft); sf_fileclose(Fright); /* initialize curr and imaging variables */ #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for(iz=0; iz<fnzx; iz++){ curr[iz]=sf_cmplx(0.,0.); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, itau) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig2[ix][iz]=0.; ccr[ix][iz]=0.; sill[ix][iz]=0.; for(itau=0; itau<ntau; itau++){ mig1[itau][ix][iz]=0.; } } } /* wave */ wave=sf_complexalloc2(fnzx, m); /* snapshot */ if(wantwf && is==snapshot) wantwf=true; else wantwf=false; /* forward propagation */ wfit=0; for(it=0; it<nt; it++){ if(verb) sf_warning("Forward propagation it=%d/%d",it+1, nt); cfft2(curr, cwave); for(im=0; im<m; im++){ #ifdef _OPENMP #pragma omp parallel for private(ik) #endif for(ik=0; ik<nk; ik++){ #ifdef SF_HAS_COMPLEX_H cwavem[ik]=cwave[ik]*rt[ik][im]; #else cwavem[ik]=sf_cmul(cwave[ik],rt[ik][im]); #endif } icfft2(wave[im],cwavem); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it) #endif for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ i=iz+ix*nz; j=iz+ix*fnz; if(it<trunc){ #ifdef SF_HAS_COMPLEX_H c=ww[it]*rr[i]; #else c=sf_crmul(ww[it],rr[i]); #endif }else{ c=sf_cmplx(0.,0.); } // c += curr[j]; for(im=0; im<m; im++){ #ifdef SF_HAS_COMPLEX_H c += lt[im][i]*wave[im][j]; #else c += sf_cmul(lt[im][i], wave[im][j]); #endif } curr[j]=c; } } if (taper!=0) { if (it%taper == 0) { cfft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*ktp[ik]; #else cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]); #endif } icfft2(curr,cwavem); } } if(it%scalet==0){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ fwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]); } } wfit++; } } //end of it /* check wfnt */ if(wfit != wfnt) sf_error("At this point, wfit should be equal to wfnt"); /* backward propagation starts from here... */ #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for(iz=0; iz<fnzx; iz++){ curr[iz]=sf_cmplx(0.,0.); } wfit=wfnt-1; for(it=nt-1; it>=0; it--){ if(verb) sf_warning("Backward propagation it=%d/%d",it+1, nt); #ifdef _OPENMP #pragma omp parallel for private(ix) #endif for(ix=0; ix<nr; ix++){ curr[(nr0+ix*ndr)*fnz+gpz]+=dd[ix][it]; } cfft2(curr, cwave); for(im=0; im<m; im++){ #ifdef _OPENMP #pragma omp parallel for private(ik) #endif for(ik=0; ik<nk; ik++){ #ifdef SF_HAS_COMPLEX_H cwavem[ik]=cwave[ik]*conjf(rt[ik][im]); #else cwavem[ik]=sf_cmul(cwave[ik],conjf(rt[ik][im])); #endif } icfft2(wave[im],cwavem); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it) #endif for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ i=iz+ix*nz; j=iz+ix*fnz; // c=curr[j]; c=sf_cmplx(0.,0.); for(im=0; im<m; im++){ #ifdef SF_HAS_COMPLEX_H c += conjf(lt[im][i])*wave[im][j]; #else c += sf_cmul(conjf(lt[im][i]), wave[im][j]); #endif } curr[j]=c; } } if (taper!=0) { if (it%taper == 0) { cfft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*ktp[ik]; #else cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]); #endif } icfft2(curr,cwavem); } } if(it%scalet==0){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ bwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]); ccr[ix][iz] += fwf[wfit][ix][iz]*bwf[wfit][ix][iz]; sill[ix][iz] += fwf[wfit][ix][iz]*fwf[wfit][ix][iz]; } } wfit--; } } //end of it if(wfit != -1) sf_error("Check program! The final wfit should be -1!"); /* free storage */ free(*rt); free(rt); free(*lt); free(lt); free(*wave); free(wave); free(left); free(right); /* normalized image */ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for (ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig2[ix][iz]=ccr[ix][iz]/(sill[ix][iz]+SF_EPS); // sill[ix][iz]=0.; } } /* time-shift imaging condition */ for(itau=0; itau<ntau; itau++){ //sf_warning("itau/ntau=%d/%d", itau+1, ntau); tau=itau*dtau+tau0; htau=tau/wfdt; for(it=abs(htau); it<wfnt-abs(htau); it++){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig1[itau][ix][iz]+=fwf[it+htau][ix][iz]*bwf[it-htau][ix][iz]; // sill[ix][iz]+=fwf[it+htau][ix][iz]*fwf[it+htau][ix][iz]; } // end of iz } // end of ix } // end of it //#ifdef _OPENMP //#pragma omp parallel for private(ix, iz) //#endif /* source illumination */ // for(ix=0; ix<rnx; ix++){ // for(iz=0; iz<rnz; iz++){ // mig1[itau][ix][iz] = mig1[itau][ix][iz]/(sill[ix][iz]+SF_EPS); // } // } } //end of itau /* output wavefield snapshot */ if(wantwf){ for(it=0; it<wfnt; it++){ if(it%snap==0){ sf_floatwrite(fwf[it][0], rnzx, Ffwf); sf_floatwrite(bwf[wfnt-1-it][0], rnzx, Fbwf); } } sf_fileclose(Ffwf); sf_fileclose(Fbwf); } /* add all the shot images that are on the same node */ #ifdef _OPENMP #pragma omp parallel for private(itau, ix, iz) #endif for(itau=0; itau<ntau; itau++){ for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ img1[itau][ix+is*nds][iz] += mig1[itau][ix][iz]; } } } #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ img2[ix+is*nds][iz] += mig2[ix][iz]; } } } // end of is<ns } // end of iturn ////////////////end of ishot MPI_Barrier(comm); cfft2_finalize(); sf_fileclose(Fdat); free(ww); free(rr); free(*dd); free(dd); if(cpuid==0) {free(**dd3); free(*dd3); free(dd3);} free(cwave); free(cwavem); free(curr); free(*ccr); free(ccr); free(*sill); free(sill); free(**fwf); free(*fwf); free(fwf); free(**bwf); free(*bwf); free(bwf); free(**mig1); free(*mig1); free(mig1); free(*mig2); free(mig2); /* sum image */ if(cpuid==0){ sendbuf=(float *)MPI_IN_PLACE; recvbuf=img1[0][0]; }else{ sendbuf=img1[0][0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, ntau*vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm); if(cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=img2[0]; }else{ sendbuf=img2[0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm); /* output image */ if(cpuid==0){ sf_floatwrite(img1[0][0], ntau*vnx*rnz, Fimg1); sf_floatwrite(img2[0], vnx*rnz, Fimg2); } MPI_Barrier(comm); sf_fileclose(Fimg1); sf_fileclose(Fimg2); free(**img1); free(*img1); free(img1); free(*img2); free(img2); gettimeofday(&tim, NULL); tend=tim.tv_sec+(tim.tv_usec/1000000.0); sf_warning(">> The computing time is %.3lf minutes <<", (tend-tstart)/60.); MPI_Finalize(); exit(0); }
void LALTfrWv (LALStatus *stat, REAL4Vector* sig, TimeFreqRep *tfr, TimeFreqParam *param) { INT4 nf; INT4 time; INT4 column, row; INT4 taumax, tau; REAL4Vector *lacf = NULL; /* local autocorrelation function */ COMPLEX8Vector *vtmp = NULL; RealFFTPlan *plan = NULL; INITSTATUS(stat); ATTATCHSTATUSPTR (stat); /* Make sure the arguments are not NULL: */ ASSERT (sig, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (param, stat, TFR_ENULL, TFR_MSGENULL); /* Make sure the data pointers are not NULL: */ ASSERT (sig->data, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->timeInstant, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->freqBin, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->map, stat, TFR_ENULL, TFR_MSGENULL); /* Make sure the requested TFR type corresponds to what will be done */ ASSERT (tfr->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME); ASSERT (param->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME); /* Make sure the number of freq bins is a positive number: */ nf = tfr->fRow; ASSERT (nf > 0 , stat, TFR_EFROW, TFR_MSGEFROW); /* Make sure the number of freq bins is a power of 2: */ while(!(nf & 1)) nf = nf>>1; ASSERT (nf == 1, stat, TFR_EFROW, TFR_MSGEFROW); /* Make sure the timeInstant indicates existing time instants */ for (column=0 ; column<tfr->tCol ; column++) { if ((tfr->timeInstant[column] < 0) || (tfr->timeInstant[column] > (INT4)(sig->length-1))) { ASSERT (tfr->timeInstant[column] > 0, stat, TFR_EBADT, TFR_MSGEBADT); ASSERT (tfr->timeInstant[column] < (INT4)sig->length, stat, TFR_EBADT, TFR_MSGEBADT); } } TRY(LALCreateForwardRealFFTPlan(stat->statusPtr, &plan,(UINT4)tfr->fRow,0),stat); TRY(LALSCreateVector(stat->statusPtr, &lacf, tfr->fRow), stat); TRY(LALCCreateVector(stat->statusPtr, &vtmp, tfr->fRow/2+1), stat); for (column = 0; column < tfr->tCol; column++) { for (row = 0; row < tfr->fRow; row++) lacf->data[row] = 0.0; time = tfr->timeInstant[column]; taumax = MIN (time, (INT4)(sig->length -1 - time)); taumax = MIN (taumax, (tfr->fRow / 2 - 1)); for (tau = -taumax; tau <= taumax; tau++) { row = (tfr->fRow+tau)%tfr->fRow; lacf->data[row] = sig->data[time + tau]*sig->data[time - tau]; } tau=tfr->fRow/2; if ((time<=(INT4)sig->length-tau-1)&(time>=tau)) lacf->data[tau] = sig->data[time+tau]*sig->data[time-tau]; LALForwardRealFFT(stat->statusPtr, vtmp, lacf, plan); for (row = 0; row < (tfr->fRow/2+1); row++) tfr->map[column][row] = crealf(vtmp->data[row]); } /* Reflecting frequency halfing in WV distrob so multiply by 1/2 */ for (row = 0; row < (tfr->fRow/2+1) ; row++) tfr->freqBin[row] = (REAL4) row / (2 *tfr->fRow); TRY(LALSDestroyVector(stat->statusPtr, &lacf), stat); TRY(LALCDestroyVector(stat->statusPtr, &vtmp), stat); TRY(LALDestroyRealFFTPlan(stat->statusPtr, &plan), stat); DETATCHSTATUSPTR (stat); (void)param; /* normal exit */ RETURN (stat); }
int main(int argc, char* argv[]) { int n1, n2, ns, nw; int is, iw, **pp, i, ip; double omega; float dw, ow; float *ahess, **ahesss, **ahessr; sf_complex **f, ***swave, ***rwave; sf_complex **stemp, **rtemp; sf_file in, out, list, us, ur, wvlt; int uts, mts; sf_init(argc,argv); in = sf_input("in"); out = sf_output("out"); if (!sf_getint("uts",&uts)) uts=0; /* number of OMP threads */ #ifdef _OPENMP mts = omp_get_max_threads(); #else mts = 1; #endif uts = (uts < 1)? mts: uts; /* read model dimensions */ if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input."); if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input."); /* read source wavefield */ if (NULL == sf_getstring("us")) sf_error("Need source wavefield us="); us = sf_input("us"); if (!sf_histint(us,"n3",&ns)) sf_error("No ns=."); if (!sf_histint(us,"n4",&nw)) sf_error("No nw=."); if (!sf_histfloat(us,"d4",&dw)) sf_error("No dw=."); if (!sf_histfloat(us,"o4",&ow)) sf_error("No ow=."); /* read receiver wavefield */ if (NULL == sf_getstring("ur")) sf_error("Need receiver wavefield ur="); ur = sf_input("ur"); /* read wavelet */ if (NULL == sf_getstring("wvlt")) sf_error("Need wvlt="); wvlt = sf_input("wvlt"); f = sf_complexalloc2(nw,ns); sf_complexread(f[0],nw*ns,wvlt); sf_fileclose(wvlt); /* read list */ if (NULL == sf_getstring("list")) sf_error("Need list="); list = sf_input("list"); pp = sf_intalloc2(2,ns); sf_intread(pp[0],2*ns,list); sf_fileclose(list); /* allocate memory */ swave = sf_complexalloc3(n1,n2,ns); rwave = sf_complexalloc3(n1,n2,ns); stemp = sf_complexalloc2(ns,ns); rtemp = sf_complexalloc2(ns,ns); ahesss = sf_floatalloc2(n1*n2,ns); ahessr = sf_floatalloc2(n1*n2,ns); ahess = sf_floatalloc(n1*n2); /* loop over frequency */ for (iw=0; iw < nw; iw++) { omega = (double) 2.*SF_PI*(ow+iw*dw); /* read wavefields */ sf_complexread(swave[0][0],n1*n2*ns,us); sf_complexread(rwave[0][0],n1*n2*ns,ur); #ifdef _OPENMP #pragma omp parallel num_threads(uts) private(is,ip,i) #endif { #ifdef _OPENMP #pragma omp for #endif for (is=0; is < ns; is++) { for (ip=0; ip < ns; ip++) { /* temps */ stemp[is][ip] = -omega*omega/conjf(f[ip][iw]) *rwave[is][pp[ip][1]][pp[ip][0]]; /* tempr */ rtemp[is][ip] = -omega*omega/conjf(f[ip][iw]) *conjf(swave[is][pp[ip][1]][pp[ip][0]]); } } /* loop over model */ #ifdef _OPENMP #pragma omp for #endif for (i=0; i < n1*n2; i++) { for (is=0; is < ns; is++) { for (ip=0; ip < ns; ip++) { ahesss[ip][i] += crealf( conjf(swave[ip][0][i]*swave[is][0][i])*stemp[is][ip]); ahessr[ip][i] += crealf( conjf(swave[ip][0][i])*rwave[is][0][i]*rtemp[is][ip]); } } } } } /* assemble */ #ifdef _OPENMP #pragma omp parallel for num_threads(uts) private(i,ip) #endif for (i=0; i < n1*n2; i++) { for (ip=0; ip < ns; ip++) { ahess[i] += powf(ahesss[ip][i]+ahessr[ip][i],2.); } } /* output hessian */ sf_floatwrite(ahess,n1*n2,out); exit(0); }
int main() { int ftype = LIQUID_IIRDES_BUTTER; // filter prototype unsigned int n = 7; // Hilbert filter order float Ap = 0.1f; // pass-band ripple [dB] float As = 60.0f; // stop-band attenuation [dB] float fc = 0.123456; // signal center frequency unsigned int num_input_samples=180; // number of samples // derived values unsigned int num_total_samples = num_input_samples + 50; // allow for filter settling // create Hilbert transform objects iirhilbf qi = iirhilbf_create(ftype,n,Ap,As); // interpolator iirhilbf qd = iirhilbf_create(ftype,n,Ap,As); // decimator iirhilbf_print(qi); // data arrays float complex x[ num_total_samples]; // complex input float y[2*num_total_samples]; // real output float complex z[ num_total_samples]; // complex output // initialize input array unsigned int i; for (i=0; i<num_total_samples; i++) { x[i] = cexpf(_Complex_I*2*M_PI*fc*i) + cexpf(_Complex_I*2*M_PI*fc*i*1.3f)*0.1f; x[i] *= (i < num_input_samples) ? 1.855f*hamming(i,num_input_samples) : 0.0f; } // execute interpolator (complex to real conversion) iirhilbf_interp_execute_block(qi, x, num_total_samples, y); // execute decimator (real to complex conversion) iirhilbf_decim_execute_block(qd, y, num_total_samples, z); // destroy Hilbert transform object iirhilbf_destroy(qi); iirhilbf_destroy(qd); // // export results to file // FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n"); fprintf(fid,"num_input_samples=%u;\n", num_input_samples); fprintf(fid,"num_total_samples=%u;\n", num_total_samples); fprintf(fid,"tx = 0:(num_total_samples-1);\n"); fprintf(fid,"ty = [0:(2*num_total_samples-1)]/2;\n"); fprintf(fid,"tz = tx;\n"); for (i=0; i<num_total_samples; i++) { // print results fprintf(fid,"x(%3u) = %12.4e + %12.4ej;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"y(%3u) = %12.4e;\n", 2*i+1, y[2*i+0]); fprintf(fid,"y(%3u) = %12.4e;\n", 2*i+2, y[2*i+1]); fprintf(fid,"z(%3u) = %12.4e + %12.4ej;\n", i+1, crealf(z[i]), cimagf(z[i])); } fprintf(fid,"figure;\n"); fprintf(fid,"subplot(3,1,1);\n"); fprintf(fid," plot(tx,real(x),'Color',[0.00 0.25 0.50],'LineWidth',1.3,...\n"); fprintf(fid," tx,imag(x),'Color',[0.00 0.50 0.25],'LineWidth',1.3);\n"); fprintf(fid," legend('real','imag','location','northeast');\n"); fprintf(fid," ylabel('transformed/complex');\n"); fprintf(fid," axis([0 num_total_samples -2 2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(3,1,2);\n"); fprintf(fid," plot(ty,y,'Color',[0.00 0.25 0.50],'LineWidth',1.3);\n"); fprintf(fid," ylabel('original/real');\n"); fprintf(fid," axis([0 num_total_samples -2 2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(3,1,3);\n"); fprintf(fid," plot(tz,real(z),'Color',[0.00 0.25 0.50],'LineWidth',1.3,...\n"); fprintf(fid," tz,imag(z),'Color',[0.00 0.50 0.25],'LineWidth',1.3);\n"); fprintf(fid," legend('real','imag','location','northeast');\n"); fprintf(fid," ylabel('transformed/complex');\n"); fprintf(fid," axis([0 num_total_samples -2 2]);\n"); fprintf(fid," grid on;\n"); // plot results fprintf(fid,"nfft=4096;\n"); fprintf(fid,"%% compute normalized windowing functions\n"); fprintf(fid,"X=20*log10(abs(fftshift(fft(x/num_input_samples,nfft))));\n"); fprintf(fid,"Y=20*log10(abs(fftshift(fft(y/num_input_samples,nfft))));\n"); fprintf(fid,"Z=20*log10(abs(fftshift(fft(z/num_input_samples,nfft))));\n"); fprintf(fid,"f =[0:(nfft-1)]/nfft-0.5;\n"); fprintf(fid,"figure; plot(f+0.5,X,'LineWidth',1,'Color',[0.50 0.50 0.50],...\n"); fprintf(fid," f*2, Y,'LineWidth',2,'Color',[0.00 0.50 0.25],...\n"); fprintf(fid," f+0.5,Z,'LineWidth',1,'Color',[0.00 0.25 0.50]);\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([-1.0 1.0 -80 20]);\n"); fprintf(fid,"xlabel('normalized frequency');\n"); fprintf(fid,"ylabel('PSD [dB]');\n"); fprintf(fid,"legend('original/cplx','transformed/real','regenerated/cplx','location','northeast');"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
// receive the 'SIGNAL' field void wlanframesync_execute_rxsignal(wlanframesync _q) { _q->timer++; if (_q->timer < 80) return; // reset timer _q->timer = 0; // run fft float complex * rc; windowcf_read(_q->input_buffer, &rc); memmove(_q->x, &rc[16-2], 64*sizeof(float complex)); // compute fft, storing result into _q->X FFT_EXECUTE(_q->fft); // recover symbol, correcting for gain, pilot phase, etc. wlanframesync_rxsymbol(_q); // demodulate, decode, ... memset(_q->signal_int, 0x00, 6*sizeof(unsigned char)); _q->signal_int[0] |= crealf(_q->X[38]) > 0.0f ? 0x80 : 0x00; _q->signal_int[0] |= crealf(_q->X[39]) > 0.0f ? 0x40 : 0x00; _q->signal_int[0] |= crealf(_q->X[40]) > 0.0f ? 0x20 : 0x00; _q->signal_int[0] |= crealf(_q->X[41]) > 0.0f ? 0x10 : 0x00; _q->signal_int[0] |= crealf(_q->X[42]) > 0.0f ? 0x08 : 0x00; // 43 : pilot _q->signal_int[0] |= crealf(_q->X[44]) > 0.0f ? 0x04 : 0x00; _q->signal_int[0] |= crealf(_q->X[45]) > 0.0f ? 0x02 : 0x00; _q->signal_int[0] |= crealf(_q->X[46]) > 0.0f ? 0x01 : 0x00; _q->signal_int[1] |= crealf(_q->X[47]) > 0.0f ? 0x80 : 0x00; _q->signal_int[1] |= crealf(_q->X[48]) > 0.0f ? 0x40 : 0x00; _q->signal_int[1] |= crealf(_q->X[49]) > 0.0f ? 0x20 : 0x00; _q->signal_int[1] |= crealf(_q->X[50]) > 0.0f ? 0x10 : 0x00; _q->signal_int[1] |= crealf(_q->X[51]) > 0.0f ? 0x08 : 0x00; _q->signal_int[1] |= crealf(_q->X[52]) > 0.0f ? 0x04 : 0x00; _q->signal_int[1] |= crealf(_q->X[53]) > 0.0f ? 0x02 : 0x00; _q->signal_int[1] |= crealf(_q->X[54]) > 0.0f ? 0x01 : 0x00; _q->signal_int[2] |= crealf(_q->X[55]) > 0.0f ? 0x80 : 0x00; _q->signal_int[2] |= crealf(_q->X[56]) > 0.0f ? 0x40 : 0x00; // 57 : pilot _q->signal_int[2] |= crealf(_q->X[58]) > 0.0f ? 0x20 : 0x00; _q->signal_int[2] |= crealf(_q->X[59]) > 0.0f ? 0x10 : 0x00; _q->signal_int[2] |= crealf(_q->X[60]) > 0.0f ? 0x08 : 0x00; _q->signal_int[2] |= crealf(_q->X[61]) > 0.0f ? 0x04 : 0x00; _q->signal_int[2] |= crealf(_q->X[62]) > 0.0f ? 0x02 : 0x00; _q->signal_int[2] |= crealf(_q->X[63]) > 0.0f ? 0x01 : 0x00; // 0 : NULL _q->signal_int[3] |= crealf(_q->X[ 1]) > 0.0f ? 0x80 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 2]) > 0.0f ? 0x40 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 3]) > 0.0f ? 0x20 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 4]) > 0.0f ? 0x10 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 5]) > 0.0f ? 0x08 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 6]) > 0.0f ? 0x04 : 0x00; // 7 : pilot _q->signal_int[3] |= crealf(_q->X[ 8]) > 0.0f ? 0x02 : 0x00; _q->signal_int[3] |= crealf(_q->X[ 9]) > 0.0f ? 0x01 : 0x00; _q->signal_int[4] |= crealf(_q->X[10]) > 0.0f ? 0x80 : 0x00; _q->signal_int[4] |= crealf(_q->X[11]) > 0.0f ? 0x40 : 0x00; _q->signal_int[4] |= crealf(_q->X[12]) > 0.0f ? 0x20 : 0x00; _q->signal_int[4] |= crealf(_q->X[13]) > 0.0f ? 0x10 : 0x00; _q->signal_int[4] |= crealf(_q->X[14]) > 0.0f ? 0x08 : 0x00; _q->signal_int[4] |= crealf(_q->X[15]) > 0.0f ? 0x04 : 0x00; _q->signal_int[4] |= crealf(_q->X[16]) > 0.0f ? 0x02 : 0x00; _q->signal_int[4] |= crealf(_q->X[17]) > 0.0f ? 0x01 : 0x00; _q->signal_int[5] |= crealf(_q->X[18]) > 0.0f ? 0x80 : 0x00; _q->signal_int[5] |= crealf(_q->X[19]) > 0.0f ? 0x40 : 0x00; _q->signal_int[5] |= crealf(_q->X[20]) > 0.0f ? 0x20 : 0x00; // 21 : pilot _q->signal_int[5] |= crealf(_q->X[22]) > 0.0f ? 0x10 : 0x00; _q->signal_int[5] |= crealf(_q->X[23]) > 0.0f ? 0x08 : 0x00; _q->signal_int[5] |= crealf(_q->X[24]) > 0.0f ? 0x04 : 0x00; _q->signal_int[5] |= crealf(_q->X[25]) > 0.0f ? 0x02 : 0x00; _q->signal_int[5] |= crealf(_q->X[26]) > 0.0f ? 0x01 : 0x00; // decode SIGNAL field wlanframesync_decode_signal(_q); // validate proper decoding if (!_q->signal_valid) { // reset synchronizer and return wlanframesync_reset(_q); return; } // set state _q->state = WLANFRAMESYNC_STATE_RXDATA; }
// frame detection void wlanframesync_execute_seekplcp(wlanframesync _q) { _q->timer++; // TODO : only check every 100 - 150 (decimates/reduced complexity) if (_q->timer < 64) return; // reset timer _q->timer = 0; // read contents of input buffer float complex * rc; windowcf_read(_q->input_buffer, &rc); // estimate gain // TODO : use gain from result of FFT unsigned int i; float g = 0.0f; for (i=16; i<80; i+=4) { // compute |rc[i]|^2 efficiently g += crealf(rc[i ])*crealf(rc[i ]) + cimagf(rc[i ])*cimagf(rc[i ]); g += crealf(rc[i+1])*crealf(rc[i+1]) + cimagf(rc[i+1])*cimagf(rc[i+1]); g += crealf(rc[i+2])*crealf(rc[i+2]) + cimagf(rc[i+2])*cimagf(rc[i+2]); g += crealf(rc[i+3])*crealf(rc[i+3]) + cimagf(rc[i+3])*cimagf(rc[i+3]); } g = 64.0f / (g + 1e-12f); // save gain (permits dynamic invocation of get_rssi() method) _q->g0 = g; // estimate S0 gain wlanframesync_estimate_gain_S0(_q, &rc[16], _q->G0a); // compute S0 metrics float complex s_hat; wlanframesync_S0_metrics(_q, _q->G0a, &s_hat); s_hat *= g; float tau_hat = cargf(s_hat) * (float)(16.0f) / (2*M_PI); #if DEBUG_WLANFRAMESYNC_PRINT printf(" - gain=%12.3f, rssi=%8.2f dB, s_hat=%12.4f <%12.8f>, tau_hat=%8.3f\n", sqrt(g), -10*log10(g), cabsf(s_hat), cargf(s_hat), tau_hat); #endif // if (cabsf(s_hat) > WLANFRAMESYNC_S0A_ABS_THRESH) { int dt = (int)roundf(tau_hat); // set timer appropriately... _q->timer = (16 + dt) % 16; //_q->timer += 32; // add delay to help ensure good S0 estimate (multiple of 16) _q->state = WLANFRAMESYNC_STATE_RXSHORT0; #if DEBUG_WLANFRAMESYNC_PRINT printf("********** frame detected! ************\n"); printf(" s_hat : %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat)); printf(" tau_hat : %12.8f\n", tau_hat); printf(" dt : %12d\n", dt); printf(" timer : %12u\n", _q->timer); #endif } }
int main(int argc, char* argv[]) { sf_file Fw_s=NULL, Fw_r=NULL; sf_file Fi=NULL, Fm=NULL, Fr=NULL; sf_axis ag,at,aw,ar; int ig,it,iw,ir; int ng,nt,nw,nr; int method; bool verb; bool adj; sf_complex **dat_s=NULL, *wfl_s=NULL; sf_complex **dat_r=NULL, *wfl_r=NULL; float **img=NULL; float **aa=NULL,**bb=NULL,**mm=NULL; sf_complex **ab=NULL; float **a0=NULL,**b0=NULL; float w,ws,wr,w0,dw; char *met=""; sf_init(argc,argv); if(! sf_getbool("verb", &verb)) verb=false; if(! sf_getint("method",&method)) method=0; /* extrapolation method */ if(! sf_getbool("adj", &adj)) adj=false;/* y=modeling; n=migration */ Fm = sf_input("abm"); Fr = sf_input("abr"); at=sf_iaxa(Fm,2); sf_setlabel(at,"t"); /* 'extrapolation axis' */ ar=sf_iaxa(Fr,1); sf_setlabel(ar,"r"); /* a,b reference */ if(method==0) sf_setn(ar,1); /* pure F-D */ nr=sf_n(ar); Fw_s = sf_input ( "in"); if (SF_COMPLEX !=sf_gettype(Fw_s)) sf_error("Need complex source"); /* 'position axis' (could be angle) */ ag = sf_iaxa(Fw_s,1); ng=sf_n(ag); sf_setlabel(ag,"g"); /* 'extrapolation axis' (could be time) */ at = sf_iaxa(Fw_s,2); nt=sf_n(at); sf_setlabel(at,"t"); aw = sf_iaxa(Fw_s,3); sf_setlabel(aw,"w"); /* frequency */ if(adj) { /* modeling */ Fw_r = sf_output("out"); sf_settype(Fw_r,SF_COMPLEX); Fi = sf_input ("img"); if (SF_FLOAT !=sf_gettype(Fi)) sf_error("Need float image"); sf_oaxa(Fw_r,ag,1); sf_oaxa(Fw_r,at,2); sf_oaxa(Fw_r,aw,3); } else { /* migration */ Fw_r = sf_input ("rwf"); if (SF_COMPLEX !=sf_gettype(Fw_r)) sf_error("Need complex data"); Fi = sf_output("out"); sf_settype(Fi,SF_FLOAT); sf_oaxa(Fi,ag,1); sf_oaxa(Fi,at,2); sf_putint(Fi,"n3",1); } img = sf_floatalloc2 (ng,nt); dat_s = sf_complexalloc2(ng,nt); dat_r = sf_complexalloc2(ng,nt); wfl_s = sf_complexalloc (ng); wfl_r = sf_complexalloc (ng); if(verb) { sf_raxa(ag); sf_raxa(at); sf_raxa(aw); sf_raxa(ar); } /* read ABM */ aa = sf_floatalloc2 (ng,nt); bb = sf_floatalloc2 (ng,nt); mm = sf_floatalloc2 (ng,nt); sf_floatread(aa[0],ng*nt,Fm); /* a coef */ sf_floatread(bb[0],ng*nt,Fm); /* b coef */ sf_floatread(mm[0],ng*nt,Fm); /* mask */ /* read ABr */ ab = sf_complexalloc2(nr,nt); a0 = sf_floatalloc2 (nr,nt); b0 = sf_floatalloc2 (nr,nt); sf_complexread(ab[0],nr*nt,Fr); for(it=0;it<nt;it++) { for(ir=0;ir<nr;ir++) { a0[it][ir] = crealf(ab[it][ir]); b0[it][ir] = cimagf(ab[it][ir]); } } /*------------------------------------------------------------*/ switch (method) { case 3: met="PSC"; break; case 2: met="FFD"; break; case 1: met="SSF"; break; case 0: met="XFD"; break; } /* from hertz to radian */ nw = sf_n(aw); dw = sf_d(aw) * 2.*SF_PI; w0 = sf_o(aw) * 2.*SF_PI; rweone_init(ag,at,aw,ar,method,verb); switch(method) { case 3: rweone_psc_coef(aa,bb,a0,b0); break; case 2: rweone_ffd_coef(aa,bb,a0,b0); break; case 1: ;/* SSF */ break; case 0: rweone_xfd_coef(aa,bb); break; } if(adj) { /* modeling */ } else { /* migration */ for(it=0;it<nt;it++) { for(ig=0;ig<ng;ig++) { img[it][ig] = 0.; } } } /*------------------------------------------------------------*/ if( adj) sf_floatread (img[0],ng*nt,Fi); for(iw=0;iw<nw;iw++) { w=w0+iw*dw; sf_warning("%s %d %d",met,iw,nw); if(adj) { sf_complexread(dat_s[0],ng*nt,Fw_s); ws = -w; /* causal */ for(ig=0;ig<ng;ig++) { wfl_s[ig] = sf_cmplx(0.,0.); } for(it=0;it<nt;it++) { for(ig=0;ig<ng;ig++) { #ifdef SF_HAS_COMPLEX_H wfl_s[ig] += dat_s[it][ig]; dat_r[it][ig] = wfl_s[ig]*img[it][ig]; #else wfl_s[ig] = sf_cadd(wfl_s[ig],dat_s[it][ig]); dat_r[it][ig] = sf_crmul(wfl_s[ig],img[it][ig]); #endif } if(method!=0) rweone_fk(ws,wfl_s,aa[it],a0[it],b0[it],mm[it],it); else rweone_fx(ws,wfl_s,aa[it],it); rweone_tap(wfl_s); } for(it=0;it<nt;it++) { for(ig=0;ig<ng;ig++) { dat_s[it][ig] = dat_r[it][ig]; } } wr = -w; /* causal */ for(ig=0;ig<ng;ig++) { wfl_r[ig] = sf_cmplx(0.,0.); } for(it=nt-1;it>=0;it--) { for(ig=0;ig<ng;ig++) { #ifdef SF_HAS_COMPLEX_H wfl_r[ig] += dat_s[it][ig]; #else wfl_r[ig] = sf_cadd(wfl_r[ig],dat_s[it][ig]); #endif dat_r[it][ig] = wfl_r[ig]; } if(method!=0) rweone_fk(wr,wfl_r,aa[it],a0[it],b0[it],mm[it],it); else rweone_fx(wr,wfl_r,aa[it],it); rweone_tap(wfl_r); } sf_complexwrite(dat_r[0],ng*nt,Fw_r); } else { ws = -w; /* causal */ wr = +w; /* anti-causal */ sf_complexread(dat_s[0],ng*nt,Fw_s); sf_complexread(dat_r[0],ng*nt,Fw_r); for(ig=0;ig<ng;ig++) { wfl_s[ig] = sf_cmplx(0,0); wfl_r[ig] = sf_cmplx(0,0); } for(it=0;it<=nt-2;it++) { for(ig=0;ig<ng;ig++) { #ifdef SF_HAS_COMPLEX_H wfl_s[ig] += dat_s[it][ig]; wfl_r[ig] += dat_r[it][ig]; #else wfl_s[ig] = sf_cadd(wfl_s[ig],dat_s[it][ig]); wfl_r[ig] = sf_cadd(wfl_r[ig],dat_r[it][ig]); #endif } rweone_spi(wfl_s,wfl_r,img[it]); if(method!=0) { rweone_fk(ws,wfl_s,aa[it],a0[it],b0[it],mm[it],it); rweone_fk(wr,wfl_r,aa[it],a0[it],b0[it],mm[it],it); } else { rweone_fx(ws,wfl_s,aa[it],it); rweone_fx(wr,wfl_r,aa[it],it); } } it=nt-1; rweone_spi(wfl_s,wfl_r,img[it]); } } if(!adj) sf_floatwrite (img[0],ng*nt,Fi); /*------------------------------------------------------------*/ exit(0); }
static int RunTest(int *iparam, float *dparam, real_Double_t *t_) { plasma_context_t *plasma; Quark_Task_Flags task_flags = Quark_Task_Flags_Initializer; PLASMA_Complex32_t *A, *AT, *A2 = NULL; PLASMA_desc *descA; real_Double_t t; int *ipiv, *ipiv2 = NULL; int i; int nb = iparam[TIMING_NB]; int m = iparam[TIMING_N]; int n = iparam[TIMING_NRHS]; int check = iparam[TIMING_CHECK]; int lda = m; PLASMA_sequence *sequence = NULL; PLASMA_request request = PLASMA_REQUEST_INITIALIZER; /* Initialize Plasma */ PLASMA_Init( iparam[TIMING_THRDNBR] ); PLASMA_Set(PLASMA_SCHEDULING_MODE, PLASMA_DYNAMIC_SCHEDULING ); PLASMA_Disable(PLASMA_AUTOTUNING); PLASMA_Set(PLASMA_TILE_SIZE, iparam[TIMING_NB] ); PLASMA_Set(PLASMA_INNER_BLOCK_SIZE, iparam[TIMING_IB] ); /* Allocate Data */ A = (PLASMA_Complex32_t *)malloc(lda*n*sizeof(PLASMA_Complex32_t)); AT = (PLASMA_Complex32_t *)malloc(lda*n*sizeof(PLASMA_Complex32_t)); /* Check if unable to allocate memory */ if ( ( !AT ) || (! A) ) { printf("Out of Memory \n "); return -1; } /* Initialiaze Data */ LAPACKE_clarnv_work(1, ISEED, lda*n, A); /* for(i=0; i<n; i++) { */ /* A[i*lda+i] += (float)m; */ /* } */ PLASMA_Desc_Create(&descA, AT, PlasmaComplexFloat, nb, nb, nb*nb, lda, n, 0, 0, m, n); PLASMA_cLapack_to_Tile((void*)A, lda, descA); /* Allocate Workspace */ ipiv = (int *)malloc( n*sizeof(int) ); /* Save AT in lapack layout for check */ if ( check ) { A2 = (PLASMA_Complex32_t *)malloc(lda*n*sizeof(PLASMA_Complex32_t)); ipiv2 = (int *)malloc( n*sizeof(int) ); LAPACKE_clacpy_work(LAPACK_COL_MAJOR,' ', m, n, A, lda, A2, lda); LAPACKE_cgetrf_work(LAPACK_COL_MAJOR, m, n, A2, lda, ipiv2 ); } plasma = plasma_context_self(); PLASMA_Sequence_Create(&sequence); QUARK_Task_Flag_Set(&task_flags, TASK_SEQUENCE, (intptr_t)sequence->quark_sequence); QUARK_Task_Flag_Set(&task_flags, TASK_THREAD_COUNT, iparam[TIMING_THRDNBR] ); plasma_dynamic_spawn(); CORE_cgetrf_rectil_init(); t = -cWtime(); QUARK_CORE_cgetrf_rectil(plasma->quark, &task_flags, *descA, AT, descA->mb*descA->nb, ipiv, sequence, &request, 0, 0, iparam[TIMING_THRDNBR]); PLASMA_Sequence_Wait(sequence); t += cWtime(); *t_ = t; PLASMA_Sequence_Destroy(sequence); /* Check the solution */ if ( check ) { float *work = (float *)malloc(max(m,n)*sizeof(float)); PLASMA_cTile_to_Lapack(descA, (void*)A, lda); /* Check ipiv */ for(i=0; i<n; i++) { if( ipiv[i] != ipiv2[i] ) { fprintf(stderr, "\nPLASMA (ipiv[%d] = %d, A[%d] = %e) / LAPACK (ipiv[%d] = %d, A[%d] = [%e])\n", i, ipiv[i], i, crealf(A[ i * lda + i ]), i, ipiv2[i], i, crealf(A2[ i * lda + i ])); break; } } dparam[TIMING_ANORM] = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaMaxNorm), m, n, A, lda, work); dparam[TIMING_XNORM] = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaMaxNorm), m, n, A2, lda, work); dparam[TIMING_BNORM] = 0.0; CORE_caxpy( m, n, -1.0, A, lda, A2, lda); dparam[TIMING_RES] = LAPACKE_clange_work(LAPACK_COL_MAJOR, lapack_const(PlasmaMaxNorm), m, n, A2, lda, work); free( A2 ); free( ipiv2 ); free( work ); } /* Deallocate Workspace */ PLASMA_Desc_Destroy(&descA); free( A ); free( AT ); free( ipiv ); PLASMA_Finalize(); return 0; }
int main() { // spectral periodogram options unsigned int nfft = 1200; // spectral periodogram FFT size unsigned int num_samples = 64000; // number of samples float fc = 0.20f; // carrier (relative to sampling rate) // create objects iirfilt_crcf filter_tx = iirfilt_crcf_create_lowpass(15, 0.05); nco_crcf mixer_tx = nco_crcf_create(LIQUID_VCO); nco_crcf mixer_rx = nco_crcf_create(LIQUID_VCO); iirfilt_crcf filter_rx = iirfilt_crcf_create_lowpass(7, 0.2); // set carrier frequencies nco_crcf_set_frequency(mixer_tx, fc * 2*M_PI); nco_crcf_set_frequency(mixer_rx, fc * 2*M_PI); // create objects for measuring power spectral density spgramcf spgram_tx = spgramcf_create_default(nfft); spgramf spgram_dac = spgramf_create_default(nfft); spgramcf spgram_rx = spgramcf_create_default(nfft); // run through loop one step at a time unsigned int i; for (i=0; i<num_samples; i++) { // STEP 1: generate input signal (filtered noise with offset tone) float complex v1 = (randnf() + randnf()*_Complex_I) + 3.0f*cexpf(-_Complex_I*0.2f*i); iirfilt_crcf_execute(filter_tx, v1, &v1); // save spectrum spgramcf_push(spgram_tx, v1); // STEP 2: mix signal up and save real part (DAC output) nco_crcf_mix_up(mixer_tx, v1, &v1); float v2 = crealf(v1); nco_crcf_step(mixer_tx); // save spectrum spgramf_push(spgram_dac, v2); // STEP 3: mix signal down and filter off image float complex v3; nco_crcf_mix_down(mixer_rx, v2, &v3); iirfilt_crcf_execute(filter_rx, v3, &v3); nco_crcf_step(mixer_rx); // save spectrum spgramcf_push(spgram_rx, v3); } // compute power spectral density output float psd_tx [nfft]; float psd_dac [nfft]; float psd_rx [nfft]; spgramcf_get_psd(spgram_tx, psd_tx); spgramf_get_psd( spgram_dac, psd_dac); spgramcf_get_psd(spgram_rx, psd_rx); // destroy objects spgramcf_destroy(spgram_tx); spgramf_destroy(spgram_dac); spgramcf_destroy(spgram_rx); iirfilt_crcf_destroy(filter_tx); nco_crcf_destroy(mixer_tx); nco_crcf_destroy(mixer_rx); iirfilt_crcf_destroy(filter_rx); // // export output file // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); fprintf(fid,"nfft = %u;\n", nfft); fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"psd_tx = zeros(1,nfft);\n"); fprintf(fid,"psd_dac= zeros(1,nfft);\n"); fprintf(fid,"psd_rx = zeros(1,nfft);\n"); for (i=0; i<nfft; i++) { fprintf(fid,"psd_tx (%6u) = %12.4e;\n", i+1, psd_tx [i]); fprintf(fid,"psd_dac(%6u) = %12.4e;\n", i+1, psd_dac[i]); fprintf(fid,"psd_rx (%6u) = %12.4e;\n", i+1, psd_rx [i]); } fprintf(fid,"figure;\n"); fprintf(fid,"hold on;\n"); fprintf(fid," plot(f, psd_tx, '-', 'LineWidth',1.5,'Color',[0.7 0.7 0.7]);\n"); fprintf(fid," plot(f, psd_dac, '-', 'LineWidth',1.5,'Color',[0.0 0.5 0.3]);\n"); fprintf(fid," plot(f, psd_rx, '-', 'LineWidth',1.5,'Color',[0.0 0.3 0.5]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid,"ylabel('Power Spectral Density [dB]');\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([-0.5 0.5 -100 60]);\n"); fprintf(fid,"legend('transmit (complex)','DAC output (real)','receive (complex)','location','northeast');\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
int main() { // options unsigned int num_channels=4; // number of channels unsigned int m=5; // filter delay unsigned int num_symbols=12; // number of symbols // derived values unsigned int num_samples = num_channels * num_symbols; unsigned int i; unsigned int j; // generate filter // NOTE : these coefficients can be random; the purpose of this // exercise is to demonstrate mathematical equivalence unsigned int h_len = 2*m*num_channels; float h[h_len]; for (i=0; i<h_len; i++) h[i] = randnf(); //for (i=0; i<h_len; i++) h[i] = 0.1f*i; //for (i=0; i<h_len; i++) h[i] = (i<=m) ? 1.0f : 0.0f; //for (i=0; i<h_len; i++) h[i] = 1.0f; // create filterbank manually dotprod_crcf dp[num_channels]; // vector dot products windowcf w[num_channels]; // window buffers #if DEBUG // print coefficients printf("h_prototype:\n"); for (i=0; i<h_len; i++) printf(" h[%3u] = %12.8f\n", i, h[i]); #endif // create objects unsigned int h_sub_len = 2*m; float h_sub[h_sub_len]; for (i=0; i<num_channels; i++) { // sub-sample prototype filter, loading coefficients in // reverse order #if 0 for (j=0; j<h_sub_len; j++) h_sub[j] = h[j*num_channels+i]; #else for (j=0; j<h_sub_len; j++) h_sub[h_sub_len-j-1] = h[j*num_channels+i]; #endif // create window buffer and dotprod objects dp[i] = dotprod_crcf_create(h_sub, h_sub_len); w[i] = windowcf_create(h_sub_len); #if DEBUG printf("h_sub[%u] : \n", i); for (j=0; j<h_sub_len; j++) printf(" h[%3u] = %12.8f\n", j, h_sub[j]); #endif } // generate DFT object float complex x[num_channels]; // time-domain buffer float complex X[num_channels]; // freq-domain buffer #if 0 fftplan fft = fft_create_plan(num_channels, X, x, LIQUID_FFT_BACKWARD, 0); #else fftplan fft = fft_create_plan(num_channels, X, x, LIQUID_FFT_FORWARD, 0); #endif // generate filter object firfilt_crcf f = firfilt_crcf_create(h, h_len); float complex y[num_samples]; // time-domain input float complex Y0[num_symbols][num_channels]; // channelized output float complex Y1[num_symbols][num_channels]; // channelized output // generate input sequence (complex noise) for (i=0; i<num_samples; i++) y[i] = randnf() * cexpf(_Complex_I*randf()*2*M_PI); // // run analysis filter bank // #if 0 unsigned int filter_index = 0; #else unsigned int filter_index = num_channels-1; #endif float complex y_hat; // input sample float complex * r; // read pointer for (i=0; i<num_symbols; i++) { // load buffers for (j=0; j<num_channels; j++) { // grab sample y_hat = y[i*num_channels + j]; // push sample into buffer at filter index windowcf_push(w[filter_index], y_hat); // decrement filter index filter_index = (filter_index + num_channels - 1) % num_channels; //filter_index = (filter_index + 1) % num_channels; } // execute filter outputs, reversing order of output (not // sure why this is necessary) for (j=0; j<num_channels; j++) { windowcf_read(w[j], &r); dotprod_crcf_execute(dp[j], r, &X[num_channels-j-1]); } // execute DFT, store result in buffer 'x' fft_execute(fft); // move to output array for (j=0; j<num_channels; j++) Y0[i][j] = x[j]; } // // run traditional down-converter (inefficient) // float dphi; // carrier frequency unsigned int n=0; for (i=0; i<num_channels; i++) { // reset filter firfilt_crcf_reset(f); // set center frequency dphi = 2.0f * M_PI * (float)i / (float)num_channels; // reset symbol counter n=0; for (j=0; j<num_samples; j++) { // push down-converted sample into filter firfilt_crcf_push(f, y[j]*cexpf(-_Complex_I*j*dphi)); // compute output at the appropriate sample time assert(n<num_symbols); if ( ((j+1)%num_channels)==0 ) { firfilt_crcf_execute(f, &Y1[n][i]); n++; } } assert(n==num_symbols); } // destroy objects for (i=0; i<num_channels; i++) { dotprod_crcf_destroy(dp[i]); windowcf_destroy(w[i]); } fft_destroy_plan(fft); firfilt_crcf_destroy(f); // print filterbank channelizer printf("\n"); printf("filterbank channelizer:\n"); for (i=0; i<num_symbols; i++) { printf("%3u: ", i); for (j=0; j<num_channels; j++) { printf(" %8.5f+j%8.5f, ", crealf(Y0[i][j]), cimagf(Y0[i][j])); } printf("\n"); } // print traditional channelizer printf("\n"); printf("traditional channelizer:\n"); for (i=0; i<num_symbols; i++) { printf("%3u: ", i); for (j=0; j<num_channels; j++) { printf(" %8.5f+j%8.5f, ", crealf(Y1[i][j]), cimagf(Y1[i][j])); } printf("\n"); } // // compare results // float mse[num_channels]; float complex d; for (i=0; i<num_channels; i++) { mse[i] = 0.0f; for (j=0; j<num_symbols; j++) { d = Y0[j][i] - Y1[j][i]; mse[i] += crealf(d*conjf(d)); } mse[i] /= num_symbols; } printf("\n"); printf("rmse: "); for (i=0; i<num_channels; i++) printf("%12.4e ", sqrt(mse[i])); printf("\n"); printf("done.\n"); return 0; }
float complex catanhf(float complex z) { z = catanf(CMPLXF(-cimagf(z), crealf(z))); return CMPLXF(cimagf(z), -crealf(z)); }
// finds the complex roots of the polynomial using Bairstow's method // _p : polynomial array, ascending powers [size: _k x 1] // _k : polynomials length (poly order = _k - 1) // _roots : resulting complex roots [size: _k-1 x 1] void POLY(_findroots_bairstow)(T * _p, unsigned int _k, TC * _roots) { T p0[_k]; // buffer 0 T p1[_k]; // buffer 1 T * p = NULL; // input polynomial T * pr = NULL; // output (reduced) polynomial unsigned int i; unsigned int k=0; // output roots counter memmove(p0, _p, _k*sizeof(T)); T u, v; unsigned int n = _k; // input counter (decrementer) unsigned int r = _k % 2; // polynomial length odd? (order even?) unsigned int L = (_k-r)/2; // semi-length for (i=0; i<L-1+r; i++) { // set polynomial and reduced polynomial buffer pointers p = (i % 2) == 0 ? p0 : p1; pr = (i % 2) == 0 ? p1 : p0; // initial estimates for u, v // TODO : ensure no division by zero if (p[n-1] == 0) { fprintf(stderr,"warning: poly_findroots_bairstow(), irreducible polynomial"); p[n-1] = 1e-12; } u = p[n-2] / p[n-1]; v = p[n-3] / p[n-1]; // compute factor using Bairstow's recursion POLY(_findroots_bairstow_recursion)(p,n,pr,&u,&v); // compute complex roots of x^2 + u*x + v TC r0 = 0.5f*(-u + csqrtf(u*u - 4.0*v)); TC r1 = 0.5f*(-u - csqrtf(u*u - 4.0*v)); // append result to output _roots[k++] = r0; _roots[k++] = r1; #if LIQUID_POLY_FINDROOTS_DEBUG // print debugging info unsigned int j; printf("initial polynomial:\n"); for (j=0; j<n; j++) printf(" p[%3u] = %12.8f + j*%12.8f\n", j, crealf(p[j]), cimagf(p[j])); printf("polynomial factor: x^2 + u*x + v\n"); printf(" u : %12.8f + j*%12.8f\n", crealf(u), cimagf(u)); printf(" v : %12.8f + j*%12.8f\n", crealf(v), cimagf(v)); printf("roots:\n"); printf(" r0 : %12.8f + j*%12.8f\n", crealf(r0), cimagf(r0)); printf(" r1 : %12.8f + j*%12.8f\n", crealf(r1), cimagf(r1)); printf("reduced polynomial:\n"); for (j=0; j<n-2; j++) printf(" pr[%3u] = %12.8f + j*%12.8f\n", j, crealf(pr[j]), cimagf(pr[j])); #endif // decrement new (reduced) polynomial size by 2 n -= 2; } if (r==0) { #if LIQUID_POLY_FINDROOTS_DEBUG assert(n==2); #endif _roots[k++] = -pr[0]/pr[1]; } }
void LALFindChirpSPData ( LALStatus *status, FindChirpSegmentVector *fcSegVec, DataSegmentVector *dataSegVec, FindChirpDataParams *params ) { UINT4 i, k; UINT4 cut; CHAR infoMsg[512]; REAL4 *w; REAL4 *amp; COMPLEX8 *wtilde; REAL4 *tmpltPower; REAL4Vector *dataVec; REAL4 *spec; COMPLEX8 *resp; COMPLEX8 *outputData; REAL4 segNormSum; /* stuff added for continous chisq test */ REAL4Vector *dataPower = NULL; REAL4 PSDsum = 0; INT4 startIX = 0; INT4 endIX = 0; COMPLEX8Vector *fftVec = NULL; FindChirpSegment *fcSeg; DataSegment *dataSeg; INITSTATUS(status); ATTATCHSTATUSPTR( status ); /* * * make sure that the arguments are reasonable * */ /* check that the output exists */ ASSERT( fcSegVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": fcSegVec" ); ASSERT( fcSegVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": fcSegVec->data" ); ASSERT( fcSegVec->data->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": fcSegVec->data->dat" ); ASSERT( fcSegVec->data->data->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": fcSegVec->data->data->data" ); /* check that the parameter structure exists */ ASSERT( params, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": params" ); /* check that the workspace vectors exist */ ASSERT( params->ampVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->ampVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->wVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->wVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->wtildeVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->wtildeVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->tmpltPowerVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->tmpltPowerVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); /* check that the fft plans exist */ ASSERT( params->fwdPlan, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); ASSERT( params->invPlan, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ); /* check that the parameter values are reasonable */ ASSERT( params->fLow >= 0, status, FINDCHIRPSPH_EFLOW, FINDCHIRPSPH_MSGEFLOW ); ASSERT( params->dynRange > 0, status, FINDCHIRPSPH_EDYNR, FINDCHIRPSPH_MSGEDYNR ); /* check that the input exists */ ASSERT( dataSegVec, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": dataSegVec" ); ASSERT( dataSegVec->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": dataSegVec->data" ); ASSERT( dataSegVec->data->chan, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": dataSegVec->data->chan" ); ASSERT( dataSegVec->data->chan->data, status, FINDCHIRPSPH_ENULL, FINDCHIRPSPH_MSGENULL ": dataSegVec->data->chan->data" ); /* check that the parameter structure is set */ /* to the correct waveform approximant */ if ( params->approximant != FindChirpSP ) { ABORT( status, FINDCHIRPSPH_EMAPX, FINDCHIRPSPH_MSGEMAPX ); } /* * * set up local segment independent pointers * */ w = params->wVec->data; amp = params->ampVec->data; wtilde = params->wtildeVec->data; tmpltPower = params->tmpltPowerVec->data; /* allocate memory to store some temporary info for the continous chisq test */ fcSeg = &(fcSegVec->data[0]); fftVec = XLALCreateCOMPLEX8Vector( fcSeg->data->data->length ); /* * * loop over data segments * */ for ( i = 0; i < dataSegVec->length; ++i ) { /* * * set up segment dependent pointers * */ dataSeg = &(dataSegVec->data[i]); fcSeg = &(fcSegVec->data[i]); dataVec = dataSeg->chan->data; spec = dataSeg->spec->data->data; resp = dataSeg->resp->data->data; outputData = fcSeg->data->data->data; dataPower = fcSeg->dataPower->data; ASSERT( params->wtildeVec->length == fcSeg->data->data->length, status, FINDCHIRPSPH_EMISM, FINDCHIRPSPH_MSGEMISM ); /* store the waveform approximant in the data segment */ fcSeg->approximant = params->approximant; /* * * compute htilde and store in fcSeg * */ LALForwardRealFFT( status->statusPtr, fcSeg->data->data, dataVec, params->fwdPlan ); CHECKSTATUSPTR( status ); /* compute strain */ for ( k = 0; k < fcSeg->data->data->length; ++k ) { REAL4 p = crealf(outputData[k]); REAL4 q = cimagf(outputData[k]); REAL4 x = crealf(resp[k]) * params->dynRange; REAL4 y = cimagf(resp[k]) * params->dynRange; outputData[k] = crectf( p*x - q*y, p*y + q*x ); } /* * * compute inverse power spectrum * */ /* set low frequency cutoff inverse power spectrum */ cut = params->fLow / dataSeg->spec->deltaF > 1 ? params->fLow / dataSeg->spec->deltaF : 1; snprintf( infoMsg, XLAL_NUM_ELEM(infoMsg), "low frequency cut off index = %d\n", cut ); LALInfo( status, infoMsg ); /* set inverse power spectrum to zero */ memset( wtilde, 0, params->wtildeVec->length * sizeof(COMPLEX8) ); /* compute inverse of S_v */ for ( k = cut; k < params->wtildeVec->length; ++k ) { if ( spec[k] == 0 ) { ABORT( status, FINDCHIRPSPH_EDIVZ, FINDCHIRPSPH_MSGEDIVZ ); } wtilde[k] = crectf( 1.0 / spec[k], cimagf(wtilde[k]) ); } /* * * truncate inverse power spectrum in time domain if required * */ if ( params->invSpecTrunc ) { /* compute square root of inverse power spectrum */ for ( k = cut; k < params->wtildeVec->length; ++k ) { wtilde[k] = crectf( sqrt( crealf(wtilde[k]) ), cimagf(wtilde[k]) ); } /* set nyquist and dc to zero */ wtilde[params->wtildeVec->length-1] = crectf( 0.0, cimagf(wtilde[params->wtildeVec->length-1]) ); wtilde[0] = crectf( 0.0, cimagf(wtilde[0]) ); /* transform to time domain */ LALReverseRealFFT( status->statusPtr, params->wVec, params->wtildeVec, params->invPlan ); CHECKSTATUSPTR (status); /* truncate in time domain */ memset( w + params->invSpecTrunc/2, 0, (params->wVec->length - params->invSpecTrunc) * sizeof(REAL4) ); /* transform to frequency domain */ LALForwardRealFFT( status->statusPtr, params->wtildeVec, params->wVec, params->fwdPlan ); CHECKSTATUSPTR (status); /* normalise fourier transform and square */ { REAL4 norm = 1.0 / (REAL4) params->wVec->length; for ( k = cut; k < params->wtildeVec->length; ++k ) { wtilde[k] = crectf( crealf(wtilde[k]) * ( norm ), cimagf(wtilde[k]) ); wtilde[k] = crectf( crealf(wtilde[k]) * ( crealf(wtilde[k]) ), cimagf(wtilde[k]) ); wtilde[k] = crectf( crealf(wtilde[k]), 0.0 ); } } /* set nyquist and dc to zero */ wtilde[params->wtildeVec->length-1] = crectf( 0.0, cimagf(wtilde[params->wtildeVec->length-1]) ); wtilde[0] = crectf( 0.0, cimagf(wtilde[0]) ); } /* set inverse power spectrum below cut to zero */ memset( wtilde, 0, cut * sizeof(COMPLEX8) ); /* convert from S_v to S_h */ for ( k = cut; k < params->wtildeVec->length; ++k ) { REAL4 respRe = crealf(resp[k]) * params->dynRange; REAL4 respIm = cimagf(resp[k]) * params->dynRange; REAL4 modsqResp = (respRe * respRe + respIm * respIm); REAL4 invmodsqResp; if ( modsqResp == 0 ) { ABORT( status, FINDCHIRPSPH_EDIVZ, FINDCHIRPSPH_MSGEDIVZ ); } invmodsqResp = 1.0 / modsqResp; wtilde[k] = crectf( crealf(wtilde[k]) * ( invmodsqResp ), cimagf(wtilde[k]) ); } /* * * compute segment normalisation, outputData, point fcSeg at data segment * */ for ( k = 0; k < cut; ++k ) { outputData[k] = 0.0; } for ( k = 0; k < cut; ++k ) { fftVec->data[k] = 0.0; } memset( tmpltPower, 0, params->tmpltPowerVec->length * sizeof(REAL4) ); memset( fcSeg->segNorm->data, 0, fcSeg->segNorm->length * sizeof(REAL4) ); fcSeg->tmpltPowerVec = params->tmpltPowerVec; segNormSum = 0.0; for ( k = 1; k < fcSeg->data->data->length; ++k ) { tmpltPower[k] = amp[k] * amp[k] * crealf(wtilde[k]); segNormSum += tmpltPower[k]; fcSeg->segNorm->data[k] = segNormSum; } /* Compute whitened data for continous chisq test */ for ( k = 0; k < fcSeg->data->data->length; ++k ) { fftVec->data[k] = crectf( crealf(outputData[k]) * sqrt( crealf(wtilde[k]) ), cimagf(outputData[k]) * sqrt( crealf(wtilde[k]) ) ); } /* get the whitened time series */ LALReverseRealFFT( status->statusPtr, dataPower, fftVec, params->invPlan ); dataPower->data[0] = 0; /* compute the cumulative power used for the continous chisq test */ for ( k = 1; k < dataPower->length; k++ ) { dataPower->data[k] = dataPower->data[k-1] + dataPower->data[k] * dataPower->data[k]; } /* hard wired to quarter segment !! */ startIX = floor(1.0/4.0 * (REAL4) dataPower->length + 0.5); endIX = floor(3.0/4.0 * (REAL4) dataPower->length + 0.5); /* compute the total power in the uncorrupted data */ dataPower->data[dataPower->length - 1 ] = 2.0 * (dataPower->data[endIX] - dataPower->data[startIX]); for ( k = cut; k < fcSeg->data->data->length; ++k ) { outputData[k] *= ((REAL4) crealf(wtilde[k]) * amp[k]); } /* set output frequency series parameters */ strncpy( fcSeg->data->name, dataSeg->chan->name, LALNameLength ); fcSeg->data->epoch.gpsSeconds = dataSeg->chan->epoch.gpsSeconds; fcSeg->data->epoch.gpsNanoSeconds = dataSeg->chan->epoch.gpsNanoSeconds; fcSeg->data->f0 = dataSeg->chan->f0; fcSeg->data->deltaF = 1.0 / ( (REAL8) dataSeg->chan->data->length * dataSeg->chan->deltaT ) ; fcSeg->deltaT = dataSeg->chan->deltaT; fcSeg->number = dataSeg->number; fcSeg->analyzeSegment = dataSeg->analyzeSegment; /* store low frequency cutoff and invSpecTrunc in segment */ fcSeg->fLow = params->fLow; fcSeg->invSpecTrunc = params->invSpecTrunc; } /* end loop over data segments */ /* Find the min power from the whitened time series */ /* For the continuous chisq test */ fcSeg = &(fcSegVec->data[0]); PSDsum = fcSeg->dataPower->data->data[fcSeg->dataPower->data->length - 1 ]; for ( i = 1; i < dataSegVec->length; ++i ) { fcSeg = &(fcSegVec->data[i]); if ( ((fcSeg->dataPower->data->data[fcSeg->dataPower->data->length - 1 ] < PSDsum) && (fcSeg->dataPower->data->data[fcSeg->dataPower->data->length - 1 ] > 0)) || PSDsum == 0 ) { PSDsum = fcSeg->dataPower->data->data[fcSeg->dataPower->data->length - 1 ]; } } /* reset each dataPower's last element to the min power */ for ( i = 0; i < dataSegVec->length; ++i ) { fcSeg = &(fcSegVec->data[i]); fcSeg->dataPower->data->data[fcSeg->dataPower->data->length - 1 ] = PSDsum; } /* clean up the data used for the continous chisq test */ XLALDestroyCOMPLEX8Vector( fftVec ); /* normal exit */ DETATCHSTATUSPTR( status ); RETURN( status ); }
// iterate over Bairstow's method, finding quadratic factor x^2 + u*x + v // _p : polynomial array, ascending powers [size: _k x 1] // _k : polynomials length (poly order = _k - 1) // _p1 : reduced polynomial (output) [size: _k-2 x 1] // _u : input: initial estimate for u; output: resulting u // _v : input: initial estimate for v; output: resulting v void POLY(_findroots_bairstow_recursion)(T * _p, unsigned int _k, T * _p1, T * _u, T * _v) { // validate length if (_k < 3) { fprintf(stderr,"findroots_bairstow_recursion(), invalid polynomial length: %u\n", _k); exit(1); } // initial estimates for u, v T u = *_u; T v = *_v; unsigned int n = _k-1; T c,d,g,h; T q; T du, dv; // reduced polynomials T b[_k]; T f[_k]; b[n] = b[n-1] = 0; f[n] = f[n-1] = 0; int i; unsigned int k=0; unsigned int max_num_iterations=50; int continue_iterating = 1; while (continue_iterating) { // update reduced polynomial coefficients for (i=n-2; i>=0; i--) { b[i] = _p[i+2] - u*b[i+1] - v*b[i+2]; f[i] = b[i+2] - u*f[i+1] - v*f[i+2]; } c = _p[1] - u*b[0] - v*b[1]; g = b[1] - u*f[0] - v*f[1]; d = _p[0] - v*b[0]; h = b[0] - v*f[0]; // compute scaling factor q = 1/(v*g*g + h*(h-u*g)); // compute u, v steps du = - q*(-h*c + g*d); dv = - q*(-g*v*c + (g*u-h)*d); #if LIQUID_POLY_FINDROOTS_DEBUG // print debugging info printf("bairstow [%u] :\n", k); printf(" u : %12.4e + j*%12.4e\n", crealf(u), cimagf(u)); printf(" v : %12.4e + j*%12.4e\n", crealf(v), cimagf(v)); printf(" b : \n"); for (i=0; i<n-2; i++) printf(" %12.4e + j*%12.4e\n", crealf(b[i]), cimagf(b[i])); printf(" fb : \n"); for (i=0; i<n-2; i++) printf(" %12.4e + j*%12.4e\n", crealf(f[i]), cimagf(f[i])); printf(" c : %12.4e + j*%12.4e\n", crealf(c), cimagf(c)); printf(" g : %12.4e + j*%12.4e\n", crealf(g), cimagf(g)); printf(" d : %12.4e + j*%12.4e\n", crealf(d), cimagf(d)); printf(" h : %12.4e + j*%12.4e\n", crealf(h), cimagf(h)); printf(" q : %12.4e + j*%12.4e\n", crealf(q), cimagf(q)); printf(" du : %12.4e + j*%12.4e\n", crealf(du), cimagf(du)); printf(" dv : %12.4e + j*%12.4e\n", crealf(dv), cimagf(dv)); printf(" step : %12.4e + j*%12.4e\n", crealf(du+dv), cimagf(du+dv)); #endif // adjust u, v if (isnan(du) || isnan(dv)) { u *= 0.5f; v *= 0.5f; } else { u += du; v += dv; } // increment iteration counter k++; // exit conditions if (cabsf(du+dv) < 1e-6f || k == max_num_iterations) continue_iterating = 0; } // set resulting reduced polynomial for (i=0; i<_k-2; i++) _p1[i] = b[i]; // set output pairs *_u = u; *_v = v; }
void LALExtractFrameResponse(LALStatus * status, COMPLEX8FrequencySeries * output, LALCache * calCache, CalibrationUpdateParams * calfacts) { const LALUnit strainPerCount = { 0, {0, 0, 0, 0, 0, 1, -1}, {0, 0, 0, 0, 0, 0, 0} }; LALCache *refCache = NULL; LALCache *facCache = NULL; LALFrStream *refStream = NULL; LALFrStream *facStream = NULL; FrChanIn frameChan; LALFrStreamPos facPos; CHAR facDsc[LALNameLength]; CHAR channelName[LALNameLength]; COMPLEX8FrequencySeries R0; COMPLEX8FrequencySeries C0; COMPLEX8TimeSeries ab; COMPLEX8TimeSeries a; /* * COMPLEX8Vector abVec; * COMPLEX8Vector aVec; * COMPLEX8 abData; * COMPLEX8 aData; */ CalibrationFunctions calfuncs; LIGOTimeGPS seekEpoch; UINT4 length; REAL8 duration_real; const REAL8 fuzz = 0.1 / 16384.0; INITSTATUS(status); ATTATCHSTATUSPTR(status); ASSERT(output, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(output->data, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(output->data->data, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calCache, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calfacts, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(calfacts->ifo, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(crealf(calfacts->alpha) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(cimagf(calfacts->alpha) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(crealf(calfacts->alphabeta) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); ASSERT(cimagf(calfacts->alphabeta) == 0, status, FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL); /* * * set up and clear the structures to hold the input data * */ memset(&R0, 0, sizeof(COMPLEX8FrequencySeries)); memset(&C0, 0, sizeof(COMPLEX8FrequencySeries)); memset(&ab, 0, sizeof(COMPLEX8TimeSeries)); memset(&a, 0, sizeof(COMPLEX8TimeSeries)); memset(&calfuncs, 0, sizeof(CalibrationFunctions)); calfuncs.responseFunction = &R0; calfuncs.sensingFunction = &C0; calfacts->openLoopFactor = &ab; calfacts->sensingFactor = &a; calfacts->epoch = output->epoch; frameChan.name = channelName; /* * * get the reference calibration and cavity gain frequency series * */ /* sieve the calibration cache for the reference frame */ refCache = XLALCacheDuplicate(calCache); XLALCacheSieve(refCache, 0, 0, NULL, REF_TYPE, NULL); if (!refCache->length) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_ECREF, FRAMECALIBRATIONH_MSGECREF); } /* open the reference calibration frame */ LALFrCacheOpen(status->statusPtr, &refStream, refCache); if (status->statusPtr->statusCode) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_EOREF, FRAMECALIBRATIONH_MSGEOREF); } XLALDestroyCache(refCache); if (status->statusPtr->statusCode) { TRY(LALFrClose(status->statusPtr, &refStream), status); ABORT(status, FRAMECALIBRATIONH_EDCHE, FRAMECALIBRATIONH_MSGEDCHE); } /* read in the frequency series for the reference calbration */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" RESPONSE_CHAN, calfacts->ifo); LALFrGetCOMPLEX8FrequencySeries(status->statusPtr, &R0, &frameChan, refStream); if (status->statusCode) { /* if we don't have a reference calibration, we can't do anything */ XLALDestroyCache(refCache); ABORT(status, FRAMECALIBRATIONH_EREFR, FRAMECALIBRATIONH_MSGEREFR); } /* read in the reference cavity gain frequency series */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_GAIN_CHAN, calfacts->ifo); LALFrGetCOMPLEX8FrequencySeries(status->statusPtr, &C0, &frameChan, refStream); BEGINFAIL(status) { /* no cavity gain response to update point cal */ XLALDestroyCache(refCache); TRY(LALFrClose(status->statusPtr, &refStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALFrClose(status->statusPtr, &refStream); BEGINFAIL(status) { RETURN_POINT_CAL; } ENDFAIL(status); /* * * get the factors necessary to update the reference calibration * */ /* try and get some update factors. first we try to get a cache */ /* containing sensemon frames. if that fails, try the S1 type */ /* calibration data, otherwise just return the point calibration */ do { /* try and get sensemon frames */ snprintf(facDsc, LALNameLength * sizeof(CHAR), SENSEMON_FAC_TYPE); facCache = XLALCacheDuplicate(calCache); XLALCacheSieve(facCache, 0, 0, NULL, facDsc, NULL); if (!facCache) { RETURN_POINT_CAL; } if (facCache->length) { /* sensemon stores fac times series as real_8 adc trend data */ REAL8TimeSeries sensemonTS; REAL8 alphaDeltaT; UINT4 i; memset(&sensemonTS, 0, sizeof(REAL8TimeSeries)); OPEN_FAC; snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_FAC_CHAN ".mean", calfacts->ifo); /* get the sample rate of the alpha channel */ LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* determine number of calibration points required */ duration_real = XLALGPSGetREAL8(&(calfacts->duration)); length = (UINT4) ceil(duration_real / sensemonTS.deltaT); ++length; /* make sure we get the first point before the requested cal time */ alphaDeltaT = sensemonTS.deltaT; seekEpoch = output->epoch; XLALGPSAdd(&seekEpoch, fuzz - sensemonTS.deltaT); sensemonTS.epoch = seekEpoch; GET_POS; /* create memory for the alpha values */ LALDCreateVector(status->statusPtr, &(sensemonTS.data), length); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha values */ LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALCCreateVector(status->statusPtr, &(a.data), length); BEGINFAIL(status) { TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); for (i = 0; i < length; ++i) { a.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 ); } a.epoch = sensemonTS.epoch; a.deltaT = sensemonTS.deltaT; strncpy(a.name, sensemonTS.name, LALNameLength); LALFrSetPos(status->statusPtr, &facPos, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha*beta values */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" OLOOP_FAC_CHAN ".mean", calfacts->ifo); LALFrGetREAL8TimeSeries(status->statusPtr, &sensemonTS, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* check that alpha and alpha*beta have the same sample rate */ if (fabs(alphaDeltaT - sensemonTS.deltaT) > LAL_REAL8_EPS) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; ABORT(status, FRAMECALIBRATIONH_EDTMM, FRAMECALIBRATIONH_MSGEDTMM); } LALCCreateVector(status->statusPtr, &(ab.data), length); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); for (i = 0; i < length; ++i) { ab.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 ); } ab.epoch = sensemonTS.epoch; ab.deltaT = sensemonTS.deltaT; strncpy(ab.name, sensemonTS.name, LALNameLength); /* destroy the sensemonTS.data */ LALDDestroyVector(status->statusPtr, &(sensemonTS.data)); CHECKSTATUSPTR(status); break; } /* destroy the empty frame cache and try again */ XLALDestroyCache(facCache); /* try and get the the factors from lalapps_mkcalfac frames */ facCache = XLALCacheDuplicate(calCache); XLALCacheSieve(facCache, 0, 0, NULL, FAC_TYPE, NULL); if (!facCache) { RETURN_POINT_CAL; } if (facCache->length) { /* the lalapps frames are complex_8 proc data */ OPEN_FAC; snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" CAV_FAC_CHAN, calfacts->ifo); /* get the sample rate of the alpha channel */ LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &a, &frameChan, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* determine number of calibration points required */ duration_real = XLALGPSGetREAL8(&(calfacts->duration)); length = (UINT4) ceil(duration_real / a.deltaT); ++length; /* make sure we get the first point before the requested cal time */ seekEpoch = output->epoch; XLALGPSAdd(&seekEpoch, fuzz - a.deltaT); a.epoch = ab.epoch = seekEpoch; GET_POS; /* create storage for the alpha values */ LALCCreateVector(status->statusPtr, &(a.data), length); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha values */ LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &a, &frameChan, facStream); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); LALFrSetPos(status->statusPtr, &facPos, facStream); BEGINFAIL(status) { TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* create storage for the alpha*beta values */ LALCCreateVector(status->statusPtr, &(ab.data), length); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* get the alpha*beta values */ snprintf(channelName, LALNameLength * sizeof(CHAR), "%s:" OLOOP_FAC_CHAN, calfacts->ifo); LALFrGetCOMPLEX8TimeSeries(status->statusPtr, &ab, &frameChan, facStream); BEGINFAIL(status) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; } ENDFAIL(status); /* check that alpha and alpha*beta have the same sample rate */ if (fabs(a.deltaT - ab.deltaT) > LAL_REAL8_EPS) { TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status); TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status); TRY(LALFrClose(status->statusPtr, &facStream), status); RETURN_POINT_CAL; ABORT(status, FRAMECALIBRATIONH_EDTMM, FRAMECALIBRATIONH_MSGEDTMM); } break; }
// finds the complex roots of the polynomial using the Durand-Kerner method // _p : polynomial array, ascending powers [size: _k x 1] // _k : polynomials length (poly order = _k - 1) // _roots : resulting complex roots [size: _k-1 x 1] void POLY(_findroots_durandkerner)(T * _p, unsigned int _k, TC * _roots) { if (_k < 2) { fprintf(stderr,"%s_findroots_durandkerner(), order must be greater than 0\n", POLY_NAME); exit(1); } else if (_p[_k-1] != 1) { fprintf(stderr,"%s_findroots_durandkerner(), _p[_k-1] must be equal to 1\n", POLY_NAME); exit(1); } unsigned int i; unsigned int num_roots = _k-1; T r0[num_roots]; T r1[num_roots]; // find intial magnitude float g = 0.0f; float gmax = 0.0f; for (i=0; i<_k; i++) { g = cabsf(_p[i]); if (i==0 || g > gmax) gmax = g; } // initialize roots T t0 = 0.9f * (1 + gmax) * cexpf(_Complex_I*1.1526f); T t = 1.0f; for (i=0; i<num_roots; i++) { r0[i] = t; t *= t0; } unsigned int max_num_iterations = 50; int continue_iterating = 1; unsigned int j, k; T f; T fp; //for (i=0; i<num_iterations; i++) { i = 0; while (continue_iterating) { #if LIQUID_POLY_FINDROOTS_DEBUG printf("%s_findroots(), i=%3u :\n", POLY_NAME, i); for (j=0; j<num_roots; j++) printf(" r[%3u] = %12.8f + j*%12.8f\n", j, crealf(r0[j]), cimagf(r0[j])); #endif for (j=0; j<num_roots; j++) { f = POLY(_val)(_p,_k,r0[j]); fp = 1; for (k=0; k<num_roots; k++) { if (k==j) continue; fp *= r0[j] - r0[k]; } r1[j] = r0[j] - f / fp; } // stop iterating if roots have settled float delta=0.0f; T e; for (j=0; j<num_roots; j++) { e = r0[j] - r1[j]; delta += crealf(e*conjf(e)); } delta /= num_roots * gmax; #if LIQUID_POLY_FINDROOTS_DEBUG printf("delta[%3u] = %12.4e\n", i, delta); #endif if (delta < 1e-6f || i == max_num_iterations) continue_iterating = 0; memmove(r0, r1, num_roots*sizeof(T)); i++; } for (i=0; i<_k; i++) _roots[i] = r1[i]; }
int mri( float* img, float complex* f, float* mask, float lambda, int N1, int N2) { int i, j; float complex* f0 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dx_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dy_new = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildex = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* dtildey = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u_fft2 = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* u = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* fftmul = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* Lap = (float complex*) calloc(N1*N2,sizeof(float complex)); float complex* diff = (float complex*) calloc(N1*N2,sizeof(float complex)); float sum = 0; float scale = sqrtf(N1*N2); Lap(N1-1, N2-1) = 0.f; Lap(N1-1, 0) = 1.f; Lap(N1-1, 1) = 0.f; Lap(0, N2-1) = 1.f; Lap(0, 0) = -4.f; Lap(0, 1) = 1.f; Lap(1, N2-1) = 0.f; Lap(1, 0) = 1.f; Lap(1, 1) = 0.f; float complex *w1; float complex *w2; float complex *buff; double lambdaGamma1 = lambda/Gamma1; double lambdaGamma1Scale = lambda/Gamma1*scale; float Thresh=1.0/Gamma1; MPI_Datatype mpi_complexf; MPI_Type_contiguous(2, MPI_FLOAT, &mpi_complexf); MPI_Type_commit(&mpi_complexf); int np, rank; MPI_Comm_size(MPI_COMM_WORLD ,&np); MPI_Comm_rank(MPI_COMM_WORLD ,&rank); int chunksize = N1/np; int start = rank * chunksize; int cnt[np]; int disp[np]; for (i = 0 ; i < np - 1; i ++) { cnt[i] = chunksize * N2 ; disp[i] = chunksize * i * N2; } cnt[i] = (chunksize + N1%np) * N2; disp[i] = chunksize * i * N2; if (rank == np - 1) chunksize += N1%np; int end = start + chunksize; for(i=start; i<chunksize; i++) for(j=0; j<N2; j++) sum += (SQR(crealf(f(i,j))/N1) + SQR(cimagf(f(i,j))/N1)); MPI_Allreduce(&sum, &sum, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD); float normFactor = 1.f/sqrtf(sum); for(i=0; i<N1; i++) { for(j=0; j<N2; j++) { f(i, j) = f(i, j)*normFactor; f0(i, j) = f(i, j); } } dft_init(&w1, &w2, &buff, N1, N2); dft(Lap, Lap, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); MPI_Status *status; for(i=start;i<end;i++) for(j=0;j<N2;j++) fftmul(i,j) = 1.0/((lambda/Gamma1)*mask(i,j) - Lap(i,j) + Gamma2); int OuterIter,iter; for(OuterIter= 0; OuterIter<MaxOutIter; OuterIter++) { for(iter = 0; iter<MaxIter; iter++) { for(i=start;i<end;i++) for(j=0;j<N2;j++) diff(i,j) = dtildex(i,j)-dtildex(i,(j-1)>=0?(j-1):0) + dtildey(i,j)- dtildey((i-1)>=0?(i-1):0,j) ; dft(diff, diff, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); for(i=start;i<end;i++) { for(j=0;j<N2;j++) { u_fft2(i,j) = fftmul(i,j)*(f(i,j)*lambdaGamma1Scale-diff(i,j)+Gamma2*u_fft2(i,j)) ; if (iter == MaxIter - 1) f(i,j) += f0(i,j) - mask(i,j)*u_fft2(i,j)/scale; } } idft(u, u_fft2, w1, w2, buff, N1, N2, start, end, cnt, disp, mpi_complexf, rank); //MPI_Allgatherv(u + disp[rank], cnt[rank], mpi_complexf, u, cnt, disp, mpi_complexf, MPI_COMM_WORLD); if (rank == np - 1) MPI_Send(u + disp[rank], N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD); else if (rank == 0) MPI_Recv(u + disp[rank] + cnt[rank], N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD, status); else { MPI_Recv(u + disp[rank] + cnt[rank], N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD, status); MPI_Send(u + disp[rank], N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD); } for(i=start;i<end;i++) { for(j=0;j<N2;j++) { float tmp; dx(i,j) = u(i,j<(N2-1)?(j+1):j)-u(i,j)+dx(i,j)-dtildex(i,j) ; dy(i,j) = u(i<(N1-1)?(i+1):i,j)-u(i,j)+dy(i,j)-dtildey(i,j) ; tmp = sqrtf(SQR(crealf(dx(i,j)))+SQR(cimagf(dx(i,j))) + SQR(crealf(dy(i,j)))+SQR(cimagf(dy(i,j)))); tmp = max(0,tmp-Thresh)/(tmp+(tmp<Thresh)); dx_new(i,j) =dx(i,j)*tmp; dy_new(i,j) =dy(i,j)*tmp; dtildex(i,j) = 2*dx_new(i,j) - dx(i,j); dtildey(i,j) = 2*dy_new(i,j) - dy(i,j); dx(i,j) = dx_new(i,j); dy(i,j) = dy_new(i,j); } } //MPI_Allgatherv(dtildey + disp[rank], cnt[rank], mpi_complexf, dtildey, cnt, disp, mpi_complexf, MPI_COMM_WORLD); if (rank == np - 1) MPI_Recv(dtildey + disp[rank] - N2, N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD, status); else if (rank == 0) MPI_Send(dtildey + disp[rank] + cnt[rank] - N2, N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD); else { MPI_Recv(dtildey + disp[rank] - N2, N2, mpi_complexf, rank - 1, 0, MPI_COMM_WORLD, status); MPI_Send(dtildey + disp[rank] + cnt[rank] - N2, N2, mpi_complexf, rank + 1, 0, MPI_COMM_WORLD); } } } for(i=start; i<end; i++) { for(j=0; j<N2; j++) { img(i, j) = sqrt(SQR(crealf(u(i, j))) + SQR(cimagf(u(i, j)))); } } MPI_Gatherv(img + disp[rank], cnt[rank], MPI_FLOAT, img, cnt, disp, MPI_FLOAT, 0, MPI_COMM_WORLD); free(w1); free(w2); free(buff); MPI_Finalize(); if (rank > 0) exit(0); return 0; }
int main(int argc, char* argv[]) { bool verb,complx,sub,os; int it,iz,im,ik,ix,i,j; /* index variables */ int nt,nz,nx, m2, nk, nzx, nz2, nx2, nzx2, n2, pad1,nth; sf_complex c,old; /* I/O arrays*/ sf_complex *ww,*curr,*prev,*cwave,*cwavem,**wave,**lt, **rt; float *rcurr,*rr; sf_file Fw,Fr,Fo; /* I/O files */ sf_axis at,az,ax; /* cube axes */ sf_file left, right; sf_init(argc,argv); if(!sf_getbool("verb",&verb)) verb=false; /* verbosity */ if(!sf_getbool("cmplx",&complx)) complx=true; /* outputs complex wavefield */ if(!sf_getbool("os",&os)) os=true; /* one-step flag */ if (os) { sf_warning("One-step wave extrapolation"); if(!sf_getbool("sub",&sub)) sub=false; /* subtraction flag */ } else { sf_warning("Two-step wave extrapolation"); if(!sf_getbool("sub",&sub)) sub=true; /* subtraction flag */ } /* setup I/O files */ Fw = sf_input ("in" ); Fo = sf_output("out"); Fr = sf_input ("ref"); if (SF_COMPLEX != sf_gettype(Fw)) sf_error("Need complex input"); if (SF_FLOAT != sf_gettype(Fr)) sf_error("Need float ref"); if(complx) sf_settype(Fo,SF_COMPLEX); else sf_settype(Fo,SF_FLOAT); /* Read/Write axes */ at = sf_iaxa(Fw,1); nt = sf_n(at); az = sf_iaxa(Fr,1); nz = sf_n(az); ax = sf_iaxa(Fr,2); nx = sf_n(ax); sf_oaxa(Fo,az,1); sf_oaxa(Fo,ax,2); sf_oaxa(Fo,at,3); if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */ #ifdef _OPENMP #pragma omp parallel { nth = omp_get_num_threads(); } if (verb) sf_warning(">>>> Using %d threads <<<<<", nth); #endif nk = cfft2_init(pad1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; /* propagator matrices */ left = sf_input("left"); right = sf_input("right"); if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx); if (!sf_histint(left,"n2",&m2)) sf_error("Need n2= in left"); if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2); if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk); lt = sf_complexalloc2(nzx,m2); rt = sf_complexalloc2(m2,nk); sf_complexread(lt[0],nzx*m2,left); sf_complexread(rt[0],m2*nk,right); sf_fileclose(left); sf_fileclose(right); /* read wavelet & reflectivity */ ww=sf_complexalloc(nt); sf_complexread(ww,nt ,Fw); rr=sf_floatalloc(nzx); sf_floatread(rr,nzx,Fr); curr = sf_complexalloc(nzx2); if (!os) prev = sf_complexalloc(nzx2); else prev = NULL; if(!complx) rcurr = sf_floatalloc(nzx2); else rcurr=NULL; cwave = sf_complexalloc(nk); cwavem = sf_complexalloc(nk); wave = sf_complexalloc2(nzx2,m2); for (iz=0; iz < nzx2; iz++) { curr[iz] = sf_cmplx(0.,0.); if (!os) prev[iz] = sf_cmplx(0.,0.); if(!complx) rcurr[iz]= 0.; } /* MAIN LOOP */ for (it=0; it<nt; it++) { if(verb) sf_warning("it=%d;",it); /* matrix multiplication */ cfft2(curr,cwave); for (im = 0; im < m2; im++) { for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*rt[ik][im]; #else cwavem[ik] = sf_cmul(cwave[ik],rt[ik][im]); //complex multiplies complex #endif } icfft2(wave[im],cwavem); } for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H c = ww[it] * rr[i]; // source term #else c = sf_crmul(ww[it], rr[i]); // source term #endif if (sub) c += curr[j]; if (!os) { old = curr[j]; #ifdef SF_HAS_COMPLEX_H c += sub? (old-prev[j]) : -prev[j]; #else c = sf_cadd(c,sub? sf_csub(old,prev[j]) : sf_cneg(prev[j])); #endif prev[j] = old; } for (im = 0; im < m2; im++) { #ifdef SF_HAS_COMPLEX_H c += lt[im][i]*wave[im][j]; #else c += sf_cmul(lt[im][i], wave[im][j]); #endif } curr[j] = c; if (!complx) rcurr[j] = crealf(c); } /* write wavefield to output */ if (complx) sf_complexwrite(curr+ix*nz2,nz,Fo); else sf_floatwrite(rcurr+ix*nz2,nz,Fo); } } if(verb) sf_warning("."); cfft2_finalize(); exit (0); }
int main(int argc, char* argv[]) { bool sorted; int i1, n1, i2, n2, ip, np; float o1, d1, t0, t1, t2, t, a, *trace=NULL; float min, max, x; sf_complex *pick=NULL; sf_file in=NULL, out=NULL; sf_init(argc, argv); in = sf_input("in"); out = sf_output("out"); if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input"); n2 = sf_leftsize(in,1); if (!sf_histfloat(in,"d1",&d1)) d1=1.; if (!sf_histfloat(in,"o1",&o1)) o1=0.; if (!sf_getfloat("min",&min)) min=o1; /* minimum value of time */ if (!sf_getfloat("max",&max)) max=o1+(n1-1)*d1; /* maximum value of time */ if (!sf_getint("np",&np)) np=n1; /* maximum number of picks */ if (!sf_getbool("sorted",&sorted)) sorted=true; /* if y, sort by amplitude */ sf_putint(out,"n1",np); sf_settype(out,SF_COMPLEX); trace = sf_floatalloc(n1); pick = sf_complexalloc(np); for (i2=0; i2 < n2; i2++) { sf_floatread(trace,n1,in); t0 = trace[0]; t1 = trace[1]; ip = 0; for (i1=2; i1 < n1; i1++) { t2 = trace[i1]; if (ip < np && t1 > t0 && t1 > t2) { /* parabolic approximation */ t = 0.5*(t2-t0)/(2*t1-t0-t2); a = t1+0.25*(t2-t0)*t; if (t < -1.) { t=-1; a=t0; } else if (t > 1.) { t=1.; a=t2; } x = o1+(i1-1+t)*d1; if (x >= min && x <= max) { pick[ip] = sf_cmplx(x,a); ip++; } } t0 = t1; t1 = t2; } if (0==ip) { pick[0] = sf_cmplx(o1-d1,0.); ip++; } if (sorted) qsort(pick,ip,sizeof(sf_complex),pick_compare); for (i1=ip; i1 < np; i1++) { pick[i1] = sf_cmplx(crealf(pick[ip-1]),0.); } sf_complexwrite(pick,np,out); } exit(0); }
int main(int argc, char*argv[]) { // options float r = 1.1f; // resampling rate (output/input) unsigned int m = 13; // resampling filter semi-length (filter delay) float As = 60.0f; // resampling filter stop-band attenuation [dB] float bw = 0.45f; // resampling filter bandwidth unsigned int npfb = 64; // number of filters in bank (timing resolution) unsigned int n = 400; // number of input samples float fc = 0.044f; // complex sinusoid frequency int dopt; while ((dopt = getopt(argc,argv,"hr:m:b:s:p:n:f:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'r': r = atof(optarg); break; case 'm': m = atoi(optarg); break; case 'b': bw = atof(optarg); break; case 's': As = atof(optarg); break; case 'p': npfb = atoi(optarg); break; case 'n': n = atoi(optarg); break; case 'f': fc = atof(optarg); break; default: exit(1); } } // validate input if (r <= 0.0f) { fprintf(stderr,"error: %s, resampling rate must be greater than zero\n", argv[0]); exit(1); } else if (m == 0) { fprintf(stderr,"error: %s, filter semi-length must be greater than zero\n", argv[0]); exit(1); } else if (bw == 0.0f || bw >= 0.5f) { fprintf(stderr,"error: %s, filter bandwidth must be in (0,0.5)\n", argv[0]); exit(1); } else if (As < 0.0f) { fprintf(stderr,"error: %s, filter stop-band attenuation must be greater than zero\n", argv[0]); exit(1); } else if (npfb == 0) { fprintf(stderr,"error: %s, filter bank size must be greater than zero\n", argv[0]); exit(1); } else if (n == 0) { fprintf(stderr,"error: %s, number of input samples must be greater than zero\n", argv[0]); exit(1); } unsigned int i; // number of input samples (zero-padded) unsigned int nx = n + m; // output buffer with extra padding for good measure unsigned int y_len = (unsigned int) ceilf(1.1 * nx * r) + 4; // arrays float complex x[nx]; float complex y[y_len]; // create resampler resamp_crcf q = resamp_crcf_create(r,m,bw,As,npfb); // generate input signal float wsum = 0.0f; for (i=0; i<nx; i++) { // compute window float w = i < n ? kaiser(i, n, 10.0f, 0.0f) : 0.0f; // apply window to complex sinusoid x[i] = cexpf(_Complex_I*2*M_PI*fc*i) * w; // accumulate window wsum += w; } // resample unsigned int ny=0; // execute on block of samples resamp_crcf_execute_block(q, x, nx, y, &ny); // clean up allocated objects resamp_crcf_destroy(q); // // analyze resulting signal // // check that the actual resampling rate is close to the target float r_actual = (float)ny / (float)nx; float fy = fc / r; // expected output frequency // run FFT and ensure that carrier has moved and that image // frequencies and distortion have been adequately suppressed unsigned int nfft = 1 << liquid_nextpow2(ny); float complex yfft[nfft]; // fft input float complex Yfft[nfft]; // fft output for (i=0; i<nfft; i++) yfft[i] = i < ny ? y[i] : 0.0f; fft_run(nfft, yfft, Yfft, LIQUID_FFT_FORWARD, 0); fft_shift(Yfft, nfft); // run FFT shift // find peak frequency float Ypeak = 0.0f; float fpeak = 0.0f; float max_sidelobe = -1e9f; // maximum side-lobe [dB] float main_lobe_width = 0.07f; // TODO: figure this out from Kaiser's equations for (i=0; i<nfft; i++) { // normalized output frequency float f = (float)i/(float)nfft - 0.5f; // scale FFT output appropriately float Ymag = 20*log10f( cabsf(Yfft[i] / (r * wsum)) ); // find frequency location of maximum magnitude if (Ymag > Ypeak || i==0) { Ypeak = Ymag; fpeak = f; } // find peak side-lobe value, ignoring frequencies // within a certain range of signal frequency if ( fabsf(f-fy) > main_lobe_width ) max_sidelobe = Ymag > max_sidelobe ? Ymag : max_sidelobe; } // print results and check frequency location printf(" desired resampling rate : %12.8f\n", r); printf(" measured resampling rate : %12.8f (%u/%u)\n", r_actual, ny, nx); printf(" peak spectrum : %12.8f dB (expected 0.0 dB)\n", Ypeak); printf(" peak frequency : %12.8f (expected %-12.8f)\n", fpeak, fy); printf(" max sidelobe : %12.8f dB (expected at least %.2f dB)\n", max_sidelobe, -As); // export results FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s: auto-generated file\n",OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n"); fprintf(fid,"m=%u;\n", m); fprintf(fid,"npfb=%u;\n", npfb); fprintf(fid,"r=%12.8f;\n", r); fprintf(fid,"n=%u;\n", n); fprintf(fid,"nx = %u;\n", nx); fprintf(fid,"x = zeros(1,nx);\n"); for (i=0; i<nx; i++) fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"ny = %u;\n", ny); fprintf(fid,"y = zeros(1,ny);\n"); for (i=0; i<ny; i++) fprintf(fid,"y(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); fprintf(fid,"\n\n"); fprintf(fid,"%% plot time-domain result\n"); fprintf(fid,"tx=[0:(length(x)-1)];\n"); fprintf(fid,"ty=[0:(length(y)-1)]/r-m;\n"); fprintf(fid,"figure('Color','white','position',[500 500 500 900]);\n"); fprintf(fid,"subplot(4,1,1);\n"); fprintf(fid," plot(tx,real(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,real(y),'-s','Color',[0.5 0 0], 'MarkerSize',1);\n"); fprintf(fid," legend('original','resampled','location','northeast');"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('real');\n"); fprintf(fid," axis([0 n -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(4,1,2);\n"); fprintf(fid," plot(tx,imag(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,imag(y),'-s','Color',[0 0.5 0], 'MarkerSize',1);\n"); fprintf(fid," legend('original','resampled','location','northeast');"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('imag');\n"); fprintf(fid," axis([0 n -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"%% plot frequency-domain result\n"); fprintf(fid,"nfft=2^nextpow2(max(nx,ny));\n"); fprintf(fid,"%% estimate PSD, normalize by array length\n"); fprintf(fid,"X=20*log10(abs(fftshift(fft(x,nfft)/length(x))));\n"); fprintf(fid,"Y=20*log10(abs(fftshift(fft(y,nfft)/length(y))));\n"); fprintf(fid,"G=max(X);\n"); fprintf(fid,"X=X-G;\n"); fprintf(fid,"Y=Y-G;\n"); fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n"); fprintf(fid,"if r>1, fx = f/r; fy = f; %% interpolated\n"); fprintf(fid,"else, fx = f; fy = f*r; %% decimated\n"); fprintf(fid,"end;\n"); fprintf(fid,"subplot(4,1,3:4);\n"); fprintf(fid," plot(fx,X,'Color',[0.5 0.5 0.5],fy,Y,'LineWidth',2);\n"); fprintf(fid," grid on;\n"); fprintf(fid," xlabel('normalized frequency');\n"); fprintf(fid," ylabel('PSD [dB]');\n"); fprintf(fid," legend('original','resampled','location','northeast');"); fprintf(fid," axis([-0.5 0.5 -120 20]);\n"); fclose(fid); printf("results written to %s\n",OUTPUT_FILENAME); printf("done.\n"); return 0; }
void print_complex(unsigned int D, const complex float arr[D]) { for (unsigned int i = 0; i < D; i++) printf("arr[%i]: real = %f, imag = %f\n", i, crealf(arr[i]), cimagf(arr[i])); }
int main(int argc, char*argv[]) { // options float mod_index = 0.1f; // modulation index (bandwidth) float fc = 0.10f; // AM carrier liquid_ampmodem_type type = LIQUID_AMPMODEM_DSB; int suppressed_carrier = 0; // suppress the carrier? unsigned int num_samples = 201; // number of samples float SNRdB = 60.0f; // signal-to-noise ratio [dB] // derived values unsigned int nfft = 1024; // create mod/demod objects ampmodem mod = ampmodem_create(mod_index, fc, type, suppressed_carrier); ampmodem demod = ampmodem_create(mod_index, fc, type, suppressed_carrier); ampmodem_print(mod); unsigned int i; float x[num_samples]; float complex y[num_samples]; float z[num_samples]; #if 0 // generate input data: windowed sinusoid float f_audio = 0.04179f; // input sine frequency for (i=0; i<num_samples; i++) { x[i] = sinf(2*M_PI*i*f_audio) + 0.5f*sinf(2*M_PI*i*f_audio*1.8f); x[i] *= 0.7f*hamming(i,num_samples); } #else // generate un-modulated input signal (filtered noise) float fc_audio = 0.07f; float f0_audio = 0.10f; iirfilt_rrrf f = iirfilt_rrrf_create_prototype(LIQUID_IIRDES_BUTTER, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, 6, fc_audio, f0_audio, 1.0f, 1.0f); // push noise through filter for (i=0; i<100; i++) iirfilt_rrrf_execute(f, 1.5f*randnf(), &x[0]); // generate filtered/windowed output for (i=0; i<num_samples; i++) { iirfilt_rrrf_execute(f, 1.5f*randnf(), &x[i]); x[i] *= hamming(i,num_samples); } iirfilt_rrrf_destroy(f); #endif // modulate signal for (i=0; i<num_samples; i++) ampmodem_modulate(mod, x[i], &y[i]); // add noise float nstd = powf(10.0f,-SNRdB/20.0f); for (i=0; i<num_samples; i++) cawgn(&y[i], nstd); // demodulate signal for (i=0; i<num_samples; i++) ampmodem_demodulate(demod, y[i], &z[i]); // destroy objects ampmodem_destroy(mod); ampmodem_destroy(demod); // compute power spectral density float complex Y[nfft]; liquid_doc_psdwindow wtype = LIQUID_DOC_PSDWINDOW_HANN; int normalize = 1; liquid_doc_compute_psdcf(y, num_samples, Y, nfft, wtype, normalize); // // export output files // FILE * fid; // time-domain plot fid = fopen(OUTPUT_FILENAME_TIME,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open '%s' for writing\n", argv[0], OUTPUT_FILENAME_TIME); exit(1); } fprintf(fid,"# %s: auto-generated file\n\n", OUTPUT_FILENAME_TIME); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set xrange [0:%u];\n",num_samples-1); fprintf(fid,"set yrange [-1.2:1.2]\n"); fprintf(fid,"set size ratio 0.3\n"); fprintf(fid,"set xlabel 'Sample Index'\n"); fprintf(fid,"set key top right nobox\n"); fprintf(fid,"set ytics -5,0.5,5\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set pointsize 0.6\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n", LIQUID_DOC_COLOR_GRID); fprintf(fid,"set multiplot layout 2,1 scale 1.0,1.0\n"); fprintf(fid,"# input/demodulated signals\n"); fprintf(fid,"set ylabel 'input/output signal'\n"); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 2 linecolor rgb '%s' title 'input',\\\n",LIQUID_DOC_COLOR_RED); fprintf(fid," '-' using 1:2 with lines linetype 1 linecolor rgb '%s' title 'demodulated'\n",LIQUID_DOC_COLOR_GRAY); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, x[i]); fprintf(fid,"e\n"); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, z[i]); fprintf(fid,"e\n"); fprintf(fid,"# demodulated signals\n"); fprintf(fid,"set ylabel 'modulated signal'\n"); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '%s' title 'real',\\\n",LIQUID_DOC_COLOR_BLUE); fprintf(fid," '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '%s' title 'imag',\\\n",LIQUID_DOC_COLOR_GREEN); fprintf(fid," '-' using 1:2 with lines linetype 0 linewidth 2 linecolor rgb '#222222' notitle,\\\n"); fprintf(fid," '-' using 1:2 with lines linetype 0 linewidth 2 linecolor rgb '#222222' notitle\n"); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, crealf(y[i])); fprintf(fid,"e\n"); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, cimagf(y[i])); fprintf(fid,"e\n"); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, cabsf(y[i])); fprintf(fid,"e\n"); for (i=0; i<num_samples; i++) fprintf(fid,"%12u %12.4e\n", i, -cabsf(y[i])); fprintf(fid,"e\n"); fclose(fid); printf("results written to '%s\n", OUTPUT_FILENAME_TIME); // frequency-domain plot fid = fopen(OUTPUT_FILENAME_FREQ,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open '%s' for writing\n", argv[0], OUTPUT_FILENAME_FREQ); exit(1); } fprintf(fid,"# %s: auto-generated file\n\n", OUTPUT_FILENAME_FREQ); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set xrange [-0.5:0.5];\n"); fprintf(fid,"set yrange [-100:10]\n"); fprintf(fid,"set size ratio 0.6\n"); fprintf(fid,"set xlabel 'Normalized Frequency'\n"); fprintf(fid,"set ylabel 'Power Spectral Density [dB]'\n"); fprintf(fid,"set nokey\n"); fprintf(fid,"set xtics -0.5,0.1,0.5\n"); fprintf(fid,"set ytics -200,20,200\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n", LIQUID_DOC_COLOR_GRID); fprintf(fid,"# spectrum\n"); fprintf(fid,"set style fill solid 0.1\n"); fprintf(fid,"plot '-' using 1:2 with filledcurves above y1=-200 linetype 1 linewidth 3 linecolor rgb '%s' title 'input'\n",LIQUID_DOC_COLOR_PURPLE); for (i=0; i<nfft; i++) fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)nfft - 0.5f, 20*log10f(cabsf(Y[(i+nfft/2)%nfft]))); fprintf(fid,"e\n"); fclose(fid); printf("results written to '%s\n", OUTPUT_FILENAME_FREQ); return 0; }