#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>
#include <memory.h>
#include <assert.h>
#include "mex.h"
#define COLUMN_OF_G 4 /* 生成阵列数 */
#define N_ITERATION 8 /* 译码叠代次数 */
/* 定义数据结构 */
/* 生成阵结构 */
typedef struct
{
int N_num_row; /* 生成阵行数 */
int K_num_col; /* 生成阵列数 */
int *g_matrix; /* 生成阵首址 */
} TURBO_G;
/* Trellis结构 */
/*
mx_nextout(mx_lastout)为后(前)向输出数组首址:
行数:状态数, 列数:4
每行第一列和第三列为后(前)向的输入(1或-1),第二列和第四列为与之对应的输出(1或-1).
mx_nextstat(mx_laststat)为后(前)向状态数组首址:
行数:状态数, 列数:2
各列表示输入为1(0)时对应的后(前)向状态.
*/
typedef struct
{
int *mx_nextout; /* 后向输出矩阵 */
int *mx_nextstat; /* 后向状态矩阵 */
int *mx_lastout; /* 前向输出矩阵 */
int *mx_laststat; /* 前向状态矩阵 */
} TURBO_TRELLIS;
#define TERMINATED 1 /* 0不结尾;1结尾 */
#define G_ROW_1 13 /* 反馈抽头 */
#define G_ROW_2 15 /* 输出抽头 */
/* 无穷大 */
#ifndef INFTY
#define INFTY 1E10
#endif
int M_num_reg = COLUMN_OF_G-1; /* 寄存器数 */
int n_states = 8; /* 状态数:2的M_num_reg次幂 */
TURBO_G turbo_g; /* 生成阵 */
TURBO_TRELLIS turbo_trellis; /* Tellis结构 */
/* Log-MAP算法用到的查找表 */
const double lookup_index_Log_MAP[16] = {0.0, 0.08824, 0.19587, 0.31026, 0.43275, 0.56508,
0.70963, 0.86972, 1.0502, 1.2587, 1.5078, 1.8212,
2.2522, 2.9706, 3.6764, 4.3758};
const double lookup_table_Log_MAP[16] = {0.69315, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35,
0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.025, 0.0125};
/*---------------------------------------------------------------
函数:
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;
}
/*---------------------------------------------------------------
函数:
int encode_bit(int inbit, int *stat)
介绍:
比特编码器.
参数:
输入参数:
inbit -输入比特.
stat - 当前寄存器状态首址.
输出参数:
stat - 编码后寄存器状态首址.
返回值:
输出比特.
---------------------------------------------------------------*/
int encode_bit(int inbit, int *stat)
{
int j; /* 循环变量 */
int output; /* 输出比特 */
/* 计算输出比特 */
output = (*(turbo_g.g_matrix+turbo_g.K_num_col+0)) * inbit;
for (j=1; j<turbo_g.K_num_col; j++)
{
output = (output + (*(turbo_g.g_matrix+turbo_g.K_num_col+j)) * (*(stat+j-1)))%2;
}
/* 修改状态序列 */
for (j=turbo_g.K_num_col-2; j>0; j--)
{
*(stat+j)=*(stat+j-1);
}
*(stat+0) = inbit;
return output;
}
/*---------------------------------------------------------------
函数:
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:叠加反馈后的输入比特,根据生成矩阵第一行(13) */
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;
/* 计算输出比特,修改状态序列,根据生成矩阵第二行(15) */
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);
}
/*---------------------------------------------------------------
函数:
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 TurboCodingInit()
{
/* 初始化生成阵 */
turbo_g.N_num_row = 2; /* 行数 */
turbo_g.K_num_col = COLUMN_OF_G; /* 列数 */
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);
}
/* 生成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(