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

📄 ldpc_2.cpp

📁 关于Q元LDPC码的C++仿真程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <math.h>#include <stdlib.h>#include <iostream.h>#include <fstream.h>#include <ctype.h>#include "Utils_1.h"#include "LDPC_1.h"
#include "LDPC_2.h"/********************************************************************************* * * MESSAGE * *********************************************************************************/void message::DFT2()          // A real-valued DFT - also IDFT{	static message Aux;      GFq mask, n0_index, n1_index;	BYTE j_bit;      if (GFq::IsPrimeQ)      {         cout << "Error, message::DFT2:  Only q that is a power of 2 is supported.\n";         exit(1);      }      for (int i  = 0; i < GFq::log_2_q; i++)      {	   Aux = *this;			// Initialize	   mask.val = 1 << i;         for (GFq j(0); j.val < q; j.val++)         {            j_bit = (j.val & mask.val) >> i;	// obtain value of j		n0_index.val = j.val & (~mask.val);	// turn bit off		n1_index.val = j.val | mask.val;    // turn bit on		//cout << (int)j_bit;            if (j_bit == 0)               Probs[j.val] = Aux[n0_index] + Aux[n1_index];            else               Probs[j.val] = Aux[n0_index] - Aux[n1_index];         }      }}/********************************************************************************* * * CHANNEL * *********************************************************************************/void channel::SimulateOutputVector(vector &InVector, vector &OutVector){   OutVector.Allocate(InVector.GetSize());   for (int i = 0; i < InVector.GetSize(); i++)   // Add noise to each component      OutVector[i] = this->SimulateOutput( /* channel in */ InVector[i] );    }/********************************************************************************* * * BSC Channel * *********************************************************************************/void BSC_Channel::ProcessMapping(LDPC_Code &Code){   mapping &MapInUse = Code.MapInUse;   for (GFq i(0); i.val < MapInUse.q; i.val++)      if ((MapInUse.map(i) != 0) && (MapInUse.map(i) != 1))      {         cout << "mapping levels must be (0,1)\n";         exit(1);      }}double H2(double p){   return -p*log2(p) - (1-p)*log2(1-p);}double H2Reverse(double H){   double pmin = 0,           pmax = 0.5,           tol = 0.0000001,          pmid;   if (H == 0)      return 0;   else if (H == 1.)      return 0.5;   while ((pmax - pmin) > tol)   {      pmid = (pmin + pmax) / 2.;      if (H2(pmid) > H)         pmax = pmid;      else         pmin = pmid;   }   return pmid;}double BSC_Channel::CapacityInBits(){   return 1 - H2(channel_p);}void BSC_Channel::PrintChannelData(LDPC_Code &Code){   double BitRate;   BitRate = Code.Calc_Bit_Rate();   cout  << "channel_p = " << channel_p         << "\nCapacity (bits per channel use) = " << 1 - H2(channel_p)          << " Max channel_p for Bit rate: " << H2Reverse(1. - BitRate);}/********************************************************************************* * * AWGN Channel * ********************************************************************************/double GaussGenerate(double sigma)  // Simulate the result of passing the zero vector through the AWGN{  static const double pi = 3.141592653;  double normal_random_number, x1, x2;  x1 = my_rand();  x2 = my_rand();

  if (x1 < EPSILON)
   x1 = EPSILON;
  normal_random_number = sqrt(-2 * log(x1)) * cos(2*pi * x2);    clip(normal_random_number);    return sigma * normal_random_number;}void AWGN_Channel::ProcessMapping(LDPC_Code &Code){   Code.MapInUse.Normalize();
}  double AWGN_Channel::CapacityInBits(){   double No = pow(noise_sigma,2.);   double SNR = 1./No;   return 0.5 * log(1. + SNR) / log(2.);}void AWGN_Channel::PrintChannelData(LDPC_Code &Code){   double BitRate, No, SNR, SNR_dB;      BitRate = Code.Calc_Bit_Rate();   No = pow(noise_sigma,2.);   SNR = 1./No;   SNR_dB = 10. * log10(SNR);   cout << "SNR(dB) = " << SNR_dB        << " SNR = " << SNR        << " Noise Sigma = " << noise_sigma        << "\nCapacity at SNR (symbols per channel use) = "         << 0.5 * log(1. + SNR) / log((double)GFq::q)        << "\nCapacity at SNR (bits per channel use) = "         << 0.5 * log(1. + SNR) / log(2.)        << "\nMinimum SNR for rate (dB) = "         << 10. * log(pow(2., 2.*BitRate) - 1.) / log(10.)        << " (absolute value) = " << pow(2., 2.*BitRate) - 1;}// override virtual functionsdouble AWGN_Channel::CalcProbForInput( double ChannelOutput, 				       double ChannelInput ){   static const double sqrt_2pi = sqrt(2*3.141592653);   double noise_prob = (1/(sqrt_2pi * noise_sigma)*	    exp(-pow(ChannelOutput-ChannelInput,2.)/(2.*NoiseVariance())));   return noise_prob;}double AWGN_Channel::SimulateOutput(double ChannelInput)  // Simulate the result of passing the zero vector through the AWGN{  return ChannelInput + GaussGenerate(noise_sigma);}double AWGN_Channel::NoiseVariance() {   return pow(noise_sigma, 2); }double AWGN_Channel::NoiseStdDev() {   return noise_sigma; }/**************************************************************************** * * Check node * ****************************************************************************/

GFq &check_node::Value()
{
   static GFq Aux;

   Aux = 0;
   for (int i = 0; i < GetDegree(); i++)
      Aux += GetEdge(i).label * GetEdge(i).LeftNode().Symbol;

   return Aux;
}



node &check_node::AdjacentNode(int index){   return GetEdge(index).LeftNode();}message &FastCalcLeftboundMessage(message AuxLeft[],                                   message AuxRight[],			          int left_index,                                  int degree){  static message Aux;  // Init to delta pulse   Aux.Set_q(GFq::q);  Aux = AuxLeft[left_index];  Aux *= AuxRight[left_index];  Aux.DFT2();  Aux.Reverse();	// estimate of symbol value = (- sum of others)  return Aux;}void check_node::CalcAllLeftboundMessages( ){  static message Vectors[MAX_DEGREE];  static message AuxLeft[MAX_DEGREE];  static message AuxRight[MAX_DEGREE];  static GFq ZERO(0);  // Calc auxiliary DFTs  for (int i = 0; i < GetDegree(); i++)  {     Vectors[i] = GetEdge(i).RightBoundMessage;     Vectors[i].PermuteTimes(GetEdge(i).label.Inverse());  }
  //-------------------------------------------------------------
  // If power of two - use DFT2
  //-------------------------------------------------------------
  if (!GFq::IsPrimeQ)
  {     for (int i = 0; i < GetDegree(); i++)
	 {
         Vectors[i].DFT2();
	 }

      // Calc auxiliary values     AuxLeft[0].Set_q(GFq::q);     AuxLeft[0] = 1.;     for (int i = 1; i < GetDegree(); i++)     {        AuxLeft[i] = AuxLeft[i - 1];        AuxLeft[i] *= Vectors[i - 1];     }     AuxRight[GetDegree() - 1].Set_q(GFq::q);     AuxRight[GetDegree() - 1] = 1.;     for (int i = GetDegree() - 2; i >= 0; i--)     {        AuxRight[i] = AuxRight[i + 1];        AuxRight[i] *= Vectors[i + 1];     }     // Calc leftbound messages     for (int i = 0; i < GetDegree(); i++)     {       GetEdge(i).LeftBoundMessage = FastCalcLeftboundMessage(AuxLeft, AuxRight, i, GetDegree());
       GetEdge(i).LeftBoundMessage.PermuteTimes(GetEdge(i).label);     }
  }
}/************************************************************************* * * Node * *************************************************************************/void node::Disconnect(){   // while edges remain, disconnect the first one    while (degree > 0) edges[0]->Disconnect();}/************************************************************************* * * Variable node * *************************************************************************/node &variable_node::AdjacentNode(int index){   return GetEdge(index).RightNode();}message &variable_node::CalcRightboundMessage( int rightbound_index )// rightbound_index is -1 if calculation is meant for final estimate{  static message Aux;  Aux = InitialMessage;  for (int i = 0; i < GetDegree(); i++)  {     // ignore intrinsic information

⌨️ 快捷键说明

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