void fdmig (sf_complex **dat /* input data */, float **img /* output image */, sf_file movie /* save movie (if not NULL) */) /*< Migrate >*/ { int iz, ix, iw; float omega; sf_complex aa, bb, shift; for (iz=0; iz < nz; iz++) { for (ix=0; ix < nx; ix++) { img[iz][ix] = 0.; cu[ix] = sf_cmplx(0.,0.); } if (NULL != movie) sf_complexwrite(cu,nx,movie); } for (iw=1; iw < nw; iw++) { omega = dw*iw; aa = sf_cmplx(beta*omega,alpha); #ifdef SF_HAS_COMPLEX_H if (hi) aa += alpha/omega; /* add the third derivative term */ bb = omega - 2.*aa; #else if (hi) aa.r += alpha/omega; /* add the third derivative term */ bb.r = omega - 2.*aa.r; bb.i = - 2.*aa.i; #endif ctridiagonal_const_define (slv,conjf(bb),conjf(aa)); for (ix=0; ix < nx; ix++) { cu[ix] = dat[iw][ix]; } for (iz=0; iz < nz; iz++) { cd[0] = sf_cmplx(0.,0.); for (ix=1; ix < nx-1; ix++) { #ifdef SF_HAS_COMPLEX_H cd[ix] = aa*(cu[ix+1] + cu[ix-1]) + bb*cu[ix]; #else cd[ix] = sf_cadd(sf_cmul(aa,sf_cadd(cu[ix+1],cu[ix-1])), sf_cmul(bb,cu[ix])); #endif } cd[nx-1] = sf_cmplx(0.,0.); ctridiagonal_solve (slv, cd); for (ix=0; ix < nx; ix++) { shift = sf_cmplx(cosf(omega),sinf(omega)); #ifdef SF_HAS_COMPLEX_H cu[ix] = cd[ix]*shift; #else cu[ix] = sf_cmul(cd[ix],shift); #endif img[iz][ix] += crealf(cu[ix]); } if (NULL != movie) sf_complexwrite(cu,nx,movie); } } }
/***************************************************************************//** * @ingroup CORE_PLASMA_Complex32_t ******************************************************************************* * * Purpose * ======= * * CORE_clarfx2c applies a complex elementary reflector H to a diagonal corner * C=[C1, C2, C3], from both the left and the right side. C = H * C * H. * It is used in the case of general matrices, where it create a nnz at the * NEW_NNZ position, then it eliminate it and update the reflector V and TAU. * If PlasmaLower, a left apply is followed by a right apply. * If PlasmaUpper, a right apply is followed by a left apply. * H is represented in the form * * This routine is a special code for a corner C diagonal block C1 NEW_NNZ * C2 C3 * * * H = I - tau * v * v' * * where tau is a complex scalar and v is a complex vector. * * If tau = 0, then H is taken to be the unit matrix * * This version uses inline code if H has order < 11. * * Arguments * ========= * * @param[in] uplo * = PlasmaUpper: Upper triangle of A is stored; * = PlasmaLower: Lower triangle of A is stored. * * @param[in, out] V * On entry, the float complex V in the representation of H. * On exit, the float complex V in the representation of H, * updated by the elimination of the NEW_NNZ created by the * left apply in case of PlasmaLower or the right apply in * case of PlasmaUpper. * * @param[in] TAU * On entry, the value tau in the representation of H. * On exit, the value tau in the representation of H, * updated by the elimination of the NEW_NNZ created by the * left apply in case of PlasmaLower or the right apply in * case of PlasmaUpper. * * @param[in,out] C1 * On entry, the element C1. * On exit, C1 is overwritten by the result H * C * H. * * @param[in,out] C2 * On entry, the element C2. * On exit, C2 is overwritten by the result H * C * H. * * @param[in,out] C3 * On entry, the element C3. * On exit, C3 is overwritten by the result H * C * H. * * ===================================================================== * * @return * \retval PLASMA_SUCCESS successful exit * \retval <0 if -i, the i-th argument had an illegal value * ******************************************************************************/ int CORE_clarfx2ce(PLASMA_enum uplo, PLASMA_Complex32_t *V, PLASMA_Complex32_t *TAU, PLASMA_Complex32_t *C1, PLASMA_Complex32_t *C2, PLASMA_Complex32_t *C3) { PLASMA_Complex32_t T2, SUM, TEMP, VIN, TAUIN; /* Quick return */ if (*TAU == (PLASMA_Complex32_t)0.0) return PLASMA_SUCCESS; /* * Special code for a diagonal block C1 * C2 C3 */ if(uplo==PlasmaLower){ /* * Do the corner for the lower case BIDIAG ==> Left then will * create a new nnz. eliminate it and modify V TAU and then * Right L and R for the 2x2 corner * C(N-1, N-1) C(N-1,N) C1 TEMP * C(N , N-1) C(N ,N) C2 C3 */ VIN = *V; TAUIN = conjf(*TAU); /* Left 1 ==> C1 */ /* C2 */ VIN = conjf(VIN); T2 = TAUIN * conjf(VIN); SUM = *C1 + VIN*(*C2); *C1 = *C1 - SUM*TAUIN; *C2 = *C2 - SUM*T2; /* new nnz at TEMP and update C3 */ SUM = VIN * (*C3); TEMP = - SUM * TAUIN; *C3 = *C3 - SUM * T2; /* generate Householder to annihilate the nonzero created at TEMP */ *V = TEMP; LAPACKE_clarfg_work( 2, C1, V, 1, TAU); VIN = conjf(*V); TAUIN = conjf(*TAU); /* Right 1 ==> C2 C3 */ /* VIN = VIN */ T2 = TAUIN * conjf(VIN); SUM = *C2 + VIN*(*C3); *C2 = *C2 - SUM*TAUIN; *C3 = *C3 - SUM*T2; }else if(uplo==PlasmaUpper){ /* * Do the corner for the upper case BIDIAG ==> Right then will * create a new nnz. eliminate it and modify V TAU and then * Left * C(N-1, N-1) C(N-1,N) C1 C2 * C(N , N-1) C(N ,N) TEMP C3 * For Left : use conjf(TAU) and V. * For Right: use conjf(TAU) and conjf(V) as input. */ VIN = conjf(*V); TAUIN = conjf(*TAU); /* Right 1 ==> C1 C2 */ /* VIN = VIN */ T2 = TAUIN*conjf(VIN); SUM = *C1 + VIN*(*C2); *C1 = *C1 - SUM*TAUIN; *C2 = *C2 - SUM*T2; /* new nnz at TEMP and update C3 */ SUM = VIN * (*C3); TEMP = - SUM * TAUIN; *C3 = *C3 - SUM * T2; /* generate Householder to annihilate the nonzero created at TEMP */ *V = TEMP; LAPACKE_clarfg_work( 2, C1, V, 1, TAU); VIN = *V; TAUIN = conjf(*TAU); /* apply from the Left using the NEW V TAU to the remaining 2 elements [C2 C3] */ /* Left 2 ==> C2 */ /* C3 */ VIN = conjf(VIN); T2 = TAUIN*conjf(VIN); SUM = *C2 + VIN*(*C3); *C2 = *C2 - SUM*TAUIN; *C3 = *C3 - SUM*T2; } return PLASMA_SUCCESS; }
int main(int argc, char*argv[]) { // options unsigned int m = 3; // number of bits/symbol unsigned int k = 0; // filter samples/symbol unsigned int num_symbols = 200; // number of data symbols float SNRdB = 40.0f; // signal-to-noise ratio [dB] float cfo = 0.0f; // carrier frequency offset float cpo = 0.0f; // carrier phase offset float tau = 0.0f; // fractional symbol timing offset float bandwidth = 0.20; // frequency spacing int dopt; while ((dopt = getopt(argc,argv,"hm:k:b:n:s:F:P:T:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'm': m = atoi(optarg); break; case 'k': k = atoi(optarg); break; case 'b': bandwidth = atof(optarg); break; case 'n': num_symbols = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'F': cfo = atof(optarg); break; case 'P': cpo = atof(optarg); break; case 'T': tau = atof(optarg); break; default: exit(1); } } unsigned int i; unsigned int j; // derived values if (k == 0) k = 2 << m; // set samples per symbol if not otherwise specified unsigned int num_samples = k*num_symbols; unsigned int M = 1 << m; float nstd = powf(10.0f, -SNRdB/20.0f); float M2 = 0.5f*(float)(M-1); // validate input if (k < M) { fprintf(stderr,"errors: %s, samples/symbol must be at least modulation size (M=%u)\n", __FILE__,M); exit(1); } else if (k > 2048) { fprintf(stderr,"errors: %s, samples/symbol exceeds maximum (2048)\n", __FILE__); exit(1); } else if (M > 1024) { fprintf(stderr,"errors: %s, modulation size (M=%u) exceeds maximum (1024)\n", __FILE__, M); exit(1); } else if (bandwidth <= 0.0f || bandwidth >= 0.5f) { fprintf(stderr,"errors: %s, bandwidht must be in (0,0.5)\n", __FILE__); exit(1); } // compute demodulation FFT size such that FFT output bin frequencies are // as close to modulated frequencies as possible unsigned int K = 0; // demodulation FFT size float df = bandwidth / M2; // frequency spacing float err_min = 1e9f; unsigned int K_min = k; // minimum FFT size unsigned int K_max = k*4 < 16 ? 16 : k*4; // maximum FFT size unsigned int K_hat; for (K_hat=K_min; K_hat<=K_max; K_hat++) { // compute candidate FFT size float v = 0.5f*df * (float)K_hat; // bin spacing float err = fabsf( roundf(v) - v ); // fractional bin spacing // print results printf(" K_hat = %4u : v = %12.8f, err=%12.8f %s\n", K_hat, v, err, err < err_min ? "*" : ""); // save best result if (K_hat==K_min || err < err_min) { K = K_hat; err_min = err; } // perfect match; no need to continue searching if (err < 1e-6f) break; } // arrays unsigned int sym_in[num_symbols]; // input symbols float complex x[num_samples]; // transmitted signal float complex y[num_samples]; // received signal unsigned int sym_out[num_symbols]; // output symbols // determine demodulation mapping between tones and frequency bins // TODO: use gray coding unsigned int demod_map[M]; for (i=0; i<M; i++) { // print frequency bins float freq = ((float)i - M2) * bandwidth / M2; float idx = freq * (float)K; unsigned int index = (unsigned int) (idx < 0 ? roundf(idx + K) : roundf(idx)); demod_map[i] = index; printf(" s=%3u, f = %12.8f, index=%3u\n", i, freq, index); } // check for uniqueness for (i=1; i<M; i++) { if (demod_map[i] == demod_map[i-1]) { fprintf(stderr,"warning: demod map is not unique; consider increasing bandwidth\n"); break; } } // generate message symbols and modulate // TODO: use gray coding for (i=0; i<num_symbols; i++) { // generate random symbol sym_in[i] = rand() % M; // compute frequency float dphi = 2*M_PI*((float)sym_in[i] - M2) * bandwidth / M2; // generate random phase float phi = randf() * 2 * M_PI; // modulate symbol for (j=0; j<k; j++) x[i*k+j] = cexpf(_Complex_I*phi + _Complex_I*j*dphi); } // push through channel for (i=0; i<num_samples; i++) y[i] = x[i] + nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2; #if 0 // demodulate signal: high SNR method float complex buf_time[k]; unsigned int n = 0; j = 0; for (i=0; i<num_samples; i++) { // start filling time buffer with samples (assume perfect symbol timing) buf_time[n++] = y[i]; // demodulate symbol if (n==k) { // reset counter n = 0; // estimate frequency float complex metric = 0; unsigned int s; for (s=1; s<k; s++) metric += buf_time[s] * conjf(buf_time[s-1]); float dphi_hat = cargf(metric) / (2*M_PI); unsigned int v=( (unsigned int) roundf(dphi_hat*M2/bandwidth + M2) ) % M; sym_out[j++] = v; printf("%3u : %12.8f : %u\n", j, dphi_hat, v); } } #else // demodulate signal: least-squares method float complex buf_time[K]; float complex buf_freq[K]; fftplan fft = fft_create_plan(K, buf_time, buf_freq, LIQUID_FFT_FORWARD, 0); for (i=0; i<K; i++) buf_time[i] = 0.0f; unsigned int n = 0; j = 0; for (i=0; i<num_samples; i++) { // start filling time buffer with samples (assume perfect symbol timing) buf_time[n++] = y[i]; // demodulate symbol if (n==k) { // reset counter n = 0; // compute transform, storing result in 'buf_freq' fft_execute(fft); // find maximum by looking at particular bins float vmax = 0; unsigned int s; unsigned int s_opt = 0; for (s=0; s<M; s++) { float v = cabsf( buf_freq[demod_map[s]] ); if (s==0 || v > vmax) { s_opt = s; vmax =v; } } // save best result sym_out[j++] = s_opt; } } // destroy fft object fft_destroy_plan(fft); #endif // count errors unsigned int num_symbol_errors = 0; for (i=0; i<num_symbols; i++) num_symbol_errors += (sym_in[i] == sym_out[i]) ? 0 : 1; printf("symbol errors: %u / %u\n", num_symbol_errors, num_symbols); // compute power spectral density of received signal unsigned int nfft = 1200; float psd[nfft]; spgramcf_estimate_psd(nfft, y, num_samples, psd); // // export results // // truncate to at most 10 symbols if (num_symbols > 10) num_symbols = 10; num_samples = k*num_symbols; 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,"k = %u;\n", k); fprintf(fid,"M = %u;\n", M); fprintf(fid,"num_symbols = %u;\n", num_symbols); fprintf(fid,"num_samples = %u;\n", num_samples); fprintf(fid,"nfft = %u;\n", nfft); fprintf(fid,"x = zeros(1,num_samples);\n"); fprintf(fid,"y = zeros(1,num_samples);\n"); for (i=0; i<num_samples; i++) { fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i])); } // save power spectral density fprintf(fid,"psd = zeros(1,nfft);\n"); for (i=0; i<nfft; i++) fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]); fprintf(fid,"t=[0:(num_samples-1)]/k;\n"); fprintf(fid,"i = 1:k:num_samples;\n"); fprintf(fid,"figure;\n"); // plot time signal fprintf(fid,"subplot(2,1,1),\n"); fprintf(fid,"hold on;\n"); fprintf(fid," plot(t,real(y),'-', 'Color',[0 0.3 0.5]);\n"); fprintf(fid," plot(t,imag(y),'-', 'Color',[0 0.5 0.3]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"ymax = ceil(max(abs(y))*5)/5;\n"); fprintf(fid,"axis([0 num_symbols -ymax ymax]);\n"); fprintf(fid,"xlabel('time');\n"); fprintf(fid,"ylabel('x(t)');\n"); fprintf(fid,"grid on;\n"); // plot PSD fprintf(fid,"subplot(2,1,2),\n"); fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"plot(f,psd,'LineWidth',1.5,'Color',[0.5 0 0]);\n"); fprintf(fid,"axis([-0.5 0.5 -40 40]);\n"); fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid,"ylabel('PSD [dB]');\n"); fprintf(fid,"grid on;\n"); fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); return 0; }
int main(int argc, char*argv[]) { // options unsigned int k = 8; // filter samples/symbol unsigned int bps= 1; // number of bits/symbol float h = 0.5f; // modulation index (h=1/2 for MSK) unsigned int num_data_symbols = 20; // number of data symbols float SNRdB = 80.0f; // signal-to-noise ratio [dB] float cfo = 0.0f; // carrier frequency offset float cpo = 0.0f; // carrier phase offset float tau = 0.0f; // fractional symbol offset enum { TXFILT_SQUARE=0, TXFILT_RCOS_FULL, TXFILT_RCOS_HALF, TXFILT_GMSK, } tx_filter_type = TXFILT_SQUARE; float gmsk_bt = 0.35f; // GMSK bandwidth-time factor int dopt; while ((dopt = getopt(argc,argv,"ht:k:b:H:B:n:s:F:P:T:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 't': if (strcmp(optarg,"square")==0) { tx_filter_type = TXFILT_SQUARE; } else if (strcmp(optarg,"rcos-full")==0) { tx_filter_type = TXFILT_RCOS_FULL; } else if (strcmp(optarg,"rcos-half")==0) { tx_filter_type = TXFILT_RCOS_HALF; } else if (strcmp(optarg,"gmsk")==0) { tx_filter_type = TXFILT_GMSK; } else { fprintf(stderr,"error: %s, unknown filter type '%s'\n", argv[0], optarg); exit(1); } break; case 'k': k = atoi(optarg); break; case 'b': bps = atoi(optarg); break; case 'H': h = atof(optarg); break; case 'B': gmsk_bt = atof(optarg); break; case 'n': num_data_symbols = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'F': cfo = atof(optarg); break; case 'P': cpo = atof(optarg); break; case 'T': tau = atof(optarg); break; default: exit(1); } } unsigned int i; // derived values unsigned int num_symbols = num_data_symbols; unsigned int num_samples = k*num_symbols; unsigned int M = 1 << bps; // constellation size float nstd = powf(10.0f, -SNRdB/20.0f); // arrays unsigned char sym_in[num_symbols]; // input symbols float phi[num_samples]; // transmitted phase float complex x[num_samples]; // transmitted signal float complex y[num_samples]; // received signal float complex z[num_samples]; // output... //unsigned char sym_out[num_symbols]; // output symbols unsigned int ht_len = 0; unsigned int tx_delay = 0; float * ht = NULL; switch (tx_filter_type) { case TXFILT_SQUARE: // regular MSK ht_len = k; tx_delay = 1; ht = (float*) malloc(ht_len *sizeof(float)); for (i=0; i<ht_len; i++) ht[i] = h * M_PI / (float)k; break; case TXFILT_RCOS_FULL: // full-response raised-cosine pulse ht_len = k; tx_delay = 1; ht = (float*) malloc(ht_len *sizeof(float)); for (i=0; i<ht_len; i++) ht[i] = h * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)ht_len)); break; case TXFILT_RCOS_HALF: // partial-response raised-cosine pulse ht_len = 3*k; tx_delay = 2; ht = (float*) malloc(ht_len *sizeof(float)); for (i=0; i<ht_len; i++) ht[i] = 0.0f; for (i=0; i<2*k; i++) ht[i+k/2] = h * 0.5f * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)(2*k))); break; case TXFILT_GMSK: ht_len = 2*k*3+1+k; tx_delay = 4; ht = (float*) malloc(ht_len *sizeof(float)); for (i=0; i<ht_len; i++) ht[i] = 0.0f; liquid_firdes_gmsktx(k,3,gmsk_bt,0.0f,&ht[k/2]); for (i=0; i<ht_len; i++) ht[i] *= h * 2.0f / (float)k; break; default: fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]); exit(1); } for (i=0; i<ht_len; i++) printf("ht(%3u) = %12.8f;\n", i+1, ht[i]); firinterp_rrrf interp_tx = firinterp_rrrf_create(k, ht, ht_len); // generate symbols and interpolate // phase-accumulating filter (trapezoidal integrator) float b[2] = {0.5f, 0.5f}; if (tx_filter_type == TXFILT_SQUARE) { // square filter: rectangular integration with one sample of delay b[0] = 0.0f; b[1] = 1.0f; } float a[2] = {1.0f, -1.0f}; iirfilt_rrrf integrator = iirfilt_rrrf_create(b,2,a,2); float theta = 0.0f; for (i=0; i<num_symbols; i++) { sym_in[i] = rand() % M; float v = 2.0f*sym_in[i] - (float)(M-1); // +/-1, +/-3, ... +/-(M-1) firinterp_rrrf_execute(interp_tx, v, &phi[k*i]); // accumulate phase unsigned int j; for (j=0; j<k; j++) { iirfilt_rrrf_execute(integrator, phi[i*k+j], &theta); x[i*k+j] = cexpf(_Complex_I*theta); } } iirfilt_rrrf_destroy(integrator); // push through channel for (i=0; i<num_samples; i++) { // add carrier frequency/phase offset y[i] = x[i]*cexpf(_Complex_I*(cfo*i + cpo)); // add noise y[i] += nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2; } // create decimator unsigned int m = 3; float bw = 0.0f; float beta = 0.0f; firfilt_crcf decim_rx = NULL; switch (tx_filter_type) { case TXFILT_SQUARE: //bw = 0.9f / (float)k; bw = 0.4f; decim_rx = firfilt_crcf_create_kaiser(2*k*m+1, bw, 60.0f, 0.0f); firfilt_crcf_set_scale(decim_rx, 2.0f * bw); break; case TXFILT_RCOS_FULL: if (M==2) { decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.5f,0); firfilt_crcf_set_scale(decim_rx, 1.33f / (float)k); } else { decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.9f,0); firfilt_crcf_set_scale(decim_rx, 3.25f / (float)k); } break; case TXFILT_RCOS_HALF: if (M==2) { decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.3f,0); firfilt_crcf_set_scale(decim_rx, 1.10f / (float)k); } else { decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.27f,0); firfilt_crcf_set_scale(decim_rx, 2.90f / (float)k); } break; case TXFILT_GMSK: bw = 0.5f / (float)k; // TODO: figure out beta value here beta = (M == 2) ? 0.8*gmsk_bt : 1.0*gmsk_bt; decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,beta,0); firfilt_crcf_set_scale(decim_rx, 2.0f * bw); break; default: fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]); exit(1); } printf("bw = %f\n", bw); // run receiver unsigned int n=0; unsigned int num_errors = 0; unsigned int num_symbols_checked = 0; float complex z_prime = 0.0f; for (i=0; i<num_samples; i++) { // push through filter firfilt_crcf_push(decim_rx, y[i]); firfilt_crcf_execute(decim_rx, &z[i]); // decimate output if ( (i%k)==0 ) { // compute instantaneous frequency scaled by modulation index float phi_hat = cargf(conjf(z_prime) * z[i]) / (h * M_PI); // estimate transmitted symbol float v = (phi_hat + (M-1.0))*0.5f; unsigned int sym_out = ((int) roundf(v)) % M; // save current point z_prime = z[i]; // print result to screen printf("%3u : %12.8f + j%12.8f, <f=%8.4f : %8.4f> (%1u)", n, crealf(z[i]), cimagf(z[i]), phi_hat, v, sym_out); if (n >= m+tx_delay) { num_errors += (sym_out == sym_in[n-m-tx_delay]) ? 0 : 1; num_symbols_checked++; printf(" (%1u)\n", sym_in[n-m-tx_delay]); } else { printf("\n"); } n++; } } // print number of errors printf("errors : %3u / %3u\n", num_errors, num_symbols_checked); // destroy objects firinterp_rrrf_destroy(interp_tx); firfilt_crcf_destroy(decim_rx); // compute power spectral density of transmitted signal unsigned int nfft = 1024; float psd[nfft]; spgramcf periodogram = spgramcf_create_kaiser(nfft, nfft/2, 8.0f); spgramcf_estimate_psd(periodogram, y, num_samples, psd); spgramcf_destroy(periodogram); // // 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,"k = %u;\n", k); fprintf(fid,"h = %f;\n", h); fprintf(fid,"num_symbols = %u;\n", num_symbols); fprintf(fid,"num_samples = %u;\n", num_samples); fprintf(fid,"nfft = %u;\n", nfft); fprintf(fid,"delay = %u; %% receive filter delay\n", tx_delay); fprintf(fid,"x = zeros(1,num_samples);\n"); fprintf(fid,"y = zeros(1,num_samples);\n"); fprintf(fid,"z = zeros(1,num_samples);\n"); fprintf(fid,"phi = zeros(1,num_samples);\n"); for (i=0; i<num_samples; i++) { fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i])); fprintf(fid,"z(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(z[i]), cimagf(z[i])); fprintf(fid,"phi(%4u) = %12.8f;\n", i+1, phi[i]); } // save PSD fprintf(fid,"psd = zeros(1,nfft);\n"); for (i=0; i<nfft; i++) fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]); fprintf(fid,"t=[0:(num_samples-1)]/k;\n"); fprintf(fid,"i = 1:k:num_samples;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(3,4,1:3);\n"); fprintf(fid," plot(t,real(x),'-', t(i),real(x(i)),'bs','MarkerSize',4,...\n"); fprintf(fid," t,imag(x),'-', t(i),imag(x(i)),'gs','MarkerSize',4);\n"); fprintf(fid," axis([0 num_symbols -1.2 1.2]);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('x(t)');\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(3,4,5:7);\n"); fprintf(fid," plot(t-delay,real(z),'-', t(i)-delay,real(z(i)),'bs','MarkerSize',4,...\n"); fprintf(fid," t-delay,imag(z),'-', t(i)-delay,imag(z(i)),'gs','MarkerSize',4);\n"); fprintf(fid," axis([0 num_symbols -1.2 1.2]);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('\"matched\" filter output');\n"); fprintf(fid," grid on;\n"); // plot I/Q constellations fprintf(fid,"subplot(3,4,4);\n"); fprintf(fid," plot(real(y),imag(y),'-',real(y(i)),imag(y(i)),'rs','MarkerSize',3);\n"); fprintf(fid," xlabel('I');\n"); fprintf(fid," ylabel('Q');\n"); fprintf(fid," axis([-1 1 -1 1]*1.2);\n"); fprintf(fid," axis square;\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(3,4,8);\n"); fprintf(fid," plot(real(z),imag(z),'-',real(z(i)),imag(z(i)),'rs','MarkerSize',3);\n"); fprintf(fid," xlabel('I');\n"); fprintf(fid," ylabel('Q');\n"); fprintf(fid," axis([-1 1 -1 1]*1.2);\n"); fprintf(fid," axis square;\n"); fprintf(fid," grid on;\n"); // plot PSD fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"subplot(3,4,9:12);\n"); fprintf(fid," plot(f,psd,'LineWidth',1.5);\n"); fprintf(fid," axis([-0.5 0.5 -40 20]);\n"); fprintf(fid," xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid," ylabel('PSD [dB]');\n"); fprintf(fid," grid on;\n"); #if 0 fprintf(fid,"figure;\n"); fprintf(fid," %% compute instantaneous received frequency\n"); fprintf(fid," freq_rx = arg( conj(z(:)) .* circshift(z(:),-1) )';\n"); fprintf(fid," freq_rx(1:(k*delay)) = 0;\n"); fprintf(fid," freq_rx(end) = 0;\n"); fprintf(fid," %% compute instantaneous tx/rx phase\n"); if (tx_filter_type == TXFILT_SQUARE) { fprintf(fid," theta_tx = filter([0 1],[1 -1],phi)/(h*pi);\n"); fprintf(fid," theta_rx = filter([0 1],[1 -1],freq_rx)/(h*pi);\n"); } else { fprintf(fid," theta_tx = filter([0.5 0.5],[1 -1],phi)/(h*pi);\n"); fprintf(fid," theta_rx = filter([0.5 0.5],[1 -1],freq_rx)/(h*pi);\n"); } fprintf(fid," %% plot instantaneous tx/rx phase\n"); fprintf(fid," plot(t, theta_tx,'-b', t(i), theta_tx(i),'sb',...\n"); fprintf(fid," t-delay,theta_rx,'-r', t(i)-delay,theta_rx(i),'sr');\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('instantaneous phase/(h \\pi)');\n"); fprintf(fid," legend('transmitted','syms','received/filtered','syms','location','northwest');\n"); fprintf(fid," grid on;\n"); #else // plot filter response fprintf(fid,"ht_len = %u;\n", ht_len); fprintf(fid,"ht = zeros(1,ht_len);\n"); for (i=0; i<ht_len; i++) fprintf(fid,"ht(%4u) = %12.8f;\n", i+1, ht[i]); fprintf(fid,"gt1 = filter([0.5 0.5],[1 -1],ht) / (pi*h);\n"); fprintf(fid,"gt2 = filter([0.0 1.0],[1 -1],ht) / (pi*h);\n"); fprintf(fid,"tfilt = [0:(ht_len-1)]/k - delay + 0.5;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(tfilt,ht, '-x','MarkerSize',4,...\n"); fprintf(fid," tfilt,gt1,'-x','MarkerSize',4,...\n"); fprintf(fid," tfilt,gt2,'-x','MarkerSize',4);\n"); fprintf(fid,"axis([tfilt(1) tfilt(end) -0.1 1.1]);\n"); fprintf(fid,"legend('pulse','trap. int.','rect. int.','location','northwest');\n"); fprintf(fid,"grid on;\n"); #endif fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); // free allocated filter memory free(ht); return 0; }
void shot_ani_convlv3dtest(sf_complex *wld_z,sf_complex *conapp,sf_complex *conapm,int tnx,int tny, struct shot_ker_par_type ker_par, int signn) { int nx,ny,tn; sf_complex *tmpwld_z; //(:,:) sf_complex *conap,*conam; int iy,ix,ic,icx,icy; tn=tnx*tny; nx=ker_par.nx; ny=ker_par.ny; tmpwld_z=ker_par.tmp_wld; //allocate(tmpwld_z(nx,ny)) ker_par.tmp_wld is allocated in ker_init in kernal.c conap=sf_complexalloc(tn); conam=sf_complexalloc(tn); vector_cp_c(tmpwld_z,wld_z,nx*ny); //tmpwld_z=wld_z; vector_cp_c(conap,conapp,tn); vector_cp_c(conam,conapm,tn); vector_value_c(wld_z,sf_cmplx(0.0,0.0),nx*ny); if (signn==+1) { for(ic=0;ic<tn;ic++){ conap[ic]=conjf(conapp[ic]); conam[ic]=conjf(conapm[ic]); } //for(ic) } else{ for(ic=0;ic<tn;ic++){ conap[ic]=(conapp[ic]); conam[ic]=(conapm[ic]); } //for(ic) } for(icy=1;icy<tny;icy++){ for(icx=0; icx<tnx; icx++){ ic=icy*tnx+icx; conap[ic]=0.5*conap[ic]; conam[ic]=0.5*conam[ic]; } } // for (ic=0;ic<tn;ic++){ // printf("ic=%d,(%f,%f)",ic,__real__ conap[ic],__imag__ conap[ic]); // } printf("begin convlv\n"); for( iy=0;iy<ny;iy++){ for(ix=0;ix<nx;ix++){ wld_z[i2(iy,ix,nx)]=conap[0]*tmpwld_z[i2(iy,ix,nx)]; for(icy=1,icx=0; icy<tny;icy++){ ic=icy*tnx+icx; if (iy+icy <ny) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix,nx)]); if (iy-icy >=0) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy-icy,ix,nx)]); } for(icy=0,icx=1;icx<tnx; icx++){ ic=icy*tnx+icx; if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*tmpwld_z[i2(iy,ix+icx,nx)]; if (ix-ic >= 0 )wld_z[i2(iy,ix,nx)]+=conam[ic]*tmpwld_z[i2(iy,ix-icx,nx)]; } for(icy=1;icy<tny; icy++){ if (iy+icy <ny && iy-icy >=0 ){ for(icx=1;icx<tnx; icx++){ ic=icy*tnx+icx; if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix+icx,nx)]+tmpwld_z[i2(iy-icy,ix+icx,nx)]); if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy+icy,ix-icx,nx)]+tmpwld_z[i2(iy-icy,ix-icx,nx)]); } } if (iy+icy<ny && iy-icy <0){ for(icx=1;icx<tnx; icx++){ ic=icy*tnx+icx; if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix+icx,nx)]); if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy+icy,ix-icx,nx)]); } } if (iy+icy >=ny && iy-icy >=0){ for(icx=1;icx<tnx; icx++){ ic=icy*tnx+icx; if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy-icy,ix+icx,nx)]); if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy-icy,ix-icx,nx)]); } } } }// for(ix) }// for(iy) free(conap); free(conam); }
ofdmoqamframe64sync ofdmoqamframe64sync_create(unsigned int _m, float _beta, ofdmoqamframe64sync_callback _callback, void * _userdata) { ofdmoqamframe64sync q = (ofdmoqamframe64sync) malloc(sizeof(struct ofdmoqamframe64sync_s)); q->num_subcarriers = 64; // validate input if (_m < 1) { fprintf(stderr,"error: ofdmoqamframe64sync_create(), filter delay must be > 0\n"); exit(1); } else if (_beta < 0.0f) { fprintf(stderr,"error: ofdmoqamframe64sync_create(), filter excess bandwidth must be > 0\n"); exit(1); } q->m = _m; q->beta = _beta; // synchronizer parameters q->rxx_thresh = 0.60f; // auto-correlation threshold q->rxy_thresh = 0.60f; // cross-correlation threshold q->zeta = 64.0f/sqrtf(52.0f); // scaling factor // create analysis filter banks q->ca0 = firpfbch_create(q->num_subcarriers, q->m, q->beta, 0.0f /*dt*/,FIRPFBCH_ROOTNYQUIST,0/*gradient*/); q->ca1 = firpfbch_create(q->num_subcarriers, q->m, q->beta, 0.0f /*dt*/,FIRPFBCH_ROOTNYQUIST,0/*gradient*/); q->X0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->X1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->Y0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->Y1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); // allocate memory for PLCP arrays q->S0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->S1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->S2 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); ofdmoqamframe64_init_S0(q->S0); ofdmoqamframe64_init_S1(q->S1); ofdmoqamframe64_init_S2(q->S2); unsigned int i; for (i=0; i<q->num_subcarriers; i++) { q->S0[i] *= q->zeta; q->S1[i] *= q->zeta; q->S2[i] *= q->zeta; } q->S1a = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->S1b = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); // set pilot sequence q->ms_pilot = msequence_create_default(8); q->x_phase[0] = -21.0f; q->x_phase[1] = -7.0f; q->x_phase[2] = 7.0f; q->x_phase[3] = 21.0f; // create NCO for pilots q->nco_pilot = nco_crcf_create(LIQUID_VCO); q->pll_pilot = pll_create(); pll_set_bandwidth(q->pll_pilot,0.01f); pll_set_damping_factor(q->pll_pilot,4.0f); // create agc | signal detection object q->sigdet = agc_crcf_create(); agc_crcf_set_bandwidth(q->sigdet,0.1f); // create NCO for CFO compensation q->nco_rx = nco_crcf_create(LIQUID_VCO); // create auto-correlator objects q->autocorr_length = OFDMOQAMFRAME64SYNC_AUTOCORR_LEN; q->autocorr_delay = q->num_subcarriers / 4; q->autocorr = autocorr_cccf_create(q->autocorr_length, q->autocorr_delay); // create cross-correlator object q->hxy = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); ofdmoqam cs = ofdmoqam_create(q->num_subcarriers,q->m,q->beta, 0.0f, // dt OFDMOQAM_SYNTHESIZER, 0); // gradient for (i=0; i<2*(q->m); i++) ofdmoqam_execute(cs,q->S1,q->hxy); // time reverse, complex conjugate (same as fftshift for // this particular sequence) memmove(q->X0, q->hxy, 64*sizeof(float complex)); for (i=0; i<64; i++) q->hxy[i] = conjf(q->X0[64-i-1]); // fftshift //fft_shift(q->hxy,64); q->crosscorr = firfilt_cccf_create(q->hxy, q->num_subcarriers); ofdmoqam_destroy(cs); // input buffer q->input_buffer = windowcf_create((q->num_subcarriers)); // gain q->g = 1.0f; q->G0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->G1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->G = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); q->data = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex)); // reset object ofdmoqamframe64sync_reset(q); #if DEBUG_OFDMOQAMFRAME64SYNC q->debug_x = windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_rxx= windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_rxy= windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_framesyms= windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_pilotphase= windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_pilotphase_hat= windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); q->debug_rssi= windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN); #endif q->callback = _callback; q->userdata = _userdata; return q; }
int main (void) { /* For each type, test both runtime and compile time (constant folding) optimization. */ volatile float _Complex fc = 1.0F + 2.0iF; volatile double _Complex dc = 1.0 + 2.0i; volatile long double _Complex ldc = 1.0L + 2.0iL; /* Test floats. */ if (conjf (fc) != 1.0F - 2.0iF) abort (); if (__builtin_conjf (fc) != 1.0F - 2.0iF) abort (); if (conjf (1.0F + 2.0iF) != 1.0F - 2.0iF) link_failure (); if (__builtin_conjf (1.0F + 2.0iF) != 1.0F - 2.0iF) link_failure (); if (crealf (fc) != 1.0F) abort (); if (__builtin_crealf (fc) != 1.0F) abort (); if (crealf (1.0F + 2.0iF) != 1.0F) link_failure (); if (__builtin_crealf (1.0F + 2.0iF) != 1.0F) link_failure (); if (cimagf (fc) != 2.0F) abort (); if (__builtin_cimagf (fc) != 2.0F) abort (); if (cimagf (1.0F + 2.0iF) != 2.0F) link_failure (); if (__builtin_cimagf (1.0F + 2.0iF) != 2.0F) link_failure (); /* Test doubles. */ if (conj (dc) != 1.0 - 2.0i) abort (); if (__builtin_conj (dc) != 1.0 - 2.0i) abort (); if (conj (1.0 + 2.0i) != 1.0 - 2.0i) link_failure (); if (__builtin_conj (1.0 + 2.0i) != 1.0 - 2.0i) link_failure (); if (creal (dc) != 1.0) abort (); if (__builtin_creal (dc) != 1.0) abort (); if (creal (1.0 + 2.0i) != 1.0) link_failure (); if (__builtin_creal (1.0 + 2.0i) != 1.0) link_failure (); if (cimag (dc) != 2.0) abort (); if (__builtin_cimag (dc) != 2.0) abort (); if (cimag (1.0 + 2.0i) != 2.0) link_failure (); if (__builtin_cimag (1.0 + 2.0i) != 2.0) link_failure (); /* Test long doubles. */ if (conjl (ldc) != 1.0L - 2.0iL) abort (); if (__builtin_conjl (ldc) != 1.0L - 2.0iL) abort (); if (conjl (1.0L + 2.0iL) != 1.0L - 2.0iL) link_failure (); if (__builtin_conjl (1.0L + 2.0iL) != 1.0L - 2.0iL) link_failure (); if (creall (ldc) != 1.0L) abort (); if (__builtin_creall (ldc) != 1.0L) abort (); if (creall (1.0L + 2.0iL) != 1.0L) link_failure (); if (__builtin_creall (1.0L + 2.0iL) != 1.0L) link_failure (); if (cimagl (ldc) != 2.0L) abort (); if (__builtin_cimagl (ldc) != 2.0L) abort (); if (cimagl (1.0L + 2.0iL) != 2.0L) link_failure (); if (__builtin_cimagl (1.0L + 2.0iL) != 2.0L) link_failure (); exit (0); }
int lrosback2(sf_complex **img, sf_complex ***wavfld, float **sill, sf_complex **rcd, bool adj, bool verb, bool wantwf, sf_complex **lt, sf_complex **rt, int m2, geopar geop, int pad1, bool illum) /*< low-rank one-step backward propagation + imaging >*/ { int it,iz,im,ik,ix,i,j; /* index variables */ int nxb,nzb,dx,dz,gpz,gpx,gpl,snpint,dt,wfit; int nt,nz,nx, nk, nzx, nz2, nx2, nzx2; sf_complex c; sf_complex *cwave, *cwavem, *currm; sf_complex **wave, *curr; sf_complex **ccr; nx = geop->nx; nz = geop->nz; nxb = geop->nxb; nzb = geop->nzb; dx = geop->dx; dz = geop->dz; gpz = geop->gpz; gpx = geop->gpx; gpl = geop->gpl; snpint = geop->snpint; nt = geop->nt; dt = geop->dt; ccr = sf_complexalloc2(nz, nx); nk = cfft2_init(pad1,nzb,nxb,&nz2,&nx2); nzx = nzb*nxb; nzx2 = nz2*nx2; curr = sf_complexalloc(nzx2); cwave = sf_complexalloc(nk); cwavem = sf_complexalloc(nk); wave = sf_complexalloc2(nzx2,m2); if (!adj) { currm = sf_complexalloc(nzx2); icfft2_allocate(cwave); } else { cwavem = sf_complexalloc(nk); icfft2_allocate(cwavem); } #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for (iz=0; iz < nzx2; iz++) { curr[iz] = sf_cmplx(0.,0.); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for (ix = 0; ix < nx; ix++) { for (iz = 0; iz < nz; iz++) { ccr[ix][iz] = sf_cmplx(0.,0.); } } if (adj) { /* migration */ /* step backward in time (PSPI) */ /*Main loop*/ wfit = (int)(nt-1)/snpint; for (it = nt-1; it>=0; it--) { if (verb) sf_warning("Backward receiver it=%d/%d;", it, nt-1); #ifdef _OPENMP #pragma omp parallel for private(ix,j) #endif for (ix=0; ix<gpl; ix++) { j = (gpz+geop->top)+(ix+gpx+geop->lft)*nz2; /* padded grid */ curr[j]+=rcd[ix][it]; /* data injection */ } /*matrix multiplication*/ cfft2(curr,cwave); for (im = 0; im < m2; 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,lt,wave) #endif for (ix = 0; ix < nxb; ix++) { for (iz=0; iz < nzb; iz++) { i = iz+ix*nzb; /* original grid */ j = iz+ix*nz2; /* padded grid */ c = sf_cmplx(0.,0.); // initialize 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; } } /*cross-correlation imaging condition*/ if (it%snpint == 0 ) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,j) #endif for (ix=0; ix<nx; ix++) { for (iz=0; iz<nz; iz++) { j = (iz+geop->top)+(ix+geop->lft)*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H ccr[ix][iz] += conjf(wavfld[wfit][ix][iz])*curr[j]; #else ccr[ix][iz] += sf_cmul(conjf(wavfld[wfit][ix][iz]),curr[j]); #endif } } wfit--; } } /*Main loop*/ if (verb) sf_warning("."); #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for (ix=0; ix<nx; ix++) { for (iz=0; iz<nz; iz++) { if (illum) { #ifdef SF_HAS_COMPLEX_H img[ix][iz] = ccr[ix][iz]/(sill[ix][iz]+SF_EPS); #else img[ix][iz] = sf_crmul(ccr[ix][iz],1./(sill[ix][iz]+SF_EPS)); #endif } else img[ix][iz] = ccr[ix][iz]; } } } else { /* modeling */ /* adjoint of source illumination */ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for (ix=0; ix<nx; ix++) { for (iz=0; iz<nz; iz++) { if (illum) { #ifdef SF_HAS_COMPLEX_H ccr[ix][iz] = img[ix][iz]/(sill[ix][iz]+SF_EPS); #else ccr[ix][iz] = sf_crmul(img[ix][iz],1./(sill[ix][iz]+SF_EPS)); #endif } else ccr[ix][iz] = img[ix][iz]; } } /* step forward in time (NSPS) */ /*Main loop*/ wfit=0; for (it=0; it<nt; it++) { if (verb) sf_warning("Forward receiver it=%d/%d;", it, nt-1); /*adjoint of cross-correlation imaging condition*/ if (it%snpint == 0 ) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,j) #endif for (ix=0; ix<nx; ix++) { for (iz=0; iz<nz; iz++) { j = (iz+geop->top)+(ix+geop->lft)*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H curr[j] += (wavfld[wfit][ix][iz])*ccr[ix][iz];//adjoint of ccr[ix][iz] += conjf(wavfld[wfit][ix][iz])*curr[j]; ??? #else curr[j] += sf_cmul((wavfld[wfit][ix][iz]),ccr[ix][iz]); #endif } } wfit++; } /*matrix multiplication*/ for (im = 0; im < m2; im++) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,i,j) shared(currm,lt,curr) #endif for (ix = 0; ix < nxb; ix++) { for (iz=0; iz < nzb; iz++) { i = iz+ix*nzb; /* original grid */ j = iz+ix*nz2; /* padded grid */ #ifdef SF_HAS_COMPLEX_H currm[j] = conjf(lt[im][i])*curr[j]; #else currm[j] = sf_cmul(conjf(lt[im][i]), curr[j]); #endif } } cfft2(currm,wave[im]); } #ifdef _OPENMP #pragma omp parallel for private(ik,im,c) shared(wave,rt,cwave) #endif 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]*conjf(rt[ik][im]); #else c += sf_cmul(wave[im][ik],conjf(rt[ik][im])); //complex multiplies complex #endif } cwave[ik] = c; } icfft2(curr,cwave); #ifdef _OPENMP #pragma omp parallel for private(ix,j) #endif for (ix=0; ix<gpl; ix++) { j = (gpz+geop->top)+(ix+gpx+geop->lft)*nz2; /* padded grid */ rcd[ix][it]=curr[j]; } } /*Main loop*/ } cfft2_finalize(); return 0; }
int main(int argc, char*argv[]) { srand(time(NULL)); // options unsigned int k=2; // filter samples/symbol unsigned int m=4; // filter delay (symbols) float beta=0.3f; // bandwidth-time product float dt = 0.0f; // fractional sample timing offset unsigned int num_sync_symbols = 64; // number of data symbols float SNRdB = 30.0f; // signal-to-noise ratio [dB] float dphi = 0.0f; // carrier frequency offset float phi = 0.0f; // carrier phase offset unsigned int num_delay_symbols = 12; unsigned int num_dphi_hat = 21; // number of frequency offset estimates float dphi_hat_step = 0.01f; // frequency offset step size int dopt; while ((dopt = getopt(argc,argv,"uhk:m:n:b:t:F:P:s:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'k': k = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'n': num_sync_symbols = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 't': dt = atof(optarg); break; case 'F': dphi = atof(optarg); break; case 'P': phi = atof(optarg); break; case 's': SNRdB = atof(optarg); break; default: exit(1); } } unsigned int i; // validate input if (beta <= 0.0f || beta >= 1.0f) { fprintf(stderr,"error: %s, bandwidth-time product must be in (0,1)\n", argv[0]); exit(1); } else if (dt < -0.5 || dt > 0.5) { fprintf(stderr,"error: %s, fractional sample offset must be in (0,1)\n", argv[0]); exit(1); } // derived values unsigned int num_symbols = num_delay_symbols + num_sync_symbols + 2*m; unsigned int num_samples = k*num_symbols; unsigned int num_sync_samples = k*num_sync_symbols; float nstd = powf(10.0f, -SNRdB/20.0f); // arrays float complex seq[num_sync_symbols]; // data sequence (symbols) float complex s0[num_sync_samples]; // data sequence (interpolated samples) float complex x[num_samples]; // transmitted signal float complex y[num_samples]; // received signal float rxy[num_dphi_hat][num_samples]; // pre-demod output matrix // generate sequence for (i=0; i<num_sync_symbols; i++) { float sym_i = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2; float sym_q = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2; seq[i] = sym_i + _Complex_I*sym_q; } // create interpolated sequence, compensating for filter delay firinterp_crcf interp_seq = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,0.0f); for (i=0; i<num_sync_symbols+m; i++) { if (i < m) firinterp_crcf_execute(interp_seq, seq[i], &s0[0]); else if (i < num_sync_symbols) firinterp_crcf_execute(interp_seq, seq[i], &s0[k*(i-m)]); else firinterp_crcf_execute(interp_seq, 0, &s0[k*(i-m)]); } firinterp_crcf_destroy(interp_seq); // compute g = E{ |s0|^2 } float g = 0.0f; for (i=0; i<num_sync_samples; i++) g += crealf( s0[i]*conjf(s0[i]) ); // create transmit interpolator and generate sequence firinterp_crcf interp_tx = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,dt); unsigned int n=0; for (i=0; i<num_delay_symbols; i++) { firinterp_crcf_execute(interp_tx, 0, &x[k*n]); n++; } for (i=0; i<num_sync_symbols; i++) { firinterp_crcf_execute(interp_tx, seq[i], &x[k*n]); n++; } for (i=0; i<2*m; i++) { firinterp_crcf_execute(interp_tx, 0, &x[k*n]); n++; } assert(n==num_symbols); firinterp_crcf_destroy(interp_tx); // add channel impairments for (i=0; i<num_samples; i++) { y[i] = x[i]*cexp(_Complex_I*(dphi*i + phi)) + nstd*( randnf() + _Complex_I*randnf() ); } float complex z; // filter output sample for (n=0; n<num_dphi_hat; n++) { float dphi_hat = ((float)n - 0.5*(float)(num_dphi_hat-1)) * dphi_hat_step; printf(" dphi_hat : %12.8f\n", dphi_hat); // create flipped, conjugated coefficients float complex s1[num_sync_samples]; for (i=0; i<num_sync_samples; i++) s1[i] = conjf( s0[num_sync_samples-i-1]*cexpf(_Complex_I*(dphi_hat*i)) ); // create matched filter and detect signal firfilt_cccf fsync = firfilt_cccf_create(s1, num_sync_samples); for (i=0; i<num_samples; i++) { firfilt_cccf_push(fsync, y[i]); firfilt_cccf_execute(fsync, &z); rxy[n][i] = cabsf(z) / g; } // destroy filter firfilt_cccf_destroy(fsync); } // print results //printf("rxy (max) : %12.8f\n", rxy_max); // // 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,"k = %u;\n", k); fprintf(fid,"m = %u;\n", m); fprintf(fid,"beta = %f;\n", beta); fprintf(fid,"num_sync_symbols = %u;\n", num_sync_symbols); fprintf(fid,"num_sync_samples = k*num_sync_symbols;\n"); fprintf(fid,"num_symbols = %u;\n", num_symbols); fprintf(fid,"num_samples = %u;\n", num_samples); fprintf(fid,"num_dphi_hat = %u;\n", num_dphi_hat); fprintf(fid,"dphi_hat_step = %f;\n", dphi_hat_step); // save sequence symbols fprintf(fid,"seq = zeros(1,num_sync_symbols);\n"); for (i=0; i<num_sync_symbols; i++) fprintf(fid,"seq(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(seq[i]), cimagf(seq[i])); // save interpolated sequence fprintf(fid,"s = zeros(1,num_sync_samples);\n"); for (i=0; i<num_sync_samples; i++) fprintf(fid,"s(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(s0[i]), cimagf(s0[i])); fprintf(fid,"x = zeros(1,num_samples);\n"); fprintf(fid,"y = zeros(1,num_samples);\n"); for (i=0; i<num_samples; i++) { fprintf(fid,"x(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"y(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i])); } // save cross-correlation output fprintf(fid,"rxy = zeros(num_dphi_hat,num_samples);\n"); for (n=0; n<num_dphi_hat; n++) { for (i=0; i<num_samples; i++) { fprintf(fid,"rxy(%6u,%6u) = %12.8f;\n", n+1, i+1, rxy[n][i]); } } fprintf(fid,"t=[0:(num_samples-1)]/k;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(1:length(s),real(s), 1:length(s),imag(s));\n"); fprintf(fid,"dphi_hat = ( [0:(num_dphi_hat-1)] - (num_dphi_hat-1)/2 ) * dphi_hat_step;\n"); fprintf(fid,"mesh(dphi_hat, t, rxy');\n"); #if 0 fprintf(fid,"z = abs( z );\n"); fprintf(fid,"[zmax i] = max(z);\n"); fprintf(fid,"plot(1:length(z),z,'-x');\n"); fprintf(fid,"axis([(i-8*k) (i+8*k) 0 zmax*1.2]);\n"); fprintf(fid,"grid on\n"); #endif fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); return 0; }
void cbanded_const_define (float diag /* diagonal */, const sf_complex *offd /* lower off-diagonal */) /*< set matrix coefficients (constant along diagonals) >*/ { int k, m, j; sf_complex ct; float rt; d[0] = diag; for (k = 0; k < band-1; k++) { for (m = k; m >= 0; m--) { ct = offd[m]; for (j = m+1; j < k-1; j++) { #ifdef SF_HAS_COMPLEX_H ct -= o[j][k-j]*conjf(o[j-m-1][k-j])*d[k-j]; #else ct = sf_csub(ct,sf_cmul(o[j][k-j], sf_crmul(conjf(o[j-m-1][k-j]), d[k-j]))); #endif } #ifdef SF_HAS_COMPLEX_H o[m][k-m] = ct/d[k-m]; #else o[m][k-m] = sf_crmul(ct,1./d[k-m]); #endif } rt = diag; for (m = 0; m <= k; m++) { #ifdef SF_HAS_COMPLEX_H rt -= crealf(o[m][k-m]*conjf(o[m][k-m]))*d[k-m]; #else rt -= crealf(sf_cmul(o[m][k-m],conjf(o[m][k-m])))*d[k-m]; #endif } d[k+1] = rt; } for (k = band-1; k < n-1; k++) { for (m = band-1; m >= 0; m--) { ct = offd[m]; for (j = m+1; j < band; j++) { #ifdef SF_HAS_COMPLEX_H ct -= o[j][k-j]*conjf(o[j-m-1][k-j])*d[k-j]; #else ct = sf_csub(ct,sf_cmul(o[j][k-j], sf_crmul(conjf(o[j-m-1][k-j]), d[k-j]))); #endif } #ifdef SF_HAS_COMPLEX_H o[m][k-m] = ct/d[k-m]; #else o[m][k-m] = sf_crmul(ct,1./d[k-m]); #endif } rt = diag; for (m = 0; m < band; m++) { #ifdef SF_HAS_COMPLEX_H rt -= crealf(o[m][k-m]*conjf(o[m][k-m]))*d[k-m]; #else rt -= crealf(sf_cmul(o[m][k-m],conjf(o[m][k-m])))*d[k-m]; #endif } d[k+1] = rt; } }
int main(int argc, char *argv[]) { int nw, n1, n2, n4, iw, i1, i2, i4, s1, x1, s2, x2, m, fold; int jumpo, jumps, newn1, newn2, tn; float d1, d2, newd1, newd2; bool verb, stack, both; sf_complex *dd, *ref=NULL, *mm=NULL, *mtemp=NULL; sf_file in, out, mul=NULL; sf_init(argc,argv); in = sf_input("in"); out = sf_output("out"); if (SF_COMPLEX != sf_gettype(in)) sf_error("Need complex input"); if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input"); if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input"); if (!sf_histint(in,"n3",&nw)) sf_error("No n3= in input"); if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input"); if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input"); if (d1!=d2) sf_error("Need d1==d2"); n4 = sf_leftsize(in,3); fold = 0; if (!sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if (!sf_getbool("stack",&stack)) stack=true; /* stack flag, if y, no common pseudoprimary gather */ if (!sf_getbool("both",&both)) both=false; /* receiver flag, if y, receiver with both sides */ if (!stack) { if (!sf_getint("jumpo",&jumpo)) jumpo=1; /* jump in offset dimension, only for stack=n */ if (!sf_getint("jumps",&jumps)) jumps=1; /* jump in shot dimension, only for stack=n */ } newn1 = n1; newn2 = n2; if (!stack) { if (!both) { sf_putint(out,"n1",(2*n1-1)); sf_putfloat(out,"d1",d1); sf_putfloat(out,"o1",(1-n1)*d1); } else { sf_putint(out,"n1",n1); sf_putfloat(out,"d1",d1); sf_putfloat(out,"o1",(-1*n1/2)*d1); } (void) sf_shiftdim(in, out, 1); if (n1%jumpo == 0) { newn1 = n1 / jumpo; } else { newn1 = n1 / jumpo +1; } if (n2%jumps == 0) { newn2 = n2 / jumps; } else { newn2 = n2 / jumps +1; } newd1 = (float) (d1 * jumpo); newd2 = (float) (d2 * jumps); sf_putint(out,"n2",newn1); sf_putfloat(out,"d2",newd1); sf_putint(out,"n3",newn2); sf_putfloat(out,"d3",newd2); } if (NULL != sf_getstring ("mul")) { mul = sf_input("mul"); ref = sf_complexalloc(n1*n2); } else { mul = NULL; } dd = sf_complexalloc(n1*n2); if (stack) { mm = sf_complexalloc(n1*n2); } else { if (!both) { mm = sf_complexalloc((2*n1-1)*n1*n2); mtemp = sf_complexalloc((2*n1-1)*newn1*newn2); } else { mm = sf_complexalloc(n1*n1*n2); mtemp = sf_complexalloc(n1*newn1*newn2); } } /* loop over n4 */ for (i4=0; i4 < n4; i4++) { if (verb) sf_warning("slice %d of %d",i4+1,n4); for (iw=0; iw < nw; iw++) { /* loop over frequency */ if (verb) sf_warning("frequency %d of %d;",iw+1,nw); sf_complexread(dd,n1*n2,in); if (NULL != mul) { sf_complexread(ref,n1*n2,mul); } if (!both) { for (i2=0; i2 < n2; i2++) { for (i1=0; i1 < n1; i1++) { mm[i2*n1+i1] = sf_cmplx(0.,0.); fold = 0; for (m=(-1*n1+1); m < n1; m++) { if (m < 0) { x1 = -1*m; s1 = i2 + m; x2 = i1 - m; s2 = m + i2; } else if ((i1-m) < 0) { x1 = m; s1 = i2; x2 = m - i1; s2 = i2 + i1; } else { x1 = m; s1 = i2; x2 = i1 - m; s2 = m + i2; } if (stack) { if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) { #ifdef SF_HAS_COMPLEX_H if(NULL != mul) { mm[i2*n1+i1] += conjf(dd[s1*n1+x1])*ref[s2*n1+x2]; } else { mm[i2*n1+i1] += conjf(dd[s1*n1+x1])*dd[s2*n1+x2]; } #else if(NULL != mul) { mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(sf_conjf(dd[s1*n1+x1]),ref[s2*n1+x2])); } else { mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(sf_conjf(dd[s1*n1+x1]),dd[s2*n1+x2])); } #endif } else { mm[i2*n1+i1] = sf_cmplx(0.,0.); } if (0.0 != cabsf(mm[i2*n1+i1])) fold++; } else { if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) { #ifdef SF_HAS_COMPLEX_H if(NULL != mul) { mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = dd[s1*n1+x1]*ref[s2*n1+x2]; } else { mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = dd[s1*n1+x1]*dd[s2*n1+x2]; } #else if(NULL != mul) { mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2]); } else { mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2]); } #endif } else { mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmplx(0.,0.); } } } if (stack) { #ifdef SF_HAS_COMPLEX_H mm[i2*n1+i1] = mm[i2*n1+i1]/(fold+SF_EPS); #else mm[i2*n1+i1] = sf_crmul(mm[i2*n1+i1],1.0/(fold+SF_EPS)); #endif } } } if (!stack) { tn = 0; for (i2=0; i2 < n2; i2++) { for (i1=0; i1 < n1; i1++) { if ((i2 % jumps == 0) && (i1 % jumpo == 0)) { for (m=(-1*n1+1); m < n1; m++) { mtemp[tn] = mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1]; tn ++; } } } } if (tn!=(2*n1-1)*newn1*newn2) sf_error("jump error!"); sf_complexwrite(mtemp,tn,out); } else { sf_complexwrite(mm,n1*n2,out); } } else { for (i2=0; i2 < n2; i2++) { for (i1=0; i1 < n1; i1++) { mm[i2*n1+i1] = sf_cmplx(0.,0.); fold = 0; for (m=0; m < n1; m++) { x1 = m; s1 = i2; x2 = i1 - m + n1/2; s2 = m + i2 - n1/2; if (stack) { if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) { #ifdef SF_HAS_COMPLEX_H if(NULL != mul) { mm[i2*n1+i1] += dd[s1*n1+x1]*ref[s2*n1+x2]; } else { mm[i2*n1+i1] += dd[s1*n1+x1]*dd[s2*n1+x2]; } #else if(NULL != mul) { mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2])); } else { mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2])); } #endif } else { mm[i2*n1+i1] = sf_cmplx(0.,0.); } if (0.0 != cabsf(mm[i2*n1+i1])) fold++; } else { if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) { #ifdef SF_HAS_COMPLEX_H if(NULL != mul) { mm[i2*n1*n1+i1*n1+m] = dd[s1*n1+x1]*ref[s2*n1+x2]; } else { mm[i2*n1*n1+i1*n1+m] = dd[s1*n1+x1]*dd[s2*n1+x2]; } #else if(NULL != mul) { mm[i2*n1*n1+i1*n1+m] = sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2]); } else { mm[i2*n1*n1+i1*n1+m] = sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2]); } #endif } else { mm[i2*n1*n1+i1*n1+m] = sf_cmplx(0.,0.); } } } if (stack) { #ifdef SF_HAS_COMPLEX_H mm[i2*n1+i1] = mm[i2*n1+i1]/(fold+SF_EPS); #else mm[i2*n1+i1] = sf_crmul(mm[i2*n1+i1],1.0/(fold+SF_EPS)); #endif } } } if (!stack) { tn = 0; for (i2=0; i2 < n2; i2++) { for (i1=0; i1 < n1; i1++) { if (i2 % jumps == 0 && i1 % jumpo == 0) { for (m=0; m < n1; m++) { mtemp[tn] = mm[i2*n1*n1+i1*n1+m]; tn ++; } } } } if (tn!=n1*newn1*newn2) sf_error("jump error!"); sf_complexwrite(mtemp,tn,out); } else { sf_complexwrite(mm,n1*n2,out); } } } if (verb) sf_warning("."); } exit(0); }
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, gpz, n, m, pad1, trunc, spx, spz; float dt, t0, z0, dz, x0, dx, s0, ds, wfdt, srctrunc; float dtau, tau0, tau; char *path1, *path2, number[5], *left, *right; double tstart, tend; struct timeval tim; sf_complex c, **lt, **rt; sf_complex *ww, **dd; 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; float *sendbuf, *recvbuf; 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_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("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="); /* input/output files */ Fdat=sf_input("in"); Fimg1=sf_output("out"); 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); 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", &rnx)) sf_error("Need n2= in input!"); if(!sf_histfloat(Fdat, "d2", &dx)) sf_error("Need d2= 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; /* print axies parameters for double check */ sf_warning("cpuid=%d, numprocs=%d", cpuid, numprocs); 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("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; trunc=srctrunc/dt+0.5; dd=sf_complexalloc2(nt, rnx); rr=sf_floatalloc(nzx); reflgen(nz, nx, spz, spx, rectz, rectx, 0, 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); #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 (is=cpuid; is<ns; is+=numprocs){ /* 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); /* read data */ sf_seek(Fdat, is*rnx*nt*sizeof(float complex), SEEK_SET); sf_complexread(dd[0], rnx*nt, Fdat); /* 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; 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(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<rnx; ix++){ curr[(ix+nb)*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(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.; } } /* calculate time shift gathers */ 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 ishot MPI_Barrier(comm); cfft2_finalize(); sf_fileclose(Fdat); free(ww); free(rr); free(*dd); free(dd); 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); }
int CORE_cttqrt(int M, int N, int IB, PLASMA_Complex32_t *A1, int LDA1, PLASMA_Complex32_t *A2, int LDA2, PLASMA_Complex32_t *T, int LDT, PLASMA_Complex32_t *TAU, PLASMA_Complex32_t *WORK) { static PLASMA_Complex32_t zone = 1.0; static PLASMA_Complex32_t zzero = 0.0; static int ione = 1; PLASMA_Complex32_t alpha; int i, j, ii, sb, mi, ni; /* Check input arguments */ if (M < 0) { coreblas_error(1, "Illegal value of M"); return -1; } if (N < 0) { coreblas_error(2, "Illegal value of N"); return -2; } if (IB < 0) { coreblas_error(3, "Illegal value of IB"); return -3; } if ((LDA2 < max(1,M)) && (M > 0)) { coreblas_error(7, "Illegal value of LDA2"); return -7; } /* Quick return */ if ((M == 0) || (N == 0) || (IB == 0)) return PLASMA_SUCCESS; for(ii = 0; ii < N; ii += IB) { sb = min(N-ii, IB); for(i = 0; i < sb; i++) { /* * Generate elementary reflector H( II*IB+I ) to annihilate * A( II*IB+I:mi, II*IB+I ). */ mi = ii + i + 1; LAPACKE_clarfg_work(mi+1, &A1[LDA1*(ii+i)+ii+i], &A2[LDA2*(ii+i)], ione, &TAU[ii+i]); if (sb-i-1>0) { /* * Apply H( II*IB+I ) to A( II*IB+I:M, II*IB+I+1:II*IB+IB ) from the left. */ ni = sb-i-1; cblas_ccopy( ni, &A1[LDA1*(ii+i+1)+(ii+i)], LDA1, WORK, 1); #ifdef COMPLEX LAPACKE_clacgv_work(ni, WORK, ione); #endif cblas_cgemv( CblasColMajor, (CBLAS_TRANSPOSE)PlasmaConjTrans, mi, ni, CBLAS_SADDR(zone), &A2[LDA2*(ii+i+1)], LDA2, &A2[LDA2*(ii+i)], 1, CBLAS_SADDR(zone), WORK, 1); #ifdef COMPLEX LAPACKE_clacgv_work(ni, WORK, ione); #endif alpha = -conjf(TAU[ii+i]); cblas_caxpy( ni, CBLAS_SADDR(alpha), WORK, 1, &A1[LDA1*(ii+i+1)+ii+i], LDA1); #ifdef COMPLEX LAPACKE_clacgv_work(ni, WORK, ione); #endif cblas_cgerc( CblasColMajor, mi, ni, CBLAS_SADDR(alpha), &A2[LDA2*(ii+i)], 1, WORK, 1, &A2[LDA2*(ii+i+1)], LDA2); } /* * Calculate T. */ if (i > 0 ) { cblas_ccopy(i, &A2[LDA2*(ii+i)+ii], 1, &WORK[ii], 1); cblas_ctrmv( CblasColMajor, (CBLAS_UPLO)PlasmaUpper, (CBLAS_TRANSPOSE)PlasmaConjTrans, (CBLAS_DIAG)PlasmaNonUnit, i, &A2[LDA2*ii+ii], LDA2, &WORK[ii], 1); alpha = -(TAU[ii+i]); for(j = 0; j < i; j++) { WORK[ii+j] = alpha * WORK[ii+j]; } if (ii > 0) { cblas_cgemv( CblasColMajor, (CBLAS_TRANSPOSE)PlasmaConjTrans, ii, i, CBLAS_SADDR(alpha), &A2[LDA2*ii], LDA2, &A2[LDA2*(ii+i)], 1, CBLAS_SADDR(zzero), WORK, 1); cblas_caxpy(i, CBLAS_SADDR(zone), &WORK[ii], 1, WORK, 1); } cblas_ccopy(i, WORK, 1, &T[LDT*(ii+i)], 1); cblas_ctrmv( CblasColMajor, (CBLAS_UPLO)PlasmaUpper, (CBLAS_TRANSPOSE)PlasmaNoTrans, (CBLAS_DIAG)PlasmaNonUnit, i, &T[LDT*ii], LDT, &T[LDT*(ii+i)], 1); } T[LDT*(ii+i)+i] = TAU[ii+i]; } /* Apply Q' to the rest of the matrix to the left */ if (N > ii+sb) { CORE_cttrfb( PlasmaLeft, PlasmaConjTrans, PlasmaForward, PlasmaColumnwise, sb, N-(ii+sb), ii+sb, N-(ii+sb), sb, &A1[LDA1*(ii+sb)+ii], LDA1, &A2[LDA2*(ii+sb)], LDA2, &A2[LDA2*ii], LDA2, &T[LDT*ii], LDT, WORK, sb); } } return PLASMA_SUCCESS; }
int main(int argc, char*argv[]) { // options unsigned int num_channels=16; // number of channels unsigned int m = 5; // filter semi-length (symbols) unsigned int num_symbols=25; // number of symbols float As = 80.0f; // filter stop-band attenuation int dopt; while ((dopt = getopt(argc,argv,"hM:m:s:n:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'M': num_channels = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 's': As = atof(optarg); break; case 'n': num_symbols = atof(optarg); break; default: exit(1); } } unsigned int i; // validate input if (num_channels < 2 || num_channels % 2) { fprintf(stderr,"error: %s, number of channels must be greater than 2 and even\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 (num_symbols == 0) { fprintf(stderr,"error: %s, number of symbols must be greater than zero", argv[0]); exit(1); } // derived values unsigned int num_samples = num_channels * num_symbols; // allocate arrays float complex x[num_samples]; float complex y[num_samples]; // generate input signal unsigned int w_len = (unsigned int)(0.4*num_samples); for (i=0; i<num_samples; i++) { //x[i] = (i==0) ? 1.0f : 0.0f; //x[i] = cexpf( (-0.05f + 0.07f*_Complex_I)*i ); // decaying complex exponential x[i] = cexpf( _Complex_I * (1.3f*i - 0.007f*i*i) ); x[i] *= i < w_len ? hamming(i,w_len) : 0.0f; //x[i] = (i==0) ? 1.0f : 0.0f; } // create filterbank objects from prototype firpfbch2_crcf qa = firpfbch2_crcf_create_kaiser(LIQUID_ANALYZER, num_channels, m, As); firpfbch2_crcf qs = firpfbch2_crcf_create_kaiser(LIQUID_SYNTHESIZER, num_channels, m, As); firpfbch2_crcf_print(qa); firpfbch2_crcf_print(qs); // run channelizer float complex Y[num_channels]; for (i=0; i<num_samples; i+=num_channels/2) { // run analysis filterbank firpfbch2_crcf_execute(qa, &x[i], Y); // run synthesis filterbank firpfbch2_crcf_execute(qs, Y, &y[i]); } // destroy fiterbank objects firpfbch2_crcf_destroy(qa); // analysis fitlerbank firpfbch2_crcf_destroy(qs); // synthesis filterbank // print output for (i=0; i<num_samples; i++) printf("%4u : %12.8f + %12.8fj\n", i, crealf(y[i]), cimagf(y[i])); // compute RMSE float rmse = 0.0f; unsigned int delay = 2*num_channels*m - num_channels/2 + 1; for (i=0; i<num_samples; i++) { float complex err = y[i] - (i < delay ? 0.0f : x[i-delay]); rmse += crealf( err*conjf(err) ); } rmse = sqrtf( rmse/(float)num_samples ); printf("rmse : %12.4e\n", rmse); // // EXPORT DATA TO FILES // FILE * fid = NULL; fid = fopen(OUTPUT_FILENAME_TIME,"w"); fprintf(fid,"# %s: auto-generated file\n", OUTPUT_FILENAME_TIME); fprintf(fid,"#\n"); fprintf(fid,"# %8s %12s %12s %12s %12s %12s %12s\n", "time", "real(x)", "imag(x)", "real(y)", "imag(y)", "real(e)", "imag(e)"); // save input and output arrays for (i=0; i<num_samples; i++) { float complex e = (i < delay) ? 0.0f : y[i] - x[i-delay]; fprintf(fid," %8.1f %12.4e %12.4e %12.4e %12.4e %12.4e %12.4e\n", (float)i, crealf(x[i]), cimagf(x[i]), crealf(y[i]), cimagf(y[i]), crealf(e), cimagf(e)); } fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME_TIME); // // export frequency data // unsigned int nfft = 2048; float complex y_time[nfft]; float complex y_freq[nfft]; for (i=0; i<nfft; i++) y_time[i] = i < num_samples ? y[i] : 0.0f; fft_run(nfft, y_time, y_freq, LIQUID_FFT_FORWARD, 0); // filter spectrum unsigned int h_len = 2*num_channels*m+1; float h[h_len]; float fc = 0.5f/(float)num_channels; liquid_firdes_kaiser(h_len, fc, As, 0.0f, h); float complex h_time[nfft]; float complex h_freq[nfft]; for (i=0; i<nfft; i++) h_time[i] = i < h_len ? 2*h[i]*fc : 0.0f; fft_run(nfft, h_time, h_freq, LIQUID_FFT_FORWARD, 0); // error spectrum float complex e_time[nfft]; float complex e_freq[nfft]; for (i=0; i<nfft; i++) e_time[i] = i < delay || i > num_samples ? 0.0f : y[i] - x[i-delay]; fft_run(nfft, e_time, e_freq, LIQUID_FFT_FORWARD, 0); fid = fopen(OUTPUT_FILENAME_FREQ,"w"); fprintf(fid,"# %s: auto-generated file\n", OUTPUT_FILENAME_FREQ); fprintf(fid,"#\n"); fprintf(fid,"# nfft = %u\n", nfft); fprintf(fid,"# %12s %12s %12s %12s\n", "freq", "PSD [dB]", "filter [dB]", "error [dB]"); // save input and output arrays for (i=0; i<nfft; i++) { float f = (float)i/(float)nfft - 0.5f; unsigned int k = (i + nfft/2)%nfft; fprintf(fid," %12.8f %12.8f %12.8f %12.8f\n", f, 20*log10f(cabsf(y_freq[k])), 20*log10f(cabsf(h_freq[k])), 20*log10f(cabsf(e_freq[k]))); } fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME_FREQ); printf("done.\n"); return 0; }
/* Decodes the phich channel and saves the CFI in the cfi pointer. * * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error */ int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) { /* Set pointers for layermapping & precoding */ int i, j; cf_t *x[SRSLTE_MAX_LAYERS]; cf_t *ce_precoding[SRSLTE_MAX_PORTS]; if (q == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } if (subframe >= SRSLTE_NSUBFRAMES_X_FRAME) { fprintf(stderr, "Invalid nslot %d\n", subframe); return SRSLTE_ERROR_INVALID_INPUTS; } if (SRSLTE_CP_ISEXT(q->cell.cp)) { if (nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) { fprintf(stderr, "Invalid nseq %d\n", nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } else { if (nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) { fprintf(stderr, "Invalid nseq %d\n", nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } if (ngroup >= srslte_regs_phich_ngroups(q->regs)) { fprintf(stderr, "Invalid ngroup %d\n", ngroup); return SRSLTE_ERROR_INVALID_INPUTS; } DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d\n", ngroup, nseq); /* number of layers equals number of ports */ for (i = 0; i < SRSLTE_MAX_PORTS; i++) { x[i] = q->x[i]; } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { ce_precoding[i] = q->ce[i]; } /* extract symbols */ if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, slot_symbols, q->symbols[0], ngroup)) { fprintf(stderr, "There was an error getting the phich symbols\n"); return SRSLTE_ERROR; } /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i], q->ce[i], ngroup)) { fprintf(stderr, "There was an error getting the phich symbols\n"); return SRSLTE_ERROR; } } /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ srslte_predecoding_single(q->symbols[0], q->ce[0], q->d0, SRSLTE_PHICH_MAX_NSYMB, noise_estimate); } else { srslte_predecoding_diversity(&q->precoding, q->symbols[0], ce_precoding, x, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, noise_estimate); srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); } DEBUG("Recv!!: \n", 0); DEBUG("d0: ", 0); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); if (SRSLTE_CP_ISEXT(q->cell.cp)) { if (ngroup % 2) { for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) { q->d[2 * i + 0] = q->d0[4 * i + 2]; q->d[2 * i + 1] = q->d0[4 * i + 3]; } } else { for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) { q->d[2 * i + 0] = q->d0[4 * i]; q->d[2 * i + 1] = q->d0[4 * i + 1]; } } } else { memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); } DEBUG("d: ", 0); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB); srslte_scrambling_c(&q->seq[subframe], q->d); /* De-spreading */ if (SRSLTE_CP_ISEXT(q->cell.cp)) { for (i = 0; i < SRSLTE_PHICH_NBITS; i++) { q->z[i] = 0; for (j = 0; j < SRSLTE_PHICH_EXT_NSF; j++) { q->z[i] += conjf(w_ext[nseq][j]) * q->d[i * SRSLTE_PHICH_EXT_NSF + j] / SRSLTE_PHICH_EXT_NSF; } } } else { for (i = 0; i < SRSLTE_PHICH_NBITS; i++) { q->z[i] = 0; for (j = 0; j < SRSLTE_PHICH_NORM_NSF; j++) { q->z[i] += conjf(w_normal[nseq][j]) * q->d[i * SRSLTE_PHICH_NORM_NSF + j] / SRSLTE_PHICH_NORM_NSF; } } } DEBUG("z: ", 0); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS); srslte_demod_soft_demodulate(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS); if (ack) { *ack = srslte_phich_ack_decode(q->data_rx, distance); } return SRSLTE_SUCCESS; }
int main(int argc, char* argv[]) { bool hermite_false, hermite_true; int n1, n2, npml, pad1, pad2, ns, nw, nh; float d1, d2, **v, ds, os, dw, ow; double omega; sf_complex ***f, ***srcw, ***recw, ***obs, ***obs_cut; sf_file in, out, source, receiver, record; int uts, mts; char *order; int is, i, j, iw, ih; float ***image, **recloc; sf_init(argc, argv); in = sf_input("in"); out = sf_output("out"); if (!sf_getint("nh",&nh)) nh=0; if (!sf_getint("uts",&uts)) uts=0; //#ifdef _OPENMP // mts = omp_get_max_threads(); //#else mts = 1; //#endif uts = (uts < 1)? mts: uts; hermite_false=false; hermite_true=true; /* Hermite operator */ if (!sf_getint("npml",&npml)) npml=20; /* PML width */ if (NULL == (order = sf_getstring("order"))) order="j"; /* discretization scheme (default optimal 9-point) */ fdprep_order(order); /* read input dimension */ if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input."); if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input."); if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input."); if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input."); v = sf_floatalloc2(n1,n2); sf_floatread(v[0],n1*n2,in); /* PML padding */ pad1 = n1+2*npml; pad2 = n2+2*npml; /* read receiver */ if (NULL == sf_getstring("receiver")) sf_error("Need receiver="); receiver = sf_input("receiver"); recloc=sf_floatalloc2(n1,n2); sf_floatread(recloc[0],n1*n2,receiver); /* read source */ if (NULL == sf_getstring("source")) sf_error("Need source="); source = sf_input("source"); if (!sf_histint(source,"n3",&ns)) sf_error("No ns=."); if (!sf_histfloat(source,"d3",&ds)) ds=d2; if (!sf_histfloat(source,"o3",&os)) os=0.; f = sf_complexalloc3(n1,n2,ns); /* read observed data */ if (NULL == sf_getstring("record")) sf_error("Need record="); record = sf_input("record"); if (!sf_histint(record,"n4",&nw)) sf_error("No nw=."); if (!sf_histfloat(record,"d4",&dw)) sf_error("No dw=."); if (!sf_histfloat(record,"o4",&ow)) sf_error("No ow=."); obs = sf_complexalloc3(n1,n2,ns); obs_cut = sf_complexalloc3(n1,n2,ns); srcw = sf_complexalloc3(n1,n2,ns); recw = sf_complexalloc3(n1,n2,ns); image = sf_floatalloc3(n1,n2,2*nh+1); /* Loop over frequency */ for (iw=0; iw<nw; iw++ ) { omega=(double) 2.*SF_PI*(ow+iw*dw); sf_warning("Calculating frequency %d out of %d for %f HZ.",iw+1,nw,ow+iw*dw); sf_complexread(f[0][0],n1*n2*ns,source); sf_complexread(obs[0][0],n1*n2*ns,record); /* generate adjoint source for reverse time migration */ genadjsrc_rtm(obs, obs_cut, recloc, n1, n2, ns); /* initialize sparse solver */ sparse_init(uts, pad1, pad2); /* factorize matrix, change according to different frequencies and models */ sparse_factor(omega,n1,n2,d1,d2,v,npml,pad1,pad2,uts); for (is=0; is < ns; is++ ) { for (j=0; j < n2; j++ ) { for (i=0; i < n1; i++ ) { srcw[is][j][i]=f[is][j][i]; recw[is][j][i]=obs_cut[is][j][i]; } } } /* sparse solver for source wavefield */ sparse_solve(npml, pad1, pad2, srcw, hermite_false, ns, uts); /* sparse solver for receiver wavefield */ sparse_solve(npml, pad1, pad2, recw, hermite_true, ns, uts); /* imaging condition */ for (ih=-nh; ih < nh+1; ih++ ) { for (j=0; j<n2; j++ ) { for (i=0; i< n1; i++ ) { for (is=0; is < ns; is++ ) { if (j-abs(ih) >= 0 && j+abs(ih) < n2) { image[ih+nh][j][i] += crealf(omega*omega*conjf(srcw[is][j-ih][i])*recw[is][j+ih][i]/(v[j][i]*v[j][i])); } } } } } /* free memory */ sparse_free(uts); } /* end frequency */ sf_putint(out,"n1",n1); sf_putint(out,"n2",n2); sf_putint(out,"n3",2*nh+1); sf_putfloat(out,"d3",d2); sf_putfloat(out,"o3", (float) -nh*d2); sf_floatwrite(image[0][0],n1*n2*(2*nh+1),out); exit(0); }
d = cpow(d, d); f = cpowf(f, f); ld = cpowl(ld, ld); TEST_TRACE(C99 7.3.8.3) d = csqrt(d); f = csqrtf(f); ld = csqrtl(ld); TEST_TRACE(C99 7.3.9.1) d = carg(d); f = cargf(f); ld = cargl(ld); TEST_TRACE(C99 7.3.9.2) d = cimag(d); f = cimagf(f); ld = cimagl(ld); TEST_TRACE(C99 7.3.9.3) d = conj(d); f = conjf(f); ld = conjl(ld); TEST_TRACE(C99 7.3.9.4) d = cproj(d); f = cprojf(f); ld = cprojl(ld); } TEST_TRACE(C99 7.3.9.5) double rd = creal(d); float rf = crealf(f); long double rld = creall(ld); END_GROUP
// compute ISI for entire system // _gt : transmit filter [size: _gt_len x 1] // _hc : channel filter [size: _hc_len x 1] // _gr : receive filter [size: _gr_len x 1] float eqlms_cccf_isi(unsigned int _k, float complex * _gt, unsigned int _gt_len, float complex * _hc, unsigned int _hc_len, float complex * _gr, unsigned int _gr_len) { // generate composite by convolving all filters together unsigned int i; #if 0 printf("\n"); for (i=0; i<_gt_len; i++) printf(" gt(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_gt[i]), cimagf(_gt[i])); printf("\n"); for (i=0; i<_hc_len; i++) printf(" hc(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_hc[i]), cimagf(_hc[i])); printf("\n"); for (i=0; i<_gr_len; i++) printf(" gr(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_gr[i]), cimagf(_gr[i])); printf("\n"); #endif windowcf w; float complex * rc; // start by convolving transmit and channel filters unsigned int gthc_len = _gt_len + _hc_len - 1; float complex gthc[gthc_len]; w = windowcf_create(_gt_len); for (i=0; i<gthc_len; i++) { if (i < _hc_len) windowcf_push(w, conjf(_hc[_hc_len-i-1])); else windowcf_push(w, 0.0f); windowcf_read(w, &rc); dotprod_cccf_run(_gt, rc, _gt_len, >hc[i]); } windowcf_destroy(w); #if 0 printf("composite filter:\n"); for (i=0; i<gthc_len; i++) printf(" gthc(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(gthc[i]), cimagf(gthc[i])); #endif // convolve result with equalizer unsigned int h_len = gthc_len + _gr_len - 1; float complex h[h_len]; w = windowcf_create(gthc_len); for (i=0; i<h_len; i++) { if (i < _gr_len) windowcf_push(w, conjf(_gr[i])); else windowcf_push(w, 0.0f); windowcf_read(w, &rc); dotprod_cccf_run(gthc, rc, gthc_len, &h[i]); } windowcf_destroy(w); #if 0 printf("composite filter:\n"); for (i=0; i<h_len; i++) printf(" h(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(h[i]), cimagf(h[i])); #endif // compute resulting ISI unsigned int n0 = (_gt_len + _gr_len + (_gt_len + _gr_len)%2)/2 - 1; float isi = 0.0f; unsigned int n=0; for (i=0; i<h_len; i++) { if (i == n0) continue; else if ( (i%_k)==0 ) { isi += crealf( h[i]*conjf(h[i]) ); n++; } } isi /= crealf( h[n0]*conjf(h[n0]) ); isi = sqrtf(isi / (float)n); return isi; }
int lrexp(sf_complex **img, sf_complex **dat, bool adj, sf_complex **lt, sf_complex **rt, sf_complex *ww, geopar geop, int pad1, bool verb, int snap, sf_complex ***wvfld) /*< zero-offset exploding reflector modeling/migration >*/ { int it, nt, ix, nx, nx2, iz, nz, nz2, nzx2, wfnt, wfit; int im, i, j, m2, ik, nk; float dt, dx, dz, ox; sf_complex *curr, **wave, *cwave, *cwavem, c; sf_complex *currm; nx = geop->nx; nz = geop->nz; dx = geop->dx; dz = geop->dz; ox = geop->ox; nt = geop->nt; dt = geop->dt; snap= geop->snap; nzx2= geop->nzx2; m2 = geop->m2; wfnt= geop->wfnt; nk = cfft2_init(pad1,nz,nx,&nz2,&nx2); if (nk!=geop->nk) sf_error("nk discrepancy!"); curr = sf_complexalloc(nzx2); cwave = sf_complexalloc(nk); wave = sf_complexalloc2(nzx2,m2); if (adj) { currm = sf_complexalloc(nzx2); icfft2_allocate(cwave); } else { cwavem = sf_complexalloc(nk); icfft2_allocate(cwavem); } #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for (iz=0; iz < nzx2; iz++) { curr[iz] = sf_cmplx(0.,0.); } if (adj) { /* migration <- read wavefield */ #ifdef _OPENMP #pragma omp parallel for private(ix,iz) #endif for (ix=0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { curr[iz+ix*nz2]=dat[ix][iz]; } } wfit = (int)(nt-1)/snap; // wfnt-1 /* time stepping */ for (it=nt-1; it > -1; it--) { if (verb) sf_warning("it=%d;",it); /* matrix multiplication */ for (im = 0; im < m2; im++) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,i,j) shared(currm,lt,curr) #endif 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] = conjf(lt[im][i])*curr[j]; #else currm[j] = sf_cmul(conjf(lt[im][i]), curr[j]); #endif } } cfft2(currm,wave[im]); } #ifdef _OPENMP #pragma omp parallel for private(ik,im,c) shared(wave,rt,cwave) #endif 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]*conjf(rt[ik][im]); #else c += sf_cmul(wave[im][ik],conjf(rt[ik][im])); //complex multiplies complex #endif } cwave[ik] = c; } icfft2(curr,cwave); if (snap > 0 && it%snap == 0) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,j) #endif for ( ix = 0; ix < nx; ix++) { for ( iz = 0; iz<nz; iz++ ) { j = iz+ix*nz2; /* padded grid */ wvfld[wfit][ix][iz] = curr[j]; } } wfit--; } } /*time iteration*/ /*generate image*/ #ifdef _OPENMP #pragma omp parallel for private(ix,iz) #endif for (ix=0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { img[ix][iz] = curr[iz+ix*nz2]; } } } else { /* modeling -> write data */ /*point source*/ wfit = 0; /* time stepping */ for (it=0; it < nt; it++) { if (verb) sf_warning("it=%d;",it); /* matrix multiplication */ cfft2(curr,cwave); for (im = 0; im < m2; 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,lt,wave) #endif 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] * crealf(img[ix][iz]); // source term #else c = sf_crmul(ww[it], crealf(img[ix][iz])); // source term #endif 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; } } /* record wavefield*/ #ifdef _OPENMP #pragma omp parallel for private(ix,iz) #endif for (ix=0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { dat[ix][iz] = curr[iz+ix*nz2]; } } if (snap > 0 && it%snap == 0) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz,j) #endif for ( ix = 0; ix < nx; ix++) { for ( iz = 0; iz<nz; iz++ ) { j = iz+ix*nz2; /* padded grid */ wvfld[wfit][ix][iz] = curr[j]; } } wfit++; } } } if (verb) sf_warning("."); cfft2_finalize(); return 0; }
int main(int argc, char*argv[]) { // options unsigned int num_symbols=500; // number of symbols to observe float SNRdB = 30.0f; // signal-to-noise ratio [dB] unsigned int hc_len=5; // channel filter length unsigned int k=2; // matched filter samples/symbol unsigned int m=3; // matched filter delay (symbols) float beta=0.3f; // matched filter excess bandwidth factor unsigned int p=3; // equalizer length (symbols, gr_len = 2*k*p+1) float mu = 0.09f; // LMS learning rate // modulation type/depth modulation_scheme ms = LIQUID_MODEM_QPSK; // plotting options unsigned int nfft = 512; // fft size float gnuplot_version = 4.2; char filename_base[256] = "figures.gen/eqlms_cccf_blind"; int dopt; while ((dopt = getopt(argc,argv,"hf:g:n:s:c:k:m:b:p:u:M:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'f': strncpy(filename_base,optarg,256); break; case 'g': gnuplot_version = atoi(optarg); break; case 'n': num_symbols = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'c': hc_len = atoi(optarg); break; case 'k': k = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 'p': p = atoi(optarg); break; case 'u': mu = 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); } } // validate input if (num_symbols == 0) { fprintf(stderr,"error: %s, number of symbols must be greater than zero\n", argv[0]); exit(1); } else if (hc_len == 0) { fprintf(stderr,"error: %s, channel must have at least 1 tap\n", argv[0]); exit(1); } else if (k < 2) { fprintf(stderr,"error: %s, samples/symbol must be at least 2\n", argv[0]); exit(1); } else if (m == 0) { fprintf(stderr,"error: %s, filter semi-length must be at least 1 symbol\n", argv[0]); exit(1); } else if (beta < 0.0f || beta > 1.0f) { fprintf(stderr,"error: %s, filter excess bandwidth must be in [0,1]\n", argv[0]); exit(1); } else if (p == 0) { fprintf(stderr,"error: %s, equalizer semi-length must be at least 1 symbol\n", argv[0]); exit(1); } else if (mu < 0.0f || mu > 1.0f) { fprintf(stderr,"error: %s, equalizer learning rate must be in [0,1]\n", argv[0]); exit(1); } // set 'random' seed on options srand( hc_len + p + nfft ); // derived values unsigned int gt_len = 2*k*m+1; // matched filter length unsigned int gr_len = 2*k*p+1; // equalizer filter length unsigned int num_samples = k*num_symbols; // bookkeeping variables float complex sym_tx[num_symbols]; // transmitted data sequence float complex x[num_samples]; // interpolated time series float complex y[num_samples]; // channel output float complex z[num_samples]; // equalized output // least mean-squares (LMS) equalizer float mse[num_symbols]; // equalizer mean-squared error float complex gr[gr_len]; // equalizer filter coefficients unsigned int i; // generate matched filter response float gtf[gt_len]; // matched filter response liquid_firdes_rnyquist(LIQUID_RNYQUIST_RRC, k, m, beta, 0.0f, gtf); // convert to complex coefficients float complex gt[gt_len]; for (i=0; i<gt_len; i++) gt[i] = gtf[i]; //+ 0.1f*(randnf() + _Complex_I*randnf()); // create interpolator interp_cccf interp = interp_cccf_create(k, gt, gt_len); // create the modem objects modem mod = modem_create(ms); modem demod = modem_create(ms); unsigned int bps = modem_get_bps(mod); unsigned int M = 1 << bps; // generate channel impulse response, filter #if 0 float complex hc[hc_len]; // channel filter coefficients hc[0] = 1.0f; for (i=1; i<hc_len; i++) hc[i] = 0.09f*(randnf() + randnf()*_Complex_I); #else // use fixed channel hc_len = 8; float complex hc[hc_len]; // channel filter coefficients hc[0] = 1.00000000+ 0.00000000*_Complex_I; hc[1] = 0.08077553+ -0.00247592*_Complex_I; hc[2] = 0.03625883+ -0.09219734*_Complex_I; hc[3] = 0.05764082+ 0.03277601*_Complex_I; hc[4] = -0.04773349+ -0.18766306*_Complex_I; hc[5] = -0.00101735+ -0.00270737*_Complex_I; hc[6] = -0.05796884+ -0.12665297*_Complex_I; hc[7] = 0.03805391+ -0.07609370*_Complex_I; #endif firfilt_cccf fchannel = firfilt_cccf_create(hc, hc_len); firfilt_cccf_print(fchannel); // generate random symbols for (i=0; i<num_symbols; i++) modem_modulate(mod, rand()%M, &sym_tx[i]); // interpolate for (i=0; i<num_symbols; i++) interp_cccf_execute(interp, sym_tx[i], &x[i*k]); // push through channel float nstd = powf(10.0f, -SNRdB/20.0f); for (i=0; i<num_samples; i++) { firfilt_cccf_push(fchannel, x[i]); firfilt_cccf_execute(fchannel, &y[i]); // add noise y[i] += nstd*(randnf() + randnf()*_Complex_I)*M_SQRT1_2; } // push through equalizers float grf[gr_len]; liquid_firdes_rnyquist(LIQUID_RNYQUIST_RRC, k, p, beta, 0.0f, grf); for (i=0; i<gr_len; i++) { gr[i] = grf[i] / (float)k; } // create LMS equalizer eqlms_cccf eq = eqlms_cccf_create(gr, gr_len); eqlms_cccf_set_bw(eq, mu); // filtered error vector magnitude (emperical MSE) //float zeta=0.05f; // smoothing factor (small zeta -> smooth MSE) float complex d_hat = 0.0f; unsigned int num_symbols_rx=0; for (i=0; i<num_samples; i++) { // push samples into equalizers eqlms_cccf_push(eq, y[i]); // compute outputs eqlms_cccf_execute(eq, &d_hat); // store outputs z[i] = d_hat; // check to see if buffer is full if ( i < gr_len) continue; // decimate by k if ( (i%k) != 0 ) continue; // estimate transmitted signal unsigned int sym_out; // output symbol float complex d_prime; // estimated input sample // LMS modem_demodulate(demod, d_hat, &sym_out); modem_get_demodulator_sample(demod, &d_prime); // update equalizers eqlms_cccf_step(eq, d_prime, d_hat); #if 0 // update filtered evm estimate float evm = crealf( (d_prime-d_hat)*conjf(d_prime-d_hat) ); if (num_symbols_rx == 0) { mse[num_symbols_rx] = evm; } else { mse[num_symbols_rx] = mse[num_symbols_rx-1]*(1-zeta) + evm*zeta; } #else // compute ISI for entire system eqlms_cccf_get_weights(eq, gr); mse[num_symbols_rx] = eqlms_cccf_isi(k, gt, gt_len, hc, hc_len, gr, gr_len); #endif // print filtered evm (emperical rms error) if ( ((num_symbols_rx+1)%100) == 0 ) printf("%4u : mse = %12.8f dB\n", num_symbols_rx+1, 20*log10f(mse[num_symbols_rx])); // increment output symbol counter num_symbols_rx++; } // get equalizer weights eqlms_cccf_get_weights(eq, gr); // destroy objects eqlms_cccf_destroy(eq); interp_cccf_destroy(interp); firfilt_cccf_destroy(fchannel); modem_destroy(mod); modem_destroy(demod); // // export output // FILE * fid = NULL; char filename[300]; // // const: constellation // strncpy(filename, filename_base, 256); strcat(filename, "_const.gnu"); fid = fopen(filename,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename); return 1; } fprintf(fid,"# %s: auto-generated file\n\n", filename); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set size ratio 1\n"); fprintf(fid,"set xrange [-1.5:1.5];\n"); fprintf(fid,"set yrange [-1.5:1.5];\n"); fprintf(fid,"set xlabel 'In-phase'\n"); fprintf(fid,"set ylabel 'Quadrature phase'\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' linewidth 1\n",LIQUID_DOC_COLOR_GRID); fprintf(fid,"plot '-' using 1:2 with points pointtype 7 pointsize 0.5 linecolor rgb '%s' title 'first 50%%',\\\n", LIQUID_DOC_COLOR_GRAY); fprintf(fid," '-' using 1:2 with points pointtype 7 pointsize 0.7 linecolor rgb '%s' title 'last 50%%'\n", LIQUID_DOC_COLOR_RED); // first half of symbols for (i=2*p; i<num_symbols/2; i+=k) fprintf(fid," %12.4e %12.4e\n", crealf(y[i]), cimagf(y[i])); fprintf(fid,"e\n"); // second half of symbols for ( ; i<num_symbols; i+=k) fprintf(fid," %12.4e %12.4e\n", crealf(z[i]), cimagf(z[i])); fprintf(fid,"e\n"); fclose(fid); printf("results written to '%s'\n", filename); // // mse : mean-squared error // strncpy(filename, filename_base, 256); strcat(filename, "_mse.gnu"); fid = fopen(filename,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename); return 1; } fprintf(fid,"# %s: auto-generated file\n\n", filename); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set size ratio 0.3\n"); fprintf(fid,"set xrange [0:%u];\n", num_symbols); fprintf(fid,"set yrange [1e-3:1e-1];\n"); fprintf(fid,"set format y '10^{%%L}'\n"); fprintf(fid,"set log y\n"); fprintf(fid,"set xlabel 'symbol index'\n"); fprintf(fid,"set ylabel 'mean-squared error'\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' linewidth 1\n",LIQUID_DOC_COLOR_GRID); fprintf(fid,"plot '-' using 1:2 with lines linewidth 4 linetype 1 linecolor rgb '%s' title 'LMS MSE'\n", LIQUID_DOC_COLOR_RED); // LMS for (i=0; i<num_symbols_rx; i++) fprintf(fid," %4u %16.8e\n", i, mse[i]); fprintf(fid,"e\n"); fclose(fid); printf("results written to '%s'\n", filename); // // psd : power spectral density // // scale transmit filter appropriately for (i=0; i<gt_len; i++) gt[i] /= (float)k; float complex Gt[nfft]; // transmit matched filter float complex Hc[nfft]; // channel response float complex Gr[nfft]; // equalizer response liquid_doc_compute_psdcf(gt, gt_len, Gt, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0); liquid_doc_compute_psdcf(hc, hc_len, Hc, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0); liquid_doc_compute_psdcf(gr, gr_len, Gr, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0); fft_shift(Gt, nfft); fft_shift(Hc, nfft); fft_shift(Gr, nfft); float freq[nfft]; for (i=0; i<nfft; i++) freq[i] = (float)(i) / (float)nfft - 0.5f; strncpy(filename, filename_base, 256); strcat(filename, "_freq.gnu"); fid = fopen(filename,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename); return 1; } fprintf(fid,"# %s: auto-generated file\n\n", filename); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set size ratio 0.6\n"); fprintf(fid,"set xrange [-0.5:0.5];\n"); fprintf(fid,"set yrange [-10:6]\n"); fprintf(fid,"set xlabel 'Normalized Frequency'\n"); fprintf(fid,"set ylabel 'Power Spectral Density [dB]'\n"); fprintf(fid,"set key top right nobox\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,"plot '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'transmit',\\\n", LIQUID_DOC_COLOR_GRAY); fprintf(fid," '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'channel',\\\n", LIQUID_DOC_COLOR_RED); fprintf(fid," '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'equalizer',\\\n", LIQUID_DOC_COLOR_GREEN); fprintf(fid," '-' using 1:2 with lines linetype 1 linewidth 4.0 linecolor rgb '%s' title 'composite',\\\n", LIQUID_DOC_COLOR_BLUE); fprintf(fid," '-' using 1:2 with points pointtype 7 pointsize 0.6 linecolor rgb '%s' notitle\n", LIQUID_DOC_COLOR_BLUE); // received signal for (i=0; i<nfft; i++) fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Gt[i])) ); fprintf(fid,"e\n"); // channel for (i=0; i<nfft; i++) fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Hc[i])) ); fprintf(fid,"e\n"); // equalizer for (i=0; i<nfft; i++) fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Gr[i])) ); fprintf(fid,"e\n"); // composite for (i=0; i<nfft; i++) fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f( cabsf(Gt[i])*cabsf(Hc[i])*cabsf(Gr[i])) ); fprintf(fid,"e\n"); // composite fprintf(fid,"%12.8f %12.4e\n", -0.5f/(float)k, 20*log10f(0.5f)); fprintf(fid,"%12.8f %12.4e\n", 0.5f/(float)k, 20*log10f(0.5f)); fprintf(fid,"e\n"); fclose(fid); printf("results written to '%s'\n", filename); // // time... // strncpy(filename, filename_base, 256); strcat(filename, "_time.gnu"); fid = fopen(filename,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename); return 1; } fprintf(fid,"# %s: auto-generated file\n\n", filename); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set xrange [0:%u];\n",num_symbols); fprintf(fid,"set yrange [-1.5:1.5]\n"); fprintf(fid,"set size ratio 0.3\n"); fprintf(fid,"set xlabel 'Symbol Index'\n"); fprintf(fid,"set key top right nobox\n"); //fprintf(fid,"set ytics -5,1,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"); // real fprintf(fid,"# real\n"); fprintf(fid,"set ylabel 'Real'\n"); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '#999999' notitle,\\\n"); fprintf(fid," '-' using 1:2 with points pointtype 7 linecolor rgb '%s' notitle'\n", LIQUID_DOC_COLOR_BLUE); // for (i=0; i<num_samples; i++) fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, crealf(z[i])); fprintf(fid,"e\n"); // for (i=0; i<num_samples; i+=k) fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, crealf(z[i])); fprintf(fid,"e\n"); // imag fprintf(fid,"# imag\n"); fprintf(fid,"set ylabel 'Imag'\n"); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '#999999' notitle,\\\n"); fprintf(fid," '-' using 1:2 with points pointtype 7 linecolor rgb '%s' notitle'\n", LIQUID_DOC_COLOR_GREEN); // for (i=0; i<num_samples; i++) fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, cimagf(z[i])); fprintf(fid,"e\n"); // for (i=0; i<num_samples; i+=k) fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, cimagf(z[i])); fprintf(fid,"e\n"); fprintf(fid,"unset multiplot\n"); // close output file fclose(fid); printf("results written to '%s'\n", filename); return 0; }
void docomplexf (void) { #ifndef NO_FLOAT complex float ca, cb, cc; float f1; ca = 1.0 + 1.0 * I; cb = 1.0 - 1.0 * I; f1 = cabsf (ca); fprintf (stdout, "cabsf : %f\n", f1); cc = cacosf (ca); fprintf (stdout, "cacosf : %f %fi\n", crealf (cc), cimagf (cc)); cc = cacoshf (ca); fprintf (stdout, "cacoshf: %f %fi\n", crealf (cc), cimagf (cc)); f1 = cargf (ca); fprintf (stdout, "cargf : %f\n", f1); cc = casinf (ca); fprintf (stdout, "casinf : %f %fi\n", crealf (cc), cimagf (cc)); cc = casinhf (ca); fprintf (stdout, "casinhf: %f %fi\n", crealf (cc), cimagf (cc)); cc = catanf (ca); fprintf (stdout, "catanf : %f %fi\n", crealf (cc), cimagf (cc)); cc = catanhf (ca); fprintf (stdout, "catanhf: %f %fi\n", crealf (cc), cimagf (cc)); cc = ccosf (ca); fprintf (stdout, "ccosf : %f %fi\n", crealf (cc), cimagf (cc)); cc = ccoshf (ca); fprintf (stdout, "ccoshf : %f %fi\n", crealf (cc), cimagf (cc)); cc = cexpf (ca); fprintf (stdout, "cexpf : %f %fi\n", crealf (cc), cimagf (cc)); f1 = cimagf (ca); fprintf (stdout, "cimagf : %f\n", f1); cc = clogf (ca); fprintf (stdout, "clogf : %f %fi\n", crealf (cc), cimagf (cc)); cc = conjf (ca); fprintf (stdout, "conjf : %f %fi\n", crealf (cc), cimagf (cc)); cc = cpowf (ca, cb); fprintf (stdout, "cpowf : %f %fi\n", crealf (cc), cimagf (cc)); cc = cprojf (ca); fprintf (stdout, "cprojf : %f %fi\n", crealf (cc), cimagf (cc)); f1 = crealf (ca); fprintf (stdout, "crealf : %f\n", f1); cc = csinf (ca); fprintf (stdout, "csinf : %f %fi\n", crealf (cc), cimagf (cc)); cc = csinhf (ca); fprintf (stdout, "csinhf : %f %fi\n", crealf (cc), cimagf (cc)); cc = csqrtf (ca); fprintf (stdout, "csqrtf : %f %fi\n", crealf (cc), cimagf (cc)); cc = ctanf (ca); fprintf (stdout, "ctanf : %f %fi\n", crealf (cc), cimagf (cc)); cc = ctanhf (ca); fprintf (stdout, "ctanhf : %f %fi\n", crealf (cc), cimagf (cc)); #endif }
int CORE_ctsmqr_corner( int m1, int n1, int m2, int n2, int m3, int n3, int k, int ib, int nb, PLASMA_Complex32_t *A1, int lda1, PLASMA_Complex32_t *A2, int lda2, PLASMA_Complex32_t *A3, int lda3, PLASMA_Complex32_t *V, int ldv, PLASMA_Complex32_t *T, int ldt, PLASMA_Complex32_t *WORK, int ldwork) { int i, j; PLASMA_enum side, trans; if ( m1 != n1 ) { coreblas_error(1, "Illegal value of M1, N1"); return -1; } /* Rebuild the symmetric block: WORK <- A1 */ for (j = 0; j < n1; j++) for (i = j; i < m1; i++){ *(WORK + i + j*ldwork) = *(A1 + i + j*lda1); if (i > j){ *(WORK + j + i*ldwork) = conjf( *(WORK + i + j*ldwork) ); } } /* Copy the transpose of A2: WORK+nb*ldwork <- A2' */ for (j = 0; j < n2; j++) for (i = 0; i < m2; i++){ *(WORK + j + (i + nb) * ldwork) = conjf( *(A2 + i + j*lda2) ); } side = PlasmaLeft; trans = PlasmaConjTrans; /* Left application on |A1| */ /* |A2| */ CORE_ctsmqr(side, trans, m1, n1, m2, n2, k, ib, WORK, ldwork, A2, lda2, V, ldv, T, ldt, WORK + 3*nb*ldwork, ldwork); /* Rebuild the symmetric block: WORK+2*nb*ldwork <- A3 */ for (j = 0; j < n3; j++) for (i = j; i < m3; i++){ *(WORK + i + (j + 2*nb) * ldwork) = *(A3 + i + j*lda3); if (i != j){ *(WORK + j + (i + 2*nb) * ldwork) = conjf( *(WORK + i + (j + 2*nb) * ldwork) ); } } /* Left application on | A2'| */ /* | A3 | */ CORE_ctsmqr(side, trans, n2, m2, m3, n3, k, ib, WORK+nb*ldwork, ldwork, WORK+2*nb*ldwork, ldwork, V, ldv, T, ldt, WORK + 3*nb*ldwork, ldwork); side = PlasmaRight; trans = PlasmaNoTrans; /* Right application on | A1 A2' | */ CORE_ctsmqr(side, trans, m1, n1, n2, m2, k, ib, WORK, ldwork, WORK+nb*ldwork, ldwork, V, ldv, T, ldt, WORK + 3*nb*ldwork, ldwork); /* Copy back the final result to the lower part of A1 */ /* A1 = WORK */ for (j = 0; j < n1; j++) for (i = j; i < m1; i++) *(A1 + i + j*lda1) = *(WORK + i + j*ldwork); /* Right application on | A2 A3 | */ CORE_ctsmqr(side, trans, m2, n2, m3, n3, k, ib, A2, lda2, WORK+2*nb*ldwork, ldwork, V, ldv, T, ldt, WORK + 3*nb*ldwork, ldwork); /* Copy back the final result to the lower part of A3 */ /* A3 = WORK+2*nb*ldwork */ for (j = 0; j < n3; j++) for (i = j; i < m3; i++) *(A3 + i + j*lda3) = *(WORK + i + (j+ 2*nb) * ldwork); return PLASMA_SUCCESS; }
int CORE_chbelr(int uplo, int N, PLASMA_desc *A, PLASMA_Complex32_t *V, PLASMA_Complex32_t *TAU, int st, int ed, int eltsize) { int NB, J1, J2; int len1, len2, t1ed, t2st; int i; static PLASMA_Complex32_t zzero = 0.0; PLASMA_desc vA=*A; /* Check input arguments */ if (N < 0) { coreblas_error(2, "Illegal value of N"); return -2; } if (ed <= st) { coreblas_error(23, "Illegal value of st and ed (internal)"); return -23; } /* Quick return */ if (N == 0) return PLASMA_SUCCESS; NB = A->mb; if( uplo == PlasmaLower ) { /* ======================== * LOWER CASE * ========================*/ for (i = ed; i >= st+1 ; i--){ /* generate Householder to annihilate a(i+k-1,i) within the band */ *V(i) = *A(i, (st-1)); *A(i, (st-1)) = zzero; LAPACKE_clarfg_work( 2, A((i-1),(st-1)), V(i), 1, TAU(i)); /* apply reflector from the left (horizontal row) and from the right for only the diagonal 2x2.*/ J1 = st; J2 = i-2; t1ed = (J2/NB)*NB; t2st = max(t1ed+1,J1); len1 = t1ed-J1+1; /* can be negative */ len2 = J2-t2st+1; if(len1>0)CORE_clarfx2(PlasmaLeft, len1 , *V(i), conjf(*TAU(i)), A(i-1, J1 ), ELTLDD(vA, i-1), A(i, J1 ), ELTLDD(vA, i) ); if(len2>0)CORE_clarfx2(PlasmaLeft, len2 , *V(i), conjf(*TAU(i)), A(i-1, t2st), ELTLDD(vA, i-1), A(i, t2st), ELTLDD(vA, i) ); CORE_clarfx2c(PlasmaLower, *V(i), *TAU(i), A(i-1, i-1), A(i, i-1), A(i, i)); } /* APPLY RIGHT ON THE REMAINING ELEMENT OF KERNEL 1 */ for (i = ed; i >= st+1 ; i--){ J1 = i+1; J2 = min(ed,N); t1ed = (J2/NB)*NB; t2st = max(t1ed+1,J1); len1 = t1ed-J1+1; /* can be negative */ len2 = J2-t2st+1; if(len1>0)CORE_clarfx2(PlasmaRight, len1, *V(i), *TAU(i), A(J1, i-1), ELTLDD(vA, J1) , A(J1 , i), ELTLDD(vA, J1) ); if(len2>0)CORE_clarfx2(PlasmaRight, len2, *V(i), *TAU(i), A(t2st,i-1), ELTLDD(vA, t2st), A(t2st, i), ELTLDD(vA, t2st) ); } }else{ /* ======================== * UPPER CASE * ========================*/ for (i = ed; i >= st+1 ; i--){ /* generate Householder to annihilate a(i+k-1,i) within the band*/ *V(i) = *A((st-1), i); *A((st-1), i) = zzero; LAPACKE_clarfg_work( 2, A(st-1, i-1), V(i), 1, TAU(i)); /* apply reflector from the left (horizontal row) and from the right for only the diagonal 2x2.*/ J1 = st; J2 = i-2; t1ed = (J2/NB)*NB; t2st = max(t1ed+1,J1); len1 = t1ed-J1+1; /* can be negative */ len2 = J2-t2st+1; if(len1>0)CORE_clarfx2(PlasmaRight, len1, conjf(*V(i)), conjf(*TAU(i)), A(J1, i-1), ELTLDD(vA, J1) , A(J1 , i), ELTLDD(vA, J1) ); if(len2>0)CORE_clarfx2(PlasmaRight, len2, conjf(*V(i)), conjf(*TAU(i)), A(t2st,i-1), ELTLDD(vA, t2st), A(t2st, i), ELTLDD(vA, t2st) ); CORE_clarfx2c(PlasmaUpper, *V(i), *TAU(i), A(i-1, i-1), A(i-1, i), A(i,i)); } /* APPLY LEFT ON THE REMAINING ELEMENT OF KERNEL 1 */ for (i = ed; i >= st+1 ; i--){ J1 = i+1; J2 = min(ed,N); t1ed = (J2/NB)*NB; t2st = max(t1ed+1,J1); len1 = t1ed-J1+1; /* can be negative */ len2 = J2-t2st+1; if(len1>0)CORE_clarfx2(PlasmaLeft, len1 , conjf(*V(i)), *TAU(i), A(i-1, J1 ), ELTLDD(vA, i-1), A(i, J1 ), ELTLDD(vA, i) ); if(len2>0)CORE_clarfx2(PlasmaLeft, len2 , conjf(*V(i)), *TAU(i), A(i-1, t2st), ELTLDD(vA, i-1), A(i, t2st), ELTLDD(vA, i) ); } } /* end of else for the upper case */ return PLASMA_SUCCESS; }
int main() { // parameters float phase_offset = 0.8f; // carrier phase offset float frequency_offset = 0.01f; // carrier frequency offset float wn = 0.05f; // pll bandwidth float zeta = 0.707f; // pll damping factor float K = 1000; // pll loop gain unsigned int n = 256; // number of samples unsigned int d = n/32; // print every "d" lines // float theta[n]; // input phase float complex x[n]; // input sinusoid float phi[n]; // output phase float complex y[n]; // output sinusoid // generate iir loop filter object iirfilt_rrrf H = iirfilt_rrrf_create_pll(wn, zeta, K); iirfilt_rrrf_print(H); unsigned int i; // generate input float t=phase_offset; float dt = frequency_offset; for (i=0; i<n; i++) { theta[i] = t; x[i] = cexpf(_Complex_I*theta[i]); t += dt; } // run loop float phi_hat=0.0f; for (i=0; i<n; i++) { y[i] = cexpf(_Complex_I*phi_hat); // compute error float e = cargf(x[i]*conjf(y[i])); if ( (i%d)==0 ) printf("e(%3u) = %12.8f;\n", i, e); // filter error iirfilt_rrrf_execute(H,e,&phi_hat); phi[i] = phi_hat; } // destroy filter iirfilt_rrrf_destroy(H); // open output file FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"clear all;\n"); fprintf(fid,"n=%u;\n",n); for (i=0; i<n; i++) { fprintf(fid,"theta(%3u) = %16.8e;\n", i+1, theta[i]); fprintf(fid," phi(%3u) = %16.8e;\n", i+1, phi[i]); } fprintf(fid,"t=0:(n-1);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(t,theta,t,phi);\n"); fprintf(fid,"xlabel('sample index');\n"); fprintf(fid,"ylabel('phase');\n"); fclose(fid); printf("output written to %s.\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
/***************************************************************************//** * @ingroup CORE_PLASMA_Complex32_t ******************************************************************************* * * Purpose * ======= * * CORE_clarfx2c applies a complex elementary reflector H to a diagonal corner * C=[C1, C2, C3], from both the left and the right side. C = H * C * H. * It is used in the case of Hermetian. * If PlasmaLower, a left apply is followed by a right apply. * If PlasmaUpper, a right apply is followed by a left apply. * H is represented in the form * * This routine is a special code for a corner C diagonal block C1 * C2 C3 * * * H = I - tau * v * v' * * where tau is a complex scalar and v is a complex vector. * * If tau = 0, then H is taken to be the unit matrix * * This version uses inline code if H has order < 11. * * Arguments * ========= * * @param[in] uplo * = PlasmaUpper: Upper triangle of A is stored; * = PlasmaLower: Lower triangle of A is stored. * * @param[in] V * The float complex V in the representation of H. * * @param[in] TAU * The value tau in the representation of H. * * @param[in,out] C1 * On entry, the element C1. * On exit, C1 is overwritten by the result H * C * H. * * @param[in,out] C2 * On entry, the element C2. * On exit, C2 is overwritten by the result H * C * H. * * @param[in,out] C3 * On entry, the element C3. * On exit, C3 is overwritten by the result H * C * H. * * ===================================================================== * * @return * \retval PLASMA_SUCCESS successful exit * \retval <0 if -i, the i-th argument had an illegal value * ******************************************************************************/ int CORE_clarfx2c(PLASMA_enum uplo, PLASMA_Complex32_t V, PLASMA_Complex32_t TAU, PLASMA_Complex32_t *C1, PLASMA_Complex32_t *C2, PLASMA_Complex32_t *C3) { PLASMA_Complex32_t T2, SUM, TEMP; /* Quick return */ if (TAU == (PLASMA_Complex32_t)0.0) return PLASMA_SUCCESS; /* * Special code for a diagonal block C1 * C2 C3 */ if(uplo==PlasmaLower) { /* * Do the corner Left then Right (used for the lower case * tridiag) L and R for the 2x2 corner * C(N-1, N-1) C(N-1,N) C1 TEMP * C(N , N-1) C(N ,N) C2 C3 * For Left : use conjf(TAU) and V. * For Right: nothing, keep TAU and V. * Left 1 ==> C1 * C2 */ TEMP = conjf(*C2); /* copy C2 here before modifying it. */ T2 = conjf(TAU) * V; SUM = *C1 + conjf(V) * (*C2); *C1 = *C1 - SUM * conjf(TAU); *C2 = *C2 - SUM * T2; /* Left 2 ==> TEMP */ /* C3 */ SUM = TEMP + conjf(V) * (*C3); TEMP = TEMP - SUM * conjf(TAU); *C3 = *C3 - SUM * T2; /* Right 1 ==> C1 TEMP. NB: no need to compute corner (2,2)=TEMP */ T2 = TAU * conjf(V); SUM = *C1 + V*TEMP; *C1 = *C1 - SUM*TAU; /* Right 2 ==> C2 C3 */ SUM = *C2 + V*(*C3); *C2 = *C2 - SUM*TAU; *C3 = *C3 - SUM*T2; } else { /* * Do the corner Right then Left (used for the upper case tridiag) * C(N-1, N-1) C(N-1,N) C1 C2 * C(N , N-1) C(N ,N) TEMP C3 * For Left : use TAU and conjf(V). * For Right: use conjf(TAU) and conjf(V). * Right 1 ==> C1 C2 */ V = conjf(V); TEMP = conjf(*C2); /* copy C2 here before modifying it. */ T2 = conjf(TAU) * conjf(V); SUM = *C1 + V * (*C2); *C1 = *C1 - SUM * conjf(TAU); *C2 = *C2 - SUM * T2; /* Right 2 ==> TEMP C3 */ SUM = TEMP + V * (*C3); TEMP = TEMP - SUM * conjf(TAU); *C3 = *C3 - SUM * T2; /* Left 1 ==> C1 */ /* TEMP. NB: no need to compute corner (2,1)=TEMP */ T2 = TAU * V; SUM = *C1 + conjf(V) * TEMP; *C1 = *C1 - SUM * TAU; /* Left 2 ==> C2 */ /* C3 */ SUM = *C2 + conjf(V) * (*C3); *C2 = *C2 - SUM * TAU; *C3 = *C3 - SUM * T2; } return PLASMA_SUCCESS; }
TEST(complex, conjf) { ASSERT_EQ(0.0f, conjf(0)); }
// Q/R decomposition using the Gram-Schmidt algorithm void MATRIX(_qrdecomp_gramschmidt)(T * _x, unsigned int _rx, unsigned int _cx, T * _Q, T * _R) { // validate input if (_rx != _cx) { fprintf(stderr,"error: matrix_qrdecomp_gramschmidt(), input matrix not square\n"); exit(-1); } unsigned int n = _rx; unsigned int i; unsigned int j; unsigned int k; // generate and initialize matrices T e[n*n]; // normalized... for (i=0; i<n*n; i++) e[i] = 0.0f; for (k=0; k<n; k++) { // e(i,k) <- _x(i,k) for (i=0; i<n; i++) matrix_access(e,n,n,i,k) = matrix_access(_x,n,n,i,k); // subtract... for (i=0; i<k; i++) { // compute dot product _x(:,k) * e(:,i) T g = 0; for (j=0; j<n; j++) { T prod = matrix_access(_x,n,n,j,k) * conj( matrix_access(e,n,n,j,i) ); g += prod; } //printf(" i=%2u, g = %12.4e\n", i, crealf(g)); for (j=0; j<n; j++) matrix_access(e,n,n,j,k) -= matrix_access(e,n,n,j,i) * g; } // compute e_k = e_k / |e_k| float ek = 0.0f; T ak; for (i=0; i<n; i++) { ak = matrix_access(e,n,n,i,k); ek += fabsf( ak*conjf(ak) ); } ek = sqrtf(ek); // normalize e for (i=0; i<n; i++) matrix_access(e,n,n,i,k) /= ek; } // move Q memmove(_Q, e, n*n*sizeof(T)); // compute R // j : row // k : column for (j=0; j<n; j++) { for (k=0; k<n; k++) { if (k < j) { matrix_access(_R,n,n,j,k) = 0.0f; } else { // compute dot product between and Q(:,j) and _x(:,k) T g = 0; for (i=0; i<n; i++) { T prod = conj( matrix_access(_Q,n,n,i,j) ) * matrix_access(_x,n,n,i,k); g += prod; } matrix_access(_R,n,n,j,k) = g; } } } }
int main(int argc, char*argv[]) { srand(time(NULL)); // options unsigned int num_symbols=500; // number of symbols to observe float SNRdB = 30.0f; // signal-to-noise ratio [dB] unsigned int hc_len=5; // channel filter length unsigned int k=2; // matched filter samples/symbol unsigned int m=3; // matched filter delay (symbols) float beta=0.3f; // matched filter excess bandwidth factor unsigned int p=3; // equalizer length (symbols, hp_len = 2*k*p+1) float mu = 0.08f; // learning rate // modulation type/depth modulation_scheme ms = LIQUID_MODEM_QPSK; int dopt; while ((dopt = getopt(argc,argv,"hn:s:c:k:m:b:p:u:M:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'n': num_symbols = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'c': hc_len = atoi(optarg); break; case 'k': k = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 'p': p = atoi(optarg); break; case 'u': mu = 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); } } // validate input if (num_symbols == 0) { fprintf(stderr,"error: %s, number of symbols must be greater than zero\n", argv[0]); exit(1); } else if (hc_len == 0) { fprintf(stderr,"error: %s, channel must have at least 1 tap\n", argv[0]); exit(1); } else if (k < 2) { fprintf(stderr,"error: %s, samples/symbol must be at least 2\n", argv[0]); exit(1); } else if (m == 0) { fprintf(stderr,"error: %s, filter semi-length must be at least 1 symbol\n", argv[0]); exit(1); } else if (beta < 0.0f || beta > 1.0f) { fprintf(stderr,"error: %s, filter excess bandwidth must be in [0,1]\n", argv[0]); exit(1); } else if (p == 0) { fprintf(stderr,"error: %s, equalizer semi-length must be at least 1 symbol\n", argv[0]); exit(1); } else if (mu < 0.0f || mu > 1.0f) { fprintf(stderr,"error: %s, equalizer learning rate must be in [0,1]\n", argv[0]); exit(1); } // derived values unsigned int hm_len = 2*k*m+1; // matched filter length unsigned int hp_len = 2*k*p+1; // equalizer filter length unsigned int num_samples = k*num_symbols; // bookkeeping variables float complex sym_tx[num_symbols]; // transmitted data sequence float complex x[num_samples]; // interpolated time series float complex y[num_samples]; // channel output float complex z[num_samples]; // equalized output float hm[hm_len]; // matched filter response float complex hc[hc_len]; // channel filter coefficients float complex hp[hp_len]; // equalizer filter coefficients unsigned int i; // generate matched filter response liquid_firdes_rnyquist(LIQUID_FIRFILT_RRC, k, m, beta, 0.0f, hm); firinterp_crcf interp = firinterp_crcf_create(k, hm, hm_len); // create the modem objects modem mod = modem_create(ms); modem demod = modem_create(ms); unsigned int M = 1 << modem_get_bps(mod); // generate channel impulse response, filter hc[0] = 1.0f; for (i=1; i<hc_len; i++) hc[i] = 0.09f*(randnf() + randnf()*_Complex_I); firfilt_cccf fchannel = firfilt_cccf_create(hc, hc_len); // generate random symbols for (i=0; i<num_symbols; i++) modem_modulate(mod, rand()%M, &sym_tx[i]); // interpolate for (i=0; i<num_symbols; i++) firinterp_crcf_execute(interp, sym_tx[i], &x[i*k]); // push through channel float nstd = powf(10.0f, -SNRdB/20.0f); for (i=0; i<num_samples; i++) { firfilt_cccf_push(fchannel, x[i]); firfilt_cccf_execute(fchannel, &y[i]); // add noise y[i] += nstd*(randnf() + randnf()*_Complex_I)*M_SQRT1_2; } // push through equalizer // create equalizer, intialized with square-root Nyquist filter eqlms_cccf eq = eqlms_cccf_create_rnyquist(LIQUID_FIRFILT_RRC, k, p, beta, 0.0f); eqlms_cccf_set_bw(eq, mu); // get initialized weights eqlms_cccf_get_weights(eq, hp); // filtered error vector magnitude (emperical RMS error) float evm_hat = 0.03f; float complex d_hat = 0.0f; for (i=0; i<num_samples; i++) { // print filtered evm (emperical rms error) if ( ((i+1)%50)==0 ) printf("%4u : rms error = %12.8f dB\n", i+1, 10*log10(evm_hat)); eqlms_cccf_push(eq, y[i]); eqlms_cccf_execute(eq, &d_hat); // store output z[i] = d_hat; // decimate by k if ( (i%k) != 0 ) continue; // estimate transmitted signal unsigned int sym_out; // output symbol float complex d_prime; // estimated input sample modem_demodulate(demod, d_hat, &sym_out); modem_get_demodulator_sample(demod, &d_prime); // update equalizer eqlms_cccf_step(eq, d_prime, d_hat); // update filtered evm estimate float evm = crealf( (d_prime-d_hat)*conjf(d_prime-d_hat) ); evm_hat = 0.98f*evm_hat + 0.02f*evm; } // get equalizer weights eqlms_cccf_get_weights(eq, hp); // destroy objects eqlms_cccf_destroy(eq); firinterp_crcf_destroy(interp); firfilt_cccf_destroy(fchannel); modem_destroy(mod); modem_destroy(demod); // // export output // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n\n", OUTPUT_FILENAME); fprintf(fid,"clear all\n"); fprintf(fid,"close all\n"); fprintf(fid,"k = %u;\n", k); fprintf(fid,"m = %u;\n", m); fprintf(fid,"num_symbols = %u;\n", num_symbols); fprintf(fid,"num_samples = num_symbols*k;\n"); // save transmit matched-filter response fprintf(fid,"hm_len = 2*k*m+1;\n"); fprintf(fid,"hm = zeros(1,hm_len);\n"); for (i=0; i<hm_len; i++) fprintf(fid,"hm(%4u) = %12.4e;\n", i+1, hm[i]); // save channel impulse response fprintf(fid,"hc_len = %u;\n", hc_len); fprintf(fid,"hc = zeros(1,hc_len);\n"); for (i=0; i<hc_len; i++) fprintf(fid,"hc(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(hc[i]), cimagf(hc[i])); // save equalizer response fprintf(fid,"hp_len = %u;\n", hp_len); fprintf(fid,"hp = zeros(1,hp_len);\n"); for (i=0; i<hp_len; i++) fprintf(fid,"hp(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(hp[i]), cimagf(hp[i])); // save sample sets fprintf(fid,"x = zeros(1,num_samples);\n"); fprintf(fid,"y = zeros(1,num_samples);\n"); fprintf(fid,"z = zeros(1,num_samples);\n"); for (i=0; i<num_samples; i++) { fprintf(fid,"x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"y(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); fprintf(fid,"z(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(z[i]), cimagf(z[i])); } // plot time response fprintf(fid,"t = 0:(num_samples-1);\n"); fprintf(fid,"tsym = 1:k:num_samples;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(t,real(z),...\n"); fprintf(fid," t(tsym),real(z(tsym)),'x');\n"); // plot constellation fprintf(fid,"tsym0 = tsym(1:(length(tsym)/2));\n"); fprintf(fid,"tsym1 = tsym((length(tsym)/2):end);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(real(z(tsym0)),imag(z(tsym0)),'x','Color',[1 1 1]*0.7,...\n"); fprintf(fid," real(z(tsym1)),imag(z(tsym1)),'x','Color',[1 1 1]*0.0);\n"); fprintf(fid,"xlabel('In-Phase');\n"); fprintf(fid,"ylabel('Quadrature');\n"); fprintf(fid,"axis([-1 1 -1 1]*1.5);\n"); fprintf(fid,"axis square;\n"); fprintf(fid,"grid on;\n"); // compute composite response fprintf(fid,"g = real(conv(conv(hm,hc),hp));\n"); // plot responses fprintf(fid,"nfft = 1024;\n"); fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"Hm = 20*log10(abs(fftshift(fft(hm/k,nfft))));\n"); fprintf(fid,"Hc = 20*log10(abs(fftshift(fft(hc, nfft))));\n"); fprintf(fid,"Hp = 20*log10(abs(fftshift(fft(hp, nfft))));\n"); fprintf(fid,"G = 20*log10(abs(fftshift(fft(g/k, nfft))));\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(f,Hm, f,Hc, f,Hp, f,G,'-k','LineWidth',2, [-0.5/k 0.5/k],[-6.026 -6.026],'or');\n"); fprintf(fid,"xlabel('Normalized Frequency');\n"); fprintf(fid,"ylabel('Power Spectral Density');\n"); fprintf(fid,"legend('transmit','channel','equalizer','composite','half-power points',1);\n"); fprintf(fid,"axis([-0.5 0.5 -12 8]);\n"); fprintf(fid,"grid on;\n"); fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); return 0; }
// frame detection void ofdmframesync_execute_S0b(ofdmframesync _q) { //printf("t = %u\n", _q->timer); _q->timer++; if (_q->timer < _q->M2) return; // reset timer _q->timer = _q->M + _q->cp_len - _q->backoff; // float complex * rc; windowcf_read(_q->input_buffer, &rc); // estimate S0 gain ofdmframesync_estimate_gain_S0(_q, &rc[_q->cp_len], _q->G1); float complex s_hat; ofdmframesync_S0_metrics(_q, _q->G1, &s_hat); s_hat *= _q->g0; _q->s_hat_1 = s_hat; #if DEBUG_OFDMFRAMESYNC_PRINT float tau_hat = cargf(s_hat) * (float)(_q->M2) / (2*M_PI); printf("********** S0[1] received ************\n"); printf(" s_hat : %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat)); printf(" tau_hat : %12.8f\n", tau_hat); // new timing offset estimate tau_hat = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI); printf(" tau_hat * : %12.8f\n", tau_hat); printf("**********\n"); #endif // re-adjust timer accordingly float tau_prime = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI); _q->timer -= (int)roundf(tau_prime); #if 0 if (cabsf(s_hat) < 0.3f) { #if DEBUG_OFDMFRAMESYNC_PRINT printf("false alarm S0[1]\n"); #endif // false alarm ofdmframesync_reset(_q); return; } #endif float complex g_hat = 0.0f; unsigned int i; for (i=0; i<_q->M; i++) g_hat += _q->G1[i] * conjf(_q->G0[i]); #if 0 // compute carrier frequency offset estimate using freq. domain method float nu_hat = 2.0f * cargf(g_hat) / (float)(_q->M); #else // compute carrier frequency offset estimate using ML method float complex t0 = 0.0f; for (i=0; i<_q->M2; i++) { t0 += conjf(rc[i]) * _q->s0[i] * rc[i+_q->M2] * conjf(_q->s0[i+_q->M2]); } float nu_hat = cargf(t0) / (float)(_q->M2); #endif #if DEBUG_OFDMFRAMESYNC_PRINT printf(" nu_hat : %12.8f\n", nu_hat); #endif // set NCO frequency nco_crcf_set_frequency(_q->nco_rx, nu_hat); _q->state = OFDMFRAMESYNC_STATE_PLCPLONG; }
static void zconj(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = conjf(src[i]); }