📄 convolutional.h
字号:
/* Assign to output */
for (j=0;j<nn;j++)
output_p[nn*i+j] = bin_vec[j];
}
}
free(bin_vec);
return;
}
/* function Gamma()
Description: Computes the branch metric used for decoding.
Output parameters:
(returned float) The metric between the hypothetical symbol and the recevieved vector
Input parameters:
rec_array The received vector, of length nn
symbol The hypothetical symbol
nn The length of the received vector
This function is used by siso() */
static float Gamma(float rec_array[],
int symbol,
int nn )
{
float rm = 0;
int i;
int mask;
mask = 1;
for (i=0;i<nn;i++) {
if (symbol&mask)
rm += rec_array[nn-i-1];
mask = mask<<1;
}
return(rm);
}
/* Function Viterbi()
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
Input parameters:
out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
state0[] The next state if input is a 0 (generated by rsc_transit).
out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
state1[] The next state if input is a 1 (generated by rsc_transit).
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
KK The constraint length of the convolutional code.
LL The number of data bits.
Output parameters:
output_u_int[] Hard decisions on the data bits
*/
static void Viterbi(
int output_u_int[],
int out0[],
int state0[],
int out1[],
int state1[],
float input_c[],
int KK,
int nn,
int LL
)
{
int i, t, state, mm, states;
int number_symbols;
float metric;
float *prev_section, *next_section;
int *prev_bit;
int *prev_state;
float *metric_c; /* Set of all possible branch metrics */
float *rec_array; /* Received values for one trellis section */
float max_val;
/* some derived constants */
mm = KK-1;
states = 1 << mm; /* 2^mm */
number_symbols = 1 << nn; /* 2^nn */
/* dynamically allocate memory */
prev_section = calloc( states, sizeof(float) );
next_section = calloc( states, sizeof(float) );
prev_bit = calloc( states*(LL+mm), sizeof(int) );
prev_state = calloc( states*(LL+mm), sizeof(int) );
rec_array = calloc( nn, sizeof(float) );
metric_c = calloc( number_symbols, sizeof(float) );
/* initialize trellis */
for (state=0;state<states;state++) {
prev_section[state] = -MAXLOG;
next_section[state] = -MAXLOG;
}
prev_section[0] = 0; /* start in all-zeros state */
/* go through trellis */
for (t=0;t<LL+mm;t++) {
for (i=0;i<nn;i++)
rec_array[i] = input_c[nn*t+i];
/* precompute all possible branch metrics */
for (i=0;i<number_symbols;i++)
metric_c[i] = Gamma( rec_array, i, nn );
/* step through all states */
for (state=0;state<states;state++) {
/* hypothesis: info bit is a zero */
metric = prev_section[state] + metric_c[ out0[ state ] ];
/* store new metric if more than metric in storage */
if ( metric > next_section[state0[state]] ) {
next_section[state0[state]] = metric;
prev_state[t*states+state0[state]] = state;
prev_bit[t*states+state0[state]] = 0;
}
/* hypothesis: info bit is a one */
metric = prev_section[state] + metric_c[ out1[ state ] ];
/* store new metric if more than metric in storage */
if ( metric > next_section[state1[state]] ) {
next_section[state1[state]] = metric;
prev_state[t*states+state1[state]] = state;
prev_bit[t*states+state1[state]] = 1;
}
}
/* normalize */
max_val = 0;
for (state=0;state<states;state++) {
if (next_section[state]>max_val){
max_val = next_section[state];
}
}
for (state=0;state<states;state++) {
prev_section[state] = next_section[state] - max_val;
next_section[state] = -MAXLOG;
}
}
/* trace-back operation */
state = 0;
/* tail, no need to output */
for (t=LL+mm-1; t>=LL; t--) {
state = prev_state[t*states+state];
}
for (t=LL-1; t>=0; t--) {
output_u_int[t] = prev_bit[t*states+state];
state = prev_state[t*states+state];
}
/* free the dynamically allocated memory */
free(prev_section);
free(next_section);
free(prev_bit);
free(prev_state);
free(rec_array);
free(metric_c);
}
/* Function ViterbiTb()
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a tail-biting convolutional code.
Input parameters:
out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
state0[] The next state if input is a 0 (generated by rsc_transit).
out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
state1[] The next state if input is a 1 (generated by rsc_transit).
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
KK The constraint length of the convolutional code.
LL The number of data bits.
depth head and tail decoding length [Ref. W. Sung, Electronics Letters, vol. 36, no. 7]
Output parameters:
output_u_int[] Hard decisions on the data bits
*/
static void ViterbiTb(
int output_u_int[],
int out0[],
int state0[],
int out1[],
int state1[],
float input_c[],
int KK,
int nn,
int LL,
int depth
)
{
int i, t, state, mm, states, max_state;
int number_symbols, starting_bit;
float metric;
float *prev_section, *next_section;
int *prev_bit;
int *prev_state;
float *metric_c; /* Set of all possible branch metrics */
float *rec_array; /* Received values for one trellis section */
float max_val;
/* some derived constants */
mm = KK-1;
states = 1 << mm; /* 2^mm */
number_symbols = 1 << nn; /* 2^nn */
/* dynamically allocate memory */
prev_section = calloc( states, sizeof(float) );
next_section = calloc( states, sizeof(float) );
prev_bit = calloc( states*(LL+depth), sizeof(int) );
prev_state = calloc( states*(LL+depth), sizeof(int) );
rec_array = calloc( nn, sizeof(float) );
metric_c = calloc( number_symbols, sizeof(float) );
/* initialize trellis */
for (state=0;state<states;state++) {
prev_section[state] = 0; /* equally likely starting state */
next_section[state] = -MAXLOG;
}
/* go through trellis */
for (t=-depth;t<LL+depth;t++) {
/* determine the corresponding data bits */
starting_bit = nn*(t%LL);
if (starting_bit < 0 )
starting_bit = nn*LL + starting_bit;
/* printf( "start at %d\n", starting_bit ); */
for (i=0;i<nn;i++) {
rec_array[i] = input_c[starting_bit+i];
/* printf( "%1f\n", rec_array[i] ); */
}
/* precompute all possible branch metrics */
for (i=0;i<number_symbols;i++)
metric_c[i] = Gamma( rec_array, i, nn );
/* step through all states */
for (state=0;state<states;state++) {
/* hypothesis: info bit is a zero */
metric = prev_section[state] + metric_c[ out0[ state ] ];
/* store new metric if more than metric in storage */
if ( metric > next_section[state0[state]] ) {
next_section[state0[state]] = metric;
if (t>=0) {
prev_state[t*states+state0[state]] = state;
prev_bit[t*states+state0[state]] = 0;
}
}
/* hypothesis: info bit is a one */
metric = prev_section[state] + metric_c[ out1[ state ] ];
/* store new metric if more than metric in storage */
if ( metric > next_section[state1[state]] ) {
next_section[state1[state]] = metric;
if (t>=0) {
prev_state[t*states+state1[state]] = state;
prev_bit[t*states+state1[state]] = 1;
}
}
}
/* normalize */
max_val = 0;
for (state=0;state<states;state++) {
if (next_section[state]>max_val){
max_val = next_section[state];
max_state = state;
}
}
for (state=0;state<states;state++) {
prev_section[state] = next_section[state] - max_val;
next_section[state] = -MAXLOG;
}
}
/* trace-back operation */
state = max_state;
/* tail, no need to output */
for (t=LL+depth-1; t>=LL; t--) {
state = prev_state[t*states+state];
}
for (t=LL-1; t>=0; t--) {
output_u_int[t] = prev_bit[t*states+state];
state = prev_state[t*states+state];
}
/* free the dynamically allocated memory */
free(prev_section);
free(next_section);
free(prev_bit);
free(prev_state);
free(rec_array);
free(metric_c);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -