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

📄 turbo_code_log_map.c

📁 禁忌搜索算法的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
	  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 + -