📄 turbo_code_log_map.c
字号:
*(mx_puncture_turbo+type_punc*80+101) = 0;
*(mx_puncture_turbo+type_punc*80*2+152) = 0;
*(mx_puncture_turbo+type_punc*80+152) = 0;
break;
}
case 4:
{
*(mx_puncture_turbo+type_punc*80*2+90) = 0;
*(mx_puncture_turbo+type_punc*80+90) = 0;
*(mx_puncture_turbo+type_punc*80*2+191) = 0;
*(mx_puncture_turbo+type_punc*80+191) = 0;
*(mx_puncture_turbo+type_punc*80*2+272) = 0;
*(mx_puncture_turbo+type_punc*80+272) = 0;
break;
}
default:
{
return 0;
}
}
}
return 1;
}
/*---------------------------------------------------------------
函数:
void puncture(int *data_unpunc, int length_unpunc, int *data_punctured,
int M_mx_punc, int N_mx_punc, int times_punc)
介绍:
删余.
参数:
输入参数:
data_unpunc - 未删余数据首址.
length_unpunc - 未删余数据长度.
M_mx_punc - 删余阵行数.
N_mx_punc - 删余阵列数.
times_punc - 几次使用删余阵.
输出参数:
data_punctured - 删余后数据首址.
返回值:
无.
---------------------------------------------------------------*/
void puncture(int *data_unpunc, int length_unpunc, int *data_punctured,
int M_mx_punc, int N_mx_punc, int times_punc)
{
int i, j, k=0, temp_time=0; /* 循环变量 */
int *mx_puncture_turbo; /* 用于选择删余阵 */
switch (N_mx_punc)
{
case 80:
{
mx_puncture_turbo = mx_puncture_turbo_80;
break;
}
case 160:
{
mx_puncture_turbo = mx_puncture_turbo_160;
break;
}
case 320:
{
mx_puncture_turbo = mx_puncture_turbo_320;
break;
}
default:
{
printf("error in puncturing!\n");
exit(1);
}
}
for (temp_time=0; temp_time<times_punc; temp_time++) /* 删余阵使用次数循环 */
{
/* 从头至尾遍历删余阵 */
for (j=0; j<N_mx_punc && (temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc)<length_unpunc; j++)
{
for (i=0; i<M_mx_punc && (temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i)<length_unpunc;i++)
{
if (*(mx_puncture_turbo+i*N_mx_punc+j))
{
*(data_punctured+k) = *(data_unpunc+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i);
k++;
}
}
}
}/* 删余阵使用次数循环结束 */
/* 尾比特不打孔 */
if (times_punc*M_mx_punc*N_mx_punc<length_unpunc)
{
for (i=times_punc*M_mx_punc*N_mx_punc; i<length_unpunc; i++)
{
*(data_punctured+k) = *(data_unpunc+i);
k++;
}
}
}
/*---------------------------------------------------------------
函数:
void depuncture(double *receive_punc, int length_punc, double *receive_depunced,
int M_mx_punc, int N_mx_punc, int times_punc)
介绍:
填充删余比特.
参数:
输入参数:
receive_punc - 删余后数据首址.
length_punc - 删余数据长度.
M_mx_punc - 删余阵行数.
N_mx_punc - 删余阵列数.
times_punc - 几次使用删余阵.
输出参数:
receive_depunced - 填充后数据首址.
返回值:
无.
---------------------------------------------------------------*/
void depuncture(float *receive_punc, int length_punc, float *receive_depunced,
int M_mx_punc, int N_mx_punc, int times_punc)
{
int i, j, k=0, temp_time=0; /* 循环变量 */
int *mx_puncture_turbo; /* 用于选择删余阵 */
switch (N_mx_punc)
{
case 80:
{
mx_puncture_turbo = mx_puncture_turbo_80;
break;
}
case 160:
{
mx_puncture_turbo = mx_puncture_turbo_160;
break;
}
case 320:
{
mx_puncture_turbo = mx_puncture_turbo_320;
break;
}
default:
{
printf("error in puncturing!\n");
exit(1);
}
}
for (temp_time=0; temp_time<times_punc; temp_time++)/* 删余阵使用次数循环 */
{
/* 从头至尾遍历删余阵 */
for (j=0; j<N_mx_punc; j++)
{
for (i=0; i<M_mx_punc && k<length_punc; i++)
{
/* 1则填数据 */
if (*(mx_puncture_turbo+i*N_mx_punc+j))
{
*(receive_depunced+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i) = *(receive_punc+k);
k++;
}
/* 0则填0 */
else
{
*(receive_depunced+temp_time*M_mx_punc*N_mx_punc+j*M_mx_punc+i) = 0;
}
}
}
}/* 删余阵使用次数循环结束 */
/* 加上尾比特 */
if (k<length_punc)
{
for (i=times_punc*M_mx_punc*N_mx_punc; k<length_punc; i++)
{
*(receive_depunced+i) = *(receive_punc+k);
k++;
}
}
}
/*---------------------------------------------------------------
函数:
void demultiplex(double *rec_turbo, int len_info, double *yk_turbo, int type_flow)
介绍:
解复用.
参数:
输入参数:
rec_turbo -接收数据序列首址.
len_info - 接收数据序列长度.
type_flow - 信息类型: 1-业务信息, 0补充信息.
输出参数:
yk_turbo - 解复用后数据序列首址.
返回值:
无.
---------------------------------------------------------------*/
void demultiplex(float *rec_turbo, int len_info, double *yk_turbo, int type_flow)
{
int i; /* 循环变量 */
int len_total = len_info+M_num_reg; /* 总长度 */
double *info2, *inted_info2; /* 信息位和交织后的信息位 */
if ((info2=(double *)malloc(len_info*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of info2 \n");
exit(1);
}
if ((inted_info2=(double *)malloc(len_info*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of inted_info2 \n");
exit(1);
}
/* 对信息比特 */
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_double(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 (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);
}
/*---------------------------------------------------------------
函数:
void Log_MAP_decoder(double *recs_turbo, double *La_turbo, int terminated,
double *LLR_all_turbo, int len_total)
介绍:
Log_MAP译码器.
参数:
输入参数:
rec_turbo -乘Lc后的接收序列首址.
La_turbo - 外信息.
terminated - 是否结尾.
len_total - 输入序列长度.
输出参数:
LLR_all_turbo - 似然比.
返回值:
无.
---------------------------------------------------------------*/
void Log_MAP_decoder(double *recs_turbo, double *La_turbo, int terminated, double *LLR_all_turbo, int len_total)
{
int i, j; /* 循环变量 */
double *alpha_Log, *beta_Log; /* n_states*(len_total+1) */
double *gama_Log; /* n_states*len_total*2 */
double *tempmax; /* len_total+1 */
double *temp0, *temp1; /* n_states */
double tempx, tempy;
if ((alpha_Log=(double *)malloc(n_states*(len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of alpha_Log \n");
exit(1);
}
if ((beta_Log=(double *)malloc(n_states*(len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of beta_Log \n");
exit(1);
}
if ((gama_Log=(double *)malloc(n_states*len_total*2*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of gama_Log \n");
exit(1);
}
if ((tempmax=(double *)malloc((len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of tempmax \n");
exit(1);
}
if ((temp0=(double *)malloc(n_states*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of temp0 \n");
exit(1);
}
if ((temp1=(double *)malloc(n_states*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of temp1 \n");
exit(1);
}
/*===== 初始化alpha和beta =====*/
*(alpha_Log+0) = 0;
*(beta_Log+len_total) = 0;
for (i=1; i<n_states; i++)
{
*(alpha_Log+i*(len_total+1)+0) = (double)-INFTY;
/* 结尾 */
if (terminated)
{
*(beta_Log+i*(len_total+1)+len_total) = (double)-INFTY;
}
/* 不结尾 */
else
{
*(beta_Log+i*(len_total+1)+len_total) = 0;
}
}
/*======== 计算Gama ========*/
for (i=0; i<len_total; i++) /* 逐比特循环 */
{
for (j=0; j<n_states; j++) /* 按状态循环 */
{
/* 见论文gama计算式 */
*(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;
} /* 按状态循环结束 */
} /* 逐比特循环结束 */
/*======== 前向计算alpha ========*/
for (i=1; i<len_total+1; i++) /* 逐比特循环 */
{
for (j=0; j<n_states; 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);
} /* 按状态循环结束 */
/* 计算tempmax[i],用于规一化alpha和beta */
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);
}
}
/* 规一化alpha */
for(j=0; j<n_states; j++)
{
*(alpha_Log+j*(len_total+1)+i) = *(alpha_Log+j*(len_total+1)+i) - *(tempmax+i);
}
} /* 逐比特循环结束 */
/*======== 反向计算beta ========*/
for (i=len_total-1; i>=0; i--) /* 逐比特循环 */
{
for (j=0; j<n_states; 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);
} /* 按状态循环结束 */
/* 规一化beta */
for (j=0; j<n_states; j++)
{
*(beta_Log+j*(len_total+1)+i) = *(beta_Log+j*(len_total+1)+i) - *(tempmax+i+1);
}
} /* 逐比特循环结束 */
/*=== 计算似然比LLR ===*/
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);
}
/*---------------------------------------------------------------
函数:
void MAX_Log_MAP_decoder(double *recs_turbo, double *La_turbo, int terminated,
double *LLR_all_turbo, int len_total)
介绍:
MAX_Log_MAP译码器.
参数:
输入参数:
rec_turbo -乘Lc后的接收序列首址.
La_turbo - 外信息.
terminated - 是否结尾.
len_total - 输入序列长度.
输出参数:
LLR_all_turbo - 似然比.
返回值:
无.
---------------------------------------------------------------*/
void MAX_Log_MAP_decoder(double *recs_turbo, double *La_turbo, int terminated, double *LLR_all_turbo, int len_total)
{
int i, j; /* 循环变量 */
double *alpha_Log, *beta_Log; /* n_states*(len_total+1) */
double *gama_Log; /* n_states*len_total*2 */
double *tempmax; /* len_total+1 */
double *temp0, *temp1; /* n_states */
double tempx, tempy;
if ((alpha_Log=(double *)malloc(n_states*(len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of alpha_Log \n");
exit(1);
}
if ((beta_Log=(double *)malloc(n_states*(len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of beta_Log \n");
exit(1);
}
if ((gama_Log=(double *)malloc(n_states*len_total*2*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of gama_Log \n");
exit(1);
}
if ((tempmax=(double *)malloc((len_total+1)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of tempmax \n");
exit(1);
}
if ((temp0=(double *)malloc(n_states*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of temp0 \n");
exit(1);
}
if ((temp1=(double *)malloc(n_states*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of temp1 \n");
exit(1);
}
/*===== 初始化alpha和beta =====*/
*(alpha_Log+0) = 0;
*(beta_Log+len_total) = 0;
for (i=1; i<n_states; i++)
{
*(alpha_Log+i*(len_total+1)+0) = (double)-INFTY;
/* 结尾 */
if (terminated)
{
*(beta_Log+i*(len_total+1)+len_total) = (double)-INFTY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -