📄 ldpc.c
字号:
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 + -