float cargf(float complex z) { return (atan2f(cimagf(z), crealf(z))); }
ld = cabsl(ld); TEST_TRACE(C99 7.3.8.2) 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);
int main(int argc, char*argv[]) { // options unsigned int bps=6; // bits per symbol unsigned int n=1024; // number of data points to evaluate int dopt; while ((dopt = getopt(argc,argv,"uhp:")) != EOF) { switch (dopt) { case 'u': case 'h': usage(); return 0; case 'p': bps = atoi(optarg); break; default: exit(1); } } // validate input if (bps == 0) { fprintf(stderr,"error: %s, bits/symbol must be greater than zero\n", argv[0]); exit(1); } // derived values unsigned int i; unsigned int M = 1<<bps; // constellation size // initialize constellation table float complex constellation[M]; // initialize constellation (spiral) for (i=0; i<M; i++) { float r = (float)i / logf((float)M) + 4.0f; float phi = (float)i / logf((float)M); constellation[i] = r * cexpf(_Complex_I*phi); } // create mod/demod objects modem mod = modem_create_arbitrary(constellation, M); modem demod = modem_create_arbitrary(constellation, M); modem_print(mod); // run simulation float complex x[n]; unsigned int num_errors = 0; // run simple BER simulation num_errors = 0; unsigned int sym_in; unsigned int sym_out; for (i=0; i<n; i++) { // generate and modulate random symbol sym_in = modem_gen_rand_sym(mod); modem_modulate(mod, sym_in, &x[i]); // add noise x[i] += 0.05 * randnf() * cexpf(_Complex_I*M_PI*randf()); // demodulate modem_demodulate(demod, x[i], &sym_out); // accumulate errors num_errors += count_bit_errors(sym_in,sym_out); } printf("num bit errors: %4u / %4u\n", num_errors, bps*n); // destroy modem objects modem_destroy(mod); modem_destroy(demod); // // export output file // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n"); fprintf(fid,"bps = %u;\n", bps); fprintf(fid,"M = %u;\n", M); for (i=0; i<n; i++) { fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); } // plot results fprintf(fid,"figure;\n"); fprintf(fid,"plot(x,'x','MarkerSize',1);\n"); fprintf(fid,"xlabel('in-phase');\n"); fprintf(fid,"ylabel('quadrature phase');\n"); fprintf(fid,"title(['Arbitrary ' num2str(M) '-QAM']);\n"); fprintf(fid,"axis([-1 1 -1 1]*1.9);\n"); fprintf(fid,"axis square;\n"); fprintf(fid,"grid on;\n"); fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
int main(int argc, char*argv[]) { srand(time(NULL)); // options unsigned int k = 2; // samples per symbol unsigned int m = 7; // filter delay (symbols) float beta = 0.25f; // filter excess bandwidth factor unsigned int num_symbols = 4000; // number of data symbols unsigned int hc_len = 5; // channel filter length float noise_floor = -60.0f; // noise floor [dB] float SNRdB = 30.0f; // signal-to-noise ratio [dB] float bandwidth = 0.02f; // loop filter bandwidth float tau = -0.2f; // fractional symbol offset float rate = 1.001f; // sample rate offset float dphi = 0.00f; // carrier frequency offset [radians/sample] float phi = 2.1f; // carrier phase offset [radians] modulation_scheme ms = LIQUID_MODEM_QPSK; int dopt; while ((dopt = getopt(argc,argv,"hk:m:b:H:n:s:w:t:r:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'k': k = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 'H': hc_len = atoi(optarg); break; case 'n': num_symbols = atoi(optarg); break; case 's': SNRdB = atof(optarg); break; case 'w': bandwidth = atof(optarg); break; case 't': tau = atof(optarg); break; case 'r': rate = atof(optarg); break; default: exit(1); } } // validate input if (k < 2) { fprintf(stderr,"error: k (samples/symbol) must be greater than 1\n"); exit(1); } else if (m < 1) { fprintf(stderr,"error: m (filter delay) must be greater than 0\n"); exit(1); } else if (beta <= 0.0f || beta > 1.0f) { fprintf(stderr,"error: beta (excess bandwidth factor) must be in (0,1]\n"); exit(1); } else if (bandwidth <= 0.0f) { fprintf(stderr,"error: timing PLL bandwidth must be greater than 0\n"); exit(1); } else if (num_symbols == 0) { fprintf(stderr,"error: number of symbols must be greater than 0\n"); exit(1); } else if (tau < -1.0f || tau > 1.0f) { fprintf(stderr,"error: timing phase offset must be in [-1,1]\n"); exit(1); } else if (rate > 1.02f || rate < 0.98f) { fprintf(stderr,"error: timing rate offset must be in [1.02,0.98]\n"); exit(1); } unsigned int i; // derived/fixed values unsigned int nx = num_symbols*k; unsigned int ny = (unsigned int) ceilf(rate * nx) + 64; float complex x[nx]; // input (interpolated) samples float complex y[ny]; // channel output samples float complex sym_out[num_symbols + 64];// synchronized symbols // // generate input sequence using symbol stream generator // symstreamcf gen = symstreamcf_create_linear(LIQUID_FIRFILT_ARKAISER,k,m,beta,ms); symstreamcf_write_samples(gen, x, nx); symstreamcf_destroy(gen); // create channel channel_cccf channel = channel_cccf_create(); // add channel impairments channel_cccf_add_awgn (channel, noise_floor, SNRdB); channel_cccf_add_carrier_offset(channel, dphi, phi); channel_cccf_add_multipath (channel, NULL, hc_len); channel_cccf_add_shadowing (channel, 1.0f, 0.1f); channel_cccf_add_resamp (channel, 0.0f, rate); // print channel internals channel_cccf_print(channel); // apply channel to input signal channel_cccf_execute(channel, x, nx, y, &ny); // destroy channel channel_cccf_destroy(channel); // // create and run symbol synchronizer // symtrack_cccf symtrack = symtrack_cccf_create(LIQUID_FIRFILT_RRC,k,m,beta,ms); // set tracking bandwidth symtrack_cccf_set_bandwidth(symtrack,0.05f); unsigned int num_symbols_sync = 0; symtrack_cccf_execute_block(symtrack, y, ny, sym_out, &num_symbols_sync); symtrack_cccf_destroy(symtrack); // print results printf("symbols in : %u\n", num_symbols); printf("symbols out : %u\n", num_symbols_sync); // estimate spectrum unsigned int nfft = 1200; float psd[nfft]; spgramcf periodogram = spgramcf_create_kaiser(nfft, nfft/2, 8.0f); spgramcf_estimate_psd(periodogram, y, ny, psd); spgramcf_destroy(periodogram); // // export output file // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s, auto-generated file\n\n", OUTPUT_FILENAME); fprintf(fid,"close all;\nclear all;\n\n"); fprintf(fid,"num_symbols=%u;\n",num_symbols_sync); for (i=0; i<num_symbols_sync; i++) fprintf(fid,"z(%3u) = %12.8f + j*%12.8f;\n", i+1, crealf(sym_out[i]), cimagf(sym_out[i])); // power spectral density estimate fprintf(fid,"nfft = %u;\n", nfft); fprintf(fid,"f=[0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"psd = zeros(1,nfft);\n"); for (i=0; i<nfft; i++) fprintf(fid,"psd(%3u) = %12.8f;\n", i+1, psd[i]); fprintf(fid,"iz0 = 1:round(length(z)*0.5);\n"); fprintf(fid,"iz1 = round(length(z)*0.5):length(z);\n"); fprintf(fid,"figure('Color','white','position',[500 500 800 800]);\n"); fprintf(fid,"subplot(2,2,1);\n"); fprintf(fid,"plot(real(z(iz0)),imag(z(iz0)),'x','MarkerSize',4);\n"); fprintf(fid," axis square;\n"); fprintf(fid," grid on;\n"); fprintf(fid," axis([-1 1 -1 1]*1.6);\n"); fprintf(fid," xlabel('In-phase');\n"); fprintf(fid," ylabel('Quadrature');\n"); fprintf(fid," title('First 50%% of symbols');\n"); fprintf(fid,"subplot(2,2,2);\n"); fprintf(fid," plot(real(z(iz1)),imag(z(iz1)),'x','MarkerSize',4);\n"); fprintf(fid," axis square;\n"); fprintf(fid," grid on;\n"); fprintf(fid," axis([-1 1 -1 1]*1.5);\n"); fprintf(fid," xlabel('In-phase');\n"); fprintf(fid," ylabel('Quadrature');\n"); fprintf(fid," title('Last 50%% of symbols');\n"); fprintf(fid,"subplot(2,2,3:4);\n"); fprintf(fid," plot(f, psd, 'LineWidth',1.5,'Color',[0 0.5 0.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid," pmin = 10*floor(0.1*min(psd - 5));\n"); fprintf(fid," pmax = 10*ceil (0.1*max(psd + 5));\n"); fprintf(fid," axis([-0.5 0.5 pmin pmax]);\n"); fprintf(fid," xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid," ylabel('Power Spectral Density [dB]');\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); // clean it up printf("done.\n"); return 0; }
void autotest_iirdes_cplxpair_n20() { float tol = 1e-8f; // float complex r[20] = { -0.340396183901119 + 1.109902927794652 * _Complex_I, 1.148964416793990 + 0.000000000000000 * _Complex_I, 0.190037889511651 + 0.597517076404221 * _Complex_I, -0.340396183901119 - 1.109902927794652 * _Complex_I, 0.890883293686046 + 0.000000000000000 * _Complex_I, -0.248338528396292 - 0.199390430636670 * _Complex_I, 0.190037889511651 - 0.597517076404221 * _Complex_I, 0.003180396218998 + 0.000000000000000 * _Complex_I, 0.261949046540733 - 0.739400953405199 * _Complex_I, 0.261949046540733 + 0.739400953405199 * _Complex_I, 0.309342570837113 + 0.000000000000000 * _Complex_I, 0.035516103001236 + 0.000000000000000 * _Complex_I, -0.184159864176452 - 0.240335024546875 * _Complex_I, -0.485244526317243 + 0.452251520655749 * _Complex_I, -0.485244526317243 - 0.452251520655749 * _Complex_I, -0.581633365450190 + 0.000000000000000 * _Complex_I, -0.248338528396292 + 0.199390430636670 * _Complex_I, -0.184159864176452 + 0.240335024546875 * _Complex_I, 1.013685316242435 + 0.000000000000000 * _Complex_I, -0.089598596934739 + 0.000000000000000 * _Complex_I }; float complex p[20]; float complex ptest[20] = { -0.485244526317243 - 0.452251520655749 * _Complex_I, -0.485244526317243 + 0.452251520655749 * _Complex_I, -0.340396183901119 - 1.109902927794652 * _Complex_I, -0.340396183901119 + 1.109902927794652 * _Complex_I, -0.248338528396292 - 0.199390430636670 * _Complex_I, -0.248338528396292 + 0.199390430636670 * _Complex_I, -0.184159864176452 - 0.240335024546875 * _Complex_I, -0.184159864176452 + 0.240335024546875 * _Complex_I, 0.190037889511651 - 0.597517076404221 * _Complex_I, 0.190037889511651 + 0.597517076404221 * _Complex_I, 0.261949046540733 - 0.739400953405199 * _Complex_I, 0.261949046540733 + 0.739400953405199 * _Complex_I, -0.581633365450190 + 0.000000000000000 * _Complex_I, -0.089598596934739 + 0.000000000000000 * _Complex_I, 0.003180396218998 + 0.000000000000000 * _Complex_I, 0.035516103001236 + 0.000000000000000 * _Complex_I, 0.309342570837113 + 0.000000000000000 * _Complex_I, 0.890883293686046 + 0.000000000000000 * _Complex_I, 1.013685316242435 + 0.000000000000000 * _Complex_I, 1.148964416793990 + 0.000000000000000 * _Complex_I }; // compute complex pairs liquid_cplxpair(r,20,1e-6f,p); unsigned int i; if (liquid_autotest_verbose) { printf("complex set:\n"); for (i=0; i<20; i++) printf(" r[%3u] : %12.8f + j*%12.8f\n", i, crealf(r[i]), cimagf(r[i])); printf("complex pairs:\n"); for (i=0; i<20; i++) printf(" p[%3u] : %12.8f + j*%12.8f\n", i, crealf(p[i]), cimagf(p[i])); } // run test for (i=0; i<20; i++) { CONTEND_DELTA( crealf(p[i]), crealf(ptest[i]), tol ); CONTEND_DELTA( cimagf(p[i]), cimagf(ptest[i]), tol ); } }
float (cimagf)(float complex z) { return cimagf(z); }
float sf_cabs(sf_complex c) /*< complex absolute value >*/ { return hypotf(crealf(c),cimagf(c)); }\
int main(int argc, char*argv[]) { // options unsigned int num_channels=6; // number of channels (must be even) unsigned int m=4; // filter delay unsigned int num_symbols=4*m; // number of symbols // validate input if (num_channels%2) { fprintf(stderr,"error: %s, number of channels must be even\n", argv[0]); exit(1); } // derived values unsigned int num_samples = num_channels * num_symbols; unsigned int i; unsigned int j; // generate filter // NOTE : these coefficients can be random; the purpose of this // exercise is to demonstrate mathematical equivalence #if 0 unsigned int h_len = 2*m*num_channels; float h[h_len]; for (i=0; i<h_len; i++) h[i] = randnf(); #else unsigned int h_len = 2*m*num_channels+1; float h[h_len]; // NOTE: 81.29528 dB > beta = 8.00000 (6 channels, m=4) liquid_firdes_kaiser(h_len, 1.0f/(float)num_channels, 81.29528f, 0.0f, h); #endif // normalize float hsum = 0.0f; for (i=0; i<h_len; i++) hsum += h[i]; for (i=0; i<h_len; i++) h[i] = h[i] * num_channels / hsum; // sub-sampled filters for M=6 channels, m=4, beta=8.0 // -3.2069e-19 -6.7542e-04 -1.3201e-03 2.2878e-18 3.7613e-03 5.8033e-03 // -7.2899e-18 -1.2305e-02 -1.7147e-02 1.6510e-17 3.1187e-02 4.0974e-02 // -3.0032e-17 -6.8026e-02 -8.6399e-02 4.6273e-17 1.3732e-01 1.7307e-01 // -6.2097e-17 -2.8265e-01 -3.7403e-01 7.3699e-17 8.0663e-01 1.6438e+00 // 2.0001e+00 1.6438e+00 8.0663e-01 7.3699e-17 -3.7403e-01 -2.8265e-01 // -6.2097e-17 1.7307e-01 1.3732e-01 4.6273e-17 -8.6399e-02 -6.8026e-02 // -3.0032e-17 4.0974e-02 3.1187e-02 1.6510e-17 -1.7147e-02 -1.2305e-02 // -7.2899e-18 5.8033e-03 3.7613e-03 2.2878e-18 -1.3201e-03 -6.7542e-04 // create filterbank manually dotprod_crcf dp[num_channels]; // vector dot products windowcf w[num_channels]; // window buffers #if DEBUG // print coefficients printf("h_prototype:\n"); for (i=0; i<h_len; i++) printf(" h[%3u] = %12.8f\n", i, h[i]); #endif // create objects unsigned int h_sub_len = 2*m; float h_sub[h_sub_len]; for (i=0; i<num_channels; i++) { // sub-sample prototype filter #if 0 for (j=0; j<h_sub_len; j++) h_sub[j] = h[j*num_channels+i]; #else // load coefficients in reverse order for (j=0; j<h_sub_len; j++) h_sub[h_sub_len-j-1] = h[j*num_channels+i]; #endif // create window buffer and dotprod objects dp[i] = dotprod_crcf_create(h_sub, h_sub_len); w[i] = windowcf_create(h_sub_len); #if DEBUG printf("h_sub[%u] : \n", i); for (j=0; j<h_sub_len; j++) printf(" h[%3u] = %12.8f\n", j, h_sub[j]); #endif } // generate DFT object float complex x[num_channels]; // time-domain buffer float complex X[num_channels]; // freq-domain buffer #if 1 fftplan fft = fft_create_plan(num_channels, X, x, LIQUID_FFT_BACKWARD, 0); #else fftplan fft = fft_create_plan(num_channels, X, x, LIQUID_FFT_FORWARD, 0); #endif float complex y[num_samples]; // time-domain input float complex Y0[2*num_symbols][num_channels]; // channelizer output float complex Y1[2*num_symbols][num_channels]; // conventional output // generate input sequence for (i=0; i<num_samples; i++) { //y[i] = randnf() * cexpf(_Complex_I*randf()*2*M_PI); y[i] = (i==0) ? 1.0f : 0.0f; y[i] = cexpf(_Complex_I*sqrtf(2.0f)*i*i); printf("y[%3u] = %12.8f + %12.8fj\n", i, crealf(y[i]), cimagf(y[i])); } // // run analysis filter bank // #if 0 unsigned int filter_index = 0; #else unsigned int filter_index = num_channels/2-1; #endif float complex y_hat; // input sample float complex * r; // buffer read pointer int toggle = 0; // flag indicating buffer/filter alignment // for (i=0; i<2*num_symbols; i++) { // load buffers in blocks of num_channels/2 for (j=0; j<num_channels/2; j++) { // grab sample y_hat = y[i*num_channels/2 + j]; // push sample into buffer at filter index windowcf_push(w[filter_index], y_hat); // decrement filter index filter_index = (filter_index + num_channels - 1) % num_channels; //filter_index = (filter_index + 1) % num_channels; } // execute filter outputs // reversing order of output (not sure why this is necessary) unsigned int offset = toggle ? num_channels/2 : 0; toggle = 1-toggle; for (j=0; j<num_channels; j++) { unsigned int buffer_index = (offset+j)%num_channels; unsigned int dotprod_index = j; windowcf_read(w[buffer_index], &r); //dotprod_crcf_execute(dp[dotprod_index], r, &X[num_channels-j-1]); dotprod_crcf_execute(dp[dotprod_index], r, &X[buffer_index]); } printf("***** i = %u\n", i); for (j=0; j<num_channels; j++) printf(" v2[%4u] = %12.8f + %12.8fj\n", j, crealf(X[j]), cimagf(X[j])); // execute DFT, store result in buffer 'x' fft_execute(fft); // scale fft output for (j=0; j<num_channels; j++) x[j] *= 1.0f / (num_channels); // move to output array for (j=0; j<num_channels; j++) Y0[i][j] = x[j]; } // destroy objects for (i=0; i<num_channels; i++) { dotprod_crcf_destroy(dp[i]); windowcf_destroy(w[i]); } fft_destroy_plan(fft); // // run traditional down-converter (inefficient) // // generate filter object firfilt_crcf f = firfilt_crcf_create(h, h_len); float dphi; // carrier frequency unsigned int n=0; for (i=0; i<num_channels; i++) { // reset filter firfilt_crcf_clear(f); // set center frequency dphi = 2.0f * M_PI * (float)i / (float)num_channels; // reset symbol counter n=0; for (j=0; j<num_samples; j++) { // push down-converted sample into filter firfilt_crcf_push(f, y[j]*cexpf(-_Complex_I*j*dphi)); // compute output at the appropriate sample time assert(n<2*num_symbols); if ( ((j+1)%(num_channels/2))==0 ) { firfilt_crcf_execute(f, &Y1[n][i]); n++; } } assert(n==2*num_symbols); } firfilt_crcf_destroy(f); // print filterbank channelizer printf("\n"); printf("filterbank channelizer:\n"); for (i=0; i<2*num_symbols; i++) { printf("%2u:", i); for (j=0; j<num_channels; j++) { printf("%6.3f+%6.3fj, ", crealf(Y0[i][j]), cimagf(Y0[i][j])); } printf("\n"); } #if 0 // print traditional channelizer printf("\n"); printf("traditional channelizer:\n"); for (i=0; i<2*num_symbols; i++) { printf("%2u:", i); for (j=0; j<num_channels; j++) { printf("%6.3f+%6.3fj, ", crealf(Y1[i][j]), cimagf(Y1[i][j])); } printf("\n"); } // // compare results // float mse[num_channels]; float complex d; for (i=0; i<num_channels; i++) { mse[i] = 0.0f; for (j=0; j<2*num_symbols; j++) { d = Y0[j][i] - Y1[j][i]; mse[i] += crealf(d*conjf(d)); } mse[i] /= num_symbols; } printf("\n"); printf(" e:"); for (i=0; i<num_channels; i++) printf("%12.4e ", sqrt(mse[i])); printf("\n"); #endif printf("done.\n"); return 0; }
float complex csinf(float complex z) { z = csinhf(cpackf(-cimagf(z), crealf(z))); return cpackf(cimagf(z), -crealf(z)); }
int main() { // options unsigned int n = 200; // input sequence length unsigned int p = 4; // prediction filter order // original filter #if 1 // autoregressive moving average filter // ./examples/iirdes_example -t butter -n3 -otf -f0.2 float b[4] = {0.01809893, 0.05429679, 0.05429679, 0.01809893}; float a[4] = {1.00000000, -1.76004195, 1.18289328, -0.27805993}; #else // autoregressive filter float b[4] = {1.0f, 0.0f, 0.0f, 0.0f}; float a[4] = {1.0f, 0.5f, 0.4f, 0.3f}; #endif // create filter object iirfilt_rrrf f = iirfilt_rrrf_create(b,4, a,4); iirfilt_rrrf_print(f); unsigned int i; // allocate memory for data arrays float x[n]; // input noise sequence float y[n]; // output filtered noise sequence float a_hat[p+1]; // lpc output float g_hat[p+1]; // lpc output // generate input noise signal for (i=0; i<n; i++) { x[i] = randnf(); //x[i] = ( (i%20) == 0 ) ? 1.0f : 0.0f; } // run filter for (i=0; i<n; i++) iirfilt_rrrf_execute(f, x[i], &y[i]); // destroy filter object iirfilt_rrrf_destroy(f); // run linear prediction algorithm liquid_lpc(y,n,p,a_hat,g_hat); // run prediction filter float a_lpc[p+1]; float b_lpc[p+1]; for (i=0; i<p+1; i++) { a_lpc[i] = (i==0) ? 1.0f : 0.0f; b_lpc[i] = (i==0) ? 0.0f : -a_hat[i]; } f = iirfilt_rrrf_create(b_lpc,p+1, a_lpc,p+1); iirfilt_rrrf_print(f); float y_hat[n]; for (i=0; i<n; i++) iirfilt_rrrf_execute(f, y[i], &y_hat[i]); iirfilt_rrrf_destroy(f); // compute prediction error float err[n]; for (i=0; i<n; i++) err[i] = y[i] - y_hat[i]; // compute autocorrelation of prediction error float lag[n]; float rxx[n]; for (i=0; i<n; i++) { lag[i] = (float)i; rxx[i] = 0.0f; unsigned int j; for (j=i; j<n; j++) rxx[i] += err[j] * err[j-i]; } float rxx0 = rxx[0]; for (i=0; i<n; i++) rxx[i] /= rxx0; // print results for (i=0; i<p+1; i++) printf(" a[%3u] = %12.8f, g[%3u] = %12.8f\n", i, a_hat[i], i, g_hat[i]); printf(" prediction rmse = %12.8f\n", sqrtf(rxx0 / n)); // // plot results to output file // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n"); fprintf(fid,"\n"); fprintf(fid,"p=%u;\n", p); fprintf(fid,"n=%u;\n",n); #if 0 fprintf(fid,"b = zeros(1,p+1);\n"); fprintf(fid,"a = zeros(1,p+1);\n"); for (i=0; i<p+1; i++) { fprintf(fid,"b(%4u) = %12.4e;\n", i+1, b_lpc[i]); fprintf(fid,"a(%4u) = %12.4e;\n", i+1, a_lpc[i]); } #endif fprintf(fid,"x = zeros(1,n);\n"); fprintf(fid,"y = zeros(1,n);\n"); fprintf(fid,"y_hat = zeros(1,n);\n"); fprintf(fid,"lag = zeros(1,n);\n"); fprintf(fid,"rxx = zeros(1,n);\n"); for (i=0; i<n; 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,"y_hat(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(y_hat[i]), cimagf(y_hat[i])); fprintf(fid,"lag(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(lag[i]), cimagf(lag[i])); fprintf(fid,"rxx(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(rxx[i]), cimagf(rxx[i])); } // plot output fprintf(fid,"t=0:(n-1);\n"); fprintf(fid,"figure;\n"); fprintf(fid," plot(t,x,'-','Color',[1 1 1]*0.5,'LineWidth',1,...\n"); fprintf(fid," t,y,'-','Color',[0 0.5 0.25],'LineWidth',2);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('real');\n"); fprintf(fid," legend('input','filtered output',1);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(5,1,1:3);\n"); fprintf(fid," plot(t,y,t,y_hat);\n"); fprintf(fid," ylabel('signal');\n"); fprintf(fid," legend('y','lpc estimate',1);\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(5,1,4);\n"); fprintf(fid," plot(t,y-y_hat);\n"); fprintf(fid," ylabel('error');\n"); fprintf(fid,"subplot(5,1,5);\n"); fprintf(fid," plot(t,rxx);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('r_{xx}(e)');\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
int main() { unsigned int h_len=20; // filter length float beta = 0.3f; // stop-band attenuation unsigned int num_samples=64; // number of samples // derived values unsigned int n = num_samples + h_len; // extend length of analysis to // incorporate filter delay // create filterbank qmfb_crcf q = qmfb_crcf_create(h_len, beta, LIQUID_QMFB_ANALYZER); qmfb_crcf_print(q); FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\nclose all;\n\n"); fprintf(fid,"n=%u;\n", n); fprintf(fid,"x = zeros(1,%u);\n", 2*n); fprintf(fid,"y = zeros(2,%u);\n", n); unsigned int i; float complex x[2*n], y[2][n]; // generate time-domain signal (windowed sinusoidal pulses) nco_crcf nco_0 = nco_crcf_create(LIQUID_VCO); nco_crcf nco_1 = nco_crcf_create(LIQUID_VCO); nco_crcf_set_frequency(nco_0, 0.122*M_PI); nco_crcf_set_frequency(nco_1, 0.779*M_PI); float complex x0,x1; for (i=0; i<2*num_samples; i++) { nco_crcf_cexpf(nco_0, &x0); nco_crcf_cexpf(nco_1, &x1); x[i] = (x0 + x1) * kaiser(i,2*num_samples,10.0f,0.0f); nco_crcf_step(nco_0); nco_crcf_step(nco_1); } // pad end with zeros for (i=2*num_samples; i<2*n; i++) x[i] = 0.0f; // compute QMF sub-channel output for (i=0; i<n; i++) { qmfb_crcf_execute(q, x[2*i+0], x[2*i+1], y[0]+i, y[1]+i); } // write results to output file for (i=0; i<n; i++) { fprintf(fid,"x(%3u) = %8.4f + j*%8.4f;\n", 2*i+1, crealf(x[2*i+0]), cimagf(x[2*i+0])); fprintf(fid,"x(%3u) = %8.4f + j*%8.4f;\n", 2*i+2, crealf(x[2*i+1]), cimagf(x[2*i+1])); fprintf(fid,"y(1,%3u) = %8.4f + j*%8.4f;\n", i+1, crealf(y[0][i]), cimagf(y[0][i])); fprintf(fid,"y(2,%3u) = %8.4f + j*%8.4f;\n", i+1, crealf(y[1][i]), cimagf(y[1][i])); } // plot time-domain results fprintf(fid,"t0=0:(2*n-1);\n"); fprintf(fid,"t1=0:(n-1);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(3,1,1); plot(t0,real(x),t0,imag(x)); ylabel('x(t)');\n"); fprintf(fid,"subplot(3,1,2); plot(t1,real(y(1,:)),t1,imag(y(1,:))); ylabel('y_0(t)');\n"); fprintf(fid,"subplot(3,1,3); plot(t1,real(y(2,:)),t1,imag(y(2,:))); ylabel('y_1(t)');\n"); // plot freq-domain results fprintf(fid,"nfft=512; %% must be even number\n"); fprintf(fid,"X=20*log10(abs(fftshift(fft(x/n,nfft))));\n"); fprintf(fid,"Y0=20*log10(abs(fftshift(fft(y(1,:)/n,nfft))));\n"); fprintf(fid,"Y1=20*log10(abs(fftshift(fft(y(2,:)/n,nfft))));\n"); // Y1 needs to be split into two regions fprintf(fid,"f=[0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"t0 = [1]:[nfft/2];\n"); fprintf(fid,"t1 = [nfft/2+1]:[nfft];\n"); fprintf(fid,"figure;\n"); fprintf(fid,"hold on;\n"); fprintf(fid," plot(f,X,'Color',[0.5 0.5 0.5]);\n"); fprintf(fid," plot(f/2,Y0,'LineWidth',2,'Color',[0 0.5 0]);\n"); fprintf(fid," plot(f(t0)/2+0.5,Y1(t0),'LineWidth',2,'Color',[0.5 0 0]);\n"); fprintf(fid," plot(f(t1)/2-0.5,Y1(t1),'LineWidth',2,'Color',[0.5 0 0]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"grid on;\nxlabel('normalized frequency');\nylabel('PSD [dB]');\n"); fprintf(fid,"legend('original','Y_0','Y_1',1);"); fprintf(fid,"axis([-0.5 0.5 -140 20]);\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); qmfb_crcf_destroy(q); nco_crcf_destroy(nco_0); nco_crcf_destroy(nco_1); printf("done.\n"); return 0; }
int main(int argc, char * argv[]) { CBlasTranspose transA, transB; size_t m, n, k; int d = 0; if (argc < 6 || argc > 7) { fprintf(stderr, "Usage: %s <transA> <transB> <m> <n> <k> [device]\n" "where:\n" " transA and transB are 'n' or 'N' for CBlasNoTrans, 't' or 'T' for CBlasTrans or 'c' or 'C' for CBlasConjTrans\n" " m, n and k are the sizes of the matrices\n" " device is the GPU to use (default 0)\n", argv[0]); return 1; } char t; if (sscanf(argv[1], "%c", &t) != 1) { fprintf(stderr, "Unable to read character from '%s'\n", argv[1]); return 1; } switch (t) { case 'N': case 'n': transA = CBlasNoTrans; break; case 'T': case 't': transA = CBlasTrans; break; case 'C': case 'c': transA = CBlasConjTrans; break; default: fprintf(stderr, "Unknown transpose '%c'\n", t); return 1; } if (sscanf(argv[2], "%c", &t) != 1) { fprintf(stderr, "Unable to read character from '%s'\n", argv[2]); return 2; } switch (t) { case 'N': case 'n': transB = CBlasNoTrans; break; case 'T': case 't': transB = CBlasTrans; break; case 'C': case 'c': transB = CBlasConjTrans; break; default: fprintf(stderr, "Unknown transpose '%c'\n", t); return 1; } if (sscanf(argv[3], "%zu", &m) != 1) { fprintf(stderr, "Unable to parse number from '%s'\n", argv[3]); return 3; } if (sscanf(argv[4], "%zu", &n) != 1) { fprintf(stderr, "Unable to parse number from '%s'\n", argv[4]); return 4; } if (sscanf(argv[5], "%zu", &k) != 1) { fprintf(stderr, "Unable to parse number from '%s'\n", argv[5]); return 5; } if (argc > 6) { if (sscanf(argv[6], "%d", &d) != 1) { fprintf(stderr, "Unable to parse number from '%s'\n", argv[6]); return 6; } } srand(0); float complex alpha, beta, * A, * B, * C, * refC; CUdeviceptr dA, dB, dC, dD; size_t lda, ldb, ldc, dlda, dldb, dldc, dldd; CU_ERROR_CHECK(cuInit(0)); CUdevice device; CU_ERROR_CHECK(cuDeviceGet(&device, d)); CUcontext context; CU_ERROR_CHECK(cuCtxCreate(&context, CU_CTX_SCHED_BLOCKING_SYNC, device)); CUBLAShandle handle; CU_ERROR_CHECK(cuBLASCreate(&handle)); alpha = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; beta = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; if (transA == CBlasNoTrans) { lda = (m + 1u) & ~1u; if ((A = malloc(lda * k * sizeof(float complex))) == NULL) { fputs("Unable to allocate A\n", stderr); return -1; } CU_ERROR_CHECK(cuMemAllocPitch(&dA, &dlda, m * sizeof(float complex), k, sizeof(float complex))); dlda /= sizeof(float complex); for (size_t j = 0; j < k; j++) { for (size_t i = 0; i < m; i++) A[j * lda + i] = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; } CUDA_MEMCPY2D copy = { 0, 0, CU_MEMORYTYPE_HOST, A, 0, NULL, lda * sizeof(float complex), 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dA, NULL, dlda * sizeof(float complex), m * sizeof(float complex), k }; CU_ERROR_CHECK(cuMemcpy2D(©)); } else { lda = (k + 1u) & ~1u; if ((A = malloc(lda * m * sizeof(float complex))) == NULL) { fputs("Unable to allocate A\n", stderr); return -1; } CU_ERROR_CHECK(cuMemAllocPitch(&dA, &dlda, k * sizeof(float complex), m, sizeof(float complex))); dlda /= sizeof(float complex); for (size_t j = 0; j < m; j++) { for (size_t i = 0; i < k; i++) A[j * lda + i] = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; } CUDA_MEMCPY2D copy = { 0, 0, CU_MEMORYTYPE_HOST, A, 0, NULL, lda * sizeof(float complex), 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dA, NULL, dlda * sizeof(float complex), k * sizeof(float complex), m }; CU_ERROR_CHECK(cuMemcpy2D(©)); } if (transB == CBlasNoTrans) { ldb = (k + 1u) & ~1u; if ((B = malloc(ldb * n * sizeof(float complex))) == NULL) { fputs("Unable to allocate B\n", stderr); return -2; } CU_ERROR_CHECK(cuMemAllocPitch(&dB, &dldb, k * sizeof(float complex), n, sizeof(float complex))); dldb /= sizeof(float complex); for (size_t j = 0; j < n; j++) { for (size_t i = 0; i < k; i++) B[j * ldb + i] = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; } CUDA_MEMCPY2D copy = { 0, 0, CU_MEMORYTYPE_HOST, B, 0, NULL, ldb * sizeof(float complex), 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dB, NULL, dldb * sizeof(float complex), k * sizeof(float complex), n }; CU_ERROR_CHECK(cuMemcpy2D(©)); } else { ldb = (n + 1u) & ~1u; if ((B = malloc(ldb * k * sizeof(float complex))) == NULL) { fputs("Unable to allocate B\n", stderr); return -2; } CU_ERROR_CHECK(cuMemAllocPitch(&dB, &dldb, n * sizeof(float complex), k, sizeof(float complex))); dldb /= sizeof(float complex); for (size_t j = 0; j < k; j++) { for (size_t i = 0; i < n; i++) B[j * ldb + i] = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; } CUDA_MEMCPY2D copy = { 0, 0, CU_MEMORYTYPE_HOST, B, 0, NULL, ldb * sizeof(float complex), 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dB, NULL, dldb * sizeof(float complex), n * sizeof(float complex), k }; CU_ERROR_CHECK(cuMemcpy2D(©)); } ldc = (m + 1u) & ~1u; if ((C = malloc(ldc * n * sizeof(float complex))) == NULL) { fputs("Unable to allocate C\n", stderr); return -3; } if ((refC = malloc(ldc * n * sizeof(float complex))) == NULL) { fputs("Unable to allocate refC\n", stderr); return -4; } CU_ERROR_CHECK(cuMemAllocPitch(&dC, &dldc, m * sizeof(float complex), n, sizeof(float complex))); dldc /= sizeof(float complex); CU_ERROR_CHECK(cuMemAllocPitch(&dD, &dldd, m * sizeof(float complex), n, sizeof(float complex))); dldd /= sizeof(float complex); for (size_t j = 0; j < n; j++) { for (size_t i = 0; i < m; i++) refC[j * ldc + i] = C[j * ldc + i] = ((float)rand() / (float)RAND_MAX) + ((float)rand() / (float)RAND_MAX) * I; } CUDA_MEMCPY2D copy = { 0, 0, CU_MEMORYTYPE_HOST, C, 0, NULL, ldc * sizeof(float complex), 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dC, NULL, dldc * sizeof(float complex), m * sizeof(float complex), n }; CU_ERROR_CHECK(cuMemcpy2D(©)); cgemm_ref(transA, transB, m, n, k, alpha, A, lda, B, ldb, beta, refC, ldc); CU_ERROR_CHECK(cuCgemm2(handle, transA, transB, m, n, k, alpha, dA, dlda, dB, dldb, beta, dC, dldc, dD, dldd, NULL)); copy = (CUDA_MEMCPY2D){ 0, 0, CU_MEMORYTYPE_DEVICE, NULL, dD, NULL, dldd * sizeof(float complex), 0, 0, CU_MEMORYTYPE_HOST, C, 0, NULL, ldc * sizeof(float complex), m * sizeof(float complex), n }; CU_ERROR_CHECK(cuMemcpy2D(©)); float rdiff = 0.0f, idiff = 0.0f; for (size_t j = 0; j < n; j++) { for (size_t i = 0; i < m; i++) { float d = fabsf(crealf(C[j * ldc + i]) - crealf(refC[j * ldc + i])); if (d > rdiff) rdiff = d; d = fabsf(cimagf(C[j * ldc + i]) - cimagf(refC[j * ldc + i])); if (d > idiff) idiff = d; } } CUevent start, stop; CU_ERROR_CHECK(cuEventCreate(&start, CU_EVENT_BLOCKING_SYNC)); CU_ERROR_CHECK(cuEventCreate(&stop, CU_EVENT_BLOCKING_SYNC)); CU_ERROR_CHECK(cuEventRecord(start, NULL)); for (size_t i = 0; i < 20; i++) CU_ERROR_CHECK(cuCgemm2(handle, transA, transB, m, n, k, alpha, dA, dlda, dB, dldb, beta, dC, dldc, dD, dldd, NULL)); CU_ERROR_CHECK(cuEventRecord(stop, NULL)); CU_ERROR_CHECK(cuEventSynchronize(stop)); float time; CU_ERROR_CHECK(cuEventElapsedTime(&time, start, stop)); time /= 20; CU_ERROR_CHECK(cuEventDestroy(start)); CU_ERROR_CHECK(cuEventDestroy(stop)); size_t flops = k * 6 + (k - 1) * 2; // k multiplies and k - 1 adds per element if (alpha != 1.0f + 0.0f * I) flops += 6; // additional multiply by alpha if (beta != 0.0f + 0.0f * I) flops += 8; // additional multiply and add by beta float error = (float)flops * 2.0f * FLT_EPSILON; // maximum per element error flops *= m * n; // m * n elements bool passed = (rdiff <= error) && (idiff <= error); fprintf(stdout, "%.3es %.3gGFlops/s Error: %.3e + %.3ei\n%sED!\n", time * 1.e-3f, ((float)flops * 1.e-6f) / time, rdiff, idiff, (passed) ? "PASS" : "FAIL"); free(A); free(B); free(C); free(refC); CU_ERROR_CHECK(cuMemFree(dA)); CU_ERROR_CHECK(cuMemFree(dB)); CU_ERROR_CHECK(cuMemFree(dC)); CU_ERROR_CHECK(cuMemFree(dD)); CU_ERROR_CHECK(cuBLASDestroy(handle)); CU_ERROR_CHECK(cuCtxDestroy(context)); return (int)!passed; }
int main(int argc, char* argv[]) { /*define variables*/ int nx,nx1,nt; int n1,n2; float d1,o1,d2,o2; int padt,padx; int ntfft,*n,nw,nk; float **d,*wavelet,**shot,**ds,**vel,**vmig,**M,v_ave; float *kx,*omega,dkx,dw; sf_complex **m,**ms,**mr,*in2a,*in2b,*cs,*cr,*c,czero; sf_complex Ls; float fmin,fmax,f_low,f_high; int if_low,if_high; int ix,iw,ik; float dt,dx,ox,dz,zmax; fftwf_plan p2a,p2b; sf_file in,out,velfile,source_wavelet; int iz,nz; int ishot,max_num_shot,ig,ng,it,index; int iswavelet; /*define sf input output*/ sf_init (argc,argv); in = sf_input("in"); out = sf_output("out"); velfile = sf_input("velfile"); if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input"); if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input"); if (!sf_histfloat(in,"o1",&o1)) o1=0.; if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in vel"); if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input"); if (!sf_histfloat(in,"o2",&o2)) o2=0.; dt = d1; dx = d2; ox = o2; nx1 = n2; nt = n1; if (!sf_histint(velfile,"n1",&nz)) sf_error("No n1= in vel"); if (!sf_histfloat(velfile,"d1",&dz)) sf_error("No n1= in vel"); if (!sf_histint(velfile,"n2",&n2)) sf_error("No n2= in vel"); if (!sf_getint("iswavelet",&iswavelet)) iswavelet = 0; source_wavelet=sf_input("source_wavelet"); max_num_shot=100; ng=700; nx=n2; padt = 2; padx = 2; ntfft = padt*nt; nw=ntfft/2+1; nk = padx*nx; dw = 2*PI/ntfft/dt; dkx = 2*PI/nk/dx; sf_putint(out,"n1",nz); sf_putint(out,"n2",nx); sf_putfloat(out,"d1",dz); sf_putstring(out,"label1","z"); sf_putstring(out,"unit1","m"); sf_putstring(out,"title","migrated"); if (!sf_getfloat("fmax",&fmax)) fmax = 0.5/d1; /* max frequency to process */ if (fmax > 0.5/d1) fmax = 0.5/d1; if (!sf_getfloat("fmin",&fmin)) fmin = 0.1; /* min frequency to process */ if (!sf_getfloat("Zmax",&zmax)) zmax = (nz-1)*dz; /* max Depth to migrate */ /*define axis variables*/ dkx=(float) 2*PI/nk/dx; dw=(float) 2*PI/ntfft/dt; /*allocate memory to dynamic arrays*/ d = sf_floatalloc2(nt,nx1); shot=sf_floatalloc2(nt,ng); ds=sf_floatalloc2(nt,nx); vel = sf_floatalloc2(nz,nx); wavelet=sf_floatalloc(nt); vmig = sf_floatalloc2(nz,nx); m = sf_complexalloc2(nw,nx); ms = sf_complexalloc2(nw,nx); mr = sf_complexalloc2(nw,nx); kx= sf_floatalloc (nk); omega= sf_floatalloc (nw); in2a = sf_complexalloc(nk); in2b = sf_complexalloc(nk); n = sf_intalloc(1); M= sf_floatalloc2(nz,nx); c = sf_complexalloc(nx); cs = sf_complexalloc(nx); cr = sf_complexalloc(nx); /*read input files*/ sf_floatread(d[0],nx1*nt,in); sf_floatread(vel[0],nx*nz,velfile); /* If there is no wavelet use delta as default If there is a wavelet use it*/ if (iswavelet==0) { for (it=0; it<nt; it++) wavelet[it] = 0.0; wavelet[0]=1; } if (iswavelet==1) sf_floatread(wavelet,nt,source_wavelet); /* This part is important: we need to define the horizontal wavenumber and frequency axes right.*/ dw = 2*PI/ntfft/dt; dkx = 2*PI/nk/dx; for (iw=0;iw<nw;iw++){ omega[iw] = dw*iw; } for (ik=0;ik<nk;ik++){ if (ik<nk/2) kx[ik] = dkx*ik; else kx[ik] = -(dkx*nk - dkx*ik); } /* Define minimum and maximum frequency index to process*/ f_low = fmin; /* min frequency to process */ f_high = fmax; /* max frequency to process */ if(f_low>0){ if_low = trunc(f_low*dt*ntfft); } else{ if_low = 0; } if(f_high*dt*ntfft+1<nw){ if_high = trunc(f_high*dt*ntfft)+1; } else{ if_high = nw; } __real__ czero = 0; __imag__ czero = 0; n[0] = nk; p2a = fftwf_plan_dft(1, n, (fftwf_complex*)in2a, (fftwf_complex*)in2a, FFTW_FORWARD, FFTW_ESTIMATE); p2b = fftwf_plan_dft(1, n, (fftwf_complex*)in2b, (fftwf_complex*)in2b, FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_execute(p2a); /* FFT x to k */ fftwf_execute(p2b); /* FFT x to k */ /* Define initial migrated model and source field as zeros*/ for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) M[ix][iz] = 0.0; } for (it=0; it<nt; it++) { for (ix=0; ix<nx; ix++) ds[ix][it] = 0.0; } for (iz=0; iz<nz;iz++){ for (ix=0;ix<nx;ix++) vmig[ix][iz]=vel[ix][iz]; } /* loop over shots*/ for (ishot=0;ishot<max_num_shot;ishot++){ for (ig=0;ig<ng;ig++){ for (it=0; it<nt; it++) shot[ig][it]=d[ishot*ng+ig][it]; } for (it=0; it<nt; it++) { for (ix=0; ix<nx; ix++) ds[ix][it] = 0.0; } index=ishot*nx/max_num_shot; for (it=0; it<nt; it++) ds[index][it]=wavelet[it]; /* apply fourier transform in time direction t-x ---> w-x*/ my_forward_fft(ms,mr,shot,ds,nt,dt,nx,padt); for (iw=if_low;iw<if_high;iw++){ for (iz=0; iz<nz;iz++){ v_ave=vmig[0][iz]; my_v_ave (v_ave,vmig,iz,nx); /*Apply phase shift to source side*/ my_phase_shift(ms,czero,iw,iz,omega,kx,nk,nx,v_ave,in2a,in2b,p2a,p2b,dz,0); for (ix=0;ix<nx;ix++) { cs[ix]= in2b[ix]; } /*Apply phase shift to receiver side*/ my_phase_shift(mr,czero,iw,iz,omega,kx,nk,nx,v_ave,in2a,in2b,p2a,p2b,dz,1); for (ix=0;ix<nx;ix++) { cr[ix]= in2b[ix]; } /*Apply split step correction to source and receiver side wavefields*/ my_split_step_correction (ms,cs,vmig,v_ave,iz,dz,iw,dw,nx,0); my_split_step_correction (mr,cr,vmig,v_ave,iz,dz,iw,dw,nx,1); /* Apply cross corrolation as an imaging condition*/ for (ix=0;ix<nx;ix++){ __real__ Ls=crealf(ms[ix][iw]); __imag__ Ls=- cimagf(ms[ix][iw]); m[ix][iw]=mr[ix][iw]*Ls; } /* Update migrated model by stacking*/ for (ix=0;ix<nx;ix++) M[ix][iz]=M[ix][iz]+2*crealf(m[ix][iw]); } } fprintf(stderr,"\r progress = %6.2f%%",(float) 100*(ishot)/(max_num_shot)); } sf_floatwrite(M[0],nz*nx,out); fftwf_destroy_plan(p2a); fftwf_free(in2a); fftwf_destroy_plan(p2b); fftwf_free(in2b); exit (0); }
int main(int argc, char*argv[]) { // options float r=0.23175f; // resampling rate (output/input) float As=60.0f; // resampling filter stop-band attenuation [dB] unsigned int n=400; // number of input samples float fc=0.017f; // complex sinusoid frequency int dopt; while ((dopt = getopt(argc,argv,"hr:s:n:f:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'r': r = atof(optarg); break; case 's': As = atof(optarg); break; case 'n': n = atoi(optarg); break; case 'f': fc = atof(optarg); break; default: exit(1); } } // validate input if (n == 0) { fprintf(stderr,"error: %s, number of input samples must be greater than zero\n", argv[0]); exit(1); } else if (r <= 0.0f) { fprintf(stderr,"error: %s, resampling rate must be greater than zero\n", argv[0]); exit(1); } else if ( fabsf(log2f(r)) > 10 ) { fprintf(stderr,"error: %s, resampling rate unreasonable\n", argv[0]); exit(1); } unsigned int i; // create multi-stage arbitrary resampler object msresamp_crcf q = msresamp_crcf_create(r,As); msresamp_crcf_print(q); float delay = msresamp_crcf_get_delay(q); // number of input samples (zero-padded) unsigned int nx = n + (int)ceilf(delay) + 10; // output buffer with extra padding for good measure unsigned int ny_alloc = (unsigned int) (2*(float)nx * r); // allocation for output // allocate memory for arrays float complex x[nx]; float complex y[ny_alloc]; // generate input signal float wsum = 0.0f; for (i=0; i<nx; i++) { // compute window float w = i < n ? kaiser(i, n, 10.0f, 0.0f) : 0.0f; // apply window to complex sinusoid x[i] = cexpf(_Complex_I*2*M_PI*fc*i) * w; // accumulate window wsum += w; } // run resampler unsigned int ny; msresamp_crcf_execute(q, x, nx, y, &ny); // clean up allocated objects msresamp_crcf_destroy(q); // // analyze resulting signal // // check that the actual resampling rate is close to the target float r_actual = (float)ny / (float)nx; float fy = fc / r; // expected output frequency // run FFT and ensure that carrier has moved and that image // frequencies and distortion have been adequately suppressed unsigned int nfft = 1 << liquid_nextpow2(ny); float complex yfft[nfft]; // fft input float complex Yfft[nfft]; // fft output for (i=0; i<nfft; i++) yfft[i] = i < ny ? y[i] : 0.0f; fft_run(nfft, yfft, Yfft, LIQUID_FFT_FORWARD, 0); fft_shift(Yfft, nfft); // run FFT shift // find peak frequency float Ypeak = 0.0f; float fpeak = 0.0f; float max_sidelobe = -1e9f; // maximum side-lobe [dB] float main_lobe_width = 0.07f; // TODO: figure this out from Kaiser's equations for (i=0; i<nfft; i++) { // normalized output frequency float f = (float)i/(float)nfft - 0.5f; // scale FFT output appropriately float Ymag = 20*log10f( cabsf(Yfft[i] / (r * wsum)) ); // find frequency location of maximum magnitude if (Ymag > Ypeak || i==0) { Ypeak = Ymag; fpeak = f; } // find peak side-lobe value, ignoring frequencies // within a certain range of signal frequency if ( fabsf(f-fy) > main_lobe_width ) max_sidelobe = Ymag > max_sidelobe ? Ymag : max_sidelobe; } // print results and check frequency location printf("output results:\n"); printf(" output delay : %12.8f samples\n", delay); printf(" desired resampling rate : %12.8f\n", r); printf(" measured resampling rate : %12.8f (%u/%u)\n", r_actual, ny, nx); printf(" peak spectrum : %12.8f dB (expected 0.0 dB)\n", Ypeak); printf(" peak frequency : %12.8f (expected %-12.8f)\n", fpeak, fy); printf(" max sidelobe : %12.8f dB (expected at least %.2f dB)\n", max_sidelobe, -As); // // export results // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s: auto-generated file\n",OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n"); fprintf(fid,"delay=%f;\n", delay); fprintf(fid,"r=%12.8f;\n", r); fprintf(fid,"nx = %u;\n", nx); fprintf(fid,"x = zeros(1,nx);\n"); for (i=0; i<nx; i++) fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid,"ny = %u;\n", ny); fprintf(fid,"y = zeros(1,ny);\n"); for (i=0; i<ny; i++) fprintf(fid,"y(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); // time-domain results fprintf(fid,"\n"); fprintf(fid,"%% plot time-domain result\n"); fprintf(fid,"tx=[0:(length(x)-1)];\n"); fprintf(fid,"ty=[0:(length(y)-1)]/r-delay;\n"); fprintf(fid,"tmin = min(tx(1), ty(1) );\n"); fprintf(fid,"tmax = max(tx(end),ty(end));\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(tx,real(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,real(y),'-s','Color',[0.5 0 0], 'MarkerSize',1);\n"); fprintf(fid," legend('original','resampled','location','northeast');"); fprintf(fid," axis([tmin tmax -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('real');\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(tx,imag(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,imag(y),'-s','Color',[0 0.5 0], 'MarkerSize',1);\n"); fprintf(fid," legend('original','resampled','location','northeast');"); fprintf(fid," axis([tmin tmax -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('imag');\n"); // frequency-domain results fprintf(fid,"\n\n"); fprintf(fid,"%% plot frequency-domain result\n"); fprintf(fid,"nfft=2^nextpow2(max(nx,ny));\n"); fprintf(fid,"%% estimate PSD, normalize by array length\n"); fprintf(fid,"X=20*log10(abs(fftshift(fft(x,nfft)/length(x))));\n"); fprintf(fid,"Y=20*log10(abs(fftshift(fft(y,nfft)/length(y))));\n"); fprintf(fid,"G=max(X);\n"); fprintf(fid,"X=X-G;\n"); fprintf(fid,"Y=Y-G;\n"); fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"if r>1, fx = f/r; fy = f; %% interpolated\n"); fprintf(fid,"else, fx = f; fy = f*r; %% decimated\n"); fprintf(fid,"end;\n"); fprintf(fid,"plot(fx,X,'LineWidth',1, 'Color',[0.5 0.5 0.5],...\n"); fprintf(fid," fy,Y,'LineWidth',1.5,'Color',[0.1 0.3 0.5]);\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"xlabel('normalized frequency');\n"); fprintf(fid,"ylabel('PSD [dB]');\n"); fprintf(fid,"legend('original','resampled','location','northeast');"); fprintf(fid,"axis([-0.5 0.5 -120 20]);\n"); fclose(fid); printf("results written to %s\n",OUTPUT_FILENAME); printf("done.\n"); return 0; }
void cprint (sf_complex c) /*< print a complex number (for debugging purposes) >*/ { sf_warning("%g+%gi",crealf(c),cimagf(c)); }
// // AUTOTEST: structured dot product, odd lengths // void autotest_dotprod_cccf_struct_lengths() { float tol = 2e-6; float complex y; float complex h[35] = { 1.11555653 + 2.30658043*_Complex_I, -0.36133676 + -0.10917327*_Complex_I, 0.17714505 + -2.14631440*_Complex_I, 2.20424609 + 0.59063608*_Complex_I, -0.44699194 + 0.23369318*_Complex_I, 0.60613931 + 0.21868288*_Complex_I, -1.18746289 + -0.52159563*_Complex_I, -0.46277775 + 0.75010157*_Complex_I, 0.93796307 + 0.28608151*_Complex_I, -2.18699829 + 0.38029319*_Complex_I, 0.16145611 + 0.18343353*_Complex_I, -0.62653631 + -1.79037656*_Complex_I, -0.67042462 + 0.11044084*_Complex_I, 0.70333438 + 1.78729174*_Complex_I, -0.32923580 + 0.78514690*_Complex_I, 0.27534332 + -0.56377431*_Complex_I, 0.41492559 + 1.37176526*_Complex_I, 3.25368958 + 2.70495218*_Complex_I, 1.63002035 + -0.14193750*_Complex_I, 2.22057186 + 0.55056461*_Complex_I, 1.40896777 + 0.80722903*_Complex_I, -0.22334033 + -0.14227395*_Complex_I, -1.48631186 + 0.53610531*_Complex_I, -1.91632185 + 0.88755083*_Complex_I, -0.52054895 + -0.35572001*_Complex_I, -1.56515607 + -0.41448794*_Complex_I, -0.91107117 + 0.17059659*_Complex_I, -0.77007659 + 2.73381816*_Complex_I, -0.46645585 + 0.38994666*_Complex_I, 0.80317663 + -0.41756968*_Complex_I, 0.26992512 + 0.41828145*_Complex_I, -0.72456446 + 1.25002030*_Complex_I, 1.19573306 + 0.98449546*_Complex_I, 1.42491943 + -0.55426305*_Complex_I, 1.08243614 + 0.35774368*_Complex_I, }; float complex x[35] = { -0.82466736 + -1.39329228*_Complex_I, -1.46176052 + -1.96218827*_Complex_I, -1.28388174 + -0.07152934*_Complex_I, -0.51910014 + -0.37915971*_Complex_I, -0.65964708 + -0.98417534*_Complex_I, -1.40213479 + -0.82198463*_Complex_I, 0.86051446 + 0.97926463*_Complex_I, 0.26257342 + 0.76586696*_Complex_I, 0.72174183 + -1.89884636*_Complex_I, -0.26018863 + 1.06920599*_Complex_I, 0.57949117 + -0.77431546*_Complex_I, 0.84635184 + -0.81123009*_Complex_I, -1.12637629 + -0.42027412*_Complex_I, -1.04214881 + 0.90519721*_Complex_I, 0.54458433 + -1.03487314*_Complex_I, -0.17847893 + 2.20358978*_Complex_I, 0.19642532 + -0.07449796*_Complex_I, -1.84958229 + 0.13218920*_Complex_I, -1.49042886 + 0.81610408*_Complex_I, -0.27466940 + -1.48438409*_Complex_I, 0.29239375 + 0.72443343*_Complex_I, -1.20243456 + -2.77032750*_Complex_I, -0.41784260 + 0.77455254*_Complex_I, 0.37737465 + -0.52426993*_Complex_I, -1.25500377 + 1.76270122*_Complex_I, 1.55976056 + -1.18189171*_Complex_I, -0.05111343 + -1.18849396*_Complex_I, -1.92966664 + 0.66504899*_Complex_I, -2.82387897 + 1.41128242*_Complex_I, -1.48171326 + -0.03347470*_Complex_I, 0.38047273 + -1.40969799*_Complex_I, 1.71995272 + 0.00298203*_Complex_I, 0.56040910 + -0.12713027*_Complex_I, -0.46653022 + -0.65450499*_Complex_I, 0.15515755 + 1.58944030*_Complex_I, }; float complex v32 = -11.5100903519506 - 15.3575526884014*_Complex_I; float complex v33 = -10.7148314918614 - 14.9578463360225*_Complex_I; float complex v34 = -11.7423673921916 - 15.6318827515320*_Complex_I; float complex v35 = -12.1430314741466 - 13.8559085000689*_Complex_I; // dotprod_cccf dp; // n = 32 dp = dotprod_cccf_create(h,32); dotprod_cccf_execute(dp, x, &y); CONTEND_DELTA(y, v32, tol); dotprod_cccf_destroy(dp); if (liquid_autotest_verbose) { printf(" dotprod-cccf-32 : %12.8f + j%12.8f (expected %12.8f + j%12.8f)\n", crealf(y), cimagf(y), crealf(v32), cimagf(v32)); } // n = 33 dp = dotprod_cccf_create(h,33); dotprod_cccf_execute(dp, x, &y); CONTEND_DELTA(y, v33, tol); dotprod_cccf_destroy(dp); if (liquid_autotest_verbose) { printf(" dotprod-cccf-33 : %12.8f + j%12.8f (expected %12.8f + j%12.8f)\n", crealf(y), cimagf(y), crealf(v33), cimagf(v33)); } // n = 34 dp = dotprod_cccf_create(h,34); dotprod_cccf_execute(dp, x, &y); CONTEND_DELTA(y, v34, tol); dotprod_cccf_destroy(dp); if (liquid_autotest_verbose) { printf(" dotprod-cccf-34 : %12.8f + j%12.8f (expected %12.8f + j%12.8f)\n", crealf(y), cimagf(y), crealf(v34), cimagf(v34)); } // n = 35 dp = dotprod_cccf_create(h,35); dotprod_cccf_execute(dp, x, &y); CONTEND_DELTA(y, v35, tol); dotprod_cccf_destroy(dp); if (liquid_autotest_verbose) { printf(" dotprod-cccf-35 : %12.8f + j%12.8f (expected %12.8f + j%12.8f)\n", crealf(y), cimagf(y), crealf(v35), cimagf(v35)); } }
int lrosfor2(sf_complex ***wavfld, float **sill, sf_complex **rcd, bool verb, sf_complex **lt, sf_complex **rt, int m2, geopar geop, sf_complex *ww, float *rr, int pad1, bool illum) /*< low-rank one-step forward modeling >*/ { int it,iz,im,ik,ix,i,j; /* index variables */ int nxb,nzb,gpz,gpx,gpl,snpint,wfit; int nt,nz,nx, nk, nz2, nx2, nzx2; float dt; sf_complex c; sf_complex *cwave, *cwavem; sf_complex **wave, *curr; #ifdef _OPENMP int nth; #endif nx = geop->nx; nz = geop->nz; nxb = geop->nxb; nzb = geop->nzb; /* dx = geop->dx; dz = geop->dz; */ /* spx = geop->spx; spz = geop->spz; */ gpz = geop->gpz; gpx = geop->gpx; gpl = geop->gpl; snpint = geop->snpint; nt = geop->nt; dt = geop->dt; #ifdef _OPENMP #pragma omp parallel { nth = omp_get_num_threads(); } sf_warning(">>>> Using %d threads <<<<<", nth); #endif /*Matrix dimensions*/ 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); 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 (illum) { #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for (ix=0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { sill[ix][iz] = 0.f; } } } /*Main loop*/ wfit = 0; for (it = 0; it < nt; it++) { if (verb) sf_warning("Forward source it=%d/%d;", it, nt-1); /*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 */ if ((it*dt)<=geop->trunc) { #ifdef SF_HAS_COMPLEX_H c = ww[it] * rr[i]; // source term #else c = sf_crmul(ww[it], rr[i]); // source term #endif } else { c = sf_cmplx(0.,0.); } for (im = 0; im < m2; im++) { #ifdef SF_HAS_COMPLEX_H c += lt[im][i]*wave[im][j]; #else c = sf_cadd(c,sf_cmul(lt[im][i], wave[im][j])); #endif } curr[j] = c; } } #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]; } 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 */ wavfld[wfit][ix][iz] = curr[j]; if (illum) sill[ix][iz] += pow(hypotf(crealf(curr[j]),cimagf(curr[j])),2); } } wfit++; } } /*Main loop*/ if (verb) sf_warning("."); cfft2_finalize(); return wfit; }