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

📄 ldpc.c

📁 介绍了ldpc编码相关的设计与实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	p_ldpc_param->MatRow		=	(short*) malloc(mat_param[1]*(mat_param[4]+1)*sizeof(short));
	p_ldpc_param->GMatrix		=	(short*) malloc(mat_param[0]*mat_param[2]*sizeof(short));
	p_ldpc_param->iterC		=	100;

	Construct_H_Matrix(p_ldpc_param->mat_param, p_ldpc_param->MatCol, p_ldpc_param->MatRow, fpLDPC);
	Construct_G_Matrix(p_ldpc_param->MatCol, p_ldpc_param->MatRow, &(p_ldpc_param->GMatrix), p_ldpc_param->mat_param);
	
}

void LDPC_encode(short *gen, short *input, short *output, short *mat_para)
{
	short  i , j;
	short  COLUMN , G_ROW , H_ROW;
	short  Max_row_weight , Max_col_weight;
	
	COLUMN = mat_para[0];
	H_ROW  = mat_para[1];
	G_ROW  = mat_para[2];
	Max_col_weight = mat_para[3];
	Max_row_weight = mat_para[4];
	
	memset(output,0,sizeof(short)*COLUMN);

	for(i=0;i<COLUMN;i++)
		for(j=0;j<G_ROW;j++)
			output[i] = output[i]^(input[j]&gen[j*COLUMN+i]);	
}

double saturate(double x, double Inf)
{
	double	tmp;
	
	tmp = x;
	
	if (x > Inf)
	{
		tmp = Inf;
	}
	if (x < -Inf)
	{
		tmp = -Inf;
	}
	
	return(tmp);
}

/**************************************************************************************************************************
 * NAME : short check_sum(short *mat_row, short *cc, short length, short row_weight)
 * ABSTRACT : check whether the parity equations satisfied  based on the encoded bits
 * ENTRY : input : short *mat_row :
                    short *cc : the encoded bits
                    short length : the check equations number
                    short row_weight : the max_row _weight
 * RETURN : flag whether the parity equations satisfied : flag = 0 ,satisfied 
 *************************************************************************************************************************/
short check_sum(short *mat_row, short *cc, short length, short row_weight)
{
	int    i,j;
    	short  temp , flag=0;
	short  weight , col;

	for(i=0;i<length;i++)
	{
		temp = 0;
		weight = mat_row[i*(row_weight+1)];
		for(j=1;j<=weight;j++)
		{
			col = mat_row[i*(row_weight+1)+j];
			temp = temp ^ cc[col];   
		}

		if (temp==1)	flag ++;
	}

	return(flag);
}
/**************************************************************************************************************************
 * NAME : double Horiz_compute_llr(double *vcQ, int row_weight, int ex_vode)
 * ABSTRACT : compute the extrinsic information passing from the check node j to the variable node i ; 
              extrinsic information is the LLR that the check node j is satified based on messages
              from connected variable nodes except i.
 * ENTRY : input : double *vcQ : array contain the extrinsic informations
                               passing from all variable nodes connected the check node to the check node.
                   int row_weight : the  Max_row_weight for current row.
                   int ex_vode: the variable node excluded.
 * RETURN :the extrinsic information passing from the check node j to the variable node i. 
 *************************************************************************************************************************/
/*double Horiz_compute_llr(double *vcQ, int row_weight, int ex_vnode)
{
	double	T;
	int	k;
	double	tmp;

	T = 1;

	for(k=0; k<row_weight; k++)
	{
		if (k != ex_vnode)
		{
			T = T*(1-exp(vcQ[k]))/(1+exp(vcQ[k]));
		}
	}
	
	tmp = log((1-T)/(1+T));
	
	tmp = saturate(tmp, 100);

	return(tmp);

}*/

/*
//The SPA decoder
double Horiz_compute_llr(double *vcQ, int row_weight, int ex_vnode)
{
	double	T,S;
	int	k;
	double	tmp,a,b;

	T = 1;
    S = 0;

	for(k=0; k<row_weight; k++)
	{
		if (k != ex_vnode)
		{
		    if(vcQ[k]>0)
			{
			    a = 1;
				b = vcQ[k];
		    }
			else
			{
				a = -1;
				b = -vcQ[k];
			}

			T = T*a; 
			 
			S = S + log((exp(b)+1)/(exp(b)-1));          
		}
	}
	
	tmp = T * log((exp(S)+1)/(exp(S)-1));
	
	tmp = saturate(tmp, 100);

	return(tmp);

}*/

/*
// the Min-Sum Decoder
double Horiz_compute_llr(double *vcQ, int row_weight, int ex_vnode)
{
	double	T;
	int	k;
	double	tmp,a,b,min;

	T = 1;
	min = 1000000;

	for(k=0; k<row_weight; k++)
	{
		if (k != ex_vnode)
		{
		    if(vcQ[k]>0)
			{
			    a = 1;
				b = vcQ[k];
		    }
			else
			{
				a = -1;
				b = -vcQ[k];
			}

			T = T*a;
			
			if(b<min)
			{
			    min = b;
			}
        
		}
	}
	
	tmp = T * min;
	
	tmp = saturate(tmp, 100);

	return(tmp);

}*/	

// the Min-Sum-Plus-Correction-Factor Decoder
double correct_factor(double x,double y)
{
     if((fabs(x+y)<2)&&(fabs(x-y)>(2*fabs(x+y))))
	        return 0.5;
	 else if( (fabs(x-y)<2) && ( (fabs(x+y)) > (2*fabs(x-y)) ) )
	        return -0.5;
	 else return 0.0;
}

double Horiz_compute_llr(double *vcQ, int row_weight, int ex_vnode)
{
	double	T;
	int	k;
	double	tmp,a,b,min,factor,tmpa,tmpb;

	T = 1;
	min = 1000000;
	tmp = T * min;

	for(k=0; k<row_weight; k++)
	{
		if (k != ex_vnode)
		{
		    factor = correct_factor(tmp,vcQ[k]);
		    
		    if(vcQ[k]>0)
			{
			    a = 1;
				b = vcQ[k];
		    }
			else
			{
				a = -1;
				b = -vcQ[k];
			}

		    if(tmp>0)
			{
			    tmpa = 1;
				tmpb = tmp;
		    }
			else
			{
				tmpa = -1;
				tmpb = -tmp;
			}

            if(b<tmpb)
			{
			    tmpb = b;
			}
			
             tmp = a * tmpa * tmpb + factor;      
		}
	}
	
	
	tmp = saturate(tmp, 100);

	return(tmp);

}  

 											
/**************************************************************************************************************************
 * NAME : double Verti_compute_llr(double *vcL, int col_weight, double f, int ex_cnode)
 * ABSTRACT : compute the extrinsic information passing from the variable node i to the check node j ; 
              extrinsic information is the LLR of the varible node i based on message from  all check node connected i except j 
 * ENTRY : input : double * vcL : array contain the extrinsic information passing from all check node to the varible node i
                   int col_weight : the  Max_clo_weight for current column.
                   double f : the current LLR of all varible nodes 
                   int ex_cnode : the check node excluded
 * RETURN : the extrinsic information passing from the variable node i to the check node j . 
 *************************************************************************************************************************/					
double Verti_compute_llr(double *cvL, int col_weight, double f, int ex_cnode)
{
	int	k;
	double	tmp;

	tmp = f;

	for(k=0; k<col_weight; k++)
	{
		if (k != ex_cnode)
		{
			tmp = tmp + cvL[k];
		}
	}

	return(tmp);
}

/**************************************************************************************************************************
 * NAME : 
 * ABSTRACT :
 * ENTRY : 
 * RETURN : 
 *************************************************************************************************************************/
void BP_decoding(double		*llr_in,
		 double		*llr_out,
		 short		*dec_out,
		 short		*mat_col,
		 short		*mat_row,
		 short		*mat_param,
		 short		iterN)
{
	double		*table_row;
	double		*table_col;

	short		*row_indx;
	short		*col_indx;

	short		Column, H_row, G_row, Max_col_weight, Max_row_weight;

	short		flag = 1;


	int		i,j,k,iter = 0;
	short		tmp_weight, tmp_col, tmp_row;

	double		tmp;

	//parameter initialize
	Column = mat_param[0];
	H_row = mat_param[1];
	G_row = mat_param[2];
	Max_col_weight = mat_param[3];
	Max_row_weight = mat_param[4];

	
	table_col = (double*) malloc(Column*Max_col_weight*sizeof(double));
	table_row = (double*) malloc(H_row*Max_row_weight*sizeof(double));
	row_indx = (short*) malloc(H_row*sizeof(short));
	col_indx = (short*) malloc(Column*sizeof(short));


	//initialize the first llr
	for(i=0; i<H_row; i++)//for all check node 
	{
		//firstly,set the number of varible nodes connected to the check node
		tmp_weight = mat_row[i*(Max_row_weight+1)];
		
		for(j=1; j<=tmp_weight; j++)//for all the varible nodes connected to the check node
		{
			tmp_col = mat_row[i*(Max_row_weight+1)+j];// 1's postion in column for specified row
			table_row[i*Max_row_weight+j-1] = llr_in[tmp_col];//table_row contain the llr of variable node in each row
		}
	}

	while((flag>0)&&(iter<iterN))
	{
		memset(col_indx, 0, Column*sizeof(short));
		memset(row_indx, 0, H_row*sizeof(short));
		
		//Horizontal step
		for(i=0; i<H_row; i++)
		{
			tmp_weight = mat_row[i*(Max_row_weight+1)];//set the number of variable nodes connected to the check node
	                
	        for(j=1;j<=tmp_weight;j++)
	        {
	           //the extrinsic information passing from the check node i to the jth varible node
	           tmp = Horiz_compute_llr(&table_row[i*Max_row_weight], tmp_weight, j-1);
	           tmp_col = mat_row[i*(Max_row_weight+1) + j];//variable node is at tmp_col'th  column
	           table_col[tmp_col*Max_col_weight+col_indx[tmp_col]] = tmp;
	           col_indx[tmp_col]++;
	        }
	    }
	        
	    //Vertical step
		for(i=0; i<Column; i++)
		{
			tmp_weight = mat_col[i*(Max_col_weight+1)];//set the number of check nodes connected to the variable nodes
			
			for(j=1; j<=tmp_weight; j++)
			{       
				//the extrinsic information passing from the variable node i to the jth check node
				tmp = Verti_compute_llr(&table_col[i*Max_col_weight], tmp_weight, llr_in[i], j-1);
				tmp_row = mat_col[i*(Max_col_weight+1)+j];//check node is at tmp_col'th  row
				table_row[tmp_row*Max_row_weight+row_indx[tmp_row]] = tmp;
				row_indx[tmp_row]++;
			}
		}
		
		//compute pseudo llr
		for(i=0; i<Column; i++)
		{
			tmp = llr_in[i];
			tmp_weight = mat_col[i*(Max_col_weight+1)];
			for(k=0; k<tmp_weight; k++)
			{
				tmp = tmp + table_col[i*Max_col_weight+k];
			}
			llr_out[i] = tmp;
			if (tmp >0)
			{
				dec_out[i] = 1;
			}
			else 
			{
				dec_out[i] = 0;
			}
		}

		flag = check_sum(mat_row, dec_out, H_row, Max_row_weight);
		iter++;
		
	}
		                	
	if (flag == 0)
	{
		for(i=0; i<Column; i++)
		{
			llr_out[i] = (llr_out[i] > 0)? 1000:-1000;
		}
	}

	free(table_col);
	free(table_row);
	free(row_indx);
	free(col_indx);	                	
}				
				 
				
			
	
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -