📄 turbo_code_log_map.c
字号:
depuncture(supflow_for_decode, 2*length_info, receive_punc, 3, length_info/4, 4);
demultiplex(receive_punc, length_info, yk_turbo, 0); /* 解复用 */
}
else
{
demultiplex(supflow_for_decode, length_info, yk_turbo, 0); /* 解复用 */
}
/* scale数据 */
for (i=0; i<2*length_total*2; i++)
{
*(yk_turbo+i) = (double)( *(yk_turbo+i) * Lc_turbo *0.5 );
}
/* 初始化外信息和似然信息 */
for (i=0; i<length_total; i++)
{
*(La_turbo+i) = *(Le_turbo+i) = *(LLR_all_turbo+i) = 0;
}
for (iteration=0; iteration<N_ITERATION; iteration++) /* 开始叠代 */
{
/* 译码器1: */
/* 得到来自译码器2的外信息 */
de_interleave_double(La_turbo, Le_turbo, TYPE_INTERLEAVER, length_info, 0);
/* 结尾处赋0 */
for (i=length_info; i<length_total; i++)
{
*(La_turbo+i) = 0;
}
switch(TYPE_DECODER)
{
case 1: /* Log-MAP算法 */
Log_MAP_decoder(yk_turbo, La_turbo, 1, LLR_all_turbo, length_total);
break;
case 2:
MAX_Log_MAP_decoder(yk_turbo, La_turbo, 1, LLR_all_turbo, length_total);
break;
default:
break;
}
/* 计算外信息 */
for (i=0; i<length_total; i++)
{
*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*i));
}
/* 译码器2: */
/* 交织来自译码器1的外信息 */
interleave_double(Le_turbo, La_turbo, TYPE_INTERLEAVER, length_info, 0);
/* 结尾处赋0 */
for (i=length_info; i<length_total; i++)
{
*(La_turbo+i) = 0;
}
switch(TYPE_DECODER)
{
case 1: /* Log-MAP算法 */
Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
break;
case 2:
MAX_Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
break;
default:
break;
}
/* 计算外信息 */
for(i=0; i<length_total; i++)
{
*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*length_total+2*i));
}
/* 译码器2结束 */
}
/* 对全部似然比判决 */
decision(LLR_all_turbo, length_total, tempout);
/* 对判决比特解交织 */
de_interleave_int(supflow_decoded, tempout, TYPE_INTERLEAVER, length_info, 0);
/* 修改长度变量 */
*supflow_length = length_info;
free(receive_punc);
free(yk_turbo);
free(La_turbo);
free(Le_turbo);
free(LLR_all_turbo);
free(tempout);
}
/*---------------------------------------------------------------
函数:
void TurboCodingInit()
介绍:
Turbo码初始化函数.
参数:
无
返回值:
无
---------------------------------------------------------------*/
void TurboCodingInit()
{
/* 初始化生成阵 */
turbo_g.N_num_row = 2; /* 行数 */
turbo_g.K_num_col = COLUMN_OF_G; /* 列数 */
/* 计算编码速率,打孔为1/2,不打孔为1/3 */
rate_coding = (double)(1/3);
if ((turbo_g.g_matrix=(int *)malloc(turbo_g.N_num_row*turbo_g.K_num_col*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of turbo_g\n");
exit(1);
}
/* 得到生成阵 */
if (!gen_g_matrix(turbo_g.K_num_col, G_ROW_1, G_ROW_2, turbo_g.g_matrix))
{
printf("error number of G\n");
exit(1);
}
/* 生成删余阵 */
if ((mx_puncture_turbo_80=(int *)malloc(sizeof(int)*3*80))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_80\n");
exit(1);
}
if ((mx_puncture_turbo_160=(int *)malloc(sizeof(int)*3*160))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_160\n");
exit(1);
}
if ((mx_puncture_turbo_320=(int *)malloc(sizeof(int)*3*320))==NULL)
{
printf("\n fail to allocate memory of mx_puncture_turbo_320\n");
exit(1);
}
if (!gen_mx_punc())
{
printf("\nError! Can not generate the puncture matrix properly!\n");
exit(1);
}
/* 生成Trellis */
if ((turbo_trellis.mx_lastout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_lastout \n");
exit(1);
}
if ((turbo_trellis.mx_laststat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_laststat \n");
exit(1);
}
if ((turbo_trellis.mx_nextout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_nextout \n");
exit(1);
}
if ((turbo_trellis.mx_nextstat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
{
printf("\n fail to allocate memory of turbo_trellis.mx_nextstat \n");
exit(1);
}
gen_trellis();
/* 为随机交织器分配内存 */
if (TYPE_INTERLEAVER==2)
{
/* 业务信息随机交织器 */
if ((index_randomintlvr=(int *)malloc(MAX_FRAME_LENGTH*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of index_randomintlvr \n");
exit(1);
}
/* 补充信息随机交织器 */
if ((index_randomintlvr_sup=(int *)malloc(SUP_FRAME_LENGTH*sizeof(int)))==NULL)
{
printf("\n fail to allocate memory of index_randomintlvr_sup \n");
exit(1);
}
}
}
/*---------------------------------------------------------------
函数:
void TurboCodingRelease()
介绍:
释放Turbo码初始化时的内存.
参数:
无
返回值:
无
---------------------------------------------------------------*/
void TurboCodingRelease()
{
/* 释放生成阵内存 */
free(turbo_g.g_matrix);
/* 释放删余阵内存 */
free(mx_puncture_turbo_80);
free(mx_puncture_turbo_160);
free(mx_puncture_turbo_320);
/* 释放trellis结构内存 */
free(turbo_trellis.mx_lastout);
free(turbo_trellis.mx_laststat);
free(turbo_trellis.mx_nextout);
free(turbo_trellis.mx_nextstat);
/* 释放随机交织器内存 */
if (TYPE_INTERLEAVER==2)
{
free(index_randomintlvr);
free(index_randomintlvr_sup);
}
}
/*---------------------------------------------------------------
函数:
int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
介绍:
得到生成阵.
参数:
输入参数:
k_column - 生成阵列数.
g_row1 - 生成阵第一行.
g_row2 - 生成阵第二行.
输出参数:
mx_g_turbo - 生成阵首址.
返回值:
1 - 成功地得到生成阵.
0 - 生成生成阵失败.
---------------------------------------------------------------*/
int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
{
int i, position; /* 循环变量 */
int high_num, low_num;
/* 第一行 */
high_num = g_row1;
position = 1; /* 第几个8进制数 */
while (high_num>0)
{
low_num = high_num%10; /* 得到这个8进制数 */
if (low_num>7) /* 判断是否为8进制数 */
{
return 0;
}
high_num = high_num/10; /* 记下其余部分 */
/* 将8进制数转为二进制并保存 */
for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
{
*(mx_g_turbo+i) = low_num%2;
low_num = low_num/2;
}
position++; /* 下一个位置 */
if (i<0)
{
break;
}
}
/* 第二行 */
high_num = g_row2;
position = 1; /* 第几个8进制数 */
while (high_num>0)
{
low_num = high_num%10; /* 得到这个8进制数 */
if (low_num>7) /* 判断是否为8进制数 */
{
return 0;
}
high_num = high_num/10; /* 记下其余部分 */
/* 将8进制数转为二进制并保存 */
for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
{
*(mx_g_turbo+k_column+i) = low_num%2;
low_num = low_num/2;
}
position++; /* 下一个位置 */
if (i<0)
{
break;
}
}
return 1;
}
/*---------------------------------------------------------------
函数:
void gen_trellis()
介绍:
生成Trellis.
参数:
无
返回值:
无
---------------------------------------------------------------*/
void gen_trellis()
{
int i, j, k; /* 循环变量 */
int dk_turbo, ak_turbo, outbit; /* 编码器内部比特和输出比特 */
int *tempstat; /* 状态序列 */
if ((tempstat=(int *)malloc(sizeof(int)*M_num_reg))==NULL)
{
printf("\n fail to allocate memory of tempstat \n");
exit(1);
}
/* 生成后向输出和后向状态矩阵 */
for (i=0; i<n_states; i++) /* 状态循环 */
{
for (j=0; j<2; j++) /* 输入为0,1 */
{
int2bin(i, tempstat, M_num_reg); /* 将状态转为二进制序列 */
/* dk */
dk_turbo = j;
/* 计算ak */
ak_turbo = (*(turbo_g.g_matrix+0)) * dk_turbo;
for (k=1; k<turbo_g.K_num_col; k++)
{
ak_turbo = ak_turbo + (*(turbo_g.g_matrix+k)) * (*(tempstat+k-1));
}
ak_turbo = ak_turbo % 2;
/* 计算输出比特,修改状态序列 */
outbit = encode_bit(ak_turbo, tempstat);
/* 写入后向输出和后向状态矩阵 */
*(turbo_trellis.mx_nextout+i*4+2*j)=2*dk_turbo-1;
*(turbo_trellis.mx_nextout+i*4+2*j+1)=2*outbit-1;
*(turbo_trellis.mx_nextstat+i*2+j)=bin2int(tempstat, M_num_reg);
} /* 输入循环结束 */
} /* 状态循环结束 */
/* 生成前向输出和前向状态矩阵 */
for (i=0; i<n_states; i++) /* 状态循环 */
{
for (j=0; j<2; j++)/* 输入为0,1 */
{
*(turbo_trellis.mx_laststat+(*(turbo_trellis.mx_nextstat+i*2+j))*2+j) = i;
*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j)
= *(turbo_trellis.mx_nextout+i*4+2*j);
*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j+1)
= *(turbo_trellis.mx_nextout+i*4+2*j+1);
} /* 输入循环结束 */
} /* 状态循环结束 */
free(tempstat);
}
/*---------------------------------------------------------------
函数:
void int2bin(int intstat, int *tempstat, int length)
介绍:
十进制数转为二进制序列.
参数:
输入参数:
intstat - 十进制数.
length - 要得到的二进制序列长度.
输出参数:
bin_stat - 二进制序列首址.
返回值:
无
---------------------------------------------------------------*/
void int2bin(int intstat, int *bin_stat, int length)
{
int i, temp;
temp = intstat;
/* 除以2求余数 */
for (i=length-1; i>=0; i--)
{
*(bin_stat+i) = temp%2;
temp = temp/2;
}
}
/*---------------------------------------------------------------
函数:
int bin2int(int *binseq, int length)
介绍:
二进制序列转为十进制数.
参数:
输入参数:
binseq - 二进制序列首址.
length - 二进制序列长度.
输出参数:
无
返回值:
得到的十进制数.
---------------------------------------------------------------*/
int bin2int(int *binseq, int length)
{
int i, j, temp;
int sum = 0;
for (i=0; i<length; i++)
{
temp = 1;
/* 计算该位权值 */
for (j=1; j<=i; j++)
{
temp = temp * 2;
}
sum = sum + temp * (*(binseq+length-1-i));
}
return sum;
}
/*---------------------------------------------------------------
函数:
double random_turbo()
介绍:
生成0-1均匀分布随机数.
参数:
无
返回值:
生成的0-1均匀分布随机数.
---------------------------------------------------------------*/
double random_turbo()
{
long z,k;
static long s1 = 12345L;
static long s2 = 1234546346L;
k= s1 / 53668L;
s1 = 40014L * (s1 - k*53668L) - k*12211L;
if (s1<0)
s1 = s1 + 2147483563L;
k = s2 / 52774;
s2 = 40692L * (s2 - k*52774L) - k*3791L;
if (s2<0)
s2 = s2 + 2147483399L;
z=s1 - s2;
if (z<1)
z = z + 2147483562L;
return (double) z / (double) 2147483563.0;
}
/*---------------------------------------------------------------
函数:
void gen_rand_index(int length, int type_flow)
介绍:
生成随机交织器的下标.
参数:
输入参数:
length - 交织器长度.
type_flow - 信息类型: 1-业务信息, 0-补充信息.
输出参数:
无
返回值:
无
---------------------------------------------------------------*/
void gen_rand_index(int length, int type_flow)
{
int *index_random; /* 需先生成的0-1均匀分布随机数序列 */
double *tempindex; /* 用以选择随机交织首址 */
double tempmax; /* 最大值 */
int selectedscr; /* 选中的下标 */
int i, j; /* 循环变量 */
if ((tempindex=(double *)malloc((length)*sizeof(double)))==NULL)
{
printf("\n fail to allocate memory of tempindex \n");
exit(1);
}
/* 由数据类型选随机交织器 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -