示例#1
0
文件: fdmig.c 项目: 1014511134/src
void fdmig (sf_complex **dat /* input data */, 
	    float **img         /* output image */, 
	    sf_file movie       /* save movie (if not NULL) */)
/*< Migrate >*/
{
    int iz, ix, iw;
    float omega;
    sf_complex aa, bb, shift; 

    for (iz=0; iz < nz; iz++) { 
	for (ix=0; ix < nx; ix++) {
	    img[iz][ix] = 0.;
	    cu[ix] = sf_cmplx(0.,0.);
	}
	if (NULL != movie) sf_complexwrite(cu,nx,movie);
    }

    
    for (iw=1; iw < nw; iw++) { 
	omega = dw*iw;
	aa = sf_cmplx(beta*omega,alpha);
#ifdef SF_HAS_COMPLEX_H
	if (hi) aa += alpha/omega; /* add the third derivative term */	
	bb = omega - 2.*aa;
#else
	if (hi) aa.r += alpha/omega; /* add the third derivative term */
	bb.r = omega - 2.*aa.r;
	bb.i = - 2.*aa.i;
#endif

	ctridiagonal_const_define (slv,conjf(bb),conjf(aa));
	    
	for (ix=0; ix < nx; ix++) {
	    cu[ix] = dat[iw][ix];
	}

	for (iz=0; iz < nz; iz++) {
	    cd[0] = sf_cmplx(0.,0.);      
	    for (ix=1; ix < nx-1; ix++) {
#ifdef SF_HAS_COMPLEX_H
		cd[ix] = aa*(cu[ix+1] + cu[ix-1]) + bb*cu[ix];
#else
		cd[ix] = sf_cadd(sf_cmul(aa,sf_cadd(cu[ix+1],cu[ix-1])),
				 sf_cmul(bb,cu[ix]));
#endif
	    }
	    cd[nx-1] = sf_cmplx(0.,0.);
	    
	    ctridiagonal_solve (slv, cd);
	    
	    for (ix=0; ix < nx; ix++) {
		shift = sf_cmplx(cosf(omega),sinf(omega));
#ifdef SF_HAS_COMPLEX_H
		cu[ix] = cd[ix]*shift;
#else
		cu[ix] = sf_cmul(cd[ix],shift);
#endif
		img[iz][ix] += crealf(cu[ix]);
	    }

	    if (NULL != movie) sf_complexwrite(cu,nx,movie);
	}
    }
}
示例#2
0
/***************************************************************************//**
 * @ingroup CORE_PLASMA_Complex32_t
 *******************************************************************************
 *
 *  Purpose
 *  =======
 *
 *  CORE_clarfx2c applies a complex elementary reflector H to a diagonal corner 
 *  C=[C1, C2, C3], from both the left and the right side. C = H * C * H.
 *  It is used in the case of general matrices, where it create a nnz at the 
 *  NEW_NNZ position, then it eliminate it and update the reflector V and TAU.
 *  If PlasmaLower, a left apply is followed by a right apply.
 *  If PlasmaUpper, a right apply is followed by a left apply.
 *  H is represented in the form
 *   
 *  This routine is a special code for a corner C diagonal block  C1  NEW_NNZ
 *                                                                C2  C3
 *   
 *
 *        H = I - tau * v * v'
 *
 *  where tau is a complex scalar and v is a complex vector.
 *
 *  If tau = 0, then H is taken to be the unit matrix
 *
 *  This version uses inline code if H has order < 11.
 *
 *  Arguments
 *  =========
 *
 * @param[in] uplo
 *          = PlasmaUpper: Upper triangle of A is stored;
 *          = PlasmaLower: Lower triangle of A is stored.
 *
 * @param[in, out] V
 *          On entry, the float complex V in the representation of H.
 *          On exit, the float complex V in the representation of H, 
 *          updated by the elimination of the NEW_NNZ created by the 
 *          left apply in case of PlasmaLower or the right apply in 
 *          case of PlasmaUpper.
 *
 * @param[in] TAU
 *          On entry, the value tau in the representation of H.
 *          On exit, the value tau in the representation of H, 
 *          updated by the elimination of the NEW_NNZ created by the 
 *          left apply in case of PlasmaLower or the right apply in 
 *          case of PlasmaUpper.
 *
 * @param[in,out] C1
 *          On entry, the element C1.
 *          On exit, C1 is overwritten by the result H * C * H.
 *
 * @param[in,out] C2
 *          On entry, the element C2.
 *          On exit, C2 is overwritten by the result H * C * H.
  *
 * @param[in,out] C3
 *          On entry, the element C3.
 *          On exit, C3 is overwritten by the result H * C * H.
 *
 *  =====================================================================
 *
 * @return
 *          \retval PLASMA_SUCCESS successful exit
 *          \retval <0 if -i, the i-th argument had an illegal value
 *
 ******************************************************************************/
int 
CORE_clarfx2ce(PLASMA_enum uplo,
               PLASMA_Complex32_t *V,
               PLASMA_Complex32_t *TAU,
               PLASMA_Complex32_t *C1,
               PLASMA_Complex32_t *C2,
               PLASMA_Complex32_t *C3)
{
    PLASMA_Complex32_t T2, SUM, TEMP, VIN, TAUIN;

    /* Quick return */
    if (*TAU == (PLASMA_Complex32_t)0.0)
        return PLASMA_SUCCESS;

    /*
     *        Special code for a diagonal block  C1
     *                                           C2  C3
     */
    if(uplo==PlasmaLower){    
        /*
         *  Do the corner for the lower case BIDIAG ==> Left then will
         *  create a new nnz. eliminate it and modify V TAU and then
         *  Right L and R for the 2x2 corner
         *             C(N-1, N-1)  C(N-1,N)        C1  TEMP 
         *             C(N  , N-1)  C(N  ,N)        C2  C3 
         */
        VIN   = *V;
        TAUIN = conjf(*TAU);
        /*  Left 1 ==> C1 */
        /*             C2 */
        VIN  = conjf(VIN);
        T2   = TAUIN * conjf(VIN);
        SUM  = *C1   + VIN*(*C2);
        *C1  = *C1   - SUM*TAUIN;
        *C2  = *C2   - SUM*T2;
        /*   new nnz at TEMP and update C3 */
        SUM  =        VIN * (*C3);
        TEMP =      - SUM * TAUIN;
        *C3  = *C3  - SUM * T2;
        /*  generate Householder to annihilate the nonzero created at TEMP */
        *V    = TEMP;
        LAPACKE_clarfg_work( 2, C1, V, 1, TAU);
        VIN   = conjf(*V);
        TAUIN = conjf(*TAU);
        /*  Right 1 ==> C2 C3 */
        /* VIN     = VIN */
        T2  = TAUIN * conjf(VIN);
        SUM = *C2   + VIN*(*C3);
        *C2 = *C2   - SUM*TAUIN;
        *C3 = *C3   - SUM*T2;
    }else if(uplo==PlasmaUpper){ 
        /*  
         * Do the corner for the upper case BIDIAG ==> Right then will
        *  create a new nnz. eliminate it and modify V TAU and then
        *  Left
        *             C(N-1, N-1)  C(N-1,N)        C1    C2 
        *             C(N  , N-1)  C(N  ,N)        TEMP  C3 
        *  For Left : use conjf(TAU) and V. 
        *  For Right: use conjf(TAU) and conjf(V) as input. 
        */
        VIN   = conjf(*V);
        TAUIN = conjf(*TAU);
        /*  Right 1 ==> C1 C2 */
        /* VIN     = VIN */
        T2   = TAUIN*conjf(VIN);
        SUM  = *C1  + VIN*(*C2);
        *C1  = *C1  - SUM*TAUIN;
        *C2  = *C2  - SUM*T2;
        /*   new nnz at TEMP and update C3 */
        SUM  =        VIN * (*C3);
        TEMP =      - SUM * TAUIN;
        *C3  = *C3  - SUM * T2;
        /*  generate Householder to annihilate the nonzero created at TEMP */
        *V    = TEMP;
        LAPACKE_clarfg_work( 2, C1, V, 1, TAU);
        VIN   = *V;
        TAUIN = conjf(*TAU);
        /*  apply from the Left using the NEW V TAU to the remaining 2 elements [C2 C3] */
        /*  Left 2 ==> C2 */
        /*             C3 */
        VIN = conjf(VIN);
        T2  = TAUIN*conjf(VIN);
        SUM = *C2 + VIN*(*C3);
        *C2 = *C2 - SUM*TAUIN;
        *C3 = *C3 - SUM*T2;
    }
    return PLASMA_SUCCESS;
}
示例#3
0
int main(int argc, char*argv[])
{
    // options
    unsigned int m           =   3;     // number of bits/symbol
    unsigned int k           =   0;     // filter samples/symbol
    unsigned int num_symbols = 200;     // number of data symbols
    float        SNRdB       = 40.0f;   // signal-to-noise ratio [dB]
    float        cfo         = 0.0f;    // carrier frequency offset
    float        cpo         = 0.0f;    // carrier phase offset
    float        tau         = 0.0f;    // fractional symbol timing offset
    float        bandwidth   = 0.20;    // frequency spacing

    int dopt;
    while ((dopt = getopt(argc,argv,"hm:k:b:n:s:F:P:T:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                      return 0;
        case 'm': m           = atoi(optarg);   break;
        case 'k': k           = atoi(optarg);   break;
        case 'b': bandwidth   = atof(optarg);   break;
        case 'n': num_symbols = atoi(optarg);   break;
        case 's': SNRdB       = atof(optarg);   break;
        case 'F': cfo         = atof(optarg);   break;
        case 'P': cpo         = atof(optarg);   break;
        case 'T': tau         = atof(optarg);   break;
        default:
            exit(1);
        }
    }

    unsigned int i;
    unsigned int j;

    // derived values
    if (k == 0) k = 2 << m; // set samples per symbol if not otherwise specified
    unsigned int num_samples = k*num_symbols;
    unsigned int M           = 1 << m;
    float        nstd        = powf(10.0f, -SNRdB/20.0f);
    float        M2          = 0.5f*(float)(M-1);

    // validate input
    if (k < M) {
        fprintf(stderr,"errors: %s, samples/symbol must be at least modulation size (M=%u)\n", __FILE__,M);
        exit(1);
    } else if (k > 2048) {
        fprintf(stderr,"errors: %s, samples/symbol exceeds maximum (2048)\n", __FILE__);
        exit(1);
    } else if (M > 1024) {
        fprintf(stderr,"errors: %s, modulation size (M=%u) exceeds maximum (1024)\n", __FILE__, M);
        exit(1);
    } else if (bandwidth <= 0.0f || bandwidth >= 0.5f) {
        fprintf(stderr,"errors: %s, bandwidht must be in (0,0.5)\n", __FILE__);
        exit(1);
    }

    // compute demodulation FFT size such that FFT output bin frequencies are
    // as close to modulated frequencies as possible
    unsigned int K = 0;                 // demodulation FFT size
    float        df = bandwidth / M2;   // frequency spacing
    float        err_min = 1e9f;
    unsigned int K_min = k;                     // minimum FFT size
    unsigned int K_max = k*4 < 16 ? 16 : k*4;   // maximum FFT size
    unsigned int K_hat;
    for (K_hat=K_min; K_hat<=K_max; K_hat++) {
        // compute candidate FFT size
        float v     = 0.5f*df * (float)K_hat;   // bin spacing
        float err = fabsf( roundf(v) - v );     // fractional bin spacing

        // print results
        printf("  K_hat = %4u : v = %12.8f, err=%12.8f %s\n", K_hat, v, err, err < err_min ? "*" : "");

        // save best result
        if (K_hat==K_min || err < err_min) {
            K = K_hat;
            err_min = err;
        }

        // perfect match; no need to continue searching
        if (err < 1e-6f)
            break;
    }

    // arrays
    unsigned int  sym_in[num_symbols];      // input symbols
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    unsigned int  sym_out[num_symbols];     // output symbols

    // determine demodulation mapping between tones and frequency bins
    // TODO: use gray coding
    unsigned int demod_map[M];
    for (i=0; i<M; i++) {
        // print frequency bins
        float freq = ((float)i - M2) * bandwidth / M2;
        float idx  = freq * (float)K;
        unsigned int index = (unsigned int) (idx < 0 ? roundf(idx + K) : roundf(idx));
        demod_map[i] = index;
        printf("  s=%3u, f = %12.8f, index=%3u\n", i, freq, index);
    }

    // check for uniqueness
    for (i=1; i<M; i++) {
        if (demod_map[i] == demod_map[i-1]) {
            fprintf(stderr,"warning: demod map is not unique; consider increasing bandwidth\n");
            break;
        }
    }

    // generate message symbols and modulate
    // TODO: use gray coding
    for (i=0; i<num_symbols; i++) {
        // generate random symbol
        sym_in[i] = rand() % M;

        // compute frequency
        float dphi = 2*M_PI*((float)sym_in[i] - M2) * bandwidth / M2;

        // generate random phase
        float phi  = randf() * 2 * M_PI;
        
        // modulate symbol
        for (j=0; j<k; j++)
            x[i*k+j] = cexpf(_Complex_I*phi + _Complex_I*j*dphi);
    }

    // push through channel
    for (i=0; i<num_samples; i++)
        y[i] = x[i] + nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2;

#if 0
    // demodulate signal: high SNR method
    float complex buf_time[k];
    unsigned int n = 0;
    j = 0;
    for (i=0; i<num_samples; i++) {
        // start filling time buffer with samples (assume perfect symbol timing)
        buf_time[n++] = y[i];

        // demodulate symbol
        if (n==k) {
            // reset counter
            n = 0;

            // estimate frequency
            float complex metric = 0;
            unsigned int s;
            for (s=1; s<k; s++)
                metric += buf_time[s] * conjf(buf_time[s-1]);
            float dphi_hat = cargf(metric) / (2*M_PI);
            unsigned int v=( (unsigned int) roundf(dphi_hat*M2/bandwidth + M2) ) % M;
            sym_out[j++] = v;
            printf("%3u : %12.8f : %u\n", j, dphi_hat, v);
        }
    }
#else
    // demodulate signal: least-squares method
    float complex buf_time[K];
    float complex buf_freq[K];
    fftplan fft = fft_create_plan(K, buf_time, buf_freq, LIQUID_FFT_FORWARD, 0);

    for (i=0; i<K; i++)
        buf_time[i] = 0.0f;
    unsigned int n = 0;
    j = 0;
    for (i=0; i<num_samples; i++) {
        // start filling time buffer with samples (assume perfect symbol timing)
        buf_time[n++] = y[i];

        // demodulate symbol
        if (n==k) {
            // reset counter
            n = 0;

            // compute transform, storing result in 'buf_freq'
            fft_execute(fft);

            // find maximum by looking at particular bins
            float vmax = 0;
            unsigned int s;
            unsigned int s_opt = 0;
            for (s=0; s<M; s++) {
                float v = cabsf( buf_freq[demod_map[s]] );
                if (s==0 || v > vmax) {
                    s_opt = s;
                    vmax  =v;
                }
            }

            // save best result
            sym_out[j++] = s_opt;
        }
    }
    // destroy fft object
    fft_destroy_plan(fft);
#endif

    // count errors
    unsigned int num_symbol_errors = 0;
    for (i=0; i<num_symbols; i++)
        num_symbol_errors += (sym_in[i] == sym_out[i]) ? 0 : 1;

    printf("symbol errors: %u / %u\n", num_symbol_errors, num_symbols);

    // compute power spectral density of received signal
    unsigned int nfft = 1200;
    float psd[nfft];
    spgramcf_estimate_psd(nfft, y, num_samples, psd);

    // 
    // export results
    //
    
    // truncate to at most 10 symbols
    if (num_symbols > 10)
        num_symbols = 10;
    num_samples = k*num_symbols;
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"M = %u;\n", M);
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"nfft        = %u;\n", nfft);

    fprintf(fid,"x   = zeros(1,num_samples);\n");
    fprintf(fid,"y   = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i]));
        fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i]));
    }
    // save power spectral density
    fprintf(fid,"psd = zeros(1,nfft);\n");
    for (i=0; i<nfft; i++)
        fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]);

    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"i = 1:k:num_samples;\n");
    fprintf(fid,"figure;\n");

    // plot time signal
    fprintf(fid,"subplot(2,1,1),\n");
    fprintf(fid,"hold on;\n");
    fprintf(fid,"  plot(t,real(y),'-', 'Color',[0 0.3 0.5]);\n");
    fprintf(fid,"  plot(t,imag(y),'-', 'Color',[0 0.5 0.3]);\n");
    fprintf(fid,"hold off;\n");
    fprintf(fid,"ymax = ceil(max(abs(y))*5)/5;\n");
    fprintf(fid,"axis([0 num_symbols -ymax ymax]);\n");
    fprintf(fid,"xlabel('time');\n");
    fprintf(fid,"ylabel('x(t)');\n");
    fprintf(fid,"grid on;\n");

    // plot PSD
    fprintf(fid,"subplot(2,1,2),\n");
    fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"plot(f,psd,'LineWidth',1.5,'Color',[0.5 0 0]);\n");
    fprintf(fid,"axis([-0.5 0.5 -40 40]);\n");
    fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"ylabel('PSD [dB]');\n");
    fprintf(fid,"grid on;\n");

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);

    return 0;
}
示例#4
0
int main(int argc, char*argv[]) {
    // options
    unsigned int k  = 8;        // filter samples/symbol
    unsigned int bps= 1;        // number of bits/symbol
    float h         = 0.5f;     // modulation index (h=1/2 for MSK)
    unsigned int num_data_symbols = 20; // number of data symbols
    float SNRdB     = 80.0f;    // signal-to-noise ratio [dB]
    float cfo       = 0.0f;     // carrier frequency offset
    float cpo       = 0.0f;     // carrier phase offset
    float tau       = 0.0f;     // fractional symbol offset
    enum {
        TXFILT_SQUARE=0,
        TXFILT_RCOS_FULL,
        TXFILT_RCOS_HALF,
        TXFILT_GMSK,
    } tx_filter_type = TXFILT_SQUARE;
    float gmsk_bt = 0.35f;              // GMSK bandwidth-time factor

    int dopt;
    while ((dopt = getopt(argc,argv,"ht:k:b:H:B:n:s:F:P:T:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                         return 0;
        case 't':
            if (strcmp(optarg,"square")==0) {
                tx_filter_type = TXFILT_SQUARE;
            } else if (strcmp(optarg,"rcos-full")==0) {
                tx_filter_type = TXFILT_RCOS_FULL;
            } else if (strcmp(optarg,"rcos-half")==0) {
                tx_filter_type = TXFILT_RCOS_HALF;
            } else if (strcmp(optarg,"gmsk")==0) {
                tx_filter_type = TXFILT_GMSK;
            } else {
                fprintf(stderr,"error: %s, unknown filter type '%s'\n", argv[0], optarg);
                exit(1);
            }
            break;
        case 'k': k = atoi(optarg);                break;
        case 'b': bps = atoi(optarg);              break;
        case 'H': h = atof(optarg);                break;
        case 'B': gmsk_bt = atof(optarg);          break;
        case 'n': num_data_symbols = atoi(optarg); break;
        case 's': SNRdB = atof(optarg);            break;
        case 'F': cfo   = atof(optarg);            break;
        case 'P': cpo   = atof(optarg);            break;
        case 'T': tau   = atof(optarg);            break;
        default:
            exit(1);
        }
    }

    unsigned int i;

    // derived values
    unsigned int num_symbols = num_data_symbols;
    unsigned int num_samples = k*num_symbols;
    unsigned int M = 1 << bps;              // constellation size
    float nstd = powf(10.0f, -SNRdB/20.0f);

    // arrays
    unsigned char sym_in[num_symbols];      // input symbols
    float phi[num_samples];                 // transmitted phase
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    float complex z[num_samples];           // output...
    //unsigned char sym_out[num_symbols];     // output symbols

    unsigned int ht_len = 0;
    unsigned int tx_delay = 0;
    float * ht = NULL;
    switch (tx_filter_type) {
    case TXFILT_SQUARE:
        // regular MSK
        ht_len = k;
        tx_delay = 1;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = h * M_PI / (float)k;
        break;
    case TXFILT_RCOS_FULL:
        // full-response raised-cosine pulse
        ht_len = k;
        tx_delay = 1;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = h * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)ht_len));
        break;
    case TXFILT_RCOS_HALF:
        // partial-response raised-cosine pulse
        ht_len = 3*k;
        tx_delay = 2;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = 0.0f;
        for (i=0; i<2*k; i++)
            ht[i+k/2] = h * 0.5f * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)(2*k)));
        break;
    case TXFILT_GMSK:
        ht_len = 2*k*3+1+k;
        tx_delay = 4;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = 0.0f;
        liquid_firdes_gmsktx(k,3,gmsk_bt,0.0f,&ht[k/2]);
        for (i=0; i<ht_len; i++)
            ht[i] *= h * 2.0f / (float)k;
        break;
    default:
        fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]);
        exit(1);
    }
    for (i=0; i<ht_len; i++)
        printf("ht(%3u) = %12.8f;\n", i+1, ht[i]);
    firinterp_rrrf interp_tx = firinterp_rrrf_create(k, ht, ht_len);

    // generate symbols and interpolate
    // phase-accumulating filter (trapezoidal integrator)
    float b[2] = {0.5f,  0.5f};
    if (tx_filter_type == TXFILT_SQUARE) {
        // square filter: rectangular integration with one sample of delay
        b[0] = 0.0f;
        b[1] = 1.0f;
    }
    float a[2] = {1.0f, -1.0f};
    iirfilt_rrrf integrator = iirfilt_rrrf_create(b,2,a,2);
    float theta = 0.0f;
    for (i=0; i<num_symbols; i++) {
        sym_in[i] = rand() % M;
        float v = 2.0f*sym_in[i] - (float)(M-1);    // +/-1, +/-3, ... +/-(M-1)
        firinterp_rrrf_execute(interp_tx, v, &phi[k*i]);

        // accumulate phase
        unsigned int j;
        for (j=0; j<k; j++) {
            iirfilt_rrrf_execute(integrator, phi[i*k+j], &theta);
            x[i*k+j] = cexpf(_Complex_I*theta);
        }
    }
    iirfilt_rrrf_destroy(integrator);

    // push through channel
    for (i=0; i<num_samples; i++) {
        // add carrier frequency/phase offset
        y[i] = x[i]*cexpf(_Complex_I*(cfo*i + cpo));

        // add noise
        y[i] += nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2;
    }
    
    // create decimator
    unsigned int m = 3;
    float bw = 0.0f;
    float beta = 0.0f;
    firfilt_crcf decim_rx = NULL;
    switch (tx_filter_type) {
    case TXFILT_SQUARE:
        //bw = 0.9f / (float)k;
        bw = 0.4f;
        decim_rx = firfilt_crcf_create_kaiser(2*k*m+1, bw, 60.0f, 0.0f);
        firfilt_crcf_set_scale(decim_rx, 2.0f * bw);
        break;
    case TXFILT_RCOS_FULL:
        if (M==2) {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.5f,0);
            firfilt_crcf_set_scale(decim_rx, 1.33f / (float)k);
        } else {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.9f,0);
            firfilt_crcf_set_scale(decim_rx, 3.25f / (float)k);
        }
        break;
    case TXFILT_RCOS_HALF:
        if (M==2) {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.3f,0);
            firfilt_crcf_set_scale(decim_rx, 1.10f / (float)k);
        } else {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.27f,0);
            firfilt_crcf_set_scale(decim_rx, 2.90f / (float)k);
        }
        break;
    case TXFILT_GMSK:
        bw = 0.5f / (float)k;
        // TODO: figure out beta value here
        beta = (M == 2) ? 0.8*gmsk_bt : 1.0*gmsk_bt;
        decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,beta,0);
        firfilt_crcf_set_scale(decim_rx, 2.0f * bw);
        break;
    default:
        fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]);
        exit(1);
    }
    printf("bw = %f\n", bw);

    // run receiver
    unsigned int n=0;
    unsigned int num_errors = 0;
    unsigned int num_symbols_checked = 0;
    float complex z_prime = 0.0f;
    for (i=0; i<num_samples; i++) {
        // push through filter
        firfilt_crcf_push(decim_rx, y[i]);
        firfilt_crcf_execute(decim_rx, &z[i]);

        // decimate output
        if ( (i%k)==0 ) {
            // compute instantaneous frequency scaled by modulation index
            float phi_hat = cargf(conjf(z_prime) * z[i]) / (h * M_PI);

            // estimate transmitted symbol
            float v = (phi_hat + (M-1.0))*0.5f;
            unsigned int sym_out = ((int) roundf(v)) % M;

            // save current point
            z_prime = z[i];

            // print result to screen
            printf("%3u : %12.8f + j%12.8f, <f=%8.4f : %8.4f> (%1u)",
                    n, crealf(z[i]), cimagf(z[i]), phi_hat, v, sym_out);
            if (n >= m+tx_delay) {
                num_errors += (sym_out == sym_in[n-m-tx_delay]) ? 0 : 1;
                num_symbols_checked++;
                printf(" (%1u)\n", sym_in[n-m-tx_delay]);
            } else {
                printf("\n");
            }
            n++;
        }
    }

    // print number of errors
    printf("errors : %3u / %3u\n", num_errors, num_symbols_checked);

    // destroy objects
    firinterp_rrrf_destroy(interp_tx);
    firfilt_crcf_destroy(decim_rx);

    // compute power spectral density of transmitted signal
    unsigned int nfft = 1024;
    float psd[nfft];
    spgramcf periodogram = spgramcf_create_kaiser(nfft, nfft/2, 8.0f);
    spgramcf_estimate_psd(periodogram, y, num_samples, psd);
    spgramcf_destroy(periodogram);

    // 
    // export results
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"h = %f;\n", h);
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"nfft        = %u;\n", nfft);
    fprintf(fid,"delay       = %u; %% receive filter delay\n", tx_delay);

    fprintf(fid,"x   = zeros(1,num_samples);\n");
    fprintf(fid,"y   = zeros(1,num_samples);\n");
    fprintf(fid,"z   = zeros(1,num_samples);\n");
    fprintf(fid,"phi = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i]));
        fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i]));
        fprintf(fid,"z(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(z[i]), cimagf(z[i]));
        fprintf(fid,"phi(%4u) = %12.8f;\n", i+1, phi[i]);
    }
    // save PSD
    fprintf(fid,"psd = zeros(1,nfft);\n");
    for (i=0; i<nfft; i++)
        fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]);

    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"i = 1:k:num_samples;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"subplot(3,4,1:3);\n");
    fprintf(fid,"  plot(t,real(x),'-', t(i),real(x(i)),'bs','MarkerSize',4,...\n");
    fprintf(fid,"       t,imag(x),'-', t(i),imag(x(i)),'gs','MarkerSize',4);\n");
    fprintf(fid,"  axis([0 num_symbols -1.2 1.2]);\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('x(t)');\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,4,5:7);\n");
    fprintf(fid,"  plot(t-delay,real(z),'-', t(i)-delay,real(z(i)),'bs','MarkerSize',4,...\n");
    fprintf(fid,"       t-delay,imag(z),'-', t(i)-delay,imag(z(i)),'gs','MarkerSize',4);\n");
    fprintf(fid,"  axis([0 num_symbols -1.2 1.2]);\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('\"matched\" filter output');\n");
    fprintf(fid,"  grid on;\n");
    // plot I/Q constellations
    fprintf(fid,"subplot(3,4,4);\n");
    fprintf(fid,"  plot(real(y),imag(y),'-',real(y(i)),imag(y(i)),'rs','MarkerSize',3);\n");
    fprintf(fid,"  xlabel('I');\n");
    fprintf(fid,"  ylabel('Q');\n");
    fprintf(fid,"  axis([-1 1 -1 1]*1.2);\n");
    fprintf(fid,"  axis square;\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,4,8);\n");
    fprintf(fid,"  plot(real(z),imag(z),'-',real(z(i)),imag(z(i)),'rs','MarkerSize',3);\n");
    fprintf(fid,"  xlabel('I');\n");
    fprintf(fid,"  ylabel('Q');\n");
    fprintf(fid,"  axis([-1 1 -1 1]*1.2);\n");
    fprintf(fid,"  axis square;\n");
    fprintf(fid,"  grid on;\n");
    // plot PSD
    fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"subplot(3,4,9:12);\n");
    fprintf(fid,"  plot(f,psd,'LineWidth',1.5);\n");
    fprintf(fid,"  axis([-0.5 0.5 -40 20]);\n");
    fprintf(fid,"  xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"  ylabel('PSD [dB]');\n");
    fprintf(fid,"  grid on;\n");

#if 0
    fprintf(fid,"figure;\n");
    fprintf(fid,"  %% compute instantaneous received frequency\n");
    fprintf(fid,"  freq_rx = arg( conj(z(:)) .* circshift(z(:),-1) )';\n");
    fprintf(fid,"  freq_rx(1:(k*delay)) = 0;\n");
    fprintf(fid,"  freq_rx(end) = 0;\n");
    fprintf(fid,"  %% compute instantaneous tx/rx phase\n");
    if (tx_filter_type == TXFILT_SQUARE) {
        fprintf(fid,"  theta_tx = filter([0 1],[1 -1],phi)/(h*pi);\n");
        fprintf(fid,"  theta_rx = filter([0 1],[1 -1],freq_rx)/(h*pi);\n");
    } else {
        fprintf(fid,"  theta_tx = filter([0.5 0.5],[1 -1],phi)/(h*pi);\n");
        fprintf(fid,"  theta_rx = filter([0.5 0.5],[1 -1],freq_rx)/(h*pi);\n");
    }
    fprintf(fid,"  %% plot instantaneous tx/rx phase\n");
    fprintf(fid,"  plot(t,      theta_tx,'-b', t(i),      theta_tx(i),'sb',...\n");
    fprintf(fid,"       t-delay,theta_rx,'-r', t(i)-delay,theta_rx(i),'sr');\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('instantaneous phase/(h \\pi)');\n");
    fprintf(fid,"  legend('transmitted','syms','received/filtered','syms','location','northwest');\n");
    fprintf(fid,"  grid on;\n");
#else
    // plot filter response
    fprintf(fid,"ht_len = %u;\n", ht_len);
    fprintf(fid,"ht     = zeros(1,ht_len);\n");
    for (i=0; i<ht_len; i++)
        fprintf(fid,"ht(%4u) = %12.8f;\n", i+1, ht[i]);
    fprintf(fid,"gt1 = filter([0.5 0.5],[1 -1],ht) / (pi*h);\n");
    fprintf(fid,"gt2 = filter([0.0 1.0],[1 -1],ht) / (pi*h);\n");
    fprintf(fid,"tfilt = [0:(ht_len-1)]/k - delay + 0.5;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(tfilt,ht, '-x','MarkerSize',4,...\n");
    fprintf(fid,"     tfilt,gt1,'-x','MarkerSize',4,...\n");
    fprintf(fid,"     tfilt,gt2,'-x','MarkerSize',4);\n");
    fprintf(fid,"axis([tfilt(1) tfilt(end) -0.1 1.1]);\n");
    fprintf(fid,"legend('pulse','trap. int.','rect. int.','location','northwest');\n");
    fprintf(fid,"grid on;\n");
#endif

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);
    
    // free allocated filter memory
    free(ht);

    return 0;
}
示例#5
0
文件: kernel.c 项目: 1014511134/src
void shot_ani_convlv3dtest(sf_complex *wld_z,sf_complex *conapp,sf_complex *conapm,int tnx,int tny,
			   struct shot_ker_par_type ker_par, int signn)
{
    int nx,ny,tn;
    sf_complex  *tmpwld_z; //(:,:)
    sf_complex *conap,*conam;
    int  iy,ix,ic,icx,icy;
    tn=tnx*tny;
    nx=ker_par.nx; ny=ker_par.ny;
    tmpwld_z=ker_par.tmp_wld;   //allocate(tmpwld_z(nx,ny)) ker_par.tmp_wld is allocated in ker_init in kernal.c
    conap=sf_complexalloc(tn); conam=sf_complexalloc(tn);
    vector_cp_c(tmpwld_z,wld_z,nx*ny); //tmpwld_z=wld_z;
    vector_cp_c(conap,conapp,tn); vector_cp_c(conam,conapm,tn);
    vector_value_c(wld_z,sf_cmplx(0.0,0.0),nx*ny);
    if (signn==+1) {
	for(ic=0;ic<tn;ic++){
	    conap[ic]=conjf(conapp[ic]); conam[ic]=conjf(conapm[ic]);
	} //for(ic)
    }
    else{
	for(ic=0;ic<tn;ic++){
	    conap[ic]=(conapp[ic]); conam[ic]=(conapm[ic]);
	} //for(ic)
    }
    for(icy=1;icy<tny;icy++){
	for(icx=0; icx<tnx; icx++){
	    ic=icy*tnx+icx;
	    conap[ic]=0.5*conap[ic];
	    conam[ic]=0.5*conam[ic];
	}
    }

//  for (ic=0;ic<tn;ic++){
//    printf("ic=%d,(%f,%f)",ic,__real__ conap[ic],__imag__ conap[ic]);
//  }
    printf("begin convlv\n");

    for( iy=0;iy<ny;iy++){
	for(ix=0;ix<nx;ix++){
	    wld_z[i2(iy,ix,nx)]=conap[0]*tmpwld_z[i2(iy,ix,nx)]; 
                            
	    for(icy=1,icx=0; icy<tny;icy++){ 
		ic=icy*tnx+icx;    
		if (iy+icy <ny)    
		    wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix,nx)]);
		if (iy-icy >=0)
		    wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy-icy,ix,nx)]);
	    }

	    for(icy=0,icx=1;icx<tnx; icx++){
		ic=icy*tnx+icx;
		if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*tmpwld_z[i2(iy,ix+icx,nx)];
		if (ix-ic >= 0 )wld_z[i2(iy,ix,nx)]+=conam[ic]*tmpwld_z[i2(iy,ix-icx,nx)];
	    }
	    for(icy=1;icy<tny; icy++){
		if (iy+icy <ny && iy-icy >=0 ){
		    for(icx=1;icx<tnx; icx++){
			ic=icy*tnx+icx;
			if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix+icx,nx)]+tmpwld_z[i2(iy-icy,ix+icx,nx)]);
			if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy+icy,ix-icx,nx)]+tmpwld_z[i2(iy-icy,ix-icx,nx)]);
		    }
		}
		if (iy+icy<ny && iy-icy <0){
		    for(icx=1;icx<tnx; icx++){
			ic=icy*tnx+icx;
			if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy+icy,ix+icx,nx)]);
			if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy+icy,ix-icx,nx)]);
		    }
		}
		if (iy+icy >=ny && iy-icy >=0){
		    for(icx=1;icx<tnx; icx++){
			ic=icy*tnx+icx;
			if (ix+icx <nx) wld_z[i2(iy,ix,nx)]+=conap[ic]*(tmpwld_z[i2(iy-icy,ix+icx,nx)]);
			if (ix-icx >=0) wld_z[i2(iy,ix,nx)]+=conam[ic]*(tmpwld_z[i2(iy-icy,ix-icx,nx)]);
		    }
		}

	    } 
     
	}// for(ix) 
    }// for(iy)
    free(conap); free(conam);
  
}
ofdmoqamframe64sync ofdmoqamframe64sync_create(unsigned int _m,
                                               float _beta,
                                               ofdmoqamframe64sync_callback _callback,
                                               void * _userdata)
{
    ofdmoqamframe64sync q = (ofdmoqamframe64sync) malloc(sizeof(struct ofdmoqamframe64sync_s));
    q->num_subcarriers = 64;

    // validate input
    if (_m < 1) {
        fprintf(stderr,"error: ofdmoqamframe64sync_create(), filter delay must be > 0\n");
        exit(1);
    } else if (_beta < 0.0f) {
        fprintf(stderr,"error: ofdmoqamframe64sync_create(), filter excess bandwidth must be > 0\n");
        exit(1);
    }
    q->m = _m;
    q->beta = _beta;

    // synchronizer parameters
    q->rxx_thresh = 0.60f;  // auto-correlation threshold
    q->rxy_thresh = 0.60f;  // cross-correlation threshold

    q->zeta = 64.0f/sqrtf(52.0f);   // scaling factor
    
    // create analysis filter banks
    q->ca0 = firpfbch_create(q->num_subcarriers, q->m, q->beta, 0.0f /*dt*/,FIRPFBCH_ROOTNYQUIST,0/*gradient*/);
    q->ca1 = firpfbch_create(q->num_subcarriers, q->m, q->beta, 0.0f /*dt*/,FIRPFBCH_ROOTNYQUIST,0/*gradient*/);
    q->X0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->X1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->Y0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->Y1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
 
    // allocate memory for PLCP arrays
    q->S0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->S1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->S2 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    ofdmoqamframe64_init_S0(q->S0);
    ofdmoqamframe64_init_S1(q->S1);
    ofdmoqamframe64_init_S2(q->S2);
    unsigned int i;
    for (i=0; i<q->num_subcarriers; i++) {
        q->S0[i] *= q->zeta;
        q->S1[i] *= q->zeta;
        q->S2[i] *= q->zeta;
    }
    q->S1a = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->S1b = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));

    // set pilot sequence
    q->ms_pilot = msequence_create_default(8);
    q->x_phase[0] = -21.0f;
    q->x_phase[1] =  -7.0f;
    q->x_phase[2] =   7.0f;
    q->x_phase[3] =  21.0f;

    // create NCO for pilots
    q->nco_pilot = nco_crcf_create(LIQUID_VCO);
    q->pll_pilot = pll_create();
    pll_set_bandwidth(q->pll_pilot,0.01f);
    pll_set_damping_factor(q->pll_pilot,4.0f);

    // create agc | signal detection object
    q->sigdet = agc_crcf_create();
    agc_crcf_set_bandwidth(q->sigdet,0.1f);

    // create NCO for CFO compensation
    q->nco_rx = nco_crcf_create(LIQUID_VCO);

    // create auto-correlator objects
    q->autocorr_length = OFDMOQAMFRAME64SYNC_AUTOCORR_LEN;
    q->autocorr_delay = q->num_subcarriers / 4;
    q->autocorr = autocorr_cccf_create(q->autocorr_length, q->autocorr_delay);

    // create cross-correlator object
    q->hxy = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    ofdmoqam cs = ofdmoqam_create(q->num_subcarriers,q->m,q->beta,
                                  0.0f,   // dt
                                  OFDMOQAM_SYNTHESIZER,
                                  0);     // gradient
    for (i=0; i<2*(q->m); i++)
        ofdmoqam_execute(cs,q->S1,q->hxy);
    // time reverse, complex conjugate (same as fftshift for
    // this particular sequence)
    memmove(q->X0, q->hxy, 64*sizeof(float complex));
    for (i=0; i<64; i++)
        q->hxy[i] = conjf(q->X0[64-i-1]);
    // fftshift
    //fft_shift(q->hxy,64);
    q->crosscorr = firfilt_cccf_create(q->hxy, q->num_subcarriers);
    ofdmoqam_destroy(cs);

    // input buffer
    q->input_buffer = windowcf_create((q->num_subcarriers));

    // gain
    q->g = 1.0f;
    q->G0 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->G1 = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));
    q->G  = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));

    q->data = (float complex*) malloc((q->num_subcarriers)*sizeof(float complex));

    // reset object
    ofdmoqamframe64sync_reset(q);

#if DEBUG_OFDMOQAMFRAME64SYNC
    q->debug_x =        windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_rxx=       windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_rxy=       windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_framesyms= windowcf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_pilotphase= windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_pilotphase_hat= windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
    q->debug_rssi=       windowf_create(DEBUG_OFDMOQAMFRAME64SYNC_BUFFER_LEN);
#endif

    q->callback = _callback;
    q->userdata = _userdata;

    return q;
}
示例#7
0
int
main (void)
{
  /* For each type, test both runtime and compile time (constant folding)
     optimization.  */
  volatile float _Complex fc = 1.0F + 2.0iF;
  volatile double _Complex dc = 1.0 + 2.0i;
  volatile long double _Complex ldc = 1.0L + 2.0iL;
  /* Test floats.  */
  if (conjf (fc) != 1.0F - 2.0iF)
    abort ();
  if (__builtin_conjf (fc) != 1.0F - 2.0iF)
    abort ();
  if (conjf (1.0F + 2.0iF) != 1.0F - 2.0iF)
    link_failure ();
  if (__builtin_conjf (1.0F + 2.0iF) != 1.0F - 2.0iF)
    link_failure ();
  if (crealf (fc) != 1.0F)
    abort ();
  if (__builtin_crealf (fc) != 1.0F)
    abort ();
  if (crealf (1.0F + 2.0iF) != 1.0F)
    link_failure ();
  if (__builtin_crealf (1.0F + 2.0iF) != 1.0F)
    link_failure ();
  if (cimagf (fc) != 2.0F)
    abort ();
  if (__builtin_cimagf (fc) != 2.0F)
    abort ();
  if (cimagf (1.0F + 2.0iF) != 2.0F)
    link_failure ();
  if (__builtin_cimagf (1.0F + 2.0iF) != 2.0F)
    link_failure ();
  /* Test doubles.  */
  if (conj (dc) != 1.0 - 2.0i)
    abort ();
  if (__builtin_conj (dc) != 1.0 - 2.0i)
    abort ();
  if (conj (1.0 + 2.0i) != 1.0 - 2.0i)
    link_failure ();
  if (__builtin_conj (1.0 + 2.0i) != 1.0 - 2.0i)
    link_failure ();
  if (creal (dc) != 1.0)
    abort ();
  if (__builtin_creal (dc) != 1.0)
    abort ();
  if (creal (1.0 + 2.0i) != 1.0)
    link_failure ();
  if (__builtin_creal (1.0 + 2.0i) != 1.0)
    link_failure ();
  if (cimag (dc) != 2.0)
    abort ();
  if (__builtin_cimag (dc) != 2.0)
    abort ();
  if (cimag (1.0 + 2.0i) != 2.0)
    link_failure ();
  if (__builtin_cimag (1.0 + 2.0i) != 2.0)
    link_failure ();
  /* Test long doubles.  */
  if (conjl (ldc) != 1.0L - 2.0iL)
    abort ();
  if (__builtin_conjl (ldc) != 1.0L - 2.0iL)
    abort ();
  if (conjl (1.0L + 2.0iL) != 1.0L - 2.0iL)
    link_failure ();
  if (__builtin_conjl (1.0L + 2.0iL) != 1.0L - 2.0iL)
    link_failure ();
  if (creall (ldc) != 1.0L)
    abort ();
  if (__builtin_creall (ldc) != 1.0L)
    abort ();
  if (creall (1.0L + 2.0iL) != 1.0L)
    link_failure ();
  if (__builtin_creall (1.0L + 2.0iL) != 1.0L)
    link_failure ();
  if (cimagl (ldc) != 2.0L)
    abort ();
  if (__builtin_cimagl (ldc) != 2.0L)
    abort ();
  if (cimagl (1.0L + 2.0iL) != 2.0L)
    link_failure ();
  if (__builtin_cimagl (1.0L + 2.0iL) != 2.0L)
    link_failure ();
  exit (0);
}
示例#8
0
文件: Mmpilrrtm.c 项目: marscfeng/src
int lrosback2(sf_complex **img, sf_complex ***wavfld, float **sill, sf_complex **rcd, bool adj,
              bool verb, bool wantwf, sf_complex **lt, sf_complex **rt, int m2,
              geopar geop, int pad1, bool illum)
/*< low-rank one-step backward propagation + imaging >*/
{
    int it,iz,im,ik,ix,i,j;     /* index variables */
    int nxb,nzb,dx,dz,gpz,gpx,gpl,snpint,dt,wfit;
    int nt,nz,nx, nk, nzx, nz2, nx2, nzx2;
    sf_complex c;
    sf_complex *cwave, *cwavem, *currm;
    sf_complex **wave, *curr;
    sf_complex **ccr;

    nx = geop->nx;
    nz = geop->nz;
    nxb = geop->nxb;
    nzb = geop->nzb;
    dx = geop->dx;
    dz = geop->dz;

    gpz  = geop->gpz;
    gpx  = geop->gpx;
    gpl  = geop->gpl;
    snpint = geop->snpint;

    nt = geop->nt;
    dt = geop->dt;

    ccr = sf_complexalloc2(nz, nx);

    nk = cfft2_init(pad1,nzb,nxb,&nz2,&nx2);
    nzx = nzb*nxb;
    nzx2 = nz2*nx2;

    curr = sf_complexalloc(nzx2);
    cwave  = sf_complexalloc(nk);
    cwavem = sf_complexalloc(nk);
    wave = sf_complexalloc2(nzx2,m2);

    if (!adj) {
        currm  = sf_complexalloc(nzx2);
        icfft2_allocate(cwave);
    } else {
        cwavem = sf_complexalloc(nk);
        icfft2_allocate(cwavem);
    }

#ifdef _OPENMP
    #pragma omp parallel for private(iz)
#endif
    for (iz=0; iz < nzx2; iz++) {
        curr[iz] = sf_cmplx(0.,0.);
    }

#ifdef _OPENMP
    #pragma omp parallel for private(ix, iz)
#endif
    for (ix = 0; ix < nx; ix++) {
        for (iz = 0; iz < nz; iz++) {
            ccr[ix][iz] = sf_cmplx(0.,0.);
        }
    }

    if (adj) { /* migration */
        /* step backward in time (PSPI) */
        /*Main loop*/
        wfit = (int)(nt-1)/snpint;
        for (it = nt-1; it>=0; it--) {
            if  (verb) sf_warning("Backward receiver it=%d/%d;", it, nt-1);
#ifdef _OPENMP
            #pragma omp parallel for private(ix,j)
#endif
            for (ix=0; ix<gpl; ix++)  {
                j = (gpz+geop->top)+(ix+gpx+geop->lft)*nz2; /* padded grid */
                curr[j]+=rcd[ix][it]; /* data injection */
            }
            /*matrix multiplication*/
            cfft2(curr,cwave);
            for (im = 0; im < m2; im++) {
#ifdef _OPENMP
                #pragma omp parallel for private(ik)
#endif
                for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
                    cwavem[ik] = cwave[ik]*rt[ik][im];
#else
                    cwavem[ik] = sf_cmul(cwave[ik],rt[ik][im]);
#endif
                }
                icfft2(wave[im],cwavem);
            }

#ifdef _OPENMP
            #pragma omp parallel for private(ix,iz,i,j,im,c) shared(curr,lt,wave)
#endif
            for (ix = 0; ix < nxb; ix++) {
                for (iz=0; iz < nzb; iz++) {
                    i = iz+ix*nzb;  /* original grid */
                    j = iz+ix*nz2; /* padded grid */
                    c = sf_cmplx(0.,0.); // initialize
                    for (im = 0; im < m2; im++) {
#ifdef SF_HAS_COMPLEX_H
                        c += lt[im][i]*wave[im][j];
#else
                        c += sf_cmul(lt[im][i], wave[im][j]);
#endif
                    }
                    curr[j] = c;
                }
            }

            /*cross-correlation imaging condition*/
            if (it%snpint == 0 ) {
#ifdef _OPENMP
                #pragma omp parallel for private(ix,iz,j)
#endif
                for (ix=0; ix<nx; ix++) {
                    for (iz=0; iz<nz; iz++) {
                        j = (iz+geop->top)+(ix+geop->lft)*nz2; /* padded grid */
#ifdef SF_HAS_COMPLEX_H
                        ccr[ix][iz] += conjf(wavfld[wfit][ix][iz])*curr[j];
#else
                        ccr[ix][iz] += sf_cmul(conjf(wavfld[wfit][ix][iz]),curr[j]);
#endif
                    }
                }
                wfit--;
            }
        } /*Main loop*/
        if (verb) sf_warning(".");
#ifdef _OPENMP
        #pragma omp parallel for private(ix, iz)
#endif
        for (ix=0; ix<nx; ix++) {
            for (iz=0; iz<nz; iz++) {
                if (illum) {
#ifdef SF_HAS_COMPLEX_H
                    img[ix][iz] = ccr[ix][iz]/(sill[ix][iz]+SF_EPS);
#else
                    img[ix][iz] = sf_crmul(ccr[ix][iz],1./(sill[ix][iz]+SF_EPS));
#endif
                } else img[ix][iz] = ccr[ix][iz];
            }
        }
    } else { /* modeling */
        /* adjoint of source illumination */
#ifdef _OPENMP
        #pragma omp parallel for private(ix, iz)
#endif
        for (ix=0; ix<nx; ix++) {
            for (iz=0; iz<nz; iz++) {
                if (illum) {
#ifdef SF_HAS_COMPLEX_H
                    ccr[ix][iz] = img[ix][iz]/(sill[ix][iz]+SF_EPS);
#else
                    ccr[ix][iz] = sf_crmul(img[ix][iz],1./(sill[ix][iz]+SF_EPS));
#endif
                } else ccr[ix][iz] = img[ix][iz];
            }
        }
        /* step forward in time (NSPS) */
        /*Main loop*/
        wfit=0;
        for (it=0; it<nt; it++) {
            if (verb) sf_warning("Forward receiver it=%d/%d;", it, nt-1);
            /*adjoint of cross-correlation imaging condition*/
            if (it%snpint == 0 ) {
#ifdef _OPENMP
                #pragma omp parallel for private(ix,iz,j)
#endif
                for (ix=0; ix<nx; ix++) {
                    for (iz=0; iz<nz; iz++) {
                        j = (iz+geop->top)+(ix+geop->lft)*nz2; /* padded grid */
#ifdef SF_HAS_COMPLEX_H
                        curr[j] += (wavfld[wfit][ix][iz])*ccr[ix][iz];//adjoint of ccr[ix][iz] += conjf(wavfld[wfit][ix][iz])*curr[j]; ???
#else
                        curr[j] += sf_cmul((wavfld[wfit][ix][iz]),ccr[ix][iz]);
#endif
                    }
                }
                wfit++;
            }
            /*matrix multiplication*/
            for (im = 0; im < m2; im++) {
#ifdef _OPENMP
                #pragma omp parallel for private(ix,iz,i,j) shared(currm,lt,curr)
#endif
                for (ix = 0; ix < nxb; ix++) {
                    for (iz=0; iz < nzb; iz++) {
                        i = iz+ix*nzb;  /* original grid */
                        j = iz+ix*nz2; /* padded grid */
#ifdef SF_HAS_COMPLEX_H
                        currm[j] = conjf(lt[im][i])*curr[j];
#else
                        currm[j] = sf_cmul(conjf(lt[im][i]), curr[j]);
#endif
                    }
                }
                cfft2(currm,wave[im]);
            }
#ifdef _OPENMP
            #pragma omp parallel for private(ik,im,c) shared(wave,rt,cwave)
#endif
            for (ik = 0; ik < nk; ik++) {
                c = sf_cmplx(0.,0.);
                for (im = 0; im < m2; im++) {
#ifdef SF_HAS_COMPLEX_H
                    c += wave[im][ik]*conjf(rt[ik][im]);
#else
                    c += sf_cmul(wave[im][ik],conjf(rt[ik][im])); //complex multiplies complex
#endif
                }
                cwave[ik] = c;
            }
            icfft2(curr,cwave);

#ifdef _OPENMP
            #pragma omp parallel for private(ix,j)
#endif
            for (ix=0; ix<gpl; ix++)  {
                j = (gpz+geop->top)+(ix+gpx+geop->lft)*nz2; /* padded grid */
                rcd[ix][it]=curr[j];
            }
        } /*Main loop*/
    }
    cfft2_finalize();
    return 0;
}
示例#9
0
int main(int argc, char*argv[])
{
    srand(time(NULL));
    // options
    unsigned int k=2;                   // filter samples/symbol
    unsigned int m=4;                   // filter delay (symbols)
    float beta=0.3f;                    // bandwidth-time product
    float dt = 0.0f;                    // fractional sample timing offset
    unsigned int num_sync_symbols = 64; // number of data symbols
    float SNRdB = 30.0f;                // signal-to-noise ratio [dB]
    float dphi = 0.0f;                  // carrier frequency offset
    float phi  = 0.0f;                  // carrier phase offset
    
    unsigned int num_delay_symbols = 12;
    unsigned int num_dphi_hat = 21;     // number of frequency offset estimates
    float dphi_hat_step = 0.01f;        // frequency offset step size

    int dopt;
    while ((dopt = getopt(argc,argv,"uhk:m:n:b:t:F:P:s:")) != EOF) {
        switch (dopt) {
        case 'h': usage();              return 0;
        case 'k': k     = atoi(optarg); break;
        case 'm': m     = atoi(optarg); break;
        case 'n': num_sync_symbols = atoi(optarg); break;
        case 'b': beta  = atof(optarg); break;
        case 't': dt    = atof(optarg); break;
        case 'F': dphi  = atof(optarg); break;
        case 'P': phi   = atof(optarg); break;
        case 's': SNRdB = atof(optarg); break;
        default:
            exit(1);
        }
    }

    unsigned int i;

    // validate input
    if (beta <= 0.0f || beta >= 1.0f) {
        fprintf(stderr,"error: %s, bandwidth-time product must be in (0,1)\n", argv[0]);
        exit(1);
    } else if (dt < -0.5 || dt > 0.5) {
        fprintf(stderr,"error: %s, fractional sample offset must be in (0,1)\n", argv[0]);
        exit(1);
    }

    // derived values
    unsigned int num_symbols = num_delay_symbols + num_sync_symbols + 2*m;
    unsigned int num_samples = k*num_symbols;
    unsigned int num_sync_samples = k*num_sync_symbols;
    float nstd = powf(10.0f, -SNRdB/20.0f);

    // arrays
    float complex seq[num_sync_symbols];    // data sequence (symbols)
    float complex s0[num_sync_samples];     // data sequence (interpolated samples)
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    float rxy[num_dphi_hat][num_samples];   // pre-demod output matrix

    // generate sequence
    for (i=0; i<num_sync_symbols; i++) {
        float sym_i = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2;
        float sym_q = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2;
        seq[i] = sym_i + _Complex_I*sym_q;
    }

    // create interpolated sequence, compensating for filter delay
    firinterp_crcf interp_seq = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,0.0f);
    for (i=0; i<num_sync_symbols+m; i++) {
        if      (i < m)                firinterp_crcf_execute(interp_seq, seq[i], &s0[0]);
        else if (i < num_sync_symbols) firinterp_crcf_execute(interp_seq, seq[i], &s0[k*(i-m)]);
        else                           firinterp_crcf_execute(interp_seq,      0, &s0[k*(i-m)]);
    }
    firinterp_crcf_destroy(interp_seq);
    
    // compute g = E{ |s0|^2 }
    float g = 0.0f;
    for (i=0; i<num_sync_samples; i++)
        g += crealf( s0[i]*conjf(s0[i]) );

    // create transmit interpolator and generate sequence
    firinterp_crcf interp_tx = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,dt);
    unsigned int n=0;
    for (i=0; i<num_delay_symbols; i++) {
        firinterp_crcf_execute(interp_tx, 0, &x[k*n]);
        n++;
    }
    for (i=0; i<num_sync_symbols; i++) {
        firinterp_crcf_execute(interp_tx, seq[i], &x[k*n]);
        n++;
    }
    for (i=0; i<2*m; i++) {
        firinterp_crcf_execute(interp_tx, 0, &x[k*n]);
        n++;
    }
    assert(n==num_symbols);
    firinterp_crcf_destroy(interp_tx);

    // add channel impairments
    for (i=0; i<num_samples; i++) {
        y[i] = x[i]*cexp(_Complex_I*(dphi*i + phi)) + nstd*( randnf() + _Complex_I*randnf() );
    }

    float complex z;    // filter output sample
    for (n=0; n<num_dphi_hat; n++) {
        float dphi_hat = ((float)n - 0.5*(float)(num_dphi_hat-1)) * dphi_hat_step;
        printf("  dphi_hat : %12.8f\n", dphi_hat);

        // create flipped, conjugated coefficients
        float complex s1[num_sync_samples];
        for (i=0; i<num_sync_samples; i++)
            s1[i] = conjf( s0[num_sync_samples-i-1]*cexpf(_Complex_I*(dphi_hat*i)) );

        // create matched filter and detect signal
        firfilt_cccf fsync = firfilt_cccf_create(s1, num_sync_samples);
        for (i=0; i<num_samples; i++) {
            firfilt_cccf_push(fsync, y[i]);
            firfilt_cccf_execute(fsync, &z);

            rxy[n][i] = cabsf(z) / g;
        }
        // destroy filter
        firfilt_cccf_destroy(fsync);
    }
    
    // print results
    //printf("rxy (max) : %12.8f\n", rxy_max);

    // 
    // export results
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"m = %u;\n", m);
    fprintf(fid,"beta = %f;\n", beta);
    fprintf(fid,"num_sync_symbols = %u;\n", num_sync_symbols);
    fprintf(fid,"num_sync_samples = k*num_sync_symbols;\n");
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"num_dphi_hat = %u;\n", num_dphi_hat);
    fprintf(fid,"dphi_hat_step = %f;\n", dphi_hat_step);

    // save sequence symbols
    fprintf(fid,"seq = zeros(1,num_sync_symbols);\n");
    for (i=0; i<num_sync_symbols; i++)
        fprintf(fid,"seq(%4u)   = %12.8f + j*%12.8f;\n", i+1, crealf(seq[i]), cimagf(seq[i]));

    // save interpolated sequence
    fprintf(fid,"s   = zeros(1,num_sync_samples);\n");
    for (i=0; i<num_sync_samples; i++)
        fprintf(fid,"s(%4u)     = %12.8f + j*%12.8f;\n", i+1, crealf(s0[i]), cimagf(s0[i]));

    fprintf(fid,"x = zeros(1,num_samples);\n");
    fprintf(fid,"y = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]),   cimagf(x[i]));
        fprintf(fid,"y(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]),   cimagf(y[i]));
    }

    // save cross-correlation output
    fprintf(fid,"rxy = zeros(num_dphi_hat,num_samples);\n");
    for (n=0; n<num_dphi_hat; n++) {
        for (i=0; i<num_samples; i++) {
            fprintf(fid,"rxy(%6u,%6u) = %12.8f;\n", n+1, i+1, rxy[n][i]);
        }
    }
    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(1:length(s),real(s), 1:length(s),imag(s));\n");
    
    fprintf(fid,"dphi_hat = ( [0:(num_dphi_hat-1)] - (num_dphi_hat-1)/2 ) * dphi_hat_step;\n");
    fprintf(fid,"mesh(dphi_hat, t, rxy');\n");
    
#if 0
    fprintf(fid,"z = abs( z );\n");
    fprintf(fid,"[zmax i] = max(z);\n");
    fprintf(fid,"plot(1:length(z),z,'-x');\n");
    fprintf(fid,"axis([(i-8*k) (i+8*k) 0 zmax*1.2]);\n");
    fprintf(fid,"grid on\n");
#endif

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);

    return 0;
}
示例#10
0
文件: cbanded.c 项目: 1014511134/src
void cbanded_const_define (float diag             /* diagonal */, 
			   const sf_complex *offd /* lower off-diagonal */)
/*< set matrix coefficients (constant along diagonals) >*/
{
    int k, m, j;
    sf_complex ct;
    float rt;

    d[0] = diag;
    for (k = 0; k < band-1; k++) {
	for (m = k; m >= 0; m--) {
	    ct = offd[m];
	    for (j = m+1; j < k-1; j++) {
#ifdef SF_HAS_COMPLEX_H
		ct -= o[j][k-j]*conjf(o[j-m-1][k-j])*d[k-j];
#else
		ct = sf_csub(ct,sf_cmul(o[j][k-j],
					sf_crmul(conjf(o[j-m-1][k-j]),
						 d[k-j])));
#endif
	    }
#ifdef SF_HAS_COMPLEX_H
	    o[m][k-m] = ct/d[k-m];
#else
	    o[m][k-m] = sf_crmul(ct,1./d[k-m]);
#endif
	}
	rt = diag;
	for (m = 0; m <= k; m++) {
#ifdef SF_HAS_COMPLEX_H
	    rt -= crealf(o[m][k-m]*conjf(o[m][k-m]))*d[k-m];
#else
	    rt -= crealf(sf_cmul(o[m][k-m],conjf(o[m][k-m])))*d[k-m];
#endif
	}
	d[k+1] = rt;
    }
    for (k = band-1; k < n-1; k++) {
	for (m = band-1; m >= 0; m--) {
	    ct = offd[m];
	    for (j = m+1; j < band; j++) {
#ifdef SF_HAS_COMPLEX_H
		ct -= o[j][k-j]*conjf(o[j-m-1][k-j])*d[k-j];
#else
		ct = sf_csub(ct,sf_cmul(o[j][k-j],
					sf_crmul(conjf(o[j-m-1][k-j]),
						 d[k-j])));
#endif
	    }
#ifdef SF_HAS_COMPLEX_H
	    o[m][k-m] = ct/d[k-m];
#else
	    o[m][k-m] = sf_crmul(ct,1./d[k-m]);
#endif
	}
	rt = diag;
	for (m = 0; m < band; m++) {
#ifdef SF_HAS_COMPLEX_H
	    rt -= crealf(o[m][k-m]*conjf(o[m][k-m]))*d[k-m];
#else
	     rt -= crealf(sf_cmul(o[m][k-m],conjf(o[m][k-m])))*d[k-m];
#endif
	}
	d[k+1] = rt;
    }
}
示例#11
0
文件: Mpseudoprim.c 项目: Seislet/src
int main(int argc, char *argv[])
{
    int nw, n1, n2, n4, iw, i1, i2, i4, s1, x1, s2, x2, m, fold;
    int jumpo, jumps, newn1, newn2, tn;
    float d1, d2, newd1, newd2;
    bool verb, stack, both;

    sf_complex *dd, *ref=NULL, *mm=NULL, *mtemp=NULL;
    sf_file in, out, mul=NULL;

    sf_init(argc,argv);

    in = sf_input("in");
    out = sf_output("out");

    if (SF_COMPLEX != sf_gettype(in)) sf_error("Need complex input");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input");
    if (!sf_histint(in,"n3",&nw)) sf_error("No n3= in input");

    if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input");
    if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input");
    
    if (d1!=d2) sf_error("Need d1==d2");

    n4 = sf_leftsize(in,3);
    fold = 0;

    if (!sf_getbool("verb",&verb)) verb=false;
    /* verbosity flag */

    if (!sf_getbool("stack",&stack)) stack=true;
    /* stack flag, if y, no common pseudoprimary gather */

    if (!sf_getbool("both",&both)) both=false;
    /* receiver flag, if y, receiver with both sides */

    if (!stack) {
	if (!sf_getint("jumpo",&jumpo)) jumpo=1;
	/* jump in offset dimension, only for stack=n */
	
	if (!sf_getint("jumps",&jumps)) jumps=1;
	/* jump in shot dimension, only for stack=n  */
    }
    newn1 = n1;
    newn2 = n2;
    if (!stack) {
	if (!both) {
	    sf_putint(out,"n1",(2*n1-1));
	    sf_putfloat(out,"d1",d1);
	    sf_putfloat(out,"o1",(1-n1)*d1);
	} else {
	    sf_putint(out,"n1",n1);
	    sf_putfloat(out,"d1",d1);
	    sf_putfloat(out,"o1",(-1*n1/2)*d1);
	}
	(void) sf_shiftdim(in, out, 1);
	if (n1%jumpo == 0) {
	    newn1 = n1 / jumpo;
	} else {
	    newn1 = n1 / jumpo +1;
	}
	if (n2%jumps == 0) {
	    newn2 = n2 / jumps;
	} else {
	    newn2 = n2 / jumps +1;
	}
	newd1 = (float) (d1 * jumpo);
	newd2 = (float) (d2 * jumps);
	sf_putint(out,"n2",newn1);
	sf_putfloat(out,"d2",newd1);
	sf_putint(out,"n3",newn2);
	sf_putfloat(out,"d3",newd2);
    }

    if (NULL != sf_getstring ("mul")) {
	mul = sf_input("mul");
	ref = sf_complexalloc(n1*n2);
    } else {
	mul = NULL;
    }	
    
    dd = sf_complexalloc(n1*n2);

    if (stack) {
	mm = sf_complexalloc(n1*n2);
    } else {
	if (!both) {
	    mm = sf_complexalloc((2*n1-1)*n1*n2);
	    mtemp = sf_complexalloc((2*n1-1)*newn1*newn2);
	} else {
	    mm = sf_complexalloc(n1*n1*n2);
	    mtemp = sf_complexalloc(n1*newn1*newn2);
	}
    }

    /* loop over n4 */
    for (i4=0; i4 < n4; i4++) {
	if (verb) sf_warning("slice %d of %d",i4+1,n4);
	for (iw=0; iw < nw; iw++) { /* loop over frequency */
	    if (verb) sf_warning("frequency %d of %d;",iw+1,nw);
	    sf_complexread(dd,n1*n2,in);
	    if (NULL != mul) {
		sf_complexread(ref,n1*n2,mul);
	    }
	    if (!both) {
		for (i2=0; i2 < n2; i2++) {
		    for (i1=0; i1 < n1; i1++) {
			mm[i2*n1+i1] = sf_cmplx(0.,0.);
			fold = 0;
			for (m=(-1*n1+1); m < n1; m++) {
			    if (m < 0) {
				x1 = -1*m;
				s1 = i2 + m;
				x2 = i1 - m;
				s2 = m + i2;
			    } else if ((i1-m) < 0) {
				x1 = m;
				s1 = i2;
				x2 = m - i1;
				s2 = i2 + i1;
			    } else {
				x1 = m;
				s1 = i2;
				x2 = i1 - m;
				s2 = m + i2;
			    }
			    if (stack) {
				if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && 
				    s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) {
#ifdef SF_HAS_COMPLEX_H
				    if(NULL != mul) {
					mm[i2*n1+i1] += conjf(dd[s1*n1+x1])*ref[s2*n1+x2];
				    } else {
					mm[i2*n1+i1] += conjf(dd[s1*n1+x1])*dd[s2*n1+x2];
				    }
#else
				    if(NULL != mul) {
					mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(sf_conjf(dd[s1*n1+x1]),ref[s2*n1+x2]));
				    } else {
					mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(sf_conjf(dd[s1*n1+x1]),dd[s2*n1+x2]));
				    }
#endif
				} else {
				    mm[i2*n1+i1] = sf_cmplx(0.,0.);
				}
				if (0.0 != cabsf(mm[i2*n1+i1])) fold++;	
			    } else {
				if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && 
				    s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) {
#ifdef SF_HAS_COMPLEX_H
				    if(NULL != mul) {
					mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = dd[s1*n1+x1]*ref[s2*n1+x2];
				    } else {
					mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = dd[s1*n1+x1]*dd[s2*n1+x2];
				    }
#else
				    if(NULL != mul) {
					mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2]);
				    } else {
					mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2]);
				    }
#endif
				} else {
				    mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1] = sf_cmplx(0.,0.);
				}
			    }
			}

			if (stack) {
#ifdef SF_HAS_COMPLEX_H
			    mm[i2*n1+i1] = mm[i2*n1+i1]/(fold+SF_EPS);
#else
			    mm[i2*n1+i1] = sf_crmul(mm[i2*n1+i1],1.0/(fold+SF_EPS));
#endif
			}

		    }
		}
		
		if (!stack) {
		    tn = 0;
		    for (i2=0; i2 < n2; i2++) {
			for (i1=0; i1 < n1; i1++) {
			    if ((i2 % jumps == 0) && (i1 % jumpo == 0)) {
				for (m=(-1*n1+1); m < n1; m++) {
				    mtemp[tn] = mm[i2*(2*n1-1)*n1+i1*(2*n1-1)+m+n1-1];
				    tn ++;
				}
			    }
			}
		    }
		    if (tn!=(2*n1-1)*newn1*newn2) sf_error("jump error!");		    
		    sf_complexwrite(mtemp,tn,out);
		} else {
		    sf_complexwrite(mm,n1*n2,out);
		}
	    } else {
		for (i2=0; i2 < n2; i2++) {
		    for (i1=0; i1 < n1; i1++) {
			mm[i2*n1+i1] = sf_cmplx(0.,0.);
			fold = 0;
			for (m=0; m < n1; m++) {
			    x1 = m;
			    s1 = i2;
			    x2 = i1 - m + n1/2;
			    s2 = m + i2 - n1/2;
			    if (stack) {
				if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && 
				    s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) {
#ifdef SF_HAS_COMPLEX_H
				    if(NULL != mul) {			
					mm[i2*n1+i1] += dd[s1*n1+x1]*ref[s2*n1+x2];
				    } else {
					mm[i2*n1+i1] += dd[s1*n1+x1]*dd[s2*n1+x2];
				    }
#else
				    if(NULL != mul) {	
					mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2]));
				    } else {
					mm[i2*n1+i1] = sf_cadd(mm[i2*n1+i1],sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2]));
				    }
#endif
				} else {
				    mm[i2*n1+i1] = sf_cmplx(0.,0.);
				}
				if (0.0 != cabsf(mm[i2*n1+i1])) fold++;				
			    } else {
				if (s1 >= 0 && s1 < n2 && x1 >= 0 && x1 < n1 && 
				    s2 >= 0 && s2 < n2 && x2 >= 0 && x2 < n1 ) {
#ifdef SF_HAS_COMPLEX_H
				    if(NULL != mul) {			
					mm[i2*n1*n1+i1*n1+m] = dd[s1*n1+x1]*ref[s2*n1+x2];
				    } else {
					mm[i2*n1*n1+i1*n1+m] = dd[s1*n1+x1]*dd[s2*n1+x2];
				    }
#else
				    if(NULL != mul) {	
					mm[i2*n1*n1+i1*n1+m] = sf_cmul(dd[s1*n1+x1],ref[s2*n1+x2]);
				    } else {
					mm[i2*n1*n1+i1*n1+m] = sf_cmul(dd[s1*n1+x1],dd[s2*n1+x2]);
				    }
#endif
				} else {
				    mm[i2*n1*n1+i1*n1+m] = sf_cmplx(0.,0.);
				}
			    }
			}
			if (stack) {
#ifdef SF_HAS_COMPLEX_H
			    mm[i2*n1+i1] = mm[i2*n1+i1]/(fold+SF_EPS);
#else
			    mm[i2*n1+i1] = sf_crmul(mm[i2*n1+i1],1.0/(fold+SF_EPS));
#endif
			}

		    }
		}
		if (!stack) {
		    tn = 0;
		    for (i2=0; i2 < n2; i2++) {
			for (i1=0; i1 < n1; i1++) {
			    if (i2 % jumps == 0 && i1 % jumpo == 0) {
				for (m=0; m < n1; m++) {
				    mtemp[tn] = mm[i2*n1*n1+i1*n1+m];
				    tn ++;
				}
			    }
			}
		    }	
		    if (tn!=n1*newn1*newn2) sf_error("jump error!");
		    sf_complexwrite(mtemp,tn,out);
		} else {
		    sf_complexwrite(mm,n1*n2,out);
		}
	    }		
	}   
	if (verb) sf_warning(".");
    
    }

    exit(0);
}
示例#12
0
int main(int argc, char *argv[])
{
	bool wantwf, verb;

	int ix, iz, is, it, wfit, im, ik, i, j, itau;
    int ns, nx, nz, nt, wfnt, rnx, rnz, nzx, rnzx, vnx, ntau, htau, nds;
	int scalet, snap, snapshot, fnx, fnz, fnzx, nk, nb;
	int rectx, rectz, gpz, n, m, pad1, trunc, spx, spz;

	float dt, t0, z0, dz, x0, dx, s0, ds, wfdt, srctrunc;
    float dtau, tau0, tau;

	char *path1, *path2, number[5], *left, *right;

	double tstart, tend;
	struct timeval tim;
	
	sf_complex c, **lt, **rt;
	sf_complex *ww, **dd;
	float ***img1, **img2, ***mig1, **mig2;
    float *rr, **ccr, **sill, ***fwf, ***bwf;
	sf_complex *cwave, *cwavem, **wave, *curr;

	sf_axis at, ax, az, atau;

	sf_file Fdat, Fsrc, Fimg1, Fimg2;
	sf_file Ffwf, Fbwf, Fvel;
	sf_file Fleft, Fright;

	int cpuid, numprocs, nth;
    float *sendbuf, *recvbuf;
	MPI_Comm comm=MPI_COMM_WORLD;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(comm, &cpuid);
	MPI_Comm_size(comm, &numprocs);

	sf_init(argc, argv);

#ifdef _OPENMP
#pragma omp parallel
	{
		nth=omp_get_num_threads();
	}
	sf_warning(">>> Using %d threads <<<", nth);
#endif

	gettimeofday(&tim, NULL);
	tstart=tim.tv_sec+(tim.tv_usec/1000000.0);

	if(!sf_getbool("wantwf", &wantwf)) wantwf=false;
    if(!sf_getbool("verb", &verb)) verb=false;
	if(!sf_getint("pad1", &pad1)) pad1=1;
	/* padding factor on the first axis */

	if(!sf_getint("nb", &nb)) sf_error("Need nb= ");
	if(!sf_getfloat("srctrunc", &srctrunc)) srctrunc=0.4;
	if(!sf_getint("rectx", &rectx)) rectx=2;
	if(!sf_getint("rectz", &rectz)) rectz=2;

	if(!sf_getint("scalet", &scalet)) scalet=1;
	if(!sf_getint("snap", &snap)) snap=100;
	/* interval of the output wavefield */
	if(!sf_getint("snapshot", &snapshot)) snapshot=0;
	/* print out the wavefield snapshots of this shot */
    if(!sf_getint("nds", &nds)) sf_error("Need nds=!");
    
    /* source and receiver positions */
	if(!sf_getint("gpz", &gpz)) sf_error("Need gpz=");
	if(!sf_getint("spx", &spx)) sf_error("Need spx=");
	if(!sf_getint("spz", &spz)) sf_error("Need spz=");
    
    /* tau parameters */
    if(!sf_getint("ntau", &ntau)) sf_error("Need ntau=");
    if(!sf_getfloat("dtau", &dtau)) sf_error("Need dtau=");
    if(!sf_getfloat("tau0", &tau0)) sf_error("Need tau0=");

	/* input/output files */
	Fdat=sf_input("in");
	Fimg1=sf_output("out");
    Fimg2=sf_output("Fimg2");
    Fsrc=sf_input("Fsrc");
    Fvel=sf_input("Fpadvel");

	if(wantwf){
		Ffwf=sf_output("Ffwf");
        Fbwf=sf_output("Fbwf");
	}

	at=sf_iaxa(Fsrc, 1); nt=sf_n(at); dt=sf_d(at); t0=sf_o(at);
    ax=sf_iaxa(Fvel, 2); vnx=sf_n(ax); x0=sf_o(ax);
	az=sf_iaxa(Fvel, 1); rnz=sf_n(az); dz=sf_d(az); z0=sf_o(az);
    if(!sf_histint(Fdat, "n2", &rnx)) sf_error("Need n2= in input!");
    if(!sf_histfloat(Fdat, "d2", &dx)) sf_error("Need d2= in input!");
    if(!sf_histint(Fdat, "n3", &ns)) sf_error("Need n3= in input!");
    if(!sf_histfloat(Fdat, "d3", &ds)) sf_error("Need d3= in input!");
    if(!sf_histfloat(Fdat, "o3", &s0)) sf_error("Need o3= in input!");
    
    wfnt=(nt-1)/scalet+1;
    wfdt=dt*scalet;
    
    /* double check the geometry parameters */
    if(nds != (int)(ds/dx)) sf_error("Need ds/dx= %d", nds);
	sf_warning("s0=%g, x0+(rnx-1)*dx/2=%g", s0, x0+(rnx-1)*dx/2);
    //if(s0 != x0+(rnx-1)*dx/2) sf_error("Wrong origin information!");
    if(vnx != nds*(ns-1)+rnx) sf_error("Wrong dimension in x axis!");

    /* set up the output files */
    atau=sf_iaxa(Fsrc, 1);
    sf_setn(atau, ntau);
    sf_setd(atau, dtau);
    sf_seto(atau, tau0);
    sf_setlabel(atau, "Tau");
    sf_setunit(atau, "s");
    
    sf_oaxa(Fimg1, az, 1);
    sf_oaxa(Fimg1, ax, 2);
    sf_oaxa(Fimg1, atau, 3);
    sf_oaxa(Fimg2, az, 1);
    sf_oaxa(Fimg2, ax, 2);
    sf_putint(Fimg2, "n3", 1);
    sf_settype(Fimg1, SF_FLOAT);
    sf_settype(Fimg2, SF_FLOAT);
    
    if(wantwf){
		sf_setn(ax, rnx);
        sf_seto(ax, -(rnx-1)*dx/2.0);
        sf_oaxa(Ffwf, az, 1);
        sf_oaxa(Ffwf, ax, 2);
        sf_putint(Ffwf, "n3", (wfnt-1)/snap+1);
        sf_putfloat(Ffwf, "d3", snap*wfdt);
        sf_putfloat(Ffwf, "o3", t0);
        sf_putstring(Ffwf, "label3", "Time");
        sf_putstring(Ffwf, "unit3", "s");
        sf_settype(Ffwf, SF_FLOAT);
        
        sf_oaxa(Fbwf, az, 1);
        sf_oaxa(Fbwf, ax, 2);
        sf_putint(Fbwf, "n3", (wfnt-1)/snap+1);
        sf_putfloat(Fbwf, "d3", -snap*wfdt);
        sf_putfloat(Fbwf, "o3", (wfnt-1)*wfdt);
        sf_putstring(Fbwf, "label3", "Time");
        sf_putstring(Fbwf, "unit3", "s");
        sf_settype(Fbwf, SF_FLOAT);
	}
	
    nx=rnx+2*nb; nz=rnz+2*nb;
	nzx=nx*nz; rnzx=rnz*rnx;
    nk=cfft2_init(pad1, nz, nx, &fnz, &fnx);
	fnzx=fnz*fnx;
    
	/* print axies parameters for double check */
    sf_warning("cpuid=%d, numprocs=%d", cpuid, numprocs);
	sf_warning("nt=%d, dt=%g, scalet=%d, wfnt=%d, wfdt=%g",nt, dt, scalet, wfnt, wfdt);
	sf_warning("vnx=%d, nx=%d, dx=%g, nb=%d, rnx=%d", vnx, nx, dx, nb, rnx);
	sf_warning("nz=%d, rnz=%d, dz=%g, z0=%g", nz, rnz, dz, z0);
	sf_warning("spx=%d, spz=%d, gpz=%d", spx, spz, gpz);
	sf_warning("ns=%d, ds=%g, s0=%g", ns, ds, s0);
    sf_warning("ntau=%d, dtau=%g, tau0=%g", ntau, dtau, tau0);
    sf_warning("nzx=%d, fnzx=%d, nk=%d", nzx, fnzx, nk);

	/* allocate storage and read data */
	ww=sf_complexalloc(nt);
	sf_complexread(ww, nt, Fsrc);
	sf_fileclose(Fsrc);
	
    gpz=gpz+nb;
    spz=spz+nb;
    spx=spx+nb;
    trunc=srctrunc/dt+0.5;
    
	dd=sf_complexalloc2(nt, rnx);
	rr=sf_floatalloc(nzx);
	reflgen(nz, nx, spz, spx, rectz, rectx, 0, rr);
    
    fwf=sf_floatalloc3(rnz, rnx, wfnt);
    bwf=sf_floatalloc3(rnz, rnx, wfnt);
    img1=sf_floatalloc3(rnz, vnx, ntau);
    img2=sf_floatalloc2(rnz, vnx);
    mig1=sf_floatalloc3(rnz, rnx, ntau);
    mig2=sf_floatalloc2(rnz, rnx);
    
    ccr=sf_floatalloc2(rnz, rnx);
    sill=sf_floatalloc2(rnz, rnx);
    
    curr=sf_complexalloc(fnzx);
	cwave=sf_complexalloc(nk);
	cwavem=sf_complexalloc(nk);
    icfft2_allocate(cwavem);
    
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, itau)
#endif
    for(ix=0; ix<vnx; ix++){
        for(iz=0; iz<rnz; iz++){
            img2[ix][iz]=0.;
            for(itau=0; itau<ntau; itau++){
                img1[itau][ix][iz]=0.;
            }
        }
    }

	path1=sf_getstring("path1");
	path2=sf_getstring("path2");
	if(path1==NULL) path1="./mat/left";
	if(path2==NULL) path2="./mat/right";
	/* shot loop */
	for (is=cpuid; is<ns; is+=numprocs){
		/* construct the names of left and right matrices */
		left=sf_charalloc(strlen(path1));
		right=sf_charalloc(strlen(path2));
		strcpy(left, path1);
		strcpy(right, path2);
		sprintf(number, "%d", is+1);
		strcat(left, number);
		strcat(right, number);

		Fleft=sf_input(left);
		Fright=sf_input(right);
		
		if(!sf_histint(Fleft, "n1", &n) || n != nzx) sf_error("Need n1=%d in Fleft", nzx);
		if(!sf_histint(Fleft, "n2", &m)) sf_error("No n2 in Fleft");
		if(!sf_histint(Fright, "n1", &n) || n != m) sf_error("Need n1=%d in Fright", m);
		if(!sf_histint(Fright, "n2", &n) || n != nk) sf_error("Need n2=%d in Fright", nk);
		
		/* allocate storage for each shot migration */
		lt=sf_complexalloc2(nzx, m);
		rt=sf_complexalloc2(m, nk);
		sf_complexread(lt[0], nzx*m, Fleft);
		sf_complexread(rt[0], m*nk, Fright);
        sf_fileclose(Fleft);
		sf_fileclose(Fright);
        
        /* read data */
        sf_seek(Fdat, is*rnx*nt*sizeof(float complex), SEEK_SET);
        sf_complexread(dd[0], rnx*nt, Fdat);
        
        /* initialize curr and imaging variables */
#ifdef _OPENMP
#pragma omp parallel for private(iz)
#endif
		for(iz=0; iz<fnzx; iz++){
			curr[iz]=sf_cmplx(0.,0.);
		}
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, itau)
#endif
        for(ix=0; ix<rnx; ix++){
            for(iz=0; iz<rnz; iz++){
                mig2[ix][iz]=0.;
                ccr[ix][iz]=0.;
                sill[ix][iz]=0.;
                for(itau=0; itau<ntau; itau++){
                    mig1[itau][ix][iz]=0.;
                }
            }
        }
        
        /* wave */
		wave=sf_complexalloc2(fnzx, m);
        
        /* snapshot */
        if(wantwf && is== snapshot) wantwf=true;
        else wantwf=false;
		
		wfit=0;
		for(it=0; it<nt; it++){
			if(verb) sf_warning("Forward propagation it=%d/%d",it+1, nt);
			
			cfft2(curr, cwave);
			for(im=0; im<m; im++){
#ifdef _OPENMP
#pragma omp parallel for private(ik)
#endif
				for(ik=0; ik<nk; ik++){
#ifdef SF_HAS_COMPLEX_H
					cwavem[ik]=cwave[ik]*rt[ik][im];
#else
					cwavem[ik]=sf_cmul(cwave[ik],rt[ik][im]);
#endif
				}
				icfft2(wave[im],cwavem);
			}

#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it)
#endif
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					i=iz+ix*nz;
					j=iz+ix*fnz;
					
					if(it<trunc){
#ifdef SF_HAS_COMPLEX_H
						c=ww[it]*rr[i];
#else
						c=sf_crmul(ww[it],rr[i]);
#endif
					}else{
						c=sf_cmplx(0.,0.);
					}
					
//                    c += curr[j];
                    
					for(im=0; im<m; im++){
#ifdef SF_HAS_COMPLEX_H
						c += lt[im][i]*wave[im][j];
#else
						c += sf_cmul(lt[im][i], wave[im][j]);
#endif
					}
					curr[j]=c;
				}
			}
			
			if(it%scalet==0){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
				for(ix=0; ix<rnx; ix++){
                    for(iz=0; iz<rnz; iz++){
                        fwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]);
                    }
                }
                wfit++;
            }
        } //end of it
        
        /* check wfnt */
        if(wfit != wfnt) sf_error("At this point, wfit should be equal to wfnt");

        
        /* backward propagation starts from here... */
#ifdef _OPENMP
#pragma omp parallel for private(iz)
#endif
		for(iz=0; iz<fnzx; iz++){
			curr[iz]=sf_cmplx(0.,0.);
		}
        
        wfit=wfnt-1;
        for(it=nt-1; it>=0; it--){
            if(verb) sf_warning("Backward propagation it=%d/%d",it+1, nt);
#ifdef _OPENMP
#pragma omp parallel for private(ix)
#endif
            for(ix=0; ix<rnx; ix++){
                curr[(ix+nb)*fnz+gpz]+=dd[ix][it];
            }
            
            cfft2(curr, cwave);
            
			for(im=0; im<m; im++){
#ifdef _OPENMP
#pragma omp parallel for private(ik)
#endif
				for(ik=0; ik<nk; ik++){
#ifdef SF_HAS_COMPLEX_H
					cwavem[ik]=cwave[ik]*conjf(rt[ik][im]);
#else
					cwavem[ik]=sf_cmul(cwave[ik],conjf(rt[ik][im]));
#endif
				}
				icfft2(wave[im],cwavem);
			}
            
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it)
#endif
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					i=iz+ix*nz;
					j=iz+ix*fnz;
					
//                    c=curr[j];
                      c=sf_cmplx(0.,0.);
					
					for(im=0; im<m; im++){
#ifdef SF_HAS_COMPLEX_H
						c += conjf(lt[im][i])*wave[im][j];
#else
						c += sf_cmul(conjf(lt[im][i]), wave[im][j]);
#endif
					}
					curr[j]=c;
				}
			}
			
			if(it%scalet==0){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
				for(ix=0; ix<rnx; ix++){
                    for(iz=0; iz<rnz; iz++){
                        bwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]);
                        ccr[ix][iz] += fwf[wfit][ix][iz]*bwf[wfit][ix][iz];
                        sill[ix][iz] += fwf[wfit][ix][iz]*fwf[wfit][ix][iz];
                    }
                }
                wfit--;
            }
        } //end of it
        if(wfit != -1) sf_error("Check program! The final wfit should be -1!");

        /* free storage */
        free(*rt); free(rt);
        free(*lt); free(lt);
        free(*wave); free(wave);
        free(left); free(right);
        
        /* normalized image */
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
        for (ix=0; ix<rnx; ix++){
            for(iz=0; iz<rnz; iz++){
                mig2[ix][iz]=ccr[ix][iz]/(sill[ix][iz]+SF_EPS);
		//		sill[ix][iz]=0.;
            }
        }
        
        /* calculate time shift gathers */
        for(itau=0; itau<ntau; itau++){
			sf_warning("itau/ntau=%d/%d", itau+1, ntau);
            tau=itau*dtau+tau0;
            htau=tau/wfdt;

            for(it=abs(htau); it<wfnt-abs(htau); it++){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
                for(ix=0; ix<rnx; ix++){
                    for(iz=0; iz<rnz; iz++){
                        mig1[itau][ix][iz]+=fwf[it+htau][ix][iz]*bwf[it-htau][ix][iz];
		//				sill[ix][iz]+=fwf[it+htau][ix][iz]*fwf[it+htau][ix][iz];
                    } // end of iz
                } // end of ix
            } // end of it
			
/*
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif */
			/* source illumination
			for(ix=0; ix<rnx; ix++){
				for(iz=0; iz<rnz; iz++){
					mig1[itau][ix][iz] = mig1[itau][ix][iz]/(sill[ix][iz]+SF_EPS);
				}
			} */
        } //end of itau
        
        /* output wavefield snapshot */
        if(wantwf){
            for(it=0; it<wfnt; it++){
                if(it%snap==0){
                    sf_floatwrite(fwf[it][0], rnzx, Ffwf);
                    sf_floatwrite(bwf[wfnt-1-it][0], rnzx, Fbwf);
                }
            }
            sf_fileclose(Ffwf);
            sf_fileclose(Fbwf);
        }
        
        /* add all the shot images that are on the same node */
#ifdef _OPENMP
#pragma omp parallel for private(itau, ix, iz)
#endif
        for(itau=0; itau<ntau; itau++){
            for(ix=0; ix<rnx; ix++){
                for(iz=0; iz<rnz; iz++){
                    img1[itau][ix+is*nds][iz] += mig1[itau][ix][iz];
                }
            }
        }
        
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
        for(ix=0; ix<rnx; ix++){
            for(iz=0; iz<rnz; iz++){
                img2[ix+is*nds][iz] += mig2[ix][iz];
            }
        }
	}
    ////////////////end of ishot
	MPI_Barrier(comm);
    
    cfft2_finalize();
    sf_fileclose(Fdat);
    
    free(ww); free(rr);
	free(*dd); free(dd);
	free(cwave); free(cwavem); free(curr);
    free(*ccr); free(ccr);
    free(*sill); free(sill);
    free(**fwf); free(*fwf); free(fwf);
    free(**bwf); free(*bwf); free(bwf);
    free(**mig1); free(*mig1); free(mig1);
    free(*mig2); free(mig2);
    
    /* sum image */
    if(cpuid==0){
        sendbuf=(float *)MPI_IN_PLACE;
        recvbuf=img1[0][0];
    }else{
        sendbuf=img1[0][0];
        recvbuf=NULL;
    }
    MPI_Reduce(sendbuf, recvbuf, ntau*vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm);
    
    if(cpuid==0){
        sendbuf=MPI_IN_PLACE;
        recvbuf=img2[0];
    }else{
        sendbuf=img2[0];
        recvbuf=NULL;
    }
    MPI_Reduce(sendbuf, recvbuf, vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm);
    
    /* output image */
    if(cpuid==0){
        sf_floatwrite(img1[0][0], ntau*vnx*rnz, Fimg1);
        sf_floatwrite(img2[0], vnx*rnz, Fimg2);
    }
	MPI_Barrier(comm);

	sf_fileclose(Fimg1);
    sf_fileclose(Fimg2);
    free(**img1); free(*img1); free(img1);
    free(*img2); free(img2);
    
	gettimeofday(&tim, NULL);
	tend=tim.tv_sec+(tim.tv_usec/1000000.0);
	sf_warning(">> The computing time is %.3lf minutes <<", (tend-tstart)/60.);

	MPI_Finalize();
	exit(0);
}
示例#13
0
int CORE_cttqrt(int M, int N, int IB,
                PLASMA_Complex32_t *A1, int LDA1,
                PLASMA_Complex32_t *A2, int LDA2,
                PLASMA_Complex32_t *T, int LDT,
                PLASMA_Complex32_t *TAU, PLASMA_Complex32_t *WORK)
{
    static PLASMA_Complex32_t zone  = 1.0;
    static PLASMA_Complex32_t zzero = 0.0;
    static int                ione  = 1;

    PLASMA_Complex32_t alpha;
    int i, j, ii, sb, mi, ni;

    /* Check input arguments */
    if (M < 0) {
        coreblas_error(1, "Illegal value of M");
        return -1;
    }
    if (N < 0) {
        coreblas_error(2, "Illegal value of N");
        return -2;
    }
    if (IB < 0) {
        coreblas_error(3, "Illegal value of IB");
        return -3;
    }
    if ((LDA2 < max(1,M)) && (M > 0)) {
        coreblas_error(7, "Illegal value of LDA2");
        return -7;
    }

    /* Quick return */
    if ((M == 0) || (N == 0) || (IB == 0))
        return PLASMA_SUCCESS;

    for(ii = 0; ii < N; ii += IB) {
        sb = min(N-ii, IB);
        for(i = 0; i < sb; i++) {
            /*
             * Generate elementary reflector H( II*IB+I ) to annihilate
             * A( II*IB+I:mi, II*IB+I ).
             */
            mi = ii + i + 1;
            LAPACKE_clarfg_work(mi+1, &A1[LDA1*(ii+i)+ii+i], &A2[LDA2*(ii+i)], ione, &TAU[ii+i]);

            if (sb-i-1>0) {
                /*
                 * Apply H( II*IB+I ) to A( II*IB+I:M, II*IB+I+1:II*IB+IB ) from the left.
                 */
                ni = sb-i-1;
                cblas_ccopy(
                    ni,
                    &A1[LDA1*(ii+i+1)+(ii+i)], LDA1,
                    WORK, 1);

#ifdef COMPLEX
                LAPACKE_clacgv_work(ni, WORK, ione);
#endif
                cblas_cgemv(
                    CblasColMajor, (CBLAS_TRANSPOSE)PlasmaConjTrans,
                    mi, ni,
                    CBLAS_SADDR(zone), &A2[LDA2*(ii+i+1)], LDA2,
                    &A2[LDA2*(ii+i)], 1,
                    CBLAS_SADDR(zone), WORK, 1);
#ifdef COMPLEX
                LAPACKE_clacgv_work(ni, WORK, ione);
#endif
                alpha = -conjf(TAU[ii+i]);
                cblas_caxpy(
                    ni, CBLAS_SADDR(alpha),
                    WORK, 1,
                    &A1[LDA1*(ii+i+1)+ii+i], LDA1);
#ifdef COMPLEX
                LAPACKE_clacgv_work(ni, WORK, ione);
#endif
                cblas_cgerc(
                    CblasColMajor, mi, ni,
                    CBLAS_SADDR(alpha), &A2[LDA2*(ii+i)], 1,
                    WORK, 1,
                    &A2[LDA2*(ii+i+1)], LDA2);
            }

            /*
             * Calculate T.
             */

            if (i > 0 ) {

                cblas_ccopy(i, &A2[LDA2*(ii+i)+ii], 1, &WORK[ii], 1);
    
                cblas_ctrmv(
                    CblasColMajor, (CBLAS_UPLO)PlasmaUpper,
                    (CBLAS_TRANSPOSE)PlasmaConjTrans, (CBLAS_DIAG)PlasmaNonUnit,
                    i, &A2[LDA2*ii+ii], LDA2,
                    &WORK[ii], 1);
    
                alpha = -(TAU[ii+i]);
                for(j = 0; j < i; j++) {
                    WORK[ii+j] = alpha * WORK[ii+j];
                }
    
                if (ii > 0) {
                    cblas_cgemv(
                        CblasColMajor, (CBLAS_TRANSPOSE)PlasmaConjTrans, ii, i,
                        CBLAS_SADDR(alpha), &A2[LDA2*ii], LDA2,
                        &A2[LDA2*(ii+i)], 1,
                        CBLAS_SADDR(zzero), WORK, 1);
    
                    cblas_caxpy(i, CBLAS_SADDR(zone), &WORK[ii], 1, WORK, 1);
                }
    
                cblas_ccopy(i, WORK, 1, &T[LDT*(ii+i)], 1);
    
                cblas_ctrmv(
                    CblasColMajor, (CBLAS_UPLO)PlasmaUpper,
                    (CBLAS_TRANSPOSE)PlasmaNoTrans, (CBLAS_DIAG)PlasmaNonUnit,
                    i, &T[LDT*ii], LDT,
                    &T[LDT*(ii+i)], 1);

            }

            T[LDT*(ii+i)+i] = TAU[ii+i];
        }

        /* Apply Q' to the rest of the matrix to the left  */
        if (N > ii+sb) {
            CORE_cttrfb(
                PlasmaLeft, PlasmaConjTrans,
                PlasmaForward, PlasmaColumnwise,
                sb, N-(ii+sb), ii+sb, N-(ii+sb), sb,
                &A1[LDA1*(ii+sb)+ii], LDA1,
                &A2[LDA2*(ii+sb)], LDA2,
                &A2[LDA2*ii], LDA2,
                &T[LDT*ii], LDT,
                WORK, sb);
        }
    }
    return PLASMA_SUCCESS;
}
int main(int argc, char*argv[])
{
    // options
    unsigned int num_channels=16;   // number of channels
    unsigned int m = 5;             // filter semi-length (symbols)
    unsigned int num_symbols=25;    // number of symbols
    float As = 80.0f;               // filter stop-band attenuation
    
    int dopt;
    while ((dopt = getopt(argc,argv,"hM:m:s:n:")) != EOF) {
        switch (dopt) {
        case 'h':   usage();                     return 0;
        case 'M':   num_channels = atoi(optarg); break;
        case 'm':   m            = atoi(optarg); break;
        case 's':   As           = atof(optarg); break;
        case 'n':   num_symbols  = atof(optarg); break;
        default:
            exit(1);
        }
    }

    unsigned int i;

    // validate input
    if (num_channels < 2 || num_channels % 2) {
        fprintf(stderr,"error: %s, number of channels must be greater than 2 and even\n", argv[0]);
        exit(1);
    } else if (m == 0) {
        fprintf(stderr,"error: %s, filter semi-length must be greater than zero\n", argv[0]);
        exit(1);
    } else if (num_symbols == 0) {
        fprintf(stderr,"error: %s, number of symbols must be greater than zero", argv[0]);
        exit(1);
    }

    // derived values
    unsigned int num_samples = num_channels * num_symbols;

    // allocate arrays
    float complex x[num_samples];
    float complex y[num_samples];

    // generate input signal
    unsigned int w_len = (unsigned int)(0.4*num_samples);
    for (i=0; i<num_samples; i++) {
        //x[i] = (i==0) ? 1.0f : 0.0f;
        //x[i] = cexpf( (-0.05f + 0.07f*_Complex_I)*i );  // decaying complex exponential
        x[i] = cexpf( _Complex_I * (1.3f*i - 0.007f*i*i) );
        x[i] *= i < w_len ? hamming(i,w_len) : 0.0f;
        //x[i] = (i==0) ? 1.0f : 0.0f;
    }

    // create filterbank objects from prototype
    firpfbch2_crcf qa = firpfbch2_crcf_create_kaiser(LIQUID_ANALYZER,    num_channels, m, As);
    firpfbch2_crcf qs = firpfbch2_crcf_create_kaiser(LIQUID_SYNTHESIZER, num_channels, m, As);
    firpfbch2_crcf_print(qa);
    firpfbch2_crcf_print(qs);

    // run channelizer
    float complex Y[num_channels];
    for (i=0; i<num_samples; i+=num_channels/2) {
        // run analysis filterbank
        firpfbch2_crcf_execute(qa, &x[i], Y);

        // run synthesis filterbank
        firpfbch2_crcf_execute(qs, Y, &y[i]);
    }

    // destroy fiterbank objects
    firpfbch2_crcf_destroy(qa); // analysis fitlerbank
    firpfbch2_crcf_destroy(qs); // synthesis filterbank

    // print output
    for (i=0; i<num_samples; i++)
        printf("%4u : %12.8f + %12.8fj\n", i, crealf(y[i]), cimagf(y[i]));

    // compute RMSE
    float rmse = 0.0f;
    unsigned int delay = 2*num_channels*m - num_channels/2 + 1;
    for (i=0; i<num_samples; i++) {
        float complex err = y[i] - (i < delay ? 0.0f : x[i-delay]);
        rmse += crealf( err*conjf(err) );
    }
    rmse = sqrtf( rmse/(float)num_samples );
    printf("rmse : %12.4e\n", rmse);

    //
    // EXPORT DATA TO FILES
    //
    FILE * fid = NULL;
    fid = fopen(OUTPUT_FILENAME_TIME,"w");
    fprintf(fid,"# %s: auto-generated file\n", OUTPUT_FILENAME_TIME);
    fprintf(fid,"#\n");
    fprintf(fid,"# %8s %12s %12s %12s %12s %12s %12s\n",
            "time", "real(x)", "imag(x)", "real(y)", "imag(y)", "real(e)", "imag(e)");

    // save input and output arrays
    for (i=0; i<num_samples; i++) {
        float complex e = (i < delay) ? 0.0f : y[i] - x[i-delay];
        fprintf(fid,"  %8.1f %12.4e %12.4e %12.4e %12.4e %12.4e %12.4e\n",
                (float)i,
                crealf(x[i]), cimagf(x[i]),
                crealf(y[i]), cimagf(y[i]),
                crealf(e),    cimagf(e));
    }
    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME_TIME);

    // 
    // export frequency data
    //
    unsigned int nfft = 2048;
    float complex y_time[nfft];
    float complex y_freq[nfft];
    for (i=0; i<nfft; i++)
        y_time[i] = i < num_samples ? y[i] : 0.0f;
    fft_run(nfft, y_time, y_freq, LIQUID_FFT_FORWARD, 0);

    // filter spectrum
    unsigned int h_len = 2*num_channels*m+1;
    float h[h_len];
    float fc = 0.5f/(float)num_channels;
    liquid_firdes_kaiser(h_len, fc, As, 0.0f, h);
    float complex h_time[nfft];
    float complex h_freq[nfft];
    for (i=0; i<nfft; i++)
        h_time[i] = i < h_len ? 2*h[i]*fc : 0.0f;
    fft_run(nfft, h_time, h_freq, LIQUID_FFT_FORWARD, 0);

    // error spectrum
    float complex e_time[nfft];
    float complex e_freq[nfft];
    for (i=0; i<nfft; i++)
        e_time[i] = i < delay || i > num_samples ? 0.0f : y[i] - x[i-delay];
    fft_run(nfft, e_time, e_freq, LIQUID_FFT_FORWARD, 0);

    fid = fopen(OUTPUT_FILENAME_FREQ,"w");
    fprintf(fid,"# %s: auto-generated file\n", OUTPUT_FILENAME_FREQ);
    fprintf(fid,"#\n");
    fprintf(fid,"# nfft = %u\n", nfft);
    fprintf(fid,"# %12s %12s %12s %12s\n", "freq", "PSD [dB]", "filter [dB]", "error [dB]");

    // save input and output arrays
    for (i=0; i<nfft; i++) {
        float f = (float)i/(float)nfft - 0.5f;
        unsigned int k = (i + nfft/2)%nfft;
        fprintf(fid,"  %12.8f %12.8f %12.8f %12.8f\n",
                f,
                20*log10f(cabsf(y_freq[k])),
                20*log10f(cabsf(h_freq[k])),
                20*log10f(cabsf(e_freq[k])));
    }
    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME_FREQ);

    printf("done.\n");
    return 0;
}
示例#15
0
/* Decodes the phich channel and saves the CFI in the cfi pointer.
 *
 * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error
 */
int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
    uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) {

  /* Set pointers for layermapping & precoding */
  int i, j;
  cf_t *x[SRSLTE_MAX_LAYERS];
  cf_t *ce_precoding[SRSLTE_MAX_PORTS];
  
  if (q == NULL || slot_symbols == NULL) {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (subframe >= SRSLTE_NSUBFRAMES_X_FRAME) {
    fprintf(stderr, "Invalid nslot %d\n", subframe);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  } else {
    if (nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  }
  if (ngroup >= srslte_regs_phich_ngroups(q->regs)) {
    fprintf(stderr, "Invalid ngroup %d\n", ngroup);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d\n", ngroup, nseq);

  /* number of layers equals number of ports */
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    x[i] = q->x[i];
  }
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    ce_precoding[i] = q->ce[i];
  }

  /* extract symbols */
  if (SRSLTE_PHICH_MAX_NSYMB
      != srslte_regs_phich_get(q->regs, slot_symbols, q->symbols[0], ngroup)) {
    fprintf(stderr, "There was an error getting the phich symbols\n");
    return SRSLTE_ERROR;
  }

  /* extract channel estimates */
  for (i = 0; i < q->cell.nof_ports; i++) {
    if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i], q->ce[i], ngroup)) {
      fprintf(stderr, "There was an error getting the phich symbols\n");
      return SRSLTE_ERROR;
    }
  }

  /* in control channels, only diversity is supported */
  if (q->cell.nof_ports == 1) {
    /* no need for layer demapping */
    srslte_predecoding_single(q->symbols[0], q->ce[0], q->d0, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
  } else {
    srslte_predecoding_diversity(&q->precoding, q->symbols[0], ce_precoding, x,
        q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
    srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports,
    SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports);
  }
  DEBUG("Recv!!: \n", 0);
  DEBUG("d0: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB);

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (ngroup % 2) {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i + 2];
        q->d[2 * i + 1] = q->d0[4 * i + 3];
      }
    } else {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i];
        q->d[2 * i + 1] = q->d0[4 * i + 1];
      }
    }
  } else {
    memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t));
  }

  DEBUG("d: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB);

  srslte_scrambling_c(&q->seq[subframe], q->d);

  /* De-spreading */
  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_EXT_NSF; j++) {
        q->z[i] += conjf(w_ext[nseq][j])
            * q->d[i * SRSLTE_PHICH_EXT_NSF + j] / SRSLTE_PHICH_EXT_NSF;
      }
    }
  } else {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_NORM_NSF; j++) {
        q->z[i] += conjf(w_normal[nseq][j])
            * q->d[i * SRSLTE_PHICH_NORM_NSF + j] / SRSLTE_PHICH_NORM_NSF;
      }
    }
  }

  DEBUG("z: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS);

  srslte_demod_soft_demodulate(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS);

  if (ack) {
    *ack = srslte_phich_ack_decode(q->data_rx, distance);    
  }

  return SRSLTE_SUCCESS;
}
int main(int argc, char* argv[])
{

    bool hermite_false, hermite_true;
    int n1, n2, npml, pad1, pad2, ns, nw, nh;
    float d1, d2, **v, ds, os, dw, ow;
    double omega;
    sf_complex ***f, ***srcw, ***recw, ***obs, ***obs_cut;
    sf_file in, out, source, receiver, record;
    int uts, mts;
    char *order;
    int is, i, j, iw, ih;
    float ***image, **recloc;

    sf_init(argc, argv);

    in = sf_input("in");
    out = sf_output("out");

    if (!sf_getint("nh",&nh)) nh=0;

    if (!sf_getint("uts",&uts)) uts=0;
//#ifdef _OPENMP
//    mts = omp_get_max_threads();
//#else
    mts = 1;
//#endif
    uts = (uts < 1)? mts: uts;

    hermite_false=false;
    hermite_true=true;
    /* Hermite operator */

    if (!sf_getint("npml",&npml)) npml=20;
    /* PML width */

    if (NULL == (order = sf_getstring("order"))) order="j";
    /* discretization scheme (default optimal 9-point) */

    fdprep_order(order);

    /* read input dimension */
    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input.");
    if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input.");

    if (!sf_histfloat(in,"d1",&d1)) sf_error("No d1= in input.");
    if (!sf_histfloat(in,"d2",&d2)) sf_error("No d2= in input.");

    v = sf_floatalloc2(n1,n2);
    sf_floatread(v[0],n1*n2,in);

	/* PML padding */
	pad1 = n1+2*npml;
	pad2 = n2+2*npml;

    /* read receiver */
    if (NULL == sf_getstring("receiver")) sf_error("Need receiver=");
    receiver = sf_input("receiver");
    recloc=sf_floatalloc2(n1,n2);
    sf_floatread(recloc[0],n1*n2,receiver);

    /* read source */
    if (NULL == sf_getstring("source")) sf_error("Need source=");
    source = sf_input("source");

    if (!sf_histint(source,"n3",&ns)) sf_error("No ns=.");
    if (!sf_histfloat(source,"d3",&ds)) ds=d2;
    if (!sf_histfloat(source,"o3",&os)) os=0.;

    f = sf_complexalloc3(n1,n2,ns);

    /* read observed data */
    if (NULL == sf_getstring("record")) sf_error("Need record=");
    record = sf_input("record");

    if (!sf_histint(record,"n4",&nw)) sf_error("No nw=.");
    if (!sf_histfloat(record,"d4",&dw)) sf_error("No dw=.");
    if (!sf_histfloat(record,"o4",&ow)) sf_error("No ow=.");

    obs = sf_complexalloc3(n1,n2,ns);
    obs_cut = sf_complexalloc3(n1,n2,ns);

    srcw = sf_complexalloc3(n1,n2,ns);
    recw = sf_complexalloc3(n1,n2,ns);
    image = sf_floatalloc3(n1,n2,2*nh+1);

    /* Loop over frequency */
    for (iw=0; iw<nw; iw++ ) {
        omega=(double) 2.*SF_PI*(ow+iw*dw);

        sf_warning("Calculating frequency %d out of %d for %f HZ.",iw+1,nw,ow+iw*dw);

    	sf_complexread(f[0][0],n1*n2*ns,source);
        sf_complexread(obs[0][0],n1*n2*ns,record);

        /* generate adjoint source for reverse time migration */
        genadjsrc_rtm(obs, obs_cut, recloc, n1, n2, ns);

        /* initialize sparse solver */
        sparse_init(uts, pad1, pad2);

        /* factorize matrix, change according to different frequencies and models */
        sparse_factor(omega,n1,n2,d1,d2,v,npml,pad1,pad2,uts);

        for (is=0; is < ns; is++ ) {
        for (j=0; j < n2; j++ ) {
        for (i=0; i < n1; i++ ) {
            srcw[is][j][i]=f[is][j][i];
            recw[is][j][i]=obs_cut[is][j][i];
        }
        }
        }

        /* sparse solver for source wavefield */
        sparse_solve(npml, pad1, pad2, srcw, hermite_false, ns, uts);

        /* sparse solver for receiver wavefield */
        sparse_solve(npml, pad1, pad2, recw, hermite_true, ns, uts);

        /* imaging condition */
        for (ih=-nh; ih < nh+1; ih++ ) {
        for (j=0; j<n2; j++ ) {
        for (i=0; i< n1; i++ ) {
        for (is=0; is < ns; is++ ) {
        if (j-abs(ih) >= 0 && j+abs(ih) < n2) {
            image[ih+nh][j][i] += crealf(omega*omega*conjf(srcw[is][j-ih][i])*recw[is][j+ih][i]/(v[j][i]*v[j][i]));
        }
        }
        }
        }
        }

        /* free memory */
        sparse_free(uts);
    } /* end frequency */

    sf_putint(out,"n1",n1);
    sf_putint(out,"n2",n2);
    sf_putint(out,"n3",2*nh+1);
    sf_putfloat(out,"d3",d2);
    sf_putfloat(out,"o3", (float) -nh*d2);

    sf_floatwrite(image[0][0],n1*n2*(2*nh+1),out);

    exit(0);
}
示例#17
0
        d = cpow(d, d);
        f = cpowf(f, f);
        ld = cpowl(ld, ld);
        TEST_TRACE(C99 7.3.8.3)
        d = csqrt(d);
        f = csqrtf(f);
        ld = csqrtl(ld);
        TEST_TRACE(C99 7.3.9.1)
        d = carg(d);
        f = cargf(f);
        ld = cargl(ld);
        TEST_TRACE(C99 7.3.9.2)
        d = cimag(d);
        f = cimagf(f);
        ld = cimagl(ld);
        TEST_TRACE(C99 7.3.9.3)
        d = conj(d);
        f = conjf(f);
        ld = conjl(ld);
        TEST_TRACE(C99 7.3.9.4)
        d = cproj(d);
        f = cprojf(f);
        ld = cprojl(ld);
    }
    TEST_TRACE(C99 7.3.9.5)
    double rd = creal(d);
    float rf = crealf(f);
    long double rld = creall(ld);
    
END_GROUP
示例#18
0
// compute ISI for entire system
//  _gt     :   transmit filter [size: _gt_len x 1]
//  _hc     :   channel filter  [size: _hc_len x 1]
//  _gr     :   receive filter  [size: _gr_len x 1]
float eqlms_cccf_isi(unsigned int    _k,
                     float complex * _gt,
                     unsigned int    _gt_len,
                     float complex * _hc,
                     unsigned int    _hc_len,
                     float complex * _gr,
                     unsigned int    _gr_len)
{
    // generate composite by convolving all filters together
    unsigned int i;
   
#if 0
    printf("\n");
    for (i=0; i<_gt_len; i++)
        printf("  gt(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_gt[i]), cimagf(_gt[i]));

    printf("\n");
    for (i=0; i<_hc_len; i++)
        printf("  hc(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_hc[i]), cimagf(_hc[i]));

    printf("\n");
    for (i=0; i<_gr_len; i++)
        printf("  gr(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(_gr[i]), cimagf(_gr[i]));
    
    printf("\n");
#endif

    windowcf w;
    float complex * rc;

    // start by convolving transmit and channel filters
    unsigned int gthc_len = _gt_len + _hc_len - 1;
    float complex gthc[gthc_len];
    w = windowcf_create(_gt_len);
    for (i=0; i<gthc_len; i++) {
        if (i < _hc_len) windowcf_push(w, conjf(_hc[_hc_len-i-1]));
        else             windowcf_push(w, 0.0f);

        windowcf_read(w, &rc);
        dotprod_cccf_run(_gt, rc, _gt_len, &gthc[i]);
    }
    windowcf_destroy(w);

#if 0
    printf("composite filter:\n");
    for (i=0; i<gthc_len; i++)
        printf("  gthc(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(gthc[i]), cimagf(gthc[i]));
#endif
    
    // convolve result with equalizer
    unsigned int h_len = gthc_len + _gr_len - 1;
    float complex h[h_len];
    w = windowcf_create(gthc_len);
    for (i=0; i<h_len; i++) {
        if (i < _gr_len) windowcf_push(w, conjf(_gr[i]));
        else             windowcf_push(w, 0.0f);

        windowcf_read(w, &rc);
        dotprod_cccf_run(gthc, rc, gthc_len, &h[i]);
    }
    windowcf_destroy(w);

#if 0
    printf("composite filter:\n");
    for (i=0; i<h_len; i++)
        printf("  h(%3u) = %16.12f + j*%16.12f;\n", i+1, crealf(h[i]), cimagf(h[i]));
#endif

    // compute resulting ISI
    unsigned int n0 = (_gt_len + _gr_len + (_gt_len + _gr_len)%2)/2 - 1;
    float isi = 0.0f;
    unsigned int n=0;
    for (i=0; i<h_len; i++) {
        if (i == n0)
            continue;
        else if ( (i%_k)==0 ) {
            isi += crealf( h[i]*conjf(h[i]) );
            n++;
        }
    }
    isi /= crealf( h[n0]*conjf(h[n0]) );
    isi = sqrtf(isi / (float)n);

    return isi;
}
示例#19
0
文件: Mlrwave2.c 项目: Seislet/src
int lrexp(sf_complex **img, sf_complex **dat, bool adj, sf_complex **lt, sf_complex **rt, sf_complex *ww, geopar geop, int pad1, bool verb, int snap, sf_complex ***wvfld)
/*< zero-offset exploding reflector modeling/migration >*/
{
    int it, nt, ix, nx, nx2, iz, nz, nz2, nzx2,  wfnt, wfit;
    int im, i, j, m2, ik, nk;
    float dt, dx, dz, ox;
    sf_complex *curr, **wave, *cwave, *cwavem, c;
    sf_complex *currm;

    nx  = geop->nx;
    nz  = geop->nz;
    dx  = geop->dx;
    dz  = geop->dz;
    ox  = geop->ox;
    nt  = geop->nt;
    dt  = geop->dt;
    snap= geop->snap;
    nzx2= geop->nzx2;
    m2  = geop->m2;
    wfnt= geop->wfnt;

    nk = cfft2_init(pad1,nz,nx,&nz2,&nx2);
    if (nk!=geop->nk) sf_error("nk discrepancy!");

    curr = sf_complexalloc(nzx2);
    cwave  = sf_complexalloc(nk);
    wave = sf_complexalloc2(nzx2,m2);
    if (adj) {
	currm  = sf_complexalloc(nzx2);
	icfft2_allocate(cwave);
    } else {
	cwavem = sf_complexalloc(nk);
	icfft2_allocate(cwavem);
    }

#ifdef _OPENMP
#pragma omp parallel for private(iz)
#endif
    for (iz=0; iz < nzx2; iz++) {
	curr[iz] = sf_cmplx(0.,0.);
    }

    if (adj) { /* migration <- read wavefield */
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
	for (ix=0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		curr[iz+ix*nz2]=dat[ix][iz];
	    }
	}
	wfit = (int)(nt-1)/snap; // wfnt-1
	/* time stepping */
	for (it=nt-1; it > -1; it--) {
	    if (verb) sf_warning("it=%d;",it);
	
	    /* matrix multiplication */
	    for (im = 0; im < m2; im++) {
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz,i,j) shared(currm,lt,curr)
#endif
		for (ix = 0; ix < nx; ix++) {
		    for (iz=0; iz < nz; iz++) {
			i = iz+ix*nz;  /* original grid */
			j = iz+ix*nz2; /* padded grid */
#ifdef SF_HAS_COMPLEX_H
			currm[j] = conjf(lt[im][i])*curr[j];
#else
			currm[j] = sf_cmul(conjf(lt[im][i]), curr[j]);
#endif
		    }
		}
		cfft2(currm,wave[im]);
	    }
#ifdef _OPENMP
#pragma omp parallel for private(ik,im,c) shared(wave,rt,cwave)
#endif	    
	    for (ik = 0; ik < nk; ik++) {
		c = sf_cmplx(0.,0.);
		for (im = 0; im < m2; im++) {
#ifdef SF_HAS_COMPLEX_H
		    c += wave[im][ik]*conjf(rt[ik][im]);
#else
		    c += sf_cmul(wave[im][ik],conjf(rt[ik][im])); //complex multiplies complex
#endif
		}
		cwave[ik] = c;
	    }

	    icfft2(curr,cwave);

	    if (snap > 0 && it%snap == 0) {
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz,j)
#endif
		for ( ix = 0; ix < nx; ix++) {
		    for ( iz = 0; iz<nz; iz++ ) { 
			j = iz+ix*nz2; /* padded grid */
			wvfld[wfit][ix][iz] = curr[j];
		    }
		}
		wfit--;
	    }
	} /*time iteration*/
	/*generate image*/
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
	for (ix=0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		img[ix][iz] = curr[iz+ix*nz2];
	    }
	}
    } else { /* modeling -> write data */
	/*point source*/
	wfit = 0;
	/* time stepping */
	for (it=0; it < nt; it++) {
	    if (verb) sf_warning("it=%d;",it);

	    /* matrix multiplication */
	    cfft2(curr,cwave);
	    
	    for (im = 0; im < m2; im++) {
#ifdef _OPENMP
#pragma omp parallel for private(ik)
#endif
		for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
		    cwavem[ik] = cwave[ik]*rt[ik][im];
#else
		    cwavem[ik] = sf_cmul(cwave[ik],rt[ik][im]);
#endif
		}
		icfft2(wave[im],cwavem);
	    }
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz,i,j,im,c) shared(curr,lt,wave)
#endif
	    for (ix = 0; ix < nx; ix++) {
		for (iz=0; iz < nz; iz++) {
		    i = iz+ix*nz;  /* original grid */
		    j = iz+ix*nz2; /* padded grid */

#ifdef SF_HAS_COMPLEX_H
		c = ww[it] * crealf(img[ix][iz]); // source term
#else
		c = sf_crmul(ww[it], crealf(img[ix][iz])); // source term
#endif
		    
		    for (im = 0; im < m2; im++) {
#ifdef SF_HAS_COMPLEX_H
			c += lt[im][i]*wave[im][j];
#else
			c += sf_cmul(lt[im][i], wave[im][j]);
#endif	    
		    }
		    curr[j] = c;
		}
	    }
	    /* record wavefield*/
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
	for (ix=0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		dat[ix][iz] = curr[iz+ix*nz2];
	    }
	}
	    if (snap > 0 && it%snap == 0) {
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz,j)
#endif
		for ( ix = 0; ix < nx; ix++) {
		    for ( iz = 0; iz<nz; iz++ ) { 
			j = iz+ix*nz2; /* padded grid */
			wvfld[wfit][ix][iz] = curr[j];
		    }
		}
		wfit++;
	    }
	}
    }
    if (verb) sf_warning(".");
    cfft2_finalize();

    return 0;
}
示例#20
0
int main(int argc, char*argv[])
{
    // options
    unsigned int num_symbols=500;   // number of symbols to observe
    float SNRdB = 30.0f;            // signal-to-noise ratio [dB]
    unsigned int hc_len=5;          // channel filter length
    unsigned int k=2;               // matched filter samples/symbol
    unsigned int m=3;               // matched filter delay (symbols)
    float beta=0.3f;                // matched filter excess bandwidth factor
    unsigned int p=3;               // equalizer length (symbols, gr_len = 2*k*p+1)
    float mu = 0.09f;               // LMS learning rate

    // modulation type/depth
    modulation_scheme ms = LIQUID_MODEM_QPSK;
    
    // plotting options
    unsigned int nfft = 512;    // fft size
    float gnuplot_version = 4.2;
    char filename_base[256] = "figures.gen/eqlms_cccf_blind";

    int dopt;
    while ((dopt = getopt(argc,argv,"hf:g:n:s:c:k:m:b:p:u:M:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                      return 0;
        case 'f': strncpy(filename_base,optarg,256);    break;
        case 'g': gnuplot_version = atoi(optarg);       break;
        case 'n': num_symbols   = atoi(optarg); break;
        case 's': SNRdB         = atof(optarg); break;
        case 'c': hc_len        = atoi(optarg); break;
        case 'k': k             = atoi(optarg); break;
        case 'm': m             = atoi(optarg); break;
        case 'b': beta          = atof(optarg); break;
        case 'p': p             = atoi(optarg); break;
        case 'u': mu            = atof(optarg); break;
        case 'M':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: %s, unknown/unsupported modulation scheme '%s'\n", argv[0], optarg);
                return 1;
            }
            break;
        default:
            exit(1);
        }
    }

    // validate input
    if (num_symbols == 0) {
        fprintf(stderr,"error: %s, number of symbols must be greater than zero\n", argv[0]);
        exit(1);
    } else if (hc_len == 0) {
        fprintf(stderr,"error: %s, channel must have at least 1 tap\n", argv[0]);
        exit(1);
    } else if (k < 2) {
        fprintf(stderr,"error: %s, samples/symbol must be at least 2\n", argv[0]);
        exit(1);
    } else if (m == 0) {
        fprintf(stderr,"error: %s, filter semi-length must be at least 1 symbol\n", argv[0]);
        exit(1);
    } else if (beta < 0.0f || beta > 1.0f) {
        fprintf(stderr,"error: %s, filter excess bandwidth must be in [0,1]\n", argv[0]);
        exit(1);
    } else if (p == 0) {
        fprintf(stderr,"error: %s, equalizer semi-length must be at least 1 symbol\n", argv[0]);
        exit(1);
    } else if (mu < 0.0f || mu > 1.0f) {
        fprintf(stderr,"error: %s, equalizer learning rate must be in [0,1]\n", argv[0]);
        exit(1);
    }

    // set 'random' seed on options
    srand( hc_len + p + nfft );

    // derived values
    unsigned int gt_len = 2*k*m+1;   // matched filter length
    unsigned int gr_len = 2*k*p+1;   // equalizer filter length
    unsigned int num_samples = k*num_symbols;

    // bookkeeping variables
    float complex sym_tx[num_symbols];  // transmitted data sequence
    float complex x[num_samples];       // interpolated time series
    float complex y[num_samples];       // channel output
    float complex z[num_samples];       // equalized output

    // least mean-squares (LMS) equalizer
    float mse[num_symbols];             // equalizer mean-squared error
    float complex gr[gr_len];           // equalizer filter coefficients

    unsigned int i;

    // generate matched filter response
    float gtf[gt_len];                   // matched filter response
    liquid_firdes_rnyquist(LIQUID_RNYQUIST_RRC, k, m, beta, 0.0f, gtf);
    
    // convert to complex coefficients
    float complex gt[gt_len];
    for (i=0; i<gt_len; i++)
        gt[i] = gtf[i]; //+ 0.1f*(randnf() + _Complex_I*randnf());

    // create interpolator
    interp_cccf interp = interp_cccf_create(k, gt, gt_len);

    // create the modem objects
    modem mod   = modem_create(ms);
    modem demod = modem_create(ms);
    unsigned int bps = modem_get_bps(mod);
    unsigned int M = 1 << bps;

    // generate channel impulse response, filter
#if 0
    float complex hc[hc_len];           // channel filter coefficients
    hc[0] = 1.0f;
    for (i=1; i<hc_len; i++)
        hc[i] = 0.09f*(randnf() + randnf()*_Complex_I);
#else
    // use fixed channel
    hc_len = 8;
    float complex hc[hc_len];           // channel filter coefficients
    hc[0] =   1.00000000+  0.00000000*_Complex_I;
    hc[1] =   0.08077553+ -0.00247592*_Complex_I;
    hc[2] =   0.03625883+ -0.09219734*_Complex_I;
    hc[3] =   0.05764082+  0.03277601*_Complex_I;
    hc[4] =  -0.04773349+ -0.18766306*_Complex_I;
    hc[5] =  -0.00101735+ -0.00270737*_Complex_I;
    hc[6] =  -0.05796884+ -0.12665297*_Complex_I;
    hc[7] =   0.03805391+ -0.07609370*_Complex_I;
#endif
    firfilt_cccf fchannel = firfilt_cccf_create(hc, hc_len);
    firfilt_cccf_print(fchannel);

    // generate random symbols
    for (i=0; i<num_symbols; i++)
        modem_modulate(mod, rand()%M, &sym_tx[i]);

    // interpolate
    for (i=0; i<num_symbols; i++)
        interp_cccf_execute(interp, sym_tx[i], &x[i*k]);
    
    // push through channel
    float nstd = powf(10.0f, -SNRdB/20.0f);
    for (i=0; i<num_samples; i++) {
        firfilt_cccf_push(fchannel, x[i]);
        firfilt_cccf_execute(fchannel, &y[i]);

        // add noise
        y[i] += nstd*(randnf() + randnf()*_Complex_I)*M_SQRT1_2;
    }

    // push through equalizers
    float grf[gr_len];
    liquid_firdes_rnyquist(LIQUID_RNYQUIST_RRC, k, p, beta, 0.0f, grf);
    for (i=0; i<gr_len; i++) {
        gr[i] = grf[i] / (float)k;
    }

    // create LMS equalizer
    eqlms_cccf eq = eqlms_cccf_create(gr, gr_len);
    eqlms_cccf_set_bw(eq, mu);

    // filtered error vector magnitude (emperical MSE)
    //float zeta=0.05f;   // smoothing factor (small zeta -> smooth MSE)

    float complex d_hat = 0.0f;
    unsigned int num_symbols_rx=0;
    for (i=0; i<num_samples; i++) {

        // push samples into equalizers
        eqlms_cccf_push(eq, y[i]);

        // compute outputs
        eqlms_cccf_execute(eq, &d_hat);

        // store outputs
        z[i] = d_hat;

        // check to see if buffer is full
        if ( i < gr_len) continue;

        // decimate by k
        if ( (i%k) != 0 ) continue;

        // estimate transmitted signal
        unsigned int sym_out;       // output symbol
        float complex d_prime;  // estimated input sample

        // LMS
        modem_demodulate(demod, d_hat, &sym_out);
        modem_get_demodulator_sample(demod, &d_prime);

        // update equalizers
        eqlms_cccf_step(eq, d_prime, d_hat);

#if 0
        // update filtered evm estimate
        float evm = crealf( (d_prime-d_hat)*conjf(d_prime-d_hat) );

        if (num_symbols_rx == 0) {
            mse[num_symbols_rx] = evm; 
        } else {
            mse[num_symbols_rx] = mse[num_symbols_rx-1]*(1-zeta) + evm*zeta;
        }
#else
        // compute ISI for entire system
        eqlms_cccf_get_weights(eq, gr);
        mse[num_symbols_rx] = eqlms_cccf_isi(k, gt, gt_len, hc, hc_len, gr, gr_len);
#endif

        // print filtered evm (emperical rms error)
        if ( ((num_symbols_rx+1)%100) == 0 )
            printf("%4u : mse = %12.8f dB\n",
                    num_symbols_rx+1,
                    20*log10f(mse[num_symbols_rx]));
        
        // increment output symbol counter
        num_symbols_rx++;
    }

    // get equalizer weights
    eqlms_cccf_get_weights(eq, gr);

    // destroy objects
    eqlms_cccf_destroy(eq);
    interp_cccf_destroy(interp);
    firfilt_cccf_destroy(fchannel);
    modem_destroy(mod);
    modem_destroy(demod);

    // 
    // export output
    //
    FILE * fid = NULL;
    char filename[300];

    // 
    // const: constellation
    //
    strncpy(filename, filename_base, 256);
    strcat(filename, "_const.gnu");
    fid = fopen(filename,"w");
    if (!fid) {
        fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename);
        return 1;
    }
    fprintf(fid,"# %s: auto-generated file\n\n", filename);
    fprintf(fid,"reset\n");
    fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n");
    fprintf(fid,"set size ratio 1\n");
    fprintf(fid,"set xrange [-1.5:1.5];\n");
    fprintf(fid,"set yrange [-1.5:1.5];\n");
    fprintf(fid,"set xlabel 'In-phase'\n");
    fprintf(fid,"set ylabel 'Quadrature phase'\n");
    fprintf(fid,"set grid xtics ytics\n");
    fprintf(fid,"set grid linetype 1 linecolor rgb '%s' linewidth 1\n",LIQUID_DOC_COLOR_GRID);
    fprintf(fid,"plot '-' using 1:2 with points pointtype 7 pointsize 0.5 linecolor rgb '%s' title 'first 50%%',\\\n", LIQUID_DOC_COLOR_GRAY);
    fprintf(fid,"     '-' using 1:2 with points pointtype 7 pointsize 0.7 linecolor rgb '%s' title 'last 50%%'\n",     LIQUID_DOC_COLOR_RED);
    // first half of symbols
    for (i=2*p; i<num_symbols/2; i+=k)
        fprintf(fid,"  %12.4e %12.4e\n", crealf(y[i]), cimagf(y[i]));
    fprintf(fid,"e\n");

    // second half of symbols
    for ( ; i<num_symbols; i+=k)
        fprintf(fid,"  %12.4e %12.4e\n", crealf(z[i]), cimagf(z[i]));
    fprintf(fid,"e\n");

    fclose(fid);
    printf("results written to '%s'\n", filename);

    // 
    // mse : mean-squared error
    //
    strncpy(filename, filename_base, 256);
    strcat(filename, "_mse.gnu");
    fid = fopen(filename,"w");
    if (!fid) {
        fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename);
        return 1;
    }
    fprintf(fid,"# %s: auto-generated file\n\n", filename);
    fprintf(fid,"reset\n");
    fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n");
    fprintf(fid,"set size ratio 0.3\n");
    fprintf(fid,"set xrange [0:%u];\n", num_symbols);
    fprintf(fid,"set yrange [1e-3:1e-1];\n");
    fprintf(fid,"set format y '10^{%%L}'\n");
    fprintf(fid,"set log y\n");
    fprintf(fid,"set xlabel 'symbol index'\n");
    fprintf(fid,"set ylabel 'mean-squared error'\n");
    fprintf(fid,"set grid xtics ytics\n");
    fprintf(fid,"set grid linetype 1 linecolor rgb '%s' linewidth 1\n",LIQUID_DOC_COLOR_GRID);
    fprintf(fid,"plot '-' using 1:2 with lines linewidth 4 linetype 1 linecolor rgb '%s' title 'LMS MSE'\n", LIQUID_DOC_COLOR_RED);
    // LMS
    for (i=0; i<num_symbols_rx; i++)
        fprintf(fid,"  %4u %16.8e\n", i, mse[i]);
    fprintf(fid,"e\n");

    fclose(fid);
    printf("results written to '%s'\n", filename);


    // 
    // psd : power spectral density
    //

    // scale transmit filter appropriately
    for (i=0; i<gt_len; i++) gt[i] /= (float)k;

    float complex Gt[nfft];     // transmit matched filter
    float complex Hc[nfft];     // channel response
    float complex Gr[nfft];     // equalizer response
    liquid_doc_compute_psdcf(gt, gt_len, Gt, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0);
    liquid_doc_compute_psdcf(hc, hc_len, Hc, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0);
    liquid_doc_compute_psdcf(gr, gr_len, Gr, nfft, LIQUID_DOC_PSDWINDOW_NONE, 0);
    fft_shift(Gt, nfft);
    fft_shift(Hc, nfft);
    fft_shift(Gr, nfft);
    float freq[nfft];
    for (i=0; i<nfft; i++)
        freq[i] = (float)(i) / (float)nfft - 0.5f;

    strncpy(filename, filename_base, 256);
    strcat(filename, "_freq.gnu");
    fid = fopen(filename,"w");
    if (!fid) {
        fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename);
        return 1;
    }
    fprintf(fid,"# %s: auto-generated file\n\n", filename);
    fprintf(fid,"reset\n");
    fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n");
    fprintf(fid,"set size ratio 0.6\n");
    fprintf(fid,"set xrange [-0.5:0.5];\n");
    fprintf(fid,"set yrange [-10:6]\n");
    fprintf(fid,"set xlabel 'Normalized Frequency'\n");
    fprintf(fid,"set ylabel 'Power Spectral Density [dB]'\n");
    fprintf(fid,"set key top right nobox\n");
    fprintf(fid,"set grid xtics ytics\n");
    fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n",LIQUID_DOC_COLOR_GRID);
    fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'transmit',\\\n",  LIQUID_DOC_COLOR_GRAY);
    fprintf(fid,"     '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'channel',\\\n",   LIQUID_DOC_COLOR_RED);
    fprintf(fid,"     '-' using 1:2 with lines linetype 1 linewidth 1.5 linecolor rgb '%s' title 'equalizer',\\\n", LIQUID_DOC_COLOR_GREEN);
    fprintf(fid,"     '-' using 1:2 with lines linetype 1 linewidth 4.0 linecolor rgb '%s' title 'composite',\\\n", LIQUID_DOC_COLOR_BLUE);
    fprintf(fid,"     '-' using 1:2 with points pointtype 7 pointsize 0.6 linecolor rgb '%s' notitle\n", LIQUID_DOC_COLOR_BLUE);
    // received signal
    for (i=0; i<nfft; i++)
        fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Gt[i])) );
    fprintf(fid,"e\n");

    // channel
    for (i=0; i<nfft; i++)
        fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Hc[i])) );
    fprintf(fid,"e\n");

    // equalizer
    for (i=0; i<nfft; i++)
        fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f(cabsf(Gr[i])) );
    fprintf(fid,"e\n");

    // composite
    for (i=0; i<nfft; i++)
        fprintf(fid,"%12.8f %12.4e\n", freq[i], 20*log10f( cabsf(Gt[i])*cabsf(Hc[i])*cabsf(Gr[i])) );
    fprintf(fid,"e\n");

    // composite
    fprintf(fid,"%12.8f %12.4e\n", -0.5f/(float)k, 20*log10f(0.5f));
    fprintf(fid,"%12.8f %12.4e\n",  0.5f/(float)k, 20*log10f(0.5f));
    fprintf(fid,"e\n");

    fclose(fid);
    printf("results written to '%s'\n", filename);

    //
    // time...
    //
    strncpy(filename, filename_base, 256);
    strcat(filename, "_time.gnu");
    fid = fopen(filename,"w");
    if (!fid) {
        fprintf(stderr,"error: %s, could not open file '%s' for writing\n", argv[0], filename);
        return 1;
    }
    fprintf(fid,"# %s: auto-generated file\n\n", filename);
    fprintf(fid,"reset\n");
    fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n");
    fprintf(fid,"set xrange [0:%u];\n",num_symbols);
    fprintf(fid,"set yrange [-1.5:1.5]\n");
    fprintf(fid,"set size ratio 0.3\n");
    fprintf(fid,"set xlabel 'Symbol Index'\n");
    fprintf(fid,"set key top right nobox\n");
    //fprintf(fid,"set ytics -5,1,5\n");
    fprintf(fid,"set grid xtics ytics\n");
    fprintf(fid,"set pointsize 0.6\n");
    fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n", LIQUID_DOC_COLOR_GRID);
    fprintf(fid,"set multiplot layout 2,1 scale 1.0,1.0\n");

    // real
    fprintf(fid,"# real\n");
    fprintf(fid,"set ylabel 'Real'\n");
    fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '#999999' notitle,\\\n");
    fprintf(fid,"     '-' using 1:2 with points pointtype 7 linecolor rgb '%s' notitle'\n", LIQUID_DOC_COLOR_BLUE);
    // 
    for (i=0; i<num_samples; i++)
        fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, crealf(z[i]));
    fprintf(fid,"e\n");
    // 
    for (i=0; i<num_samples; i+=k)
        fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, crealf(z[i]));
    fprintf(fid,"e\n");

    // imag
    fprintf(fid,"# imag\n");
    fprintf(fid,"set ylabel 'Imag'\n");
    fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 1 linecolor rgb '#999999' notitle,\\\n");
    fprintf(fid,"     '-' using 1:2 with points pointtype 7 linecolor rgb '%s' notitle'\n", LIQUID_DOC_COLOR_GREEN);
    // 
    for (i=0; i<num_samples; i++)
        fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, cimagf(z[i]));
    fprintf(fid,"e\n");
    // 
    for (i=0; i<num_samples; i+=k)
        fprintf(fid,"%12.8f %12.4e\n", (float)i/(float)k, cimagf(z[i]));
    fprintf(fid,"e\n");

    fprintf(fid,"unset multiplot\n");

    // close output file
    fclose(fid);
    printf("results written to '%s'\n", filename);

    return 0;
}
示例#21
0
void
docomplexf (void)
{
#ifndef NO_FLOAT
  complex float ca, cb, cc;
  float f1;

  ca = 1.0 + 1.0 * I;
  cb = 1.0 - 1.0 * I;

  f1 = cabsf (ca);
  fprintf (stdout, "cabsf  : %f\n", f1);

  cc = cacosf (ca);
  fprintf (stdout, "cacosf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cacoshf (ca);
  fprintf (stdout, "cacoshf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cargf (ca);
  fprintf (stdout, "cargf  : %f\n", f1);

  cc = casinf (ca);
  fprintf (stdout, "casinf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = casinhf (ca);
  fprintf (stdout, "casinhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanf (ca);
  fprintf (stdout, "catanf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanhf (ca);
  fprintf (stdout, "catanhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccosf (ca);
  fprintf (stdout, "ccosf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccoshf (ca);
  fprintf (stdout, "ccoshf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cexpf (ca);
  fprintf (stdout, "cexpf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cimagf (ca);
  fprintf (stdout, "cimagf : %f\n", f1);

  cc = clogf (ca);
  fprintf (stdout, "clogf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = conjf (ca);
  fprintf (stdout, "conjf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cpowf (ca, cb);
  fprintf (stdout, "cpowf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cprojf (ca);
  fprintf (stdout, "cprojf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = crealf (ca);
  fprintf (stdout, "crealf : %f\n", f1);

  cc = csinf (ca);
  fprintf (stdout, "csinf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csinhf (ca);
  fprintf (stdout, "csinhf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csqrtf (ca);
  fprintf (stdout, "csqrtf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanf (ca);
  fprintf (stdout, "ctanf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanhf (ca);
  fprintf (stdout, "ctanhf : %f %fi\n", crealf (cc),
	   cimagf (cc));
#endif
}
示例#22
0
int CORE_ctsmqr_corner( int m1, int n1, int m2, int n2, int m3, int n3,
                        int k, int ib, int nb,
                        PLASMA_Complex32_t *A1, int lda1,
                        PLASMA_Complex32_t *A2, int lda2,
                        PLASMA_Complex32_t *A3, int lda3,
                        PLASMA_Complex32_t *V, int ldv,
                        PLASMA_Complex32_t *T, int ldt,
                        PLASMA_Complex32_t *WORK, int ldwork)
{
    int i, j;
    PLASMA_enum side, trans;

    if ( m1 != n1 ) {
        coreblas_error(1, "Illegal value of M1, N1");
        return -1;
    }

    /*  Rebuild the symmetric block: WORK <- A1 */
    for (j = 0; j < n1; j++)
        for (i = j; i < m1; i++){
            *(WORK + i + j*ldwork) = *(A1 + i + j*lda1);
            if (i > j){
                *(WORK + j + i*ldwork) =  conjf( *(WORK + i + j*ldwork) );
            }
        }
    
    /*  Copy the transpose of A2: WORK+nb*ldwork <- A2' */
    for (j = 0; j < n2; j++)
        for (i = 0; i < m2; i++){
            *(WORK + j + (i + nb) * ldwork) = conjf( *(A2 + i + j*lda2) );
        }

    side  = PlasmaLeft;
    trans = PlasmaConjTrans;

    /*  Left application on |A1| */
    /*                      |A2| */
    CORE_ctsmqr(side, trans, m1, n1, m2, n2, k, ib, 
                WORK, ldwork, A2, lda2, 
                V, ldv, T, ldt, 
                WORK + 3*nb*ldwork, ldwork);

    /*  Rebuild the symmetric block: WORK+2*nb*ldwork <- A3 */
    for (j = 0; j < n3; j++)
        for (i = j; i < m3; i++){
            *(WORK + i + (j + 2*nb) * ldwork) = *(A3 + i + j*lda3);
            if (i != j){
                *(WORK + j + (i + 2*nb) * ldwork) =  conjf( *(WORK + i + (j + 2*nb) * ldwork) );
            }
        }
    /*  Left application on | A2'| */
    /*                      | A3 | */
    CORE_ctsmqr(side, trans, n2, m2, m3, n3, k, ib, 
                WORK+nb*ldwork, ldwork, WORK+2*nb*ldwork, ldwork, 
                V, ldv, T, ldt, 
                WORK + 3*nb*ldwork, ldwork);

    side  = PlasmaRight;
    trans = PlasmaNoTrans;

    /*  Right application on | A1 A2' | */
    CORE_ctsmqr(side, trans, m1, n1, n2, m2, k, ib, 
                WORK, ldwork, WORK+nb*ldwork, ldwork, 
                V, ldv, T, ldt, 
                WORK + 3*nb*ldwork, ldwork);

    /*  Copy back the final result to the lower part of A1 */
    /*  A1 = WORK */
    for (j = 0; j < n1; j++)
        for (i = j; i < m1; i++)
            *(A1 + i + j*lda1) = *(WORK + i + j*ldwork);

    /*  Right application on | A2 A3 | */
    CORE_ctsmqr(side, trans, m2, n2, m3, n3, k, ib, 
                A2, lda2, WORK+2*nb*ldwork, ldwork, 
                V,  ldv,  T, ldt, 
                WORK + 3*nb*ldwork, ldwork);

    /*  Copy back the final result to the lower part of A3 */
    /*  A3 = WORK+2*nb*ldwork */
    for (j = 0; j < n3; j++)
        for (i = j; i < m3; i++)
            *(A3 + i + j*lda3) = *(WORK + i + (j+ 2*nb) * ldwork);

    return PLASMA_SUCCESS;
}
示例#23
0
int 
CORE_chbelr(int uplo, int N,
            PLASMA_desc *A,
            PLASMA_Complex32_t *V,
            PLASMA_Complex32_t *TAU,
            int st,
            int ed,
            int eltsize)
{
    int    NB, J1, J2;
    int    len1, len2, t1ed, t2st;
    int    i;
    static PLASMA_Complex32_t zzero = 0.0;
    PLASMA_desc vA=*A;


    /* Check input arguments */
    if (N < 0) {
        coreblas_error(2, "Illegal value of N");
        return -2;
    }
    if (ed <= st) {
        coreblas_error(23, "Illegal value of st and ed (internal)");
        return -23;
    }

    /* Quick return */
    if (N == 0)
        return PLASMA_SUCCESS;

    NB = A->mb;
    if( uplo == PlasmaLower ) {
       /* ========================
        *     LOWER CASE
        * ========================*/
       for (i = ed; i >= st+1 ; i--){
          /* generate Householder to annihilate a(i+k-1,i) within the band */
          *V(i)          = *A(i, (st-1));
          *A(i, (st-1))  = zzero;
          LAPACKE_clarfg_work( 2, A((i-1),(st-1)), V(i), 1, TAU(i));

          /* apply reflector from the left (horizontal row) and from the right for only the diagonal 2x2.*/
          J1    = st;
          J2    = i-2;
          t1ed  = (J2/NB)*NB;
          t2st  = max(t1ed+1,J1);
          len1  = t1ed-J1+1; /* can be negative */
          len2  = J2-t2st+1;
          if(len1>0)CORE_clarfx2(PlasmaLeft, len1 , *V(i), conjf(*TAU(i)), A(i-1, J1  ), ELTLDD(vA, i-1),  A(i,  J1 ), ELTLDD(vA, i) );
          if(len2>0)CORE_clarfx2(PlasmaLeft, len2 , *V(i), conjf(*TAU(i)), A(i-1, t2st), ELTLDD(vA, i-1),  A(i, t2st), ELTLDD(vA, i) );
          CORE_clarfx2c(PlasmaLower, *V(i), *TAU(i), A(i-1, i-1), A(i, i-1), A(i, i)); 
       }
       /* APPLY RIGHT ON THE REMAINING ELEMENT OF KERNEL 1 */
       for (i = ed; i >= st+1 ; i--){
          J1    = i+1;
          J2    = min(ed,N);
          t1ed  = (J2/NB)*NB;
          t2st  = max(t1ed+1,J1);
          len1  = t1ed-J1+1; /* can be negative */
          len2  = J2-t2st+1;
          if(len1>0)CORE_clarfx2(PlasmaRight, len1, *V(i), *TAU(i), A(J1,  i-1), ELTLDD(vA, J1)  , A(J1  , i), ELTLDD(vA, J1)   );
          if(len2>0)CORE_clarfx2(PlasmaRight, len2, *V(i), *TAU(i), A(t2st,i-1), ELTLDD(vA, t2st), A(t2st, i), ELTLDD(vA, t2st) );
       }
    }else{
       /* ========================
        *       UPPER CASE
        * ========================*/
       for (i = ed; i >= st+1 ; i--){
          /* generate Householder to annihilate a(i+k-1,i) within the band*/
          *V(i)          = *A((st-1),  i);
          *A((st-1),  i) = zzero;
          LAPACKE_clarfg_work( 2, A(st-1, i-1), V(i), 1, TAU(i));

          /* apply reflector from the left (horizontal row) and from the right for only the diagonal 2x2.*/
          J1    = st;
          J2    = i-2;
          t1ed  = (J2/NB)*NB;
          t2st  = max(t1ed+1,J1);
          len1  = t1ed-J1+1; /* can be negative */
          len2  = J2-t2st+1;
          if(len1>0)CORE_clarfx2(PlasmaRight, len1, conjf(*V(i)), conjf(*TAU(i)), A(J1,  i-1), ELTLDD(vA, J1)  , A(J1  , i), ELTLDD(vA, J1)   );
          if(len2>0)CORE_clarfx2(PlasmaRight, len2, conjf(*V(i)), conjf(*TAU(i)), A(t2st,i-1), ELTLDD(vA, t2st), A(t2st, i), ELTLDD(vA, t2st) );
          CORE_clarfx2c(PlasmaUpper, *V(i), *TAU(i), A(i-1, i-1), A(i-1, i), A(i,i));
       }
       /* APPLY LEFT ON THE REMAINING ELEMENT OF KERNEL 1 */
       for (i = ed; i >= st+1 ; i--){
          J1    = i+1;
          J2    = min(ed,N);
          t1ed  = (J2/NB)*NB;
          t2st  = max(t1ed+1,J1);
          len1  = t1ed-J1+1; /* can be negative */
          len2  = J2-t2st+1;
          if(len1>0)CORE_clarfx2(PlasmaLeft, len1 , conjf(*V(i)), *TAU(i), A(i-1, J1  ), ELTLDD(vA, i-1),  A(i,  J1 ), ELTLDD(vA, i) );
          if(len2>0)CORE_clarfx2(PlasmaLeft, len2 , conjf(*V(i)), *TAU(i), A(i-1, t2st), ELTLDD(vA, i-1),  A(i, t2st), ELTLDD(vA, i) );
       }
    }  /* end of else for the upper case */

    return PLASMA_SUCCESS;

}
示例#24
0
int main() {
    // parameters
    float phase_offset      = 0.8f;     // carrier phase offset
    float frequency_offset  = 0.01f;    // carrier frequency offset
    float wn                = 0.05f;    // pll bandwidth
    float zeta              = 0.707f;   // pll damping factor
    float K                 = 1000;     // pll loop gain
    unsigned int n          = 256;      // number of samples
    unsigned int d          = n/32;     // print every "d" lines

    //
    float theta[n];         // input phase
    float complex x[n];     // input sinusoid
    float phi[n];           // output phase
    float complex y[n];     // output sinusoid

    // generate iir loop filter object
    iirfilt_rrrf H = iirfilt_rrrf_create_pll(wn, zeta, K);
    iirfilt_rrrf_print(H);

    unsigned int i;

    // generate input
    float t=phase_offset;
    float dt = frequency_offset;
    for (i=0; i<n; i++) {
        theta[i] = t;
        x[i] = cexpf(_Complex_I*theta[i]);

        t += dt;
    }

    // run loop
    float phi_hat=0.0f;
    for (i=0; i<n; i++) {
        y[i] = cexpf(_Complex_I*phi_hat);

        // compute error
        float e = cargf(x[i]*conjf(y[i]));

        if ( (i%d)==0 )
            printf("e(%3u) = %12.8f;\n", i, e);

        // filter error
        iirfilt_rrrf_execute(H,e,&phi_hat);

        phi[i] = phi_hat;
    }

    // destroy filter
    iirfilt_rrrf_destroy(H);

    // open output file
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"clear all;\n");
    fprintf(fid,"n=%u;\n",n);

    for (i=0; i<n; i++) {
        fprintf(fid,"theta(%3u) = %16.8e;\n", i+1, theta[i]);
        fprintf(fid,"  phi(%3u) = %16.8e;\n", i+1, phi[i]);
    }
    fprintf(fid,"t=0:(n-1);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(t,theta,t,phi);\n");
    fprintf(fid,"xlabel('sample index');\n");
    fprintf(fid,"ylabel('phase');\n");

    fclose(fid);

    printf("output written to %s.\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
示例#25
0
/***************************************************************************//**
 * @ingroup CORE_PLASMA_Complex32_t
 *******************************************************************************
 *
 *  Purpose
 *  =======
 *
 *  CORE_clarfx2c applies a complex elementary reflector H to a diagonal corner 
 *  C=[C1, C2, C3], from both the left and the right side. C = H * C * H.
 *  It is used in the case of Hermetian.
 *  If PlasmaLower, a left apply is followed by a right apply.
 *  If PlasmaUpper, a right apply is followed by a left apply.
 *  H is represented in the form
 *   
 *  This routine is a special code for a corner C diagonal block  C1
 *                                                                C2  C3
 *   
 *
 *        H = I - tau * v * v'
 *
 *  where tau is a complex scalar and v is a complex vector.
 *
 *  If tau = 0, then H is taken to be the unit matrix
 *
 *  This version uses inline code if H has order < 11.
 *
 *  Arguments
 *  =========
 *
 * @param[in] uplo
 *          = PlasmaUpper: Upper triangle of A is stored;
 *          = PlasmaLower: Lower triangle of A is stored.
 *
 * @param[in] V
 *          The float complex V in the representation of H.
 *
 * @param[in] TAU
 *          The value tau in the representation of H.
 *
 * @param[in,out] C1
 *          On entry, the element C1.
 *          On exit, C1 is overwritten by the result H * C * H.
 *
 * @param[in,out] C2
 *          On entry, the element C2.
 *          On exit, C2 is overwritten by the result H * C * H.
  *
 * @param[in,out] C3
 *          On entry, the element C3.
 *          On exit, C3 is overwritten by the result H * C * H.
 *
 *  =====================================================================
 *
 * @return
 *          \retval PLASMA_SUCCESS successful exit
 *          \retval <0 if -i, the i-th argument had an illegal value
 *
 ******************************************************************************/
int 
CORE_clarfx2c(PLASMA_enum uplo,
              PLASMA_Complex32_t V,
              PLASMA_Complex32_t TAU,
              PLASMA_Complex32_t *C1,
              PLASMA_Complex32_t *C2,
              PLASMA_Complex32_t *C3)
{
    PLASMA_Complex32_t T2, SUM, TEMP;

    /* Quick return */
    if (TAU == (PLASMA_Complex32_t)0.0)
        return PLASMA_SUCCESS;

    /*
     *        Special code for a diagonal block  C1
     *                                           C2  C3
     */
    if(uplo==PlasmaLower) {   
        /* 
         *  Do the corner Left then Right (used for the lower case
         *  tridiag) L and R for the 2x2 corner
         *             C(N-1, N-1)  C(N-1,N)        C1  TEMP 
         *             C(N  , N-1)  C(N  ,N)        C2  C3 
         *  For Left : use conjf(TAU) and V. 
         *  For Right: nothing, keep TAU and V. 
         *  Left 1 ==> C1 
         *             C2 
         */
        TEMP = conjf(*C2); /*  copy C2 here before modifying it. */
        T2   = conjf(TAU) * V;
        SUM  = *C1 + conjf(V) * (*C2);
        *C1  = *C1 - SUM * conjf(TAU);
        *C2  = *C2 - SUM * T2;
        /*  Left 2 ==> TEMP */
        /*             C3 */
        SUM  = TEMP + conjf(V) * (*C3);
        TEMP = TEMP - SUM * conjf(TAU);
        *C3  = *C3  - SUM * T2;
        /*  Right 1 ==>  C1 TEMP.  NB: no need to compute corner (2,2)=TEMP */
        T2  = TAU * conjf(V);
        SUM = *C1 + V*TEMP;
        *C1 = *C1 - SUM*TAU;
        /*  Right 2 ==> C2 C3 */
        SUM = *C2   + V*(*C3);
        *C2 = *C2   - SUM*TAU;
        *C3 = *C3   - SUM*T2;
    }
    else { 
        /*  
         * Do the corner Right then Left (used for the upper case tridiag) 
         *             C(N-1, N-1)  C(N-1,N)        C1    C2 
         *             C(N  , N-1)  C(N  ,N)        TEMP  C3 
         *  For Left : use TAU       and conjf(V). 
         *  For Right: use conjf(TAU) and conjf(V). 
         *  Right 1 ==> C1 C2 
         */
        V    = conjf(V);
        TEMP = conjf(*C2); /*  copy C2 here before modifying it. */
        T2   = conjf(TAU) * conjf(V);
        SUM  = *C1 + V   * (*C2);
        *C1  = *C1 - SUM * conjf(TAU);
        *C2  = *C2 - SUM * T2;
        /*  Right 2 ==> TEMP C3 */
        SUM  = TEMP + V   * (*C3);
        TEMP = TEMP - SUM * conjf(TAU);
        *C3  = *C3  - SUM * T2;
        /*  Left 1 ==> C1 */
        /*             TEMP. NB: no need to compute corner (2,1)=TEMP */
        T2  = TAU * V;
        SUM = *C1 + conjf(V) * TEMP;
        *C1 = *C1 - SUM * TAU;
        /*  Left 2 ==> C2 */
        /*             C3 */
        SUM = *C2 + conjf(V) * (*C3);
        *C2 = *C2 - SUM * TAU;
        *C3 = *C3 - SUM * T2;
    }

    return PLASMA_SUCCESS;
}
示例#26
0
TEST(complex, conjf) {
  ASSERT_EQ(0.0f, conjf(0));
}
示例#27
0
// Q/R decomposition using the Gram-Schmidt algorithm
void MATRIX(_qrdecomp_gramschmidt)(T * _x,
                                   unsigned int _rx,
                                   unsigned int _cx,
                                   T * _Q,
                                   T * _R)
{
    // validate input
    if (_rx != _cx) {
        fprintf(stderr,"error: matrix_qrdecomp_gramschmidt(), input matrix not square\n");
        exit(-1);
    }
    unsigned int n = _rx;

    unsigned int i;
    unsigned int j;
    unsigned int k;

    // generate and initialize matrices
    T e[n*n];   // normalized...
    for (i=0; i<n*n; i++)
        e[i] = 0.0f;

    for (k=0; k<n; k++) {
        // e(i,k) <- _x(i,k)
        for (i=0; i<n; i++)
            matrix_access(e,n,n,i,k) = matrix_access(_x,n,n,i,k);

        // subtract...
        for (i=0; i<k; i++) {
            // compute dot product _x(:,k) * e(:,i)
            T g = 0;
            for (j=0; j<n; j++) {
                T prod = matrix_access(_x,n,n,j,k) * conj( matrix_access(e,n,n,j,i) );
                g += prod;
            }
            //printf("  i=%2u, g = %12.4e\n", i, crealf(g));
            for (j=0; j<n; j++)
                matrix_access(e,n,n,j,k) -= matrix_access(e,n,n,j,i) * g;
        }

        // compute e_k = e_k / |e_k|
        float ek = 0.0f;
        T ak;
        for (i=0; i<n; i++) {
            ak = matrix_access(e,n,n,i,k);
            ek += fabsf( ak*conjf(ak) );
        }
        ek = sqrtf(ek);

        // normalize e
        for (i=0; i<n; i++)
            matrix_access(e,n,n,i,k) /= ek;
    }

    // move Q
    memmove(_Q, e, n*n*sizeof(T));

    // compute R
    // j : row
    // k : column
    for (j=0; j<n; j++) {
        for (k=0; k<n; k++) {
            if (k < j) {
                matrix_access(_R,n,n,j,k) = 0.0f;
            } else {
                // compute dot product between and Q(:,j) and _x(:,k)
                T g = 0;
                for (i=0; i<n; i++) {
                    T prod = conj( matrix_access(_Q,n,n,i,j) ) * matrix_access(_x,n,n,i,k);
                    g += prod;
                }
                matrix_access(_R,n,n,j,k) = g;
            }
        }
    }
}
int main(int argc, char*argv[])
{
    srand(time(NULL));

    // options
    unsigned int num_symbols=500;   // number of symbols to observe
    float SNRdB = 30.0f;            // signal-to-noise ratio [dB]
    unsigned int hc_len=5;          // channel filter length
    unsigned int k=2;               // matched filter samples/symbol
    unsigned int m=3;               // matched filter delay (symbols)
    float beta=0.3f;                // matched filter excess bandwidth factor
    unsigned int p=3;               // equalizer length (symbols, hp_len = 2*k*p+1)
    float mu = 0.08f;               // learning rate

    // modulation type/depth
    modulation_scheme ms = LIQUID_MODEM_QPSK;

    int dopt;
    while ((dopt = getopt(argc,argv,"hn:s:c:k:m:b:p:u:M:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                      return 0;
        case 'n': num_symbols   = atoi(optarg); break;
        case 's': SNRdB         = atof(optarg); break;
        case 'c': hc_len        = atoi(optarg); break;
        case 'k': k             = atoi(optarg); break;
        case 'm': m             = atoi(optarg); break;
        case 'b': beta          = atof(optarg); break;
        case 'p': p             = atoi(optarg); break;
        case 'u': mu            = atof(optarg); break;
        case 'M':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: %s, unknown/unsupported modulation scheme '%s'\n", argv[0], optarg);
                return 1;
            }
            break;
        default:
            exit(1);
        }
    }

    // validate input
    if (num_symbols == 0) {
        fprintf(stderr,"error: %s, number of symbols must be greater than zero\n", argv[0]);
        exit(1);
    } else if (hc_len == 0) {
        fprintf(stderr,"error: %s, channel must have at least 1 tap\n", argv[0]);
        exit(1);
    } else if (k < 2) {
        fprintf(stderr,"error: %s, samples/symbol must be at least 2\n", argv[0]);
        exit(1);
    } else if (m == 0) {
        fprintf(stderr,"error: %s, filter semi-length must be at least 1 symbol\n", argv[0]);
        exit(1);
    } else if (beta < 0.0f || beta > 1.0f) {
        fprintf(stderr,"error: %s, filter excess bandwidth must be in [0,1]\n", argv[0]);
        exit(1);
    } else if (p == 0) {
        fprintf(stderr,"error: %s, equalizer semi-length must be at least 1 symbol\n", argv[0]);
        exit(1);
    } else if (mu < 0.0f || mu > 1.0f) {
        fprintf(stderr,"error: %s, equalizer learning rate must be in [0,1]\n", argv[0]);
        exit(1);
    }

    // derived values
    unsigned int hm_len = 2*k*m+1;   // matched filter length
    unsigned int hp_len = 2*k*p+1;   // equalizer filter length
    unsigned int num_samples = k*num_symbols;

    // bookkeeping variables
    float complex sym_tx[num_symbols];  // transmitted data sequence
    float complex x[num_samples];       // interpolated time series
    float complex y[num_samples];       // channel output
    float complex z[num_samples];       // equalized output

    float hm[hm_len];                   // matched filter response
    float complex hc[hc_len];           // channel filter coefficients
    float complex hp[hp_len];           // equalizer filter coefficients

    unsigned int i;

    // generate matched filter response
    liquid_firdes_rnyquist(LIQUID_FIRFILT_RRC, k, m, beta, 0.0f, hm);
    firinterp_crcf interp = firinterp_crcf_create(k, hm, hm_len);

    // create the modem objects
    modem mod   = modem_create(ms);
    modem demod = modem_create(ms);
    unsigned int M = 1 << modem_get_bps(mod);

    // generate channel impulse response, filter
    hc[0] = 1.0f;
    for (i=1; i<hc_len; i++)
        hc[i] = 0.09f*(randnf() + randnf()*_Complex_I);
    firfilt_cccf fchannel = firfilt_cccf_create(hc, hc_len);

    // generate random symbols
    for (i=0; i<num_symbols; i++)
        modem_modulate(mod, rand()%M, &sym_tx[i]);

    // interpolate
    for (i=0; i<num_symbols; i++)
        firinterp_crcf_execute(interp, sym_tx[i], &x[i*k]);
    
    // push through channel
    float nstd = powf(10.0f, -SNRdB/20.0f);
    for (i=0; i<num_samples; i++) {
        firfilt_cccf_push(fchannel, x[i]);
        firfilt_cccf_execute(fchannel, &y[i]);

        // add noise
        y[i] += nstd*(randnf() + randnf()*_Complex_I)*M_SQRT1_2;
    }

    // push through equalizer
    // create equalizer, intialized with square-root Nyquist filter
    eqlms_cccf eq = eqlms_cccf_create_rnyquist(LIQUID_FIRFILT_RRC, k, p, beta, 0.0f);
    eqlms_cccf_set_bw(eq, mu);

    // get initialized weights
    eqlms_cccf_get_weights(eq, hp);

    // filtered error vector magnitude (emperical RMS error)
    float evm_hat = 0.03f;

    float complex d_hat = 0.0f;
    for (i=0; i<num_samples; i++) {
        // print filtered evm (emperical rms error)
        if ( ((i+1)%50)==0 )
            printf("%4u : rms error = %12.8f dB\n", i+1, 10*log10(evm_hat));

        eqlms_cccf_push(eq, y[i]);
        eqlms_cccf_execute(eq, &d_hat);

        // store output
        z[i] = d_hat;

        // decimate by k
        if ( (i%k) != 0 ) continue;

        // estimate transmitted signal
        unsigned int sym_out;   // output symbol
        float complex d_prime;  // estimated input sample
        modem_demodulate(demod, d_hat, &sym_out);
        modem_get_demodulator_sample(demod, &d_prime);

        // update equalizer
        eqlms_cccf_step(eq, d_prime, d_hat);

        // update filtered evm estimate
        float evm = crealf( (d_prime-d_hat)*conjf(d_prime-d_hat) );
        evm_hat = 0.98f*evm_hat + 0.02f*evm;
    }

    // get equalizer weights
    eqlms_cccf_get_weights(eq, hp);

    // destroy objects
    eqlms_cccf_destroy(eq);
    firinterp_crcf_destroy(interp);
    firfilt_cccf_destroy(fchannel);
    modem_destroy(mod);
    modem_destroy(demod);

    // 
    // export output
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");

    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"m = %u;\n", m);
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = num_symbols*k;\n");

    // save transmit matched-filter response
    fprintf(fid,"hm_len = 2*k*m+1;\n");
    fprintf(fid,"hm = zeros(1,hm_len);\n");
    for (i=0; i<hm_len; i++)
        fprintf(fid,"hm(%4u) = %12.4e;\n", i+1, hm[i]);

    // save channel impulse response
    fprintf(fid,"hc_len = %u;\n", hc_len);
    fprintf(fid,"hc = zeros(1,hc_len);\n");
    for (i=0; i<hc_len; i++)
        fprintf(fid,"hc(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(hc[i]), cimagf(hc[i]));

    // save equalizer response
    fprintf(fid,"hp_len = %u;\n", hp_len);
    fprintf(fid,"hp = zeros(1,hp_len);\n");
    for (i=0; i<hp_len; i++)
        fprintf(fid,"hp(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(hp[i]), cimagf(hp[i]));

    // save sample sets
    fprintf(fid,"x = zeros(1,num_samples);\n");
    fprintf(fid,"y = zeros(1,num_samples);\n");
    fprintf(fid,"z = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i]));
        fprintf(fid,"y(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i]));
        fprintf(fid,"z(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(z[i]), cimagf(z[i]));
    }

    // plot time response
    fprintf(fid,"t = 0:(num_samples-1);\n");
    fprintf(fid,"tsym = 1:k:num_samples;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(t,real(z),...\n");
    fprintf(fid,"     t(tsym),real(z(tsym)),'x');\n");

    // plot constellation
    fprintf(fid,"tsym0 = tsym(1:(length(tsym)/2));\n");
    fprintf(fid,"tsym1 = tsym((length(tsym)/2):end);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(real(z(tsym0)),imag(z(tsym0)),'x','Color',[1 1 1]*0.7,...\n");
    fprintf(fid,"     real(z(tsym1)),imag(z(tsym1)),'x','Color',[1 1 1]*0.0);\n");
    fprintf(fid,"xlabel('In-Phase');\n");
    fprintf(fid,"ylabel('Quadrature');\n");
    fprintf(fid,"axis([-1 1 -1 1]*1.5);\n");
    fprintf(fid,"axis square;\n");
    fprintf(fid,"grid on;\n");

    // compute composite response
    fprintf(fid,"g  = real(conv(conv(hm,hc),hp));\n");

    // plot responses
    fprintf(fid,"nfft = 1024;\n");
    fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"Hm = 20*log10(abs(fftshift(fft(hm/k,nfft))));\n");
    fprintf(fid,"Hc = 20*log10(abs(fftshift(fft(hc,  nfft))));\n");
    fprintf(fid,"Hp = 20*log10(abs(fftshift(fft(hp,  nfft))));\n");
    fprintf(fid,"G  = 20*log10(abs(fftshift(fft(g/k, nfft))));\n");

    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(f,Hm, f,Hc, f,Hp, f,G,'-k','LineWidth',2, [-0.5/k 0.5/k],[-6.026 -6.026],'or');\n");
    fprintf(fid,"xlabel('Normalized Frequency');\n");
    fprintf(fid,"ylabel('Power Spectral Density');\n");
    fprintf(fid,"legend('transmit','channel','equalizer','composite','half-power points',1);\n");
    fprintf(fid,"axis([-0.5 0.5 -12 8]);\n");
    fprintf(fid,"grid on;\n");
    
    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);

    return 0;
}
示例#29
0
// frame detection
void ofdmframesync_execute_S0b(ofdmframesync _q)
{
    //printf("t = %u\n", _q->timer);
    _q->timer++;

    if (_q->timer < _q->M2)
        return;

    // reset timer
    _q->timer = _q->M + _q->cp_len - _q->backoff;

    //
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);

    // estimate S0 gain
    ofdmframesync_estimate_gain_S0(_q, &rc[_q->cp_len], _q->G1);

    float complex s_hat;
    ofdmframesync_S0_metrics(_q, _q->G1, &s_hat);
    s_hat *= _q->g0;

    _q->s_hat_1 = s_hat;

#if DEBUG_OFDMFRAMESYNC_PRINT
    float tau_hat  = cargf(s_hat) * (float)(_q->M2) / (2*M_PI);
    printf("********** S0[1] received ************\n");
    printf("    s_hat   :   %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat));
    printf("  tau_hat   :   %12.8f\n", tau_hat);

    // new timing offset estimate
    tau_hat  = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI);
    printf("  tau_hat * :   %12.8f\n", tau_hat);

    printf("**********\n");
#endif

    // re-adjust timer accordingly
    float tau_prime = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI);
    _q->timer -= (int)roundf(tau_prime);

#if 0
    if (cabsf(s_hat) < 0.3f) {
#if DEBUG_OFDMFRAMESYNC_PRINT
        printf("false alarm S0[1]\n");
#endif
        // false alarm
        ofdmframesync_reset(_q);
        return;
    }
#endif

    float complex g_hat = 0.0f;
    unsigned int i;
    for (i=0; i<_q->M; i++)
        g_hat += _q->G1[i] * conjf(_q->G0[i]);

#if 0
    // compute carrier frequency offset estimate using freq. domain method
    float nu_hat = 2.0f * cargf(g_hat) / (float)(_q->M);
#else
    // compute carrier frequency offset estimate using ML method
    float complex t0 = 0.0f;
    for (i=0; i<_q->M2; i++) {
        t0 += conjf(rc[i])       *       _q->s0[i] * 
                    rc[i+_q->M2] * conjf(_q->s0[i+_q->M2]);
    }
    float nu_hat = cargf(t0) / (float)(_q->M2);
#endif

#if DEBUG_OFDMFRAMESYNC_PRINT
    printf("   nu_hat   :   %12.8f\n", nu_hat);
#endif

    // set NCO frequency
    nco_crcf_set_frequency(_q->nco_rx, nu_hat);

    _q->state = OFDMFRAMESYNC_STATE_PLCPLONG;
}
示例#30
0
static void zconj(long N, complex float* dst, const complex float* src)
{
	for (long i = 0; i < N; i++)
		dst[i] = conjf(src[i]);
}