// 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]); } }
// // 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 ); }
// // 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); } }
// // 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); }
// // 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); }
// // 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); } } }
// // 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); }
// // 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); }
// // 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); }
// // 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); }
// // 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 ); }
// // 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 ); }
// // 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]); } }
// 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); }
// // 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); }
// 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); } } }
// 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); }