📄 turbo_code_log_map.c
字号:
{
printf("\n fail to allocate memory of inted_info2 \n");
exit(1);
}
/* for information bits */
for(i=0; i<len_info; i++)
{
*(info2+i) = *(yk_turbo+2*i) = *(rec_turbo+3*i);
*(yk_turbo+2*i+1) = *(rec_turbo+3*i+1);
*(yk_turbo+2*len_total+2*i+1) = *(rec_turbo+3*i+2);
}
interleave_float(info2, inted_info2, TYPE_INTERLEAVER, len_info, type_flow);
for (i=0; i<len_info; i++)
{
*(yk_turbo+2*len_total+2*i) = *(inted_info2+i);
}
/* for tail bits */
for (i=0; i<2*M_num_reg; i++)
{
*(yk_turbo+2*len_info+i) = *(rec_turbo+3*len_info+i);
*(yk_turbo+2*len_total+2*len_info+i) = *(rec_turbo+3*len_info+2*M_num_reg+i);
}
free(info2);
free(inted_info2);
}
/*---------------------------------------------------------------
FUNCTION:
Log_MAP_decoder(float *recs_turbo, float *La_turbo, int terminated, float *LLR_all_turbo, int len_total)
DESCRIPTION:
Log-MAP decoder which caculate the LLR of input sequence.
PARAMETERS:
INPUT:
recs_turbo - Scaled received bits.
La_turbo - A priori information for the current decoder,
scrambled version of extrinsic information of the previous decoder.
terminated - Indicate the turbo_trellis is terminated or not.
1 - terminated
0 - not terminated
len_total - Length of the input data sequence.
OUTPUT:
LLR_all_turbo - The caculated LLR information sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void Log_MAP_decoder(float *recs_turbo, float *La_turbo, int terminated, float *LLR_all_turbo, int len_total)
{
int i, j;
float *alpha_Log, *beta_Log, *gama_Log;
float *tempmax;
float *temp0, *temp1;
float tempx, tempy;
if ((alpha_Log=(float *)malloc(n_states*(len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of alpha_Log \n");
exit(1);
}
if ((beta_Log=(float *)malloc(n_states*(len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of beta_Log \n");
exit(1);
}
if ((gama_Log=(float *)malloc(n_states*len_total*2*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of gama_Log \n");
exit(1);
}
if ((tempmax=(float *)malloc((len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of tempmax \n");
exit(1);
}
if ((temp0=(float *)malloc(n_states*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of temp0 \n");
exit(1);
}
if ((temp1=(float *)malloc(n_states*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of temp1 \n");
exit(1);
}
/*===== Initialization of alpha_Log and beta_Log =====*/
*(alpha_Log+0) = 0;
*(beta_Log+len_total) = 0;
for (i=1; i<n_states; i++)
{
*(alpha_Log+i*(len_total+1)+0) = (float)-INFTY;
if (terminated)
{
*(beta_Log+i*(len_total+1)+len_total) = (float)-INFTY;
}
else
{
*(beta_Log+i*(len_total+1)+len_total) = 0;
}
}
/*========compute Gama_Log========*/
for (i=0; i<len_total; i++) /* 0--len_total-1 代表 1--len_total */
{
for (j=0; j<n_states; j++) /* j->k */
{
*(gama_Log+j*len_total*2+i*2+0)
= -*(recs_turbo+2*i) + *(recs_turbo+2*i+1)*(*(turbo_trellis.mx_nextout+j*4+1)) - *(La_turbo+i)/2;
*(gama_Log+j*len_total*2+i*2+1)
= *(recs_turbo+2*i) + *(recs_turbo+2*i+1)*(*(turbo_trellis.mx_nextout+j*4+3)) + *(La_turbo+i)/2;
}
}
/*========Trace forward, compute Alpha_Log========*/
for (i=1; i<len_total+1; i++)
{
for (j=0; j<n_states; j++) /* 以j为中心*/
{
tempx = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+0))*len_total*2+(i-1)*2+0)
+ *(alpha_Log+(*(turbo_trellis.mx_laststat+j*2+0))*(len_total+1)+i-1);
tempy = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+1))*len_total*2+(i-1)*2+1)
+ *(alpha_Log+(*(turbo_trellis.mx_laststat+j*2+1))*(len_total+1)+i-1);
*(alpha_Log+j*(len_total+1)+i) = E_algorithm(tempx, tempy);
}
for (j=0; j<n_states; j++)
{
if (*(tempmax+i) < *(alpha_Log+j*(len_total+1)+i))
{
*(tempmax+i) = *(alpha_Log+j*(len_total+1)+i);
}
}
for(j=0; j<n_states; j++)
{
*(alpha_Log+j*(len_total+1)+i) = *(alpha_Log+j*(len_total+1)+i) - *(tempmax+i);
}
}
/*========Trace backward, compute Beta_Log========*/
for (i=len_total-1; i>=0; i--)
{
for (j=0; j<n_states; j++) /*j为中心*/
{
tempx = *(gama_Log+j*len_total*2+i*2+0)
+ *(beta_Log+(*(turbo_trellis.mx_nextstat+j*2+0))*(len_total+1)+i+1);
tempy = *(gama_Log+j*len_total*2+i*2+1)
+ *(beta_Log+(*(turbo_trellis.mx_nextstat+j*2+1))*(len_total+1)+i+1);
*(beta_Log+j*(len_total+1)+i) = E_algorithm(tempx, tempy);
}
for (j=0; j<n_states; j++)
{
*(beta_Log+j*(len_total+1)+i) = *(beta_Log+j*(len_total+1)+i) - *(tempmax+i+1);
}
}
/*===Compute the soft output,log-likelihood ratio of symbols in the frame===*/
for (i=0; i<len_total; i++)
{
for (j=0; j<n_states; j++)
{
*(temp0+j) = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+0))*len_total*2+i*2+0)
+ *(alpha_Log+*(turbo_trellis.mx_laststat+j*2+0)*(len_total+1)+i)
+ *(beta_Log+ j*(len_total+1)+i+1);
*(temp1+j) = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+1))*len_total*2+i*2+1)
+ *(alpha_Log+*(turbo_trellis.mx_laststat+j*2+1)*(len_total+1)+i)
+ *(beta_Log+j*(len_total+1)+i+1);
}
*(LLR_all_turbo+i) = E_algorithm_seq(temp1, n_states) - E_algorithm_seq(temp0, n_states);
}
free(alpha_Log);
free(beta_Log);
free(gama_Log);
free(tempmax);
free(temp0);
free(temp1);
}
/*---------------------------------------------------------------
FUNCTION:
void MAX_Log_MAP_decoder(float *recs_turbo, float *La_turbo, int terminated, float *LLR_all_turbo, int len_total)
DESCRIPTION:
MAX_Log-MAP decoder which caculate the LLR of input sequence.
PARAMETERS:
INPUT:
recs_turbo - Scaled received bits.
La_turbo - A priori information for the current decoder,
scrambled version of extrinsic information of the previous decoder.
terminated - Indicate the turbo_trellis is terminated or not.
1 - terminated
0 - not terminated
len_total - Length of the input data sequence.
OUTPUT:
LLR_all_turbo - The caculated LLR information sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void MAX_Log_MAP_decoder(float *recs_turbo, float *La_turbo, int terminated, float *LLR_all_turbo, int len_total)
{
int i, j;
float *alpha_Log, *beta_Log, *gama_Log;
float *tempmax;
float *temp0, *temp1;
float tempx, tempy;
if ((alpha_Log=(float *)malloc(n_states*(len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of alpha_Log \n");
exit(1);
}
if ((beta_Log=(float *)malloc(n_states*(len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of beta_Log \n");
exit(1);
}
if ((gama_Log=(float *)malloc(n_states*len_total*2*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of gama_Log \n");
exit(1);
}
if ((tempmax=(float *)malloc((len_total+1)*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of tempmax \n");
exit(1);
}
if ((temp0=(float *)malloc(n_states*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of temp0 \n");
exit(1);
}
if ((temp1=(float *)malloc(n_states*sizeof(float)))==NULL)
{
printf("\n fail to allocate memory of temp1 \n");
exit(1);
}
/*===== Initialization of Alpha and beta_Log =====*/
*(alpha_Log+0) = 0;
*(beta_Log+len_total) = 0;
for (i=1; i<n_states; i++)
{
*(alpha_Log+i*(len_total+1)+0) = (float)-INFTY;
if (terminated)
{
*(beta_Log+i*(len_total+1)+len_total) = (float)-INFTY;
}
else
{
*(beta_Log+i*(len_total+1)+len_total) = 0;
}
}
/*========compute Gama_Log========*/
for (i=0; i<len_total; i++) /* 0--len_total-1 代表 1--len_total */
{
for (j=0; j<n_states; j++) /* j->k */
{
*(gama_Log+j*len_total*2+i*2+0)
= -*(recs_turbo+2*i) + *(recs_turbo+2*i+1)*(*(turbo_trellis.mx_nextout+j*4+1)) - *(La_turbo+i)/2;
*(gama_Log+j*len_total*2+i*2+1)
= *(recs_turbo+2*i) + *(recs_turbo+2*i+1)*(*(turbo_trellis.mx_nextout+j*4+3)) + *(La_turbo+i)/2;
}
}
/*========Trace forward, compute Alpha_Log========*/
for (i=1; i<len_total+1; i++)
{
for (j=0; j<n_states; j++) /* 以j为中心*/
{
tempx = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+0))*len_total*2+(i-1)*2+0)
+ *(alpha_Log+(*(turbo_trellis.mx_laststat+j*2+0))*(len_total+1)+i-1);
tempy = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+1))*len_total*2+(i-1)*2+1)
+ *(alpha_Log+(*(turbo_trellis.mx_laststat+j*2+1))*(len_total+1)+i-1);
*(alpha_Log+j*(len_total+1)+i) = tempx>tempy?tempx:tempy;
}
for (j=0; j<n_states; j++)
{
if (*(tempmax+i) < *(alpha_Log+j*(len_total+1)+i))
{
*(tempmax+i) = *(alpha_Log+j*(len_total+1)+i);
}
}
for(j=0; j<n_states; j++)
{
*(alpha_Log+j*(len_total+1)+i) = *(alpha_Log+j*(len_total+1)+i) - *(tempmax+i);
}
}
/*========Trace backward, compute Beta_Log========*/
for (i=len_total-1; i>=0; i--)
{
for (j=0; j<n_states; j++) /*j为中心*/
{
tempx = *(gama_Log+j*len_total*2+i*2+0)
+ *(beta_Log+(*(turbo_trellis.mx_nextstat+j*2+0))*(len_total+1)+i+1);
tempy = *(gama_Log+j*len_total*2+i*2+1)
+ *(beta_Log+(*(turbo_trellis.mx_nextstat+j*2+1))*(len_total+1)+i+1);
*(beta_Log+j*(len_total+1)+i) = tempx>tempy?tempx:tempy;
}
for (j=0; j<n_states; j++)
{
*(beta_Log+j*(len_total+1)+i) = *(beta_Log+j*(len_total+1)+i) - *(tempmax+i+1);
}
}
/*===Compute the soft output,log-likelihood ratio of symbols in the frame===*/
for (i=0; i<len_total; i++)
{
for (j=0; j<n_states; j++)
{
*(temp0+j) = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+0))*len_total*2+i*2+0)
+ *(alpha_Log+*(turbo_trellis.mx_laststat+j*2+0)*(len_total+1)+i)
+ *(beta_Log+ j*(len_total+1)+i+1);
*(temp1+j) = *(gama_Log+(*(turbo_trellis.mx_laststat+j*2+1))*len_total*2+i*2+1)
+ *(alpha_Log+*(turbo_trellis.mx_laststat+j*2+1)*(len_total+1)+i)
+ *(beta_Log+j*(len_total+1)+i+1);
}
*(LLR_all_turbo+i) = get_max(temp1, n_states) - get_max(temp0, n_states);
}
free(alpha_Log);
free(beta_Log);
free(gama_Log);
free(tempmax);
free(temp0);
free(temp1);
}
/*---------------------------------------------------------------
FUNCTION:
get_max(float *data_seq, int length)
DESCRIPTION:
Get the maximum value of a data_seq sequence.
PARAMETERS:
INPUT:
data_seq - Contains pointer to the input sequence.
length - Length of "data_seq".
RETURN VALUE:
The maximum one of this data_seq sequence.
---------------------------------------------------------------*/
float get_max(float *data_seq, int length)
{
int i;
float temp;
temp = *(data_seq+0);
for (i=1; i<length; i++)
{
if (temp < *(data_seq+i))
{
temp = *(data_seq+i);
}
}
return temp;
}
/*---------------------------------------------------------------
FUNCTION:
E_algorithm(float x, float y)
DESCRIPTION:
Compute: log(exp(x) + exp(y)) = max(x,y)+log(1+exp(-|y-x|))
where log(1+exp(-|y-x|)) can be implemented in a lookup table.
PARAMETERS:
INPUT:
x - One number.
y - The other number.
RETURN VALUE:
log(exp(x) + exp(y)).
---------------------------------------------------------------*/
float E_algorithm(float x, float y) // log(exp(x) + exp(y)) = max(x,y)+f(-|y-x|)
{
float temp = (y-x)>0? (y-x):(x-y);
int i;
if (temp>=4.3758)
{
temp = 0;
}
else
{
for (i=0; i<16 && temp>=lookup_index_Log_MAP[i]; i++)
{
;
}
temp = (float)lookup_table_Log_MAP[i-1];
}
return ( (x>y?x:y) + temp );
}
/*---------------------------------------------------------------
FUNCTION:
E_algorithm_seq(float *data_seq, int length)
DESCRIPTION:
E_algorithm for a data_seq sequence.
PARAMETERS:
INPUT:
data_seq - Contains pointer to the input sequence.
length - Length of "data_seq".
RETURN VALUE:
The result of E_algorithm for this data_seq sequence.
---------------------------------------------------------------*/
float E_algorithm_seq(float *data_seq, int length)
{
int i;
float temp;
temp = E_algorithm(*(data_seq+0), *(data_seq+1));
for (i=2; i<length; i++)
{
temp = E_algorithm(temp, *(data_seq+i));
}
return temp;
}
/*---------------------------------------------------------------
FUNCTION:
void decision(double *LLR_seq, int length, int *output)
DESCRIPTION:
Make the final decision.
PARAMETERS:
INPUT:
LLR_seq - The LLR_seq information sequence.
length - Length of "LLR_seq".
OUTPUT:
output - Contains pointer to the output data sequence.
RETURN VALUE:
None
---------------------------------------------------------------*/
void decision(float *LLR_seq, int length, int *output)
{
int i;
for (i=0; i<length; i++)
{
if (*(LLR_seq+i) < 0)
{
*(output+i) = 0;
}
else
{
*(output+i) = 1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -