Пример #1
0
float
cargf(float complex z)
{

	return (atan2f(cimagf(z), crealf(z)));
}
Пример #2
0
     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);
 
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
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 );
    }
}
Пример #6
0
float (cimagf)(float complex z)
{
	return cimagf(z);
}
Пример #7
0
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;

}
Пример #9
0
Файл: csinf.c Проект: KGG814/AOS
float complex csinf(float complex z)
{
	z = csinhf(cpackf(-cimagf(z), crealf(z)));
	return cpackf(cimagf(z), -crealf(z));
}
Пример #10
0
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;
}
Пример #12
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(&copy));
  }
  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(&copy));
  }

  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(&copy));
  }
  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(&copy));
  }

  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(&copy));

  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(&copy));

  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;
}
Пример #13
0
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);
}
Пример #14
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;
}
Пример #15
0
void cprint (sf_complex c)
/*< print a complex number (for debugging purposes) >*/
{
    sf_warning("%g+%gi",crealf(c),cimagf(c));
}
Пример #16
0
// 
// 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));
    }
}
Пример #17
0
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;
}