Beispiel #1
0
// test sparse integer vector multiplication
void autotest_smatrixi_vmul()
{
    // 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
    smatrixi A = smatrixi_create(4, 5);
    smatrixi_set(A, 0,4, 4);
    smatrixi_set(A, 2,3, 3);
    smatrixi_set(A, 3,0, 2);
    smatrixi_set(A, 3,4, 0);
    smatrixi_set(A, 3,4, 1);

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

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

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

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

    smatrixi_destroy(A);
}
//
// AUTOTEST: SEC-DEC (22,16) codec (single error)
//
void autotest_secded2216_codec_e1()
{
    unsigned int k; // error location

    for (k=0; k<22; k++) {
        // generate symbol
        unsigned char sym_org[2];
        sym_org[0] = rand() & 0xffff;
        sym_org[1] = rand() & 0xffff;

        // encoded symbol
        unsigned char sym_enc[3];
        fec_secded2216_encode_symbol(sym_org, sym_enc);

        // generate error vector (single error)
        unsigned char e[3] = {0,0,0};
        div_t d = div(k,8);
        e[3-d.quot-1] = 1 << d.rem;

        // received symbol
        unsigned char sym_rec[3];
        sym_rec[0] = sym_enc[0] ^ e[0];
        sym_rec[1] = sym_enc[1] ^ e[1];
        sym_rec[2] = sym_enc[2] ^ e[2];

        // decoded symbol
        unsigned char sym_dec[2];
        fec_secded2216_decode_symbol(sym_rec, sym_dec);

        // validate data are the same
        CONTEND_EQUALITY(sym_org[0], sym_dec[0]);
        CONTEND_EQUALITY(sym_org[1], sym_dec[1]);
    }
}
Beispiel #3
0
// 
// AUTOTEST: count number of ones in an integer (modulo 2)
//
void autotest_count_ones_mod2() {
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0000), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0001), 1 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0003), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0xFFFF), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x00FF), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x5555), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0007), 1 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0037), 1 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0x0137), 0 );
    CONTEND_EQUALITY( liquid_count_ones_mod2(0xf137), 0 );
}
Beispiel #4
0
// 
// AUTOTEST: count number of ones in an integer
//
void autotest_count_ones() {
    CONTEND_EQUALITY( liquid_count_ones(0x0000), 0 );
    CONTEND_EQUALITY( liquid_count_ones(0x0001), 1 );
    CONTEND_EQUALITY( liquid_count_ones(0x0003), 2 );
    CONTEND_EQUALITY( liquid_count_ones(0xFFFF), 16 );
    CONTEND_EQUALITY( liquid_count_ones(0x00FF), 8 );
    CONTEND_EQUALITY( liquid_count_ones(0x5555), 8 );
    CONTEND_EQUALITY( liquid_count_ones(0x0007), 3 );
    CONTEND_EQUALITY( liquid_count_ones(0x0037), 5 );
    CONTEND_EQUALITY( liquid_count_ones(0x0137), 6 );
    CONTEND_EQUALITY( liquid_count_ones(0xf137), 10 );
}
//
// AUTOTEST: SEC-DEC (72,64) codec (no errors)
//
void autotest_secded7264_codec_e0()
{
    // arrays
    unsigned char sym_org[8];   // original symbol
    unsigned char sym_enc[9];   // encoded symbol
    unsigned char sym_dec[8];   // decoded symbol

    // generate symbol
    sym_org[0] = rand() & 0xff;
    sym_org[1] = rand() & 0xff;
    sym_org[2] = rand() & 0xff;
    sym_org[3] = rand() & 0xff;
    sym_org[4] = rand() & 0xff;
    sym_org[5] = rand() & 0xff;
    sym_org[6] = rand() & 0xff;
    sym_org[7] = rand() & 0xff;

    // encoded symbol
    fec_secded7264_encode_symbol(sym_org, sym_enc);

    // decoded symbol
    fec_secded7264_decode_symbol(sym_enc, sym_dec);

    // validate data are the same
    CONTEND_EQUALITY(sym_org[0], sym_dec[0]);
    CONTEND_EQUALITY(sym_org[1], sym_dec[1]);
    CONTEND_EQUALITY(sym_org[2], sym_dec[2]);
    CONTEND_EQUALITY(sym_org[3], sym_dec[3]);
    CONTEND_EQUALITY(sym_org[4], sym_dec[4]);
    CONTEND_EQUALITY(sym_org[5], sym_dec[5]);
    CONTEND_EQUALITY(sym_org[6], sym_dec[6]);
    CONTEND_EQUALITY(sym_org[7], sym_dec[7]);
}
//
// AUTOTEST: Hamming (31,26) codec
//
void autotest_hamming3126_codec()
{
    unsigned int n=26;  //
    unsigned int k=31;  //
    unsigned int i;     // index of bit to corrupt

    for (i=0; i<k; i++) {
        // generate symbol
        unsigned int sym_org = rand() % (1<<n);

        // encoded symbol
        unsigned int sym_enc = fec_hamming3126_encode_symbol(sym_org);

        // received symbol
        unsigned int sym_rec = sym_enc ^ (1<<(k-i-1));

        // decoded symbol
        unsigned int sym_dec = fec_hamming3126_decode_symbol(sym_rec);

        if (liquid_autotest_verbose) {
            printf("error index : %u\n", i);
            // print results
            printf("    sym org     :   "); liquid_print_bitstring(sym_org, n); printf("\n");
            printf("    sym enc     :   "); liquid_print_bitstring(sym_enc, k); printf("\n");
            printf("    sym rec     :   "); liquid_print_bitstring(sym_rec, k); printf("\n");
            printf("    sym dec     :   "); liquid_print_bitstring(sym_dec, n); printf("\n");

            // print number of bit errors
            printf("    bit errors  :   %u\n", count_bit_errors(sym_org, sym_dec));
        }

        // validate data are the same
        CONTEND_EQUALITY(sym_org, sym_dec);
    }
}
//
// AUTOTEST: Hamming (7,4) codec (soft decoding)
//
void autotest_hamming74_codec_soft()
{
    // generate each of the 2^4=16 symbols, encode, and decode
    // using soft decoding algorithm
    unsigned char s;            // original 4-bit symbol
    unsigned char c;            // encoded 7-bit symbol
    unsigned char c_soft[7];    // soft bits
    unsigned char s_hat;        // decoded symbol

    for (s=0; s<16; s++) {
        // encode using look-up table
        c = hamming74_enc_gentab[s];

        // expand soft bits
        c_soft[0] = (c & 0x40) ? 255 : 0;
        c_soft[1] = (c & 0x20) ? 255 : 0;
        c_soft[2] = (c & 0x10) ? 255 : 0;
        c_soft[3] = (c & 0x08) ? 255 : 0;
        c_soft[4] = (c & 0x04) ? 255 : 0;
        c_soft[5] = (c & 0x02) ? 255 : 0;
        c_soft[6] = (c & 0x01) ? 255 : 0;

        // decode using internal soft decoding method
        s_hat = fecsoft_hamming74_decode(c_soft);

        // contend that data are the same
        CONTEND_EQUALITY(s, s_hat);
    }
}
Beispiel #8
0
//
// AUTOTEST: ann node
//
void xautotest_ann_node()
{
    float w[4] = {1,2,3,4}; // weights vector
    float x[3] = {5,1,3};   // input vector
    float y[1];             // output vector

    // create node
    node q = node_create(w,     // weights
                         x,     // input
                         y,     // output
                         3,     // num_inputs
                         0,     // activation function ID
                         1.0f   // activation function gain
                        );

    // evaluate node
    node_evaluate(q);

    if (liquid_autotest_verbose) {
        node_print(q);
        printf("y = %12.8f\n", y[0]);
    }

    // contend equality of output
    CONTEND_EQUALITY(y[0], 20.0f);

    // destroy node
    node_destroy(q);
}
Beispiel #9
0
//
// AUTOTEST: wdelayf
//
void autotest_wdelayf()
{
    float v;    // reader
    unsigned int i;

    // create wdelay
    // wdelay: 0 0 0 0
    wdelayf w = wdelayf_create(4);

    wdelayf_read(w, &v);
    CONTEND_EQUALITY(v, 0);

    float x0[10]      = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    float y0_test[10] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6};
    float y0[10];

    for (i=0; i<10; i++) {
        wdelayf_read(w, &y0[i]);
        wdelayf_push(w,  x0[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y0[i], y0_test[i]);
    }
    // 7 8 9 10
    CONTEND_SAME_DATA(y0, y0_test, 10*sizeof(float));

    // re-create wdelay object
    // wdelay: 0 0 7 8 9 10
    w = wdelayf_recreate(w,6);

    float x1[10]     = {3, 4, 5, 6, 7, 8, 9, 2, 2, 2};
    float y1_test[10]= {0, 0, 7, 8, 9, 10,3, 4, 5, 6};
    float y1[10];
    for (i=0; i<10; i++) {
        wdelayf_read(w, &y1[i]);
        wdelayf_push(w,  x1[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y1[i], y1_test[i]);
    }
    // wdelay: 7 8 9 2 2 2
    CONTEND_SAME_DATA(y1, y1_test, 10*sizeof(float));

    // re-create wdelay object
    // wdelay: 8 9 2 2 2
    w = wdelayf_recreate(w,5);

    float x2[10]     = {1, 1, 1, 1, 1, 1, 1, 2, 3, 4};
    float y2_test[10]= {8, 9, 2, 2, 2, 1, 1, 1, 1, 1};
    float y2[10];

    for (i=0; i<10; i++) {
        wdelayf_read(w, &y2[i]);
        wdelayf_push(w,  x2[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y1[i], y1_test[i]);
    }
    // wdelay: 1 1 2 3 4
    CONTEND_SAME_DATA(y2, y2_test, 10*sizeof(float));

    // destroy object
    wdelayf_destroy(w);
}
Beispiel #10
0
// 
// AUTOTEST: test for small primes
//
void autotest_prime_small()
{
    const int is_prime_array[2500] = {
		0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,
		0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,
		0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,
		0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,
		0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,
		0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
		0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,
		0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,
		0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,
		0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,
		0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
		0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,
		0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,
		0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
		0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,
		0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,
		0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
		0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,
		0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
		0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,
		0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,
		0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,
		0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
		0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,
		0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
		0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,
		0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,
		0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,
		0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
		0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,
		0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
		0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,
		0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
		0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
		0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
		0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,
		0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
		0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,
		0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
		0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,
		0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,
		0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,
		0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,
		0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,
		0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};

	unsigned int n;
    for (n=0; n<2500; n++)
        CONTEND_EQUALITY(is_prime_array[n], liquid_is_prime(n));
}
//
// AUTOTEST: SEC-DEC (22,16) codec (no errors)
//
void autotest_secded2216_codec_e0()
{
    // generate symbol
    unsigned char sym_org[2];
    sym_org[0] = rand() & 0xffff;
    sym_org[1] = rand() & 0xffff;

    // encoded symbol
    unsigned char sym_enc[3];
    fec_secded2216_encode_symbol(sym_org, sym_enc);

    // decoded symbol
    unsigned char sym_dec[2];
    fec_secded2216_decode_symbol(sym_enc, sym_dec);

    // validate data are the same
    CONTEND_EQUALITY(sym_org[0], sym_dec[0]);
    CONTEND_EQUALITY(sym_org[1], sym_dec[1]);
}
//
// AUTOTEST: SEC-DEC (22,16) codec (double error detection)
//
void autotest_secded2216_codec_e2()
{
    // total combinations of double errors: nchoosek(22,2) = 231

    unsigned int j;
    unsigned int k;

    for (j=0; j<21; j++) {
        if (liquid_autotest_verbose)
            printf("***** %2u *****\n", j);
        
        for (k=0; k<22-j-1; k++) {
            // generate symbol
            unsigned char sym_org[2];
            sym_org[0] = rand() & 0xffff;
            sym_org[1] = rand() & 0xffff;

            // encoded symbol
            unsigned char sym_enc[3];
            fec_secded2216_encode_symbol(sym_org, sym_enc);

            // generate error vector (single error)
            unsigned char e[3] = {0,0,0};

            div_t dj = div(j,8);
            e[3-dj.quot-1] |= 1 << dj.rem;

            div_t dk = div(k+j+1,8);
            e[3-dk.quot-1] |= 1 << dk.rem;

            // received symbol
            unsigned char sym_rec[3];
            sym_rec[0] = sym_enc[0] ^ e[0];
            sym_rec[1] = sym_enc[1] ^ e[1];
            sym_rec[2] = sym_enc[2] ^ e[2];

            // decoded symbol
            unsigned char sym_dec[2];
            int syndrome_flag = fec_secded2216_decode_symbol(sym_rec, sym_dec);


            if (liquid_autotest_verbose) {
                // print error vector
                printf("%3u, e = ", k);
                liquid_print_bitstring(e[0], 6);
                liquid_print_bitstring(e[1], 8);
                liquid_print_bitstring(e[2], 8);
                printf(" flag=%2d\n", syndrome_flag);
            }

            // validate syndrome flag is '2'
            CONTEND_EQUALITY(syndrome_flag, 2);
        }
    }
}
Beispiel #13
0
//
// AUTOTEST: reverse uint32_t
//
void autotest_reverse_uint32()
{
    // 0110 0010 1101 1001 0011 1011 1111 0000
    unsigned int b = 0x62D93BF0;

    // 0000 1111 1101 1100 1001 1011 0100 0110
    unsigned int r = 0x0FDC9B46;

    // 
    CONTEND_EQUALITY(liquid_reverse_uint32(b),r);
}
Beispiel #14
0
//
// AUTOTEST: reverse byte
//
void autotest_reverse_byte()
{
    // 0110 0010
    unsigned char b = 0x62;

    // 0100 0110
    unsigned char r = 0x46;

    // 
    CONTEND_EQUALITY(liquid_reverse_byte(b),r);
}
Beispiel #15
0
//
// AUTOTEST: reverse uint16_t
//
void autotest_reverse_uint16()
{
    // 1111 0111 0101 1001
    unsigned int b = 0xF759;

    // 1001 1010 1110 1111
    unsigned int r = 0x9AEF;

    // 
    CONTEND_EQUALITY(liquid_reverse_uint16(b),r);
}
// 
// AUTOTEST: validate autocorrelation properties of
//           complementary codes
//
void complementary_codes_test(unsigned int _n)
{
    // create and initialize codes
    bsequence a = bsequence_create(_n);
    bsequence b = bsequence_create(_n);
    bsequence_create_ccodes(a, b);

    // print
    if (liquid_autotest_verbose) {
        bsequence_print(a);
        bsequence_print(b);
    }

    // generate test sequences
    bsequence ax = bsequence_create(_n);
    bsequence bx = bsequence_create(_n);
    bsequence_create_ccodes(ax, bx);

    unsigned int i;
    signed int raa, rbb;
    for (i=0; i<_n; i++) {
        // correlate like sequences
        raa = 2*bsequence_correlate(a,ax) - _n;
        rbb = 2*bsequence_correlate(b,bx) - _n;

        if (i==0) { CONTEND_EQUALITY(raa+rbb,2*_n); }
        else      { CONTEND_EQUALITY(raa+rbb,0);    }

        bsequence_circshift(ax);
        bsequence_circshift(bx);
    }
    
    // clean up memory
    bsequence_destroy(a);
    bsequence_destroy(b);
    bsequence_destroy(ax);
    bsequence_destroy(bx);
}
// 
// AUTOTEST: bpacketsync
//
void autotest_bpacketsync()
{
    // options
    unsigned int num_packets = 50;          // number of packets to encode
    unsigned int dec_msg_len = 64;          // original data message length
    crc_scheme check = LIQUID_CRC_32;       // data integrity check
    fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
    fec_scheme fec1 = LIQUID_FEC_NONE;      // outer code

    // create packet generator
    bpacketgen pg = bpacketgen_create(0, dec_msg_len, check, fec0, fec1);
    if (liquid_autotest_verbose)
        bpacketgen_print(pg);

    // compute packet length
    unsigned int enc_msg_len = bpacketgen_get_packet_len(pg);

    // initialize arrays
    unsigned char msg_org[dec_msg_len]; // original message
    unsigned char msg_enc[enc_msg_len]; // encoded message

    unsigned int num_packets_found=0;

    // create packet synchronizer
    bpacketsync ps = bpacketsync_create(0, bpacketsync_autotest_callback, (void*)&num_packets_found);

    unsigned int i;
    unsigned int n;
    for (n=0; n<num_packets; n++) {
        // initialize original data message
        for (i=0; i<dec_msg_len; i++)
            msg_org[i] = rand() % 256;

        // encode packet
        bpacketgen_encode(pg,msg_org,msg_enc);

        // push packet through synchronizer
        bpacketsync_execute(ps, msg_enc, enc_msg_len);
    }

    // count number of packets
    if (liquid_autotest_verbose)
        printf("found %u / %u packets\n", num_packets_found, num_packets);

    CONTEND_EQUALITY( num_packets_found, num_packets );

    // clean up allocated objects
    bpacketgen_destroy(pg);
    bpacketsync_destroy(ps);
}
// Help function to keep code base small
void modem_test_demodsoft(modulation_scheme _ms)
{
    // generate mod/demod
    modem mod   = modem_create(_ms);
    modem demod = modem_create(_ms);

    // 
    unsigned int bps = modem_get_bps(demod);

    // run the test
    unsigned int i, s, M=1<<bps;
    unsigned int sym_soft;
    unsigned char soft_bits[bps];
    float complex x;
    
    for (i=0; i<M; i++) {
        // modulate symbol
        modem_modulate(mod, i, &x);

        // demodulate using soft-decision
        modem_demodulate_soft(demod, x, &s, soft_bits);

        // check hard-decision output
        CONTEND_EQUALITY(s, i);

        // check soft bits
        liquid_pack_soft_bits(soft_bits, bps, &sym_soft);
        CONTEND_EQUALITY(sym_soft, i);

        // check phase error, evm, etc.
        //CONTEND_DELTA( modem_get_demodulator_phase_error(demod), 0.0f, 1e-3f);
        //CONTEND_DELTA( modem_get_demodulator_evm(demod), 0.0f, 1e-3f);
    }
    // clean it up
    modem_destroy(mod);
    modem_destroy(demod);
}
Beispiel #19
0
// 
// test accumulation of binary sequence
//
void autotest_bsequence_accumulate()
{
    // 1111 0000 1100 1010 (8 total bits)
    unsigned char v[2] = {0xf0, 0xca};

    // create and initialize sequence
    bsequence q = bsequence_create(16);
    bsequence_init(q,v);

    // run tests
    CONTEND_EQUALITY( bsequence_accumulate(q), 8 );
    
    // clean up memory
    bsequence_destroy(q);
}
Beispiel #20
0
// 
// AUTOTEST : iirdes_isstable
//
void autotest_iirdes_isstable_n2_no()
{
    // initialize unstable filter
    float a[3] = {
        1.0f,
        0.0f,
        1.171572875253810f};
    float b[3] = {
        0.292893218813452f,
        0.585786437626905f,
        0.292893218813452f};

    int stable = iirdes_isstable(b,a,3);
    CONTEND_EQUALITY( stable, 0 );
}
Beispiel #21
0
// 
// AUTOTEST : iirdes_isstable
//
void autotest_iirdes_isstable_n2_yes()
{
    // initialize pre-determined coefficient array
    // for 2^nd-order low-pass Butterworth filter
    // with cutoff frequency 0.25
    float a[3] = {
        1.0f,
        0.0f,
        0.171572875253810f};
    float b[3] = {
        0.292893218813452f,
        0.585786437626905f,
        0.292893218813452f};

    int stable = iirdes_isstable(b,a,3);
    CONTEND_EQUALITY( stable, 1 );
}
// 
// AUTOTEST : test simple recovery of frame in noise
//
void qpacketmodem_test(unsigned int _payload_len,
                       int          _check,
                       int          _fec0,
                       int          _fec1,
                       int          _ms)
{
    // derived values
    unsigned int i;

    // create and configure packet encoder/decoder object
    qpacketmodem q = qpacketmodem_create();
    qpacketmodem_configure(q, _payload_len, _check, _fec0, _fec1, _ms);
    if (liquid_autotest_verbose)
        qpacketmodem_print(q);

    // initialize payload
    unsigned char payload_tx[_payload_len];
    unsigned char payload_rx[_payload_len];

    // initialize payload
    for (i=0; i<_payload_len; i++) {
        payload_tx[i] = rand() & 0xff;
        payload_rx[i] = rand() & 0xff;
    }

    // get frame length
    unsigned int frame_len = qpacketmodem_get_frame_len(q);

    // allocate memory for frame samples
    float complex frame[frame_len];

    // encode frame
    qpacketmodem_encode(q, payload_tx, frame);

    // decode frame
    int crc_pass = qpacketmodem_decode(q, frame, payload_rx);

    // destroy object
    qpacketmodem_destroy(q);

    // check to see that frame was recovered
    CONTEND_EQUALITY( crc_pass, 1 );
    CONTEND_SAME_DATA( payload_tx, payload_rx, _payload_len );
}
Beispiel #23
0
// 
// test correlation between to sequences
//
void autotest_bsequence_correlate()
{
    // v0   :   1111 0000 1100 1010
    // v1   :   1100 1011 0001 1110
    // sim  :   1100 0100 0010 1011 (7 similar bits)
    unsigned char v0[2] = {0xf0, 0xca};
    unsigned char v1[2] = {0xcb, 0x1e};

    // create and initialize sequences
    bsequence q0 = bsequence_create(16);
    bsequence q1 = bsequence_create(16);
    bsequence_init(q0,v0);
    bsequence_init(q1,v1);

    // run tests
    CONTEND_EQUALITY( bsequence_correlate(q0,q1), 7 );
    
    // clean up memory
    bsequence_destroy(q0);
    bsequence_destroy(q1);
}
//
// AUTOTEST: Golay(24,12) codec
//
void autotest_golay2412_codec()
{
    unsigned int num_trials=50; // number of symbol trials
    unsigned int num_errors;    // number of errors
    unsigned int i;

    for (num_errors=0; num_errors<=3; num_errors++) {
        for (i=0; i<num_trials; i++) {
            // generate symbol
            unsigned int sym_org = rand() % (1<<12);

            // encoded symbol
            unsigned int sym_enc = fec_golay2412_encode_symbol(sym_org);

            // generate error vector
            unsigned int e = golay2412_generate_error_vector(num_errors);

            // received symbol
            unsigned int sym_rec = sym_enc ^ e;

            // decoded symbol
            unsigned int sym_dec = fec_golay2412_decode_symbol(sym_rec);

#if 0
            printf("error index : %u\n", i);
            // print results
            printf("    sym org     :   "); liquid_print_bitstring(sym_org, n); printf("\n");
            printf("    sym enc     :   "); liquid_print_bitstring(sym_enc, k); printf("\n");
            printf("    sym rec     :   "); liquid_print_bitstring(sym_rec, k); printf("\n");
            printf("    sym dec     :   "); liquid_print_bitstring(sym_dec, n); printf("\n");

            // print number of bit errors
            printf("    bit errors  :   %u\n", count_bit_errors(sym_org, sym_dec));
#endif

            // validate data are the same
            CONTEND_EQUALITY(sym_org, sym_dec);
        }
    }
}
//
// AUTOTEST: SEC-DEC (72,64) codec (single error)
//
void autotest_secded7264_codec_e1()
{
    // arrays
    unsigned char sym_org[8];   // original symbol
    unsigned char sym_enc[9];   // encoded symbol
    unsigned char e[9];         // error vector
    unsigned char sym_rec[9];   // received symbol
    unsigned char sym_dec[8];   // decoded symbol

    unsigned int i;
    unsigned int k; // error location

    for (k=0; k<72; k++) {
        // generate symbol
        for (i=0; i<8; i++)
            sym_org[i] = rand() & 0xff;

        // encoded symbol
        fec_secded7264_encode_symbol(sym_org, sym_enc);

        // generate error vector (single error)
        for (i=0; i<9; i++)
            e[i] = 0;
        div_t d = div(k,8);
        e[9-d.quot-1] = 1 << d.rem;   // flip bit at index k

        // received symbol
        for (i=0; i<9; i++)
            sym_rec[i] = sym_enc[i] ^ e[i];

        // decoded symbol
        fec_secded7264_decode_symbol(sym_rec, sym_dec);

        // validate data are the same
        for (i=0; i<8; i++)
            CONTEND_EQUALITY(sym_org[i], sym_dec[i]);
    }
}
Beispiel #26
0
// floating point
void autotest_cbufferf()
{
    // input array of values
    float v[] = {1, 2, 3, 4, 5, 6, 7, 8};

    // output test arrays
    float test1[] = {1, 2, 3, 4};
    float test2[] = {3, 4, 1, 2, 3, 4, 5, 6, 7, 8};
    float test3[] = {3, 4, 5, 6, 7, 8};
    float test4[] = {3, 4, 5, 6, 7, 8, 1, 2, 3};
    float *r;                   // output read pointer
    unsigned int num_requested; // number of samples requested
    unsigned int num_read;      // number of samples read

    // create new circular buffer with 10 elements
    cbufferf q = cbufferf_create(10);
    // cbuffer: { <empty> }

    // part 1: write 4 elements to the buffer
    cbufferf_write(q, v, 4);
    // cbuffer: {1 2 3 4}

    // part 2: try to read 4 elements
    num_requested = 4;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,4);
    CONTEND_SAME_DATA(r,test1,4*sizeof(float));

    // part 3: release two elements, write 8 more, read 10
    cbufferf_release(q, 2);
    // cbuffer: {3 4}
    cbufferf_write(q, v, 8);
    // cbuffer: {3 4 1 2 3 4 5 6 7 8}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,10);
    CONTEND_SAME_DATA(r,test2,10*sizeof(float));

    // part 4: pop single element from buffer
    CONTEND_EQUALITY( cbufferf_size(q), 10    );
    cbufferf_pop(q, r);
    // cbuffer: {4 1 2 3 4 5 6 7 8}
    CONTEND_EQUALITY( cbufferf_size(q),  9    );
    CONTEND_EQUALITY( *r,                3.0f );

    // part 5: release three elements, and try reading 10
    cbufferf_release(q, 3);
    // cbuffer: {3 4 5 6 7 8}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,6);
    CONTEND_SAME_DATA(r,test3,6*sizeof(float));

    // part 6: test pushing multiple elements
    cbufferf_push(q, 1);
    cbufferf_push(q, 2);
    cbufferf_push(q, 3);
    // cbuffer: {3 4 5 6 7 8 1 2 3}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,9);
    CONTEND_SAME_DATA(r,test4,9*sizeof(float));

    // part 7: add one more element; buffer should be full
    CONTEND_EXPRESSION( cbufferf_is_full(q)==0 );
    cbufferf_push(q, 1);
    // cbuffer: {3 4 5 6 7 8 1 2 3 1}
    CONTEND_EXPRESSION( cbufferf_is_full(q)==1 );

    // memory leaks are evil
    cbufferf_destroy(q);
}
Beispiel #27
0
//
// AUTOTEST: nextpow2
//
void autotest_nextpow2()
{
    CONTEND_EQUALITY(liquid_nextpow2(1),    0);

    CONTEND_EQUALITY(liquid_nextpow2(2),    1);

    CONTEND_EQUALITY(liquid_nextpow2(3),    2);
    CONTEND_EQUALITY(liquid_nextpow2(4),    2);

    CONTEND_EQUALITY(liquid_nextpow2(5),    3);
    CONTEND_EQUALITY(liquid_nextpow2(6),    3);
    CONTEND_EQUALITY(liquid_nextpow2(7),    3);
    CONTEND_EQUALITY(liquid_nextpow2(8),    3);

    CONTEND_EQUALITY(liquid_nextpow2(9),    4);
    CONTEND_EQUALITY(liquid_nextpow2(10),   4);
    CONTEND_EQUALITY(liquid_nextpow2(11),   4);
    CONTEND_EQUALITY(liquid_nextpow2(12),   4);
    CONTEND_EQUALITY(liquid_nextpow2(13),   4);
    CONTEND_EQUALITY(liquid_nextpow2(14),   4);
    CONTEND_EQUALITY(liquid_nextpow2(15),   4);

    CONTEND_EQUALITY(liquid_nextpow2(67),   7);
    CONTEND_EQUALITY(liquid_nextpow2(179),  8);
    CONTEND_EQUALITY(liquid_nextpow2(888),  10);
}
Beispiel #28
0
// test sparse binary matrix multiplication
void autotest_smatrixb_mul()
{
    // a: [8 x 12]
    unsigned char a_test[96] = {
        0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
        0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0};

    // b: [12 x 5]
    unsigned char b_test[60] = {
        1, 1, 0, 0, 0,
        0, 0, 0, 0, 1,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 1,
        0, 0, 0, 1, 0,
        0, 0, 0, 1, 0,
        0, 0, 0, 0, 0,
        0, 1, 0, 0, 1,
        1, 0, 0, 1, 0,
        0, 1, 0, 0, 0};

    // output: [8 x 5]
    unsigned char c_test[40] = {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 1, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 1,
        0, 0, 0, 1, 0};

    smatrixb a = smatrixb_create_array(a_test,  8,12);
    smatrixb b = smatrixb_create_array(b_test, 12, 5);
    smatrixb c = smatrixb_create(8, 5);

    // compute output
    smatrixb_mul(a,b,c);

    // print results (verbose)
    if (liquid_autotest_verbose) {
        printf("a:\n"); smatrixb_print_expanded(a);
        printf("b:\n"); smatrixb_print_expanded(b);
        printf("c:\n"); smatrixb_print_expanded(c);
    }

    unsigned int i;
    unsigned int j;
    for (i=0; i<8; i++) {
        for (j=0; j<5; j++) {
            CONTEND_EQUALITY( smatrixb_get(c,i,j), c_test[i*5+j]);
        }
    }
    
    // destroy objects
    smatrixb_destroy(a);
    smatrixb_destroy(b);
    smatrixb_destroy(c);
}
//
// AUTOTEST: SEC-DEC (72,64) codec (double error detection)
//
void autotest_secded7264_codec_e2()
{
    // total combinations of double errors: nchoosek(72,2) = 2556

    // arrays
    unsigned char sym_org[8];   // original symbol
    unsigned char sym_enc[9];   // encoded symbol
    unsigned char e[9];         // error vector
    unsigned char sym_rec[9];   // received symbol
    unsigned char sym_dec[8];   // decoded symbol

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

    for (j=0; j<72-1; j++) {
#if 0
        if (liquid_autotest_verbose)
            printf("***** %2u *****\n", j);
#endif
        
        for (k=0; k<72-1-j; k++) {
            // generate symbol
            for (i=0; i<8; i++)
                sym_org[i] = rand() & 0xff;

            // encoded symbol
            fec_secded7264_encode_symbol(sym_org, sym_enc);

            // generate error vector (single error)
            for (i=0; i<9; i++)
                e[i] = 0;

            div_t dj = div(j,8);
            e[9-dj.quot-1] |= 1 << dj.rem;

            div_t dk = div(k+j+1,8);
            e[9-dk.quot-1] |= 1 << dk.rem;

            // received symbol
            for (i=0; i<9; i++)
                sym_rec[i] = sym_enc[i] ^ e[i];

            // decoded symbol
            int syndrome_flag = fec_secded7264_decode_symbol(sym_rec, sym_dec);

#if 0
            if (liquid_autotest_verbose) {
                // print error vector
                printf("%3u, e = ", k);
                liquid_print_bitstring(e[0], 8);
                liquid_print_bitstring(e[1], 8);
                liquid_print_bitstring(e[2], 8);
                liquid_print_bitstring(e[3], 8);
                liquid_print_bitstring(e[4], 8);
                liquid_print_bitstring(e[5], 8);
                liquid_print_bitstring(e[6], 8);
                liquid_print_bitstring(e[7], 8);
                liquid_print_bitstring(e[8], 8);
                printf(" flag=%2d\n", syndrome_flag);
            }
#endif

            // validate syndrome flag is '2'
            CONTEND_EQUALITY(syndrome_flag, 2);
        }
    }
}
Beispiel #30
0
// test sparse binary matrix methods
void autotest_smatrixb_vmul()
{
    // A = [
    //  1   0   0   0   0   0   0   0   0   0   0   0
    //  0   0   0   1   0   0   0   0   0   0   0   0
    //  1   0   0   0   0   0   0   0   1   1   0   0
    //  0   0   1   0   0   0   1   1   0   0   0   0
    //  0   0   0   0   0   0   0   0   0   0   0   0
    //  0   0   0   0   0   0   1   0   1   0   1   0
    //  1   0   1   0   0   0   0   0   0   0   1   1
    //  0   0   1   0   0   1   1   0   0   0   0   0]
    //
    // x = [   1   1   0   0   1   0   0   1   1   1   0   1 ]
    // y = [   1   0   1   1   0   1   0   0 ]
    //
    
    // create sparse matrix and set values
    smatrixb A = smatrixb_create(8,12);
    smatrixb_set(A,0,0,  1);
    smatrixb_set(A,2,0,  1);
    smatrixb_set(A,6,0,  1);
    smatrixb_set(A,3,2,  1);
    smatrixb_set(A,6,2,  1);
    smatrixb_set(A,7,2,  1);
    smatrixb_set(A,1,3,  1);
    smatrixb_set(A,7,5,  1);
    smatrixb_set(A,3,6,  1);
    smatrixb_set(A,5,6,  1);
    smatrixb_set(A,7,6,  1);
    smatrixb_set(A,3,7,  1);
    smatrixb_set(A,2,8,  1);
    smatrixb_set(A,5,8,  1);
    smatrixb_set(A,2,9,  1);
    smatrixb_set(A,5,10, 1);
    smatrixb_set(A,6,10, 1);
    smatrixb_set(A,6,11, 1);

    // generate vectors
    unsigned char x[12]     = {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1};
    unsigned char y_test[8] = {1, 0, 1, 1, 0, 1, 0, 0};
    unsigned char y[8];

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

    CONTEND_EQUALITY( y[0], y_test[0] );
    CONTEND_EQUALITY( y[1], y_test[1] );
    CONTEND_EQUALITY( y[2], y_test[2] );
    CONTEND_EQUALITY( y[3], y_test[3] );
    CONTEND_EQUALITY( y[4], y_test[4] );
    CONTEND_EQUALITY( y[5], y_test[5] );
    CONTEND_EQUALITY( y[6], y_test[6] );
    CONTEND_EQUALITY( y[7], y_test[7] );

    // print results (verbose)
    if (liquid_autotest_verbose) {
        printf("\ncompact form:\n");
        smatrixb_print(A);

        printf("\nexpanded form:\n");
        smatrixb_print_expanded(A);

        unsigned int i;
        unsigned int j;

        printf("x = [");
        for (j=0; j<12; j++) printf("%2u", x[j]);
        printf(" ];\n");

        printf("y      = [");
        for (i=0; i<8; i++) printf("%2u", y[i]);
        printf(" ];\n");

        printf("y_test = [");
        for (i=0; i<8; i++) printf("%2u", y_test[i]);
        printf(" ];\n");
    }

    // destroy matrix object
    smatrixb_destroy(A);
}