📄 pccc_logmap_bcjr.cpp
字号:
//Author NiuKai
//Date February,22th 2003
//Function Serial Concatenated Convolutional Code Performance Test
//The PCCC structure is that the outer code is (2,1,3) NSC code and the inner code is (3,2,3) RSC code.
//Function to test BER performance
#include "PCCC_para.h"
#include "conio.h"
void PN_sequence(int [],int [],int [],int);
void Random_interleaver(float [],int [],int,int);
void Random_interleaver(int [],int [],int,int);
void AWGN_Channel_TypeI(float [],long );
void AWGN_Channel_TypeII(float [],long );
void SPC_Encoder(int [],int [],int [],float [],int , int , int );
void RSC_Trellis1n(int [],int [],int [],int [],int [],int [],int [],int [],int ,int );
void Twoway_Logmap_Algorithm(float [],float [],float [],int [],int [],int [],int [],int [],int [],int , int , int);
void main()
{ int PN_polynomial[PN_order+1]={//31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 };
//PN sequence initial state
const int PN_originvalue[PN_order]={1 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 };
int PN_initstate[PN_order];
//recursive systematic convolutional inner code polynomial
int RSC_polynomial_numerator[4]={1,1,0,1};
int RSC_polynomial_denominator[4]={1,0,1,1};
int RSC_Rate=2;
int RSC_CLen=4;
int RSC_StateNumber=(int)pow(2.0,RSC_CLen-1);
int RSC_BitCombine=2*RSC_Rate;
int RSC_TailLen=RSC_CLen-1;
//recursive systematic convolutional inner code trellis parameters
int *RSC_FST,*RSC_FBT,*RSC_RST,*RSC_RBT,*RSC_RSLT,*RSC_RBLT;
RSC_FST=(int *)calloc(2*RSC_StateNumber,sizeof(int));
RSC_FBT=(int *)calloc(2*RSC_StateNumber,sizeof(int));
RSC_RST=(int *)calloc(2*RSC_StateNumber,sizeof(int));
RSC_RBT=(int *)calloc(2*RSC_StateNumber,sizeof(int));
RSC_RSLT=(int *)calloc(RSC_BitCombine*RSC_StateNumber,sizeof(int));
RSC_RBLT=(int *)calloc(RSC_BitCombine*RSC_StateNumber,sizeof(int));
//System parameters
int puncture=1;
float PCCC_Rate=1.0/(RSC_Rate+puncture);
int RSC_SymLen=Data_Length+RSC_TailLen;
int RSC_FrameLen=RSC_SymLen*RSC_Rate;
int PCCC_FrameLen=(RSC_Rate+puncture)*Data_Length+2*RSC_Rate*RSC_TailLen;
//source and PCCC code encoding data
int *Source_seq,*Psource_seq,*Permu_seq;
float *SPC1_seq,*SPC2_seq,*PCCC_seq,*AWGN_seq;
Source_seq=(int *)calloc(Data_Length,sizeof(int));
Psource_seq=(int *)calloc(Data_Length,sizeof(int));
Permu_seq=(int *)calloc(Data_Length,sizeof(int));
SPC1_seq=(float *)calloc(Data_Length+RSC_Rate*RSC_TailLen,sizeof(float));
SPC2_seq=(float *)calloc(Data_Length+RSC_Rate*RSC_TailLen,sizeof(float));
PCCC_seq=(float *)calloc(PCCC_FrameLen,sizeof(float));
AWGN_seq=(float *)calloc(PCCC_FrameLen,sizeof(float));
//PCCC code decoding data
float variance,sigma;
float *extrinsic_info,*apriori_info,*Dec1_receive_seq,*Dec2_receive_seq,*soft_decision;
Dec1_receive_seq=(float *)calloc(RSC_FrameLen,sizeof(float));
Dec2_receive_seq=(float *)calloc(RSC_FrameLen,sizeof(float));
extrinsic_info=(float *)calloc(Data_Length,sizeof(float));
apriori_info=(float *)calloc(RSC_SymLen,sizeof(float));
soft_decision=(float *)calloc(Data_Length,sizeof(float));
//Flow control and data statistics
float SNR[TestNumber]={0.8,1.0,1.2,1.4}; //Bit signal noise ratio
float total_frame_number;
int Frame_Error_Number[TestNumber]={50,50,50,50}; //total error frame block number
int Bit_Error_Number[TestNumber]={400,4000,200,100}; //total error bit number
float BER_Pb[IteTesNumber];
float FER_Pb[IteTesNumber];
FILE * Statistics_Data;
int decision_bit,BER_flag;
int Frame_BER_counter;
time_t Iteration_start,Iteration_end;
double elapse_time;
long i,j,k;
float Gain;
RSC_Trellis1n(RSC_polynomial_numerator,RSC_polynomial_denominator,
RSC_FST,RSC_FBT,RSC_RST,RSC_RBT,RSC_RSLT,RSC_RBLT,RSC_Rate,RSC_CLen);
/*cout<<"Forward Transition Table"<<endl;
for(i=0;i<RSC_BranchNumber;i++)
{
printf("Ln=%4d,Bit=%4d ",i,i);
for(j=0;j<RSC_StateNumber;j++)
printf("%4d",RSC_FBT[i*RSC_StateNumber+j]);
cout<<endl;
printf(" ");
for(j=0;j<RSC_StateNumber;j++)
printf("%4d",RSC_FST[i*RSC_StateNumber+j]);
cout<<endl;
}
cout<<"Reverse Transition Table"<<endl;
for(i=0;i<RSC_BranchNumber;i++)
{
printf("Ln=%4d,Bit=%4d ",i,i);
for(j=0;j<RSC_StateNumber;j++)
printf("%4d",RSC_RBT[i*RSC_StateNumber+j]);
cout<<endl;
printf(" ");
for(j=0;j<RSC_StateNumber;j++)
printf("%4d",RSC_RST[i*RSC_StateNumber+j]);
cout<<endl;
}
cout<<"Reverse Transition LLR Table"<<endl;
for(i=0;i<RSC_n;i++)
for(j=0;j<2;j++)
{
printf("Ln=%4d,Bit=%4d ",2*i+j,j);
for(k=0;k<RSC_BitSel*RSC_StateNumber;k++)
printf("%4d",RSC_RBLT[(2*i+j)*RSC_BitSel*RSC_StateNumber+k]);
cout<<endl;
printf(" ");
for(k=0;k<RSC_BitSel*RSC_StateNumber;k++)
printf("%4d",RSC_RSLT[(2*i+j)*RSC_BitSel*RSC_StateNumber+k]);
cout<<endl;
}*/
//initilize BER and FER parameters
for(i=0;i<IteTesNumber;i++)
{
BER_Pb[i]=0;
FER_Pb[i]=0;
}
//srand((unsigned)time(NULL)); //random seed initialization
srand(7290077);
Statistics_Data=fopen("PCCC_Logmap_Twoway_FL500_Performance_RetestII.txt","w");
for(i=0;i<TestNumber;i++)
{
//Flow control paramenter initilization
time(&Iteration_start);
//initilize PN state values
for(j=0;j<PN_order;j++)
PN_initstate[j]=PN_originvalue[j];
sigma=sqrt(pow(10.0,(-SNR[i]/10))/PCCC_Rate/2);
variance=sigma*sigma;
total_frame_number=0;
Gain=1.0/variance;
while(1)
{
//Loop control
BER_flag=1;
for(j=0;j<IterationNumber;j++)
BER_flag&=(BER_Pb[i*IterationNumber+j]>Bit_Error_Number[i]);
if(BER_flag==1) break;
//PN and PCCC coding process
total_frame_number++;
//Transmit process
//PN source sequence generation process
PN_sequence(Source_seq,PN_initstate,PN_polynomial,Data_Length);
/*for(j=0;j<Data_Length;j++)
printf("%5d",Source_seq[j]);
cout<<endl;*/
for(j=0;j<Data_Length;j++)
Psource_seq[j]=Source_seq[j];
//Recursive Systematic Convolutional code generation process
SPC_Encoder(RSC_polynomial_numerator,RSC_polynomial_denominator,
Source_seq,SPC1_seq,RSC_Rate,RSC_CLen,Data_Length);
//Interleaving process
Random_interleaver(Psource_seq,Permu_seq,0,Data_Length);
/*for(j=0;j<Data_Length;j++)
printf("%5d",Psource_seq[j]);
cout<<endl;*/
//Recursive Systematic Convolutional inner code generation process
SPC_Encoder(RSC_polynomial_numerator,RSC_polynomial_denominator,
Psource_seq,SPC2_seq,RSC_Rate,RSC_CLen,Data_Length);
//Encoding sequence assembly
if(puncture==1)
for(j=0;j<Data_Length;j++)
{ PCCC_seq[j*(RSC_Rate+puncture)]=1-2*Source_seq[j];
PCCC_seq[j*(RSC_Rate+puncture)+1]=SPC1_seq[j];
PCCC_seq[j*(RSC_Rate+puncture)+2]=SPC2_seq[j];
}
else
for(j=0;j<Data_Length;j++)
{ PCCC_seq[j*(RSC_Rate+puncture)]=1-2*Source_seq[j];
if(j&1==0)
PCCC_seq[j*(RSC_Rate+puncture)+1]=SPC1_seq[j];
else
PCCC_seq[j*(RSC_Rate+puncture)+1]=SPC2_seq[j];
}
//Tail sequence process
for(j=0;j<RSC_Rate*RSC_TailLen;j++)
{ PCCC_seq[(RSC_Rate+puncture)*Data_Length+j]=SPC1_seq[Data_Length+j];
PCCC_seq[(RSC_Rate+puncture)*Data_Length+RSC_Rate*RSC_TailLen+j]=
SPC2_seq[Data_Length+j];
}
/*for(j=0;j<PCCC_FrameLen;j++)
printf("%5.0f",PCCC_seq[j]);
cout<<endl;*/
//AWGN additive noise channel
AWGN_Channel_TypeI(AWGN_seq,PCCC_FrameLen);
/*for(j=0;j<60;j++)
printf(" %5.2f ",AWGN_seq[j]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -