📄 tcc_binary_unix.c
字号:
/* Turbo code Test Driver: log_map, random interleaver *//* Creation date : Jan.3 2001 *//* Program written by: Gao yingzi *//* This program simulates the classical turbo encoding-decoding system *//* It uses parallel concatenated convolutional codes described in Figure 2.9 in Chapter 2. *//* Two component RSC (Recursive Systematic Convolutional) encoders are used. *//* First encoder is terminated with tails bits. (Info + tail) bits are scrambled and *//* passed to the second encoder, while second encoder is left open without tail bits. *//* Random information bits are modulated into +1/-1, and transmitted through an AWGN channel. *//* Interleavers are randomly generated for each frame. *//* Log-MAP algorithm without quantization or approximation is used. *//* By making use of ln(e^x+e^y) = max (x,y) + ln(1+e^(-abs(x-y))), *//* the Log-MAP is simplified with a look-up table for the correction term. *//* When the approximation ln(e^x+e^y) = max (x,y) is, we have MAX-Log-MAP. *//* To set the number of iterations, change the globle variable "DECITER". To set the frame length, *//* the globle variable "FRAMESIZE" should be changed. To simulate a different range of Eb/N0, change *//* the globle variable LOEBNO and HIEBNO, as well as the step size of Eb/No increment. */#include <malloc.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#define K 3 /* constraint length */#define NUMSTATES 4 /* 2^(K - 1) -- change as required */#define PUNCTURE 1 /* rate increase from 1/3 to 1/2 if puncture=0 */#define INF 1000000 /* set infinity to an arbitrarily large value */ #define PI 3.141592654 /* circumference of circle divided by diameter */#define FRAMESIZE 900 /* how many bits in each test message */#define DECITER 6 /* decoding iteration numbers */ #define LOEBN0 0.0 /* minimum Eb/No at which to test */#define HIEBN0 3.0 /* maximum Eb/No at which to test */#define EBN0STEP 0.5 /* Eb/No increment for test driver *///#define DEBUG /* test the outputs of the trellis function */void gen01dat(int data_len, int *out_array);void turbo_encd(int g[2][K], int alpha[FRAMESIZE], int *in_array, int puncture, int *turbo_en_out);void addnoise(float eb_ovr_n0, int data_len, int *in_array, float *out_array);void de_multiplex(int alpha[FRAMESIZE], int puncture, float *in_array, float *decd1_in_array, float *decd2_in_array);void logmap(int g[2][K], int len_total, int num_decd, float *rec_s, float *L_a, float *L_u);main() { int i, j, a, iter, t, start; /* loop variables */ int len_total, msg_length, channel_length; /* length of I/O files */ int puncture, num_decd; int alpha[FRAMESIZE] = {0}; /* random interleaver matric */ int *onezer; int *encoded; /* original, encoded array */ float *splusn; /* noisy data array */ float *rec_s1; float *rec_s2; float *L_a; float *L_e_1; float *L_e_2; float *L_u; float *L_all; int *turbout; FILE *fp; int m, dec_iter; /* m = K - 1,turbo decoding iteration */ float eb_ovr_n0,rate,L_c,bit_errors,temp_bit_errors,frame_errors,e_threshold,e_ber,f_ber; /* various statistics */ int g[2][K] = {{1, 1, 1}, /* 7 */ {1, 0, 1}}; /* 5 */ fp = fopen("TCC_Binary_UNIX_data","wa+"); if ((fp = fopen("TCC_Binary_UNIX_data","wa+"))==NULL){ printf("cannot open file\n"); exit (0); } printf("\ng1 = %d%d%d", g[0][0], g[0][1], g[0][2] ); printf("\ng2 = %d%d%d\n", g[1][0], g[1][1], g[1][2] ); fprintf(fp,"\ng1 = %d%d%d", g[0][0], g[0][1], g[0][2] ); fprintf(fp,"\ng2 = %d%d%d\n", g[1][0], g[1][1], g[1][2] ); puncture = PUNCTURE; rate = (float) 1.0/(2.0 + PUNCTURE); a = 1; m = K - 1; msg_length = FRAMESIZE - m; len_total = FRAMESIZE; for (i=0; i<len_total; i++){ alpha[i] = rand() % len_total; if (i>0) { for (j=0; j<i; j++) if(alpha[i] == alpha[j]) i = i-1; } } printf("\nK = %d puncture = %d message length = %d\n", K, puncture, msg_length); fprintf(fp,"\nK = %d puncture = %d message length = %d\n", K, puncture, msg_length); if (puncture > 0) channel_length = ( msg_length + m ) * 3; else channel_length = ( msg_length + m ) * 2; onezer = malloc( msg_length * sizeof( int ) ); if (onezer == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating onezer array, aborting!"); exit(1); } encoded = malloc( channel_length * sizeof(int) ); if (encoded == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating encoded array, aborting!"); exit(1); } splusn = malloc( channel_length * sizeof(float) ); if (splusn == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating splusn array, aborting!"); exit(1); } rec_s1 = malloc( channel_length * sizeof( float ) ); if (rec_s1 == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating received symbol 1 array, aborting!"); exit(1); } rec_s2 = malloc( channel_length * sizeof( float ) ); if (rec_s2 == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating received symbol 2 array, aborting!"); exit(1); } L_a = malloc( len_total * sizeof( float ) ); if (L_a == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating L_a array, aborting!"); exit(1); } L_e_1 = malloc( len_total * sizeof( float ) ); if (L_e_1 == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating L_e_1 array, aborting!"); exit(1); } L_e_2 = malloc( len_total * sizeof( float ) ); if (L_e_2 == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating L_e_2 array, aborting!"); exit(1); } L_u = malloc( len_total * sizeof( float ) ); if (L_u == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating L_u array, aborting!"); exit(1); } L_all = malloc( len_total * sizeof( float ) ); if (L_all == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating L_all array, aborting!"); exit(1); } turbout = malloc( msg_length * sizeof( int ) ); if (turbout == NULL) { printf("\n TCC_Binary_UNIX.c: error allocating turbo decoding out array, aborting!"); exit(1); } for (eb_ovr_n0 = LOEBN0; eb_ovr_n0 <= HIEBN0; eb_ovr_n0 += EBN0STEP) { start = time(NULL); L_c = 4 * a * rate * pow(10,eb_ovr_n0/10); printf("\nreliability = %f",L_c); fprintf(fp,"\nStart:Reliability = %f",L_c); printf(" channel length = %d", channel_length); fprintf(fp," channel length = %d", channel_length); bit_errors = 0.0; frame_errors = 0.0; e_ber = 0.0; f_ber = 0.0; iter = 0; if (eb_ovr_n0 <= 3.5) e_threshold = 100; /* +/- 20% */ else e_threshold = 20; /* +/- 100 % */ while (bit_errors < e_threshold) { iter += 1; gen01dat(msg_length, onezer); turbo_encd(g, alpha, onezer, puncture, encoded); addnoise(eb_ovr_n0, channel_length, encoded, splusn); de_multiplex(alpha, puncture, splusn, rec_s1, rec_s2); for (i=0; i<2*len_total; i++){ *(rec_s1+i) = 0.5*L_c**(rec_s1+i); *(rec_s2+i) = 0.5*L_c**(rec_s2+i); } for (i=0; i<len_total; i++){ *(L_a+i) = 0; *(L_e_1+i) = 0; *(L_e_2+i) = 0; *(L_u+i) = 0; } for (dec_iter = 0; dec_iter < DECITER; dec_iter++){ for (i=0; i<len_total; i++) *(L_a + alpha[i]) = *(L_e_1 + i); num_decd = 1; /* Decoder one */ logmap(g, len_total, num_decd, rec_s1, L_a, L_u); num_decd = 2; /* Decoder two */ for (i=0; i<len_total; i++) *(L_e_2+i) = *(L_u+i) - 2**(rec_s1+2*i) - *(L_a+i); for (i=0; i<len_total; i++) *(L_a + i) = *(L_e_2 + alpha[i]); logmap(g, len_total, num_decd, rec_s2, L_a, L_u); for (i=0; i<len_total; i++){ *(L_e_1+i) = *(L_u+i) - 2**(rec_s2+2*i) - *(L_a+i); } } for (i=0; i<len_total; i++) *(L_all + alpha[i]) = *(L_u + i); for (j=0; j<msg_length; j++){ if (*(L_all+j)>0.0) *(turbout+j) = 1; else *(turbout+j) = 0; } temp_bit_errors = bit_errors; for (t = 0; t < msg_length; t++) { if ( *(onezer + t) != *(turbout + t) ) { bit_errors = bit_errors + 1; } /* end if */ } /* end t for-loop */ if ((bit_errors - temp_bit_errors) > 0) frame_errors = frame_errors + 1; } e_ber = bit_errors / (msg_length * iter); f_ber = frame_errors / iter; printf("\nframe errors=%f",frame_errors); printf("\nThe elapsed time was %d seconds for %d frames: dec_iter=%d", time(NULL) - start, iter, dec_iter); fprintf(fp,"\nThe elapsed time was %d seconds for %d frames: dec_iter%d", time(NULL) - start, iter, dec_iter); printf("\nAt %1.1fdB Eb/No, ", eb_ovr_n0); fprintf(fp,"\nAt %1.1fdB Eb/No, ", eb_ovr_n0); printf("the e_ber was %1.1e the f_ber was %1.1e \n ", e_ber, f_ber); fprintf(fp,"the e_ber was %1.1e the f_ber was %1.1e\n ", e_ber, f_ber); } /* end of eb_ovr_n0 loop */ fclose (fp); free(onezer); free(encoded); free(splusn); free(rec_s1); free(rec_s2); free(L_a); free(L_e_1); free(L_e_2); free(L_u); free(L_all); free(turbout); exit(0);}/*******************//* 0/1 Generation *//*******************/void gen01dat( int data_len, int *out_array ) { int t; /* time */ rand(); /* re-seed the random number generator */ for (t = 0; t < data_len; t++) /* generate random data, write to output array */ *( out_array + t ) = (int)( rand() / (RAND_MAX / 2) > 0.5 );}/***************************//* PCCC Turbo code encoder *//***************************/void rsc_encd(int g[2][K], int input_len, int R, int *in_array, int *out_array_0, int *out_array);void turbo_encd( int g[2][K], int alpha[FRAMESIZE], int *in_array, int puncture, int *turbo_en_out){ int i,j,t,tt; /* loop variables */ int R; /* RSC encoder number */ int yy[3][FRAMESIZE],y[3*FRAMESIZE]; /* make a matrix to store the output */ int *output0,*output1,*output2; int *rsc2_in_array,*info_array,*unuse; int m,input_len,len_total; m = K-1; len_total = FRAMESIZE; input_len = len_total-m; info_array = malloc((input_len)*sizeof(int)); if (info_array == NULL) { printf("\n turbo_encd: error allocating info array, aborting!"); exit(1); } output0 = malloc((len_total)*sizeof(int)); if (output0 == NULL) { printf("\n turbo_encd: error allocating tail_RSC1 output array, aborting!"); exit(1); } output1 = malloc((len_total)*sizeof(int)); if (output1 == NULL) { printf("\n turbo_encd: error allocating RSC1 output array, aborting!"); exit(1); } rsc2_in_array = malloc((len_total)*sizeof(int)); if (rsc2_in_array == NULL) { printf("\n turbo_encd: error allocating RSC2 input array, aborting!"); exit(1); } unuse = malloc((len_total+m)*sizeof(int)); if (unuse == NULL) { printf("\n turbo_encd: error allocating RSC2 useless output array, aborting!"); exit(1); } output2 = malloc((len_total+m)*sizeof(int)); if (output2 == NULL) { printf("\n turbo_encd: error allocating RSC2 output array, aborting!"); exit(1); } for (i=0; i<input_len; i++) *(info_array + i) = *(in_array + i); R = 1; rsc_encd(g, input_len, R, info_array, output0, output1); /* make a matrix with first row corresponding to info sequence */ /* second row corresponding to RSC #1 s check/parity bits */ /* third row corresponding to RSC #2 s check/parity bits */ for (i=0; i<len_total; i++){ yy[0][i] = *(output0 + i); yy[1][i] = *(output1 + i); } for (i=0; i<len_total; i++) *(rsc2_in_array + i) = *(output0 + alpha[i]); R != 1; rsc_encd(g, len_total, R, rsc2_in_array, unuse, output2); for (i=0; i<len_total; i++){ yy[2][i] = *(output2 + i); } /* Paralell to serial multiplex to get output vector */ if (puncture > 0){ /* puncture = 1: unpunctured, rate = 1/3 */ for (i=0; i<len_total; i++){ for (j=0; j<3; j++) y[3*i+j] = yy[j][i]; } for (t=0; t<3*len_total; t++) *(turbo_en_out + t) = y[t]; } else { /* puncture = 0: rate increase from 1/3 to 1/2 */ for (i=0; i<len_total; i++){ y[2*i] = yy[0][i]; if (i%2==0) y[2*i+1] = yy[1][i]; /* even check bits from rsc1 */ else y[2*i+1] = yy[2][i]; /* odd check bits from rsc2 */ } for (tt=0; tt<2*len_total; tt++) *(turbo_en_out + tt) = y[tt]; } free(info_array); free(output0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -