Example #1
0
// 
// Test DC gain control
//
void autotest_agc_crcf_dc_gain_control()
{
    // set paramaters
    float gamma = 0.1f;     // nominal signal level
    float bt    = 0.1f;     // bandwidth-time product
    float tol   = 0.001f;   // error tolerance

    // create AGC object and initialize
    agc_crcf q = agc_crcf_create();
    agc_crcf_set_bandwidth(q, bt);

    unsigned int i;
    float complex x = gamma;    // input sample
    float complex y;            // output sample
    for (i=0; i<256; i++)
        agc_crcf_execute(q, x, &y);
    
    // Check results
    CONTEND_DELTA( crealf(y), 1.0f, tol );
    CONTEND_DELTA( cimagf(y), 0.0f, tol );
    CONTEND_DELTA( agc_crcf_get_gain(q), 1.0f/gamma, tol );

    // destroy AGC object
    agc_crcf_destroy(q);
}
//  _p      : polynomial,     [size: _order+1 x 1]
//  _r      : roots (sorted), [size: _order   x 1]
//  _ordre  : polynomial order
void polyf_findroots_testbench(float *         _p,
                               float complex * _r,
                               unsigned int    _order)
{
    float tol=1e-6f;

    float complex roots[_order];
    polyf_findroots(_p,_order+1,roots);

    unsigned int i;
    if (liquid_autotest_verbose) {
        printf("poly:\n");
        for (i=0; i<=_order; i++)
            printf("  p[%3u] = %12.8f\n", i, _p[i]);

        printf("roots:\n");
        for (i=0; i<_order; i++) {
            float e = cabsf(roots[i] - _r[i]);
            printf("  r[%3u] = %12.8f + %12.8fj (%12.8f + %12.8fj) %12.4e%s\n",
                    i,
                    crealf(roots[i]), cimagf(roots[i]),
                    crealf(   _r[i]), cimagf(   _r[i]),
                    e, e < tol ? "" : " *");
        }
    }

    // check to see if roots match within relative tolerance
    for (i=0; i<_order; i++) {
        CONTEND_DELTA(crealf(roots[i]), crealf(_r[i]), tol);
        CONTEND_DELTA(cimagf(roots[i]), cimagf(_r[i]), tol);
    }
}
// 
// AUTOTEST: inverse
//
void autotest_matrixcf_inv()
{
    float tol = 1e-3f;

    float complex x[9] = {
      0.054076+  0.263160*_I,   0.570850+ -0.208230*_I,   0.551480+ -0.189100*_I, 
     -0.223700+  0.298170*_I,   0.416250+  1.152200*_I,  -0.299920+  0.469310*_I, 
     -1.485400+ -0.192370*_I,  -0.679430+  0.528100*_I,  -0.827860+ -0.345740*_I
    };

    float complex x_inv[9];
    float complex x_inv_test[9] = {
     -0.277900+ -0.717820*_I,   0.559370+  0.305450*_I,  -0.691300+  0.080448*_I, 
     -0.026647+ -0.650270*_I,   0.702820+ -0.990530*_I,   0.237160+  0.231150*_I, 
      1.319100+  1.318300*_I,  -0.539880+  0.808700*_I,  -0.255610+  0.084624*_I
    };

    memmove(x_inv, x, sizeof(x));
    matrixcf_inv(x_inv,3,3);

    unsigned int i;
    for (i=0; i<9; i++) {
        CONTEND_DELTA(crealf(x_inv[i]), crealf(x_inv_test[i]), tol);
        CONTEND_DELTA(cimagf(x_inv[i]), cimagf(x_inv_test[i]), tol);
    }
}
Example #4
0
// autotest helper function
//  _b      :   filter coefficients (numerator)
//  _a      :   filter coefficients (denominator)
//  _h_len  :   filter coefficients length
//  _x      :   input array
//  _x_len  :   input array length
//  _y      :   output array
//  _y_len  :   output array length
void iirfilt_crcf_test(float *         _b,
                       float *         _a,
                       unsigned int    _h_len,
                       float complex * _x,
                       unsigned int    _x_len,
                       float complex * _y,
                       unsigned int    _y_len)
{
    float tol = 0.001f;

    // load filter coefficients externally
    iirfilt_crcf q = iirfilt_crcf_create(_b, _h_len, _a, _h_len);

    // allocate memory for output
    float complex y_test[_y_len];

    unsigned int i;
    // compute output
    for (i=0; i<_x_len; i++) {
        iirfilt_crcf_execute(q, _x[i], &y_test[i]);
        
        CONTEND_DELTA( crealf(y_test[i]), crealf(_y[i]), tol );
        CONTEND_DELTA( cimagf(y_test[i]), cimagf(_y[i]), tol );
    }
    
    // destroy filter object
    iirfilt_crcf_destroy(q);
}
// helper function (compare structured object to ordinal computation)
void runtest_dotprod_cccf(unsigned int _n)
{
    float tol = 1e-3;
    float complex h[_n];
    float complex x[_n];

    // generate random coefficients
    unsigned int i;
    for (i=0; i<_n; i++) {
        h[i] = randnf() + randnf() * _Complex_I;
        x[i] = randnf() + randnf() * _Complex_I;
    }
    
    // compute expected value (ordinal computation)
    float complex y_test;
    dotprod_cccf_run(h, x, _n, &y_test);

    // create and run dot product object
    float complex y;
    dotprod_cccf dp;
    dp = dotprod_cccf_create(h,_n);
    dotprod_cccf_execute(dp, x, &y);
    dotprod_cccf_destroy(dp);

    // print results
    if (liquid_autotest_verbose) {
        printf("  dotprod-cccf-%-4u : %12.8f + j%12.8f (expected %12.8f + j%12.8f)\n",
                _n, crealf(y), cimagf(y), crealf(y_test), cimagf(y_test));
    }

    // validate result
    CONTEND_DELTA(crealf(y), crealf(y_test), tol);
    CONTEND_DELTA(cimagf(y), cimagf(y_test), tol);
}
Example #6
0
// test sparse floating-point vector multiplication
void autotest_smatrixf_vmul()
{
    float tol = 1e-6f;

    // A = [
    //  0 0 0 0 4
    //  0 0 0 0 0
    //  0 0 0 3 0
    //  2 0 0 0 1

    // create sparse matrix and set values
    smatrixf A = smatrixf_create(4, 5);
    smatrixf_set(A, 0,4, 4);
    smatrixf_set(A, 2,3, 3);
    smatrixf_set(A, 3,0, 2);
    smatrixf_set(A, 3,4, 0);
    smatrixf_set(A, 3,4, 1);

    // initialize input vector
    float x[5] = {7, 1, 5, 2, 2};

    float y_test[4] = {8, 0, 6, 16};
    float y[4];

    // multiply and run test
    smatrixf_vmul(A,x,y);

    // check values
    CONTEND_DELTA( y[0], y_test[0], tol );
    CONTEND_DELTA( y[1], y_test[1], tol );
    CONTEND_DELTA( y[2], y_test[2], tol );
    CONTEND_DELTA( y[3], y_test[3], tol );

    smatrixf_destroy(A);
}
void autotest_nco_crcf_mix_block_up()
{
    // options
    unsigned int buf_len = 4096;
    float        phase   = 0.7123f;
    float        freq    = 0; //0.1324f;
    float        tol     = 1e-2f;

    // create object
    nco_crcf nco = nco_crcf_create(LIQUID_NCO);
    nco_crcf_set_phase    (nco, phase);
    nco_crcf_set_frequency(nco, freq);

    // generate signal
    float complex buf_0[buf_len];
    float complex buf_1[buf_len];
    unsigned int i;
    for (i=0; i<buf_len; i++)
        buf_0[i] = cexpf(_Complex_I*2*M_PI*randf());

    // mix signal
    nco_crcf_mix_block_up(nco, buf_0, buf_1, buf_len);

    // compare result to expected
    float phi = phase;
    for (i=0; i<buf_len; i++) {
        float complex v = buf_0[i] * cexpf(_Complex_I*phi);
        CONTEND_DELTA( crealf(buf_1[i]), crealf(v), tol);
        CONTEND_DELTA( cimagf(buf_1[i]), cimagf(v), tol);
        phi += freq;
    }

    // destroy object
    nco_crcf_destroy(nco);
}
//
// test nco block mixing
//
void autotest_nco_block_mixing()
{
    // frequency, phase
    float f = 0.1f;
    float phi = M_PI;

    // error tolerance (high for NCO)
    float tol = 0.05f;

    unsigned int i;

    // number of samples
    unsigned int num_samples = 1024;

    // store samples
    float complex * x = (float complex*)malloc(num_samples*sizeof(float complex));
    float complex * y = (float complex*)malloc(num_samples*sizeof(float complex));

    // generate complex sin/cos
    for (i=0; i<num_samples; i++)
        x[i] = cexpf(_Complex_I*(f*i + phi));

    // initialize nco object
    nco_crcf p = nco_crcf_create(LIQUID_NCO);
    nco_crcf_set_frequency(p, f);
    nco_crcf_set_phase(p, phi);

    // mix signal back to zero phase (in pieces)
    unsigned int num_remaining = num_samples;
    i = 0;
    while (num_remaining > 0) {
        unsigned int n = 7 < num_remaining ? 7 : num_remaining;
        nco_crcf_mix_block_down(p, &x[i], &y[i], n);

        i += n;
        num_remaining -= n;
    }

    // assert mixer output is correct
    for (i=0; i<num_samples; i++) {
        CONTEND_DELTA( crealf(y[i]), 1.0f, tol );
        CONTEND_DELTA( cimagf(y[i]), 0.0f, tol );
    }

    // free those buffers
    free(x);
    free(y);

    // destroy NCO object
    nco_crcf_destroy(p);
}
//
// test phase-locked loop
//  _type           :   NCO type (e.g. LIQUID_NCO)
//  _phase_offset   :   initial phase offset
//  _freq_offset    :   initial frequency offset
//  _pll_bandwidth  :   bandwidth of phase-locked loop
//  _num_iterations :   number of iterations to run
//  _tol            :   error tolerance
void nco_crcf_pll_test(int          _type,
                       float        _phase_offset,
                       float        _freq_offset,
                       float        _pll_bandwidth,
                       unsigned int _num_iterations,
                       float        _tol)
{
    // objects
    nco_crcf nco_tx = nco_crcf_create(_type);
    nco_crcf nco_rx = nco_crcf_create(_type);

    // initialize objects
    nco_crcf_set_phase(nco_tx, _phase_offset);
    nco_crcf_set_frequency(nco_tx, _freq_offset);
    nco_crcf_pll_set_bandwidth(nco_rx, _pll_bandwidth);

    // run loop
    unsigned int i;
    float phase_error;
    float complex r, v;
    for (i=0; i<_num_iterations; i++) {
        // received complex signal
        nco_crcf_cexpf(nco_tx,&r);
        nco_crcf_cexpf(nco_rx,&v);

        // error estimation
        phase_error = cargf(r*conjf(v));

        // update pll
        nco_crcf_pll_step(nco_rx, phase_error);

        // update nco objects
        nco_crcf_step(nco_tx);
        nco_crcf_step(nco_rx);
    }

    // ensure phase of oscillators is locked
    float nco_tx_phase = nco_crcf_get_phase(nco_tx);
    float nco_rx_phase = nco_crcf_get_phase(nco_rx);
    CONTEND_DELTA(nco_tx_phase, nco_rx_phase, _tol);

    // ensure frequency of oscillators is locked
    float nco_tx_freq = nco_crcf_get_frequency(nco_tx);
    float nco_rx_freq = nco_crcf_get_frequency(nco_rx);
    CONTEND_DELTA(nco_tx_freq, nco_rx_freq, _tol);

    // clean it up
    nco_crcf_destroy(nco_tx);
    nco_crcf_destroy(nco_rx);
}
Example #10
0
// 
// Test AC gain control
//
void autotest_agc_crcf_ac_gain_control()
{
    // set paramaters
    float gamma = 0.1f;             // nominal signal level
    float bt    = 0.1f;             // bandwidth-time product
    float tol   = 0.001f;           // error tolerance
    float dphi  = 0.1f;             // NCO frequency

    // create AGC object and initialize
    agc_crcf q = agc_crcf_create();
    agc_crcf_set_bandwidth(q, bt);

    unsigned int i;
    float complex x;
    float complex y;
    for (i=0; i<256; i++) {
        x = gamma * cexpf(_Complex_I*i*dphi);
        agc_crcf_execute(q, x, &y);
    }

    if (liquid_autotest_verbose)
        printf("gamma : %12.8f, rssi : %12.8f\n", gamma, agc_crcf_get_signal_level(q));

    // Check results
    CONTEND_DELTA( agc_crcf_get_gain(q), 1.0f/gamma, tol);

    // destroy AGC object
    agc_crcf_destroy(q);
}
Example #11
0
//
// AUTOTEST: regular phase-unwrapping
//
void autotest_nco_unwrap_phase()
{
    unsigned int n=32;  // number of steps
    float tol = 1e-6f;  // error tolerance
    
    // initialize data arrays
    float phi[n];       // original array
    float theta[n];     // wrapped array
    float phi_hat[n];   // unwrapped array

    float phi0 = 3.0f;  // initial phase
    float dphi = 0.1f;  // phase step

    unsigned int i;
    for (i=0; i<n; i++) {
        // phase input
        phi[i] = phi0 + i*dphi;

        // wrapped array
        theta[i] = phi[i];
        while (theta[i] >  M_PI) theta[i] -= 2*M_PI;
        while (theta[i] < -M_PI) theta[i] += 2*M_PI;

        // initialize output
        phi_hat[i] = theta[i];
    }

    // unwrap phase
    liquid_unwrap_phase(phi_hat, n);

    // compare input to output
    for (i=0; i<n; i++)
        CONTEND_DELTA( phi[i], phi_hat[i], tol );
}
Example #12
0
// autotest helper function
void fft_r2r_test(float *      _x,
                  float *      _test,
                  unsigned int _n,
                  unsigned int _kind)
{
    int _flags = 0;
    float tol=1e-4f;

    unsigned int i;

    float y[_n];

    // compute real even/odd FFT
    fftplan q = fft_create_plan_r2r_1d(_n, _x, y, _kind, _flags);
    fft_execute(q);

    // print results
    if (liquid_autotest_verbose) {
        printf("%12s %12s\n", "expected", "actual");
        for (i=0; i<_n; i++)
            printf("%12.8f %12.8f\n", _test[i], y[i]);
    }

    // validate results
    for (i=0; i<_n; i++)
        CONTEND_DELTA( y[i], _test[i], tol);

    // destroy plans
    fft_destroy_plan(q);
}
Example #13
0
//
// AUTOTEST: Q function
//
void autotest_Q()
{
    float tol = 1e-6f;
    CONTEND_DELTA(liquid_Qf(-4.0f), 0.999968329f, tol);
    CONTEND_DELTA(liquid_Qf(-3.0f), 0.998650102f, tol);
    CONTEND_DELTA(liquid_Qf(-2.0f), 0.977249868f, tol);
    CONTEND_DELTA(liquid_Qf(-1.0f), 0.841344746f, tol);
    CONTEND_DELTA(liquid_Qf( 0.0f), 0.5f,         tol);
    CONTEND_DELTA(liquid_Qf( 1.0f), 0.158655254f, tol);
    CONTEND_DELTA(liquid_Qf( 2.0f), 0.022750132f, tol);
    CONTEND_DELTA(liquid_Qf( 3.0f), 0.001349898f, tol);
    CONTEND_DELTA(liquid_Qf( 4.0f), 0.000031671f, tol);
}
Example #14
0
// test sparse floating-point matrix multiplication
void autotest_smatrixf_mul()
{
    float tol = 1e-6f;

    // intialize matrices
    smatrixf a = smatrixf_create(4, 5);
    smatrixf b = smatrixf_create(5, 3);
    smatrixf c = smatrixf_create(4, 3);

    // initialize 'a'
    // 0 0 0 0 4
    // 0 0 0 0 0
    // 0 0 0 3 0
    // 2 0 0 0 1
    smatrixf_set(a, 0,4, 4);
    smatrixf_set(a, 2,3, 3);
    smatrixf_set(a, 3,0, 2);
    smatrixf_set(a, 3,4, 0);
    smatrixf_set(a, 3,4, 1);

    // initialize 'b'
    // 7 6 0
    // 0 0 0
    // 0 0 0
    // 0 5 0
    // 2 0 0
    smatrixf_set(b, 0,0, 7);
    smatrixf_set(b, 0,1, 6);
    smatrixf_set(b, 3,1, 5);
    smatrixf_set(b, 4,0, 2);

    // compute 'c'
    //  8   0   0
    //  0   0   0
    //  0  15   0
    // 16  12   0
    smatrixf_mul(a,b,c);

    float c_test[12] = {
         8,   0,   0,
         0,   0,   0,
         0,  15,   0,
        16,  12,   0};

    // check values
    unsigned int i;
    unsigned int j;
    for (i=0; i<4; i++) {
        for (j=0; j<3; j++) {
            CONTEND_DELTA(smatrixf_get(c,i,j),
                          matrixf_access(c_test,4,3,i,j),
                          tol);
        }
    }

    smatrixf_destroy(a);
    smatrixf_destroy(b);
    smatrixf_destroy(c);
}
Example #15
0
void autotest_iirdes_cplxpair_n6()
{
    float tol = 1e-8f;

    //
    float complex r[6] = {
       0.980066577841242 + 0.198669330795061 * _Complex_I,
       5.000000000000000 + 0.000000000000000 * _Complex_I,
      -0.416146836547142 + 0.909297426825682 * _Complex_I,
       0.980066577841242 - 0.198669330795061 * _Complex_I,
       0.300000000000000 + 0.000000000000000 * _Complex_I,
      -0.416146836547142 - 0.909297426825682 * _Complex_I
    };

    float complex p[6];

    float complex ptest[6] = {
      -0.416146836547142 - 0.909297426825682 * _Complex_I,
      -0.416146836547142 + 0.909297426825682 * _Complex_I,
       0.980066577841242 - 0.198669330795061 * _Complex_I,
       0.980066577841242 + 0.198669330795061 * _Complex_I,
       0.300000000000000 + 0.000000000000000 * _Complex_I,
       5.000000000000000 + 0.000000000000000 * _Complex_I
    };

    // compute complex pairs
    liquid_cplxpair(r,6,1e-6f,p);

    unsigned int i;

    if (liquid_autotest_verbose) {
        printf("complex set:\n");
        for (i=0; i<6; i++)
            printf("  r[%3u] : %12.8f + j*%12.8f\n", i, crealf(r[i]), cimagf(r[i]));

        printf("complex pairs:\n");
        for (i=0; i<6; i++)
            printf("  p[%3u] : %12.8f + j*%12.8f\n", i, crealf(p[i]), cimagf(p[i]));
    }

    // run test
    for (i=0; i<6; i++) {
        CONTEND_DELTA( crealf(p[i]), crealf(ptest[i]), tol );
        CONTEND_DELTA( cimagf(p[i]), cimagf(ptest[i]), tol );
    }
}
Example #16
0
//
// AUTOTEST: 
//
void autotest_firinterp_rrrf_generic()
{
    float h[9] = {
      -0.2762293319046737,
       1.4757679031218007,
       0.1432569489572376,
      -0.2142368750177835,
       1.3471241294836864,
       0.1166010284926269,
       0.0536534505390281,
       0.1412672462812405,
      -0.0991854372394269};

    unsigned int M = 4;     // firinterp factor
    firinterp_rrrf q = firinterp_rrrf_create(M,h,9);

    float x[] = {1.0, -1.0, 1.0, 1.0};
    float y[16];
    float test[16] = {
      -0.2762293319046737,
       1.4757679031218007,
       0.1432569489572376,
      -0.2142368750177835,
       1.6233534613883602,
      -1.3591668746291738,
      -0.0896034984182095,
       0.3555041212990241,
      -1.7225388986277870,
       1.3591668746291738,
       0.0896034984182095,
      -0.3555041212990241,
       1.1700802348184398,
       1.5923689316144276,
       0.1969103994962658,
      -0.0729696287365430};

    float tol = 1e-6;

    unsigned int i;
    for (i=0; i<4; i++)
        firinterp_rrrf_execute(q, x[i], &y[i*M]);

    for (i=0; i<16; i++) {
        CONTEND_DELTA(y[i], test[i], tol);

        if (liquid_autotest_verbose)
            printf("  y(%u) = %8.4f;\n", i+1, y[i]);
    }

    if (liquid_autotest_verbose)
        firinterp_rrrf_print(q);

    // destroy interpolator object
    firinterp_rrrf_destroy(q);
}
// 
// AUTOTEST: polycf_findroots (random roots)
//
void xautotest_polycf_findroots_rand()
{
    unsigned int n=5;
    float tol=1e-4f;

    float complex p[n];
    float complex roots[n-1];

    float complex p_hat[n];

    unsigned int i;
    for (i=0; i<n; i++)
        p[i] = i == n-1 ? 1 : 3.0f * randnf();

    polycf_findroots(p,n,roots);

    float complex roots_hat[n-1];
    // convert form...
    for (i=0; i<n-1; i++)
        roots_hat[i] = -roots[i];

    polycf_expandroots(roots_hat,n-1,p_hat);

    if (liquid_autotest_verbose) {
        printf("poly:\n");
        for (i=0; i<n; i++)
            printf("  p[%3u] = %12.8f + j*%12.8f\n", i, crealf(p[i]), cimagf(p[i]));

        printf("roots:\n");
        for (i=0; i<n-1; i++)
            printf("  r[%3u] = %12.8f + j*%12.8f\n", i, crealf(roots[i]), cimagf(roots[i]));

        printf("poly (expanded roots):\n");
        for (i=0; i<n; i++)
            printf("  p[%3u] = %12.8f + j*%12.8f\n", i, crealf(p_hat[i]), cimagf(p_hat[i]));
    }

    for (i=0; i<n; i++) {
        CONTEND_DELTA(crealf(p[i]), crealf(p_hat[i]), tol);
        CONTEND_DELTA(cimagf(p[i]), cimagf(p_hat[i]), tol);
    }
}
Example #18
0
// 
// AUTOTEST : design 2nd-order butterworth filter (design comes
//            from [Ziemer:1998] Example 9-7, pp. 440--442)
//
void autotest_iirdes_butter_2()
{
    // initialize variables
    unsigned int order = 2; // filter order
    float fc = 0.25f;       // normalized cutoff frequency
    float f0 = 0.0f;        // center frequency (ignored for low-pass filter)
    float Ap = 1.0f;        // pass-band ripple (ignored for Butterworth)
    float As = 40.0f;       // stop-band attenuation (ignored for Butterworth)
    float tol = 1e-6f;      // error tolerance

    // initialize pre-determined coefficient array
    // for 2^nd-order low-pass Butterworth filter
    // with cutoff frequency 0.25
    float a_test[3] = {
        1.0f,
        0.0f,
        0.171572875253810f};
    float b_test[3] = {
        0.292893218813452f,
        0.585786437626905f,
        0.292893218813452f};

    // output coefficients
    float a[3];
    float b[3];

    // design butterworth filter
    liquid_iirdes(LIQUID_IIRDES_BUTTER,
                  LIQUID_IIRDES_LOWPASS,
                  LIQUID_IIRDES_TF,
                  order,
                  fc, f0,
                  Ap, As,
                  b, a);

    // Ensure data are equal to within tolerance
    unsigned int i;
    for (i=0; i<3; i++) {
        CONTEND_DELTA( b[i], b_test[i], tol );
        CONTEND_DELTA( a[i], a_test[i], tol );
    }
}
Example #19
0
// Help function to keep code base small
//  _kf     :   modulation factor
//  _type   :   demodulation type {LIQUID_FREQDEM_DELAYCONJ, LIQUID_FREQDEM_PLL}
void freqmodem_test(float               _kf,
                    liquid_freqdem_type _type)
{
    // options
    unsigned int num_samples = 1024;
    //float tol = 1e-2f;

    unsigned int i;

    // create mod/demod objects
    freqmod mod = freqmod_create(_kf);          // modulator
    freqdem dem = freqdem_create(_kf,_type);    // demodulator

    // allocate arrays
    float         m[num_samples];   // message signal
    float complex r[num_samples];   // received signal (complex baseband)
    float         y[num_samples];   // demodulator output

    // generate message signal (single-frequency sine)
    for (i=0; i<num_samples; i++)
        m[i] = 0.7f*cosf(2*M_PI*0.013f*i + 0.0f);

    // modulate/demodulate signal
    for (i=0; i<num_samples; i++) {
        // modulate
        freqmod_modulate(mod, m[i], &r[i]);

        // demodulate
        freqdem_demodulate(dem, r[i], &y[i]);
    }

    // delete modem objects
    freqmod_destroy(mod);
    freqdem_destroy(dem);

#if 0
    // compute power spectral densities and compare
    float complex mcf[num_samples];
    float complex ycf[num_samples];
    float complex M[num_samples];
    float complex Y[num_samples];
    for (i=0; i<num_samples; i++) {
        mcf[i] = m[i] * hamming(i,num_samples);
        ycf[i] = y[i] * hamming(i,num_samples);
    }
    fft_run(num_samples, mcf, M, LIQUID_FFT_FORWARD, 0);
    fft_run(num_samples, ycf, Y, LIQUID_FFT_FORWARD, 0);

    // run test: compare spectral magnitude
    for (i=0; i<num_samples; i++)
        CONTEND_DELTA( cabsf(Y[i]), cabsf(M[i]), tol );
#endif
}
// 
// test Cholesky decomposition
//
void autotest_matrixcf_chol()
{
    float tol = 1e-3f;  // error tolerance

    // lower triangular matrix with positive values on diagonal
    float complex L[16]= {
        1.01,                    0,                       0,                       0,
       -1.42 + _Complex_I*0.25,  0.50,                    0,                       0,
        0.32 - _Complex_I*1.23,  2.01 + _Complex_I*0.78,  0.30,                    0,
       -1.02 + _Complex_I*1.02, -0.32 - _Complex_I*0.03, -1.65 + _Complex_I*2.01,  1.07};

    float complex A[16];    // A = L * L^T
    float complex Lp[16];   // output Cholesky decomposition

    unsigned int i;

    // compute A
    matrixcf_mul_transpose(L,4,4,A);

    // force A to be positive definite
    for (i=0; i<4; i++)
        matrix_access(A,4,4,i,i) = creal(matrix_access(A,4,4,i,i));

    // run decomposition
    matrixcf_chol(A,4,Lp);

    if (liquid_autotest_verbose) {
        printf("L :\n");
        matrixcf_print(L,4,4);
        printf("A :\n");
        matrixcf_print(A,4,4);
        printf("Lp:\n");
        matrixcf_print(Lp,4,4);
    }

    for (i=0; i<16; i++) {
        CONTEND_DELTA( crealf(L[i]), crealf(Lp[i]), tol );
        CONTEND_DELTA( cimagf(L[i]), cimagf(Lp[i]), tol );
    }
}
Example #21
0
//
// AUTOTEST : iir group delay (second-order sections), n=8
//
void autotest_iir_groupdelay_sos_n8()
{
    // create coefficients arrays (7th-order Butterworth)
    float B[12] = {
        0.00484212,   0.00968423,   0.00484212,
        1.00000000,   2.00000000,   1.00000000,
        1.00000000,   2.00000000,   1.00000000,
        1.00000000,   1.00000000,   0.00000000};

    float A[12] = {
        1.00000000,  -0.33283597,   0.07707999,
        1.00000000,  -0.38797498,   0.25551325,
        1.00000000,  -0.51008475,   0.65066898,
        1.00000000,  -0.15838444,   0.00000000};

    float tol = 1e-3f;
    unsigned int i;

    // create testing vectors
    float fc[7] = { 0.00000,
                    0.06250,
                    0.12500,
                    0.18750,
                    0.25000,
                    0.31250,
                    0.37500};

    float g0[7] = { 3.09280801068444,
                    3.30599360247944,
                    4.18341028373046,
                    7.71934054380586,
                    4.34330109915390,
                    2.60203085226210,
                    1.97868452107144};

    //
    // test with iir filter (second-order sections)
    //

    // create filter
    iirfilt_rrrf filter = iirfilt_rrrf_create_sos(B,A,4);

    // run tests
    float g;
    for (i=0; i<7; i++) {
        g = iirfilt_rrrf_groupdelay(filter, fc[i]);
        CONTEND_DELTA( g, g0[i], tol );
    }

    // destroy filter
    iirfilt_rrrf_destroy(filter);
}
Example #22
0
//
// AUTOTEST : iir group delay, n=3
//
void autotest_iir_groupdelay_n3()
{
    // create coefficients array
    float b[3] = {0.20657210,  0.41314420, 0.20657210};
    float a[3] = {1.00000000, -0.36952737, 0.19581573};

    float tol = 1e-3f;
    unsigned int i;

    // create testing vectors
    float fc[4] = { 0.000,
                    0.125,
                    0.250,
                    0.375};
    
    float g0[4] = { 0.973248939389634,
                    1.366481121240365,
                    1.227756735863196,
                    0.651058521306726};

    // run tests
    float g;
    for (i=0; i<4; i++) {
        g = iir_group_delay(b, 3, a, 3, fc[i]);
        CONTEND_DELTA( g, g0[i], tol );
    }

    // create filter
    iirfilt_rrrf filter = iirfilt_rrrf_create(b,3,a,3);

    // run tests again
    for (i=0; i<4; i++) {
        g = iirfilt_rrrf_groupdelay(filter, fc[i]);
        CONTEND_DELTA( g, g0[i], tol );
    }

    // destroy filter
    iirfilt_rrrf_destroy(filter);
}
Example #23
0
//
// AUTOTEST : fir group delay, n=3
//
void autotest_fir_groupdelay_n3()
{
    // create coefficients array
    float h[3] = {0.1, 0.2, 0.4};

    float tol = 1e-3f;
    unsigned int i;

    // create testing vectors
    float fc[4] = { 0.000,
                    0.125,
                    0.250,
                    0.375};
    
    float g0[4] = { 1.42857142857143,
                    1.54756605839643,
                    2.15384615384615,
                    2.56861651421767};


    // run tests
    float g;
    for (i=0; i<4; i++) {
        g = fir_group_delay(h, 3, fc[i]);
        CONTEND_DELTA( g, g0[i], tol );
    }

    // create filter
    firfilt_rrrf filter = firfilt_rrrf_create(h,3);

    // run tests again
    for (i=0; i<4; i++) {
        g = firfilt_rrrf_groupdelay(filter, fc[i]);
        CONTEND_DELTA( g, g0[i], tol );
    }

    // destroy filter
    firfilt_rrrf_destroy(filter);
}
Example #24
0
// 
// AUTOTEST: bsync_crcf/simple correlation with phase
//           offset
//
void xautotest_bsync_crcf_phase_15()
{
    // generate sequence (15-bit msequence)
    float h[15] = {
         1.0,  1.0,  1.0,  1.0, 
        -1.0,  1.0, -1.0,  1.0, 
         1.0, -1.0, -1.0,  1.0, 
        -1.0, -1.0, -1.0
    };
    float tol = 1e-3f;
    float theta = 0.3f;

    // generate synchronizer
    bsync_crcf fs = bsync_crcf_create(15,h);

    // 
    // run tests
    //
    unsigned int i;
    float complex rxy;

    // fill buffer with sequence
    for (i=0; i<15; i++)
        bsync_crcf_correlate(fs,h[i]*cexpf(_Complex_I*theta),&rxy);

    // correlation should be 1.0
    CONTEND_DELTA( crealf(rxy), 1.0f*cosf(theta), tol );
    CONTEND_DELTA( cimagf(rxy), 1.0f*sinf(theta), tol );

    // all other cross-correlations should be exactly -1/15
    for (i=0; i<14; i++) {
        bsync_crcf_correlate(fs,h[i]*cexpf(_Complex_I*theta),&rxy);
        CONTEND_DELTA( crealf(rxy), -1.0f/15.0f*cosf(theta), tol );
        CONTEND_DELTA( cimagf(rxy), -1.0f/15.0f*sinf(theta), tol );
    }

    // clean it up
    bsync_crcf_destroy(fs);
}
Example #25
0
// 
// AUTOTEST: Factorial
//
void autotest_factorial()
{
    float tol = 1e-3f;
    CONTEND_DELTA(liquid_factorialf(0), 1,   tol);
    CONTEND_DELTA(liquid_factorialf(1), 1,   tol);
    CONTEND_DELTA(liquid_factorialf(2), 2,   tol);
    CONTEND_DELTA(liquid_factorialf(3), 6,   tol);
    CONTEND_DELTA(liquid_factorialf(4), 24,  tol);
    CONTEND_DELTA(liquid_factorialf(5), 120, tol);
    CONTEND_DELTA(liquid_factorialf(6), 720, tol);
}
// autotest helper function
//  _theta  :   input phase
//  _cos    :   expected output: cos(_theta)
//  _sin    :   expected output: sin(_theta)
//  _type   :   NCO type (e.g. LIQUID_NCO)
//  _tol    :   error tolerance
void nco_crcf_phase_test(float _theta,
                         float _cos,
                         float _sin,
                         int   _type,
                         float _tol)
{
    // create object
    nco_crcf nco = nco_crcf_create(_type);

    // set phase
    nco_crcf_set_phase(nco, _theta);

    // compute cosine and sine outputs
    float c = nco_crcf_cos(nco);
    float s = nco_crcf_sin(nco);

    // run tests
    CONTEND_DELTA( c, _cos, _tol );
    CONTEND_DELTA( s, _sin, _tol );

    // destroy object
    nco_crcf_destroy(nco);
}
//
// test nco mixing
//
void autotest_nco_mixing() {
    // frequency, phase
    float f = 0.1f;
    float phi = M_PI;

    // error tolerance (high for NCO)
    float tol = 0.05f;

    // initialize nco object
    nco_crcf p = nco_crcf_create(LIQUID_NCO);
    nco_crcf_set_frequency(p, f);
    nco_crcf_set_phase(p, phi);

    unsigned int i;
    float nco_i, nco_q;
    for (i=0; i<64; i++) {
        // generate sin/cos
        nco_crcf_sincos(p, &nco_q, &nco_i);

        // mix back to zero phase
        complex float nco_cplx_in = nco_i + _Complex_I*nco_q;
        complex float nco_cplx_out;
        nco_crcf_mix_down(p, nco_cplx_in, &nco_cplx_out);

        // assert mixer output is correct
        CONTEND_DELTA(crealf(nco_cplx_out), 1.0f, tol);
        CONTEND_DELTA(cimagf(nco_cplx_out), 0.0f, tol);
        //printf("%3u : %12.8f + j*%12.8f\n", i, crealf(nco_cplx_out), cimagf(nco_cplx_out));

        // step nco
        nco_crcf_step(p);
    }

    // destroy NCO object
    nco_crcf_destroy(p);
}
Example #28
0
// 
// AUTOTEST: bsync_rrrf/simple correlation
//
void autotest_bsync_rrrf_15()
{
    // generate sequence (15-bit msequence)
    float h[15] = {
         1.0,  1.0,  1.0,  1.0, 
        -1.0,  1.0, -1.0,  1.0, 
         1.0, -1.0, -1.0,  1.0, 
        -1.0, -1.0, -1.0
    };
    float tol = 1e-3f;

    // generate synchronizer
    bsync_rrrf fs = bsync_rrrf_create(15,h);

    // 
    // run tests
    //
    unsigned int i;
    float rxy;

    // fill buffer with sequence
    for (i=0; i<15; i++)
        bsync_rrrf_correlate(fs,h[i],&rxy);

    // correlation should be 1.0
    CONTEND_DELTA( rxy, 1.0f, tol );

    // all other cross-correlations should be exactly -1/15
    for (i=0; i<14; i++) {
        bsync_rrrf_correlate(fs,h[i],&rxy);
        CONTEND_DELTA( rxy, -1.0f/15.0f, tol );
    }

    // clean it up
    bsync_rrrf_destroy(fs);
}
Example #29
0
// autotest helper function
//  _x      :   fft input array
//  _test   :   expected fft output
//  _n      :   fft size
void fft_test(float complex * _x,
              float complex * _test,
              unsigned int    _n)
{
    int _method = 0;
    float tol=2e-4f;

    unsigned int i;

    float complex y[_n], z[_n];

    // compute FFT
    fftplan pf = fft_create_plan(_n, _x, y, LIQUID_FFT_FORWARD, _method);
    fft_execute(pf);

    // compute IFFT
    fftplan pr = fft_create_plan(_n, y, z, LIQUID_FFT_BACKWARD, _method);
    fft_execute(pr);

    // normalize inverse
    for (i=0; i<_n; i++)
        z[i] /= (float) _n;

    // validate results
    float fft_error, ifft_error;
    for (i=0; i<_n; i++) {
        fft_error = cabsf( y[i] - _test[i] );
        ifft_error = cabsf( _x[i] - z[i] );
        CONTEND_DELTA( fft_error, 0, tol);
        CONTEND_DELTA( ifft_error, 0, tol);
    }

    // destroy plans
    fft_destroy_plan(pf);
    fft_destroy_plan(pr);
}
void autotest_iirfiltsos_impulse_n2()
{
    // initialize filter with 2nd-order low-pass butterworth filter
    float a[3] = {
        1.000000000000000,
       -0.942809041582063,
        0.333333333333333};

    float b[3] = {
        0.0976310729378175,
        0.1952621458756350,
        0.0976310729378175};

    iirfiltsos_rrrf f = iirfiltsos_rrrf_create(b,a);

    // initialize oracle; expected output (generated with octave)
    float test[15] = {
       9.76310729378175e-02,
       2.87309604180767e-01,
       3.35965474513536e-01,
       2.20981418970514e-01,
       9.63547883225231e-02,
       1.71836926400291e-02,
      -1.59173219853878e-02,
      -2.07348926322729e-02,
      -1.42432702548109e-02,
      -6.51705310050832e-03,
      -1.39657983602602e-03,
       8.55642936806248e-04,
       1.27223450919543e-03,
       9.14259886013424e-04,
       4.37894317157432e-04};

    unsigned int i;
    float v, y;
    float tol=1e-4f;

    // hit filter with impulse, compare output
    for (i=0; i<15; i++) {
        v = (i==0) ? 1.0f : 0.0f;

        iirfiltsos_rrrf_execute(f, v, &y);

        CONTEND_DELTA(test[i], y, tol);
    }

    iirfiltsos_rrrf_destroy(f);
}