⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turbo_code_log_map.c

📁 一些关于Turbo编码译码实现所需的函数和原程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
				*(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 + -