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

📄 ldpc_2.cpp

📁 关于Q元LDPC码的C++仿真程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
     if (i == rightbound_index)	continue;     Aux *= GetEdge(i).LeftBoundMessage;  }  Aux.Normalize();         return Aux;}void variable_node::CalcFinalMessage(){   FinalEstimate = CalcRightboundMessage( /* NO rightbound index */ -1 );   Symbol = FinalEstimate.Decision();}void variable_node::CalcAllRightboundMessages(){   for (int i = 0; i < GetDegree(); i++)      GetEdge(i).RightBoundMessage = CalcRightboundMessage( /* rightbound index */ i);   CalcFinalMessage();}

message &GenerateChannelMessage(GFq v,                                channel &TransmitChannel,                                 mapping &MapInUse,                                double ChannelOut ){   static message InitialMessage;   int q = MapInUse.GetQ();   double CandidateIn, ChannelIn;     ChannelIn = MapInUse.map(v);        // mapping of (0 + v) % q;     // Generate InitialMessage   InitialMessage.Set_q(q);   for (GFq i(0); i.val < q; i.val++)   {      CandidateIn  = MapInUse.map(i + v);      InitialMessage[i.val] = TransmitChannel.CalcProbForInput(		                       ChannelOut, CandidateIn );   }   InitialMessage.Normalize();    // Make valid probability vector    return InitialMessage;}void variable_node::Initialize( channel &TransmitChannel, double ChannelOut ){   InitialMessage = GenerateChannelMessage(v, TransmitChannel, *MapInUse, ChannelOut );   FinalEstimate = InitialMessage;     // Generate Rightbound messages   for (int j = 0; j < degree; j++)      GetEdge(j).RightBoundMessage = InitialMessage;}BOOLEAN variable_node::IsRightConnectedTo( node *n ){  for (int i = 0; i < degree; i++)    if (&edges[i]->RightNode() == n) return TRUE;  return FALSE;}/********************************************************************************** * * Graph * **********************************************************************************/void bipartite_graph::Reset( 	     int p_N,                            // number of variable nodes	     int lambda_degs[],                  // left-degrees, terminated by -1	     double lambda_wts[],                // weights corresponding to above degrees
	     int rho_degs[],       		  // right-degree, terminated by NULL	     double rho_wts[],                  // weights corresponding to above degrees
		 mapping &MapInUse){  //-----------------------------------------------------------------------  // Clean up  //-----------------------------------------------------------------------  Clear();  //-----------------------------------------------------------------------  // Calc M, N and E  //-----------------------------------------------------------------------  double Ratio;     // M/N  double Nominator, Denominator;  Nominator = 0;  for (int i = 0; rho_degs[i] != -1; i++)    Nominator += rho_wts[i] / rho_degs[i];  Denominator = 0;  for (int j = 0; lambda_degs[j] != -1; j++)    Denominator += lambda_wts[j] / lambda_degs[j];  Ratio = Nominator / Denominator;  N = p_N;  M = (int)ceil(Ratio * N);  E = (int)floor(N / Denominator);    //----------------------------------------------------------------------------------------  // Create variables, checks and edges  //----------------------------------------------------------------------------------------  edges = new edge[E];  variable_nodes = new variable_node[N];  check_nodes = new check_node[M];  EdgeStack = new edge* [E * 2];   // Buffer used to manage memory allocation for nodes  if ((edges == NULL) ||      (variable_nodes == NULL) ||      (check_nodes == NULL) ||      (EdgeStack == NULL))    {      cout << "Error allocating memory\n";      exit(1);    }  //--------------------------------------------------------------------------  // Generate sockets  //--------------------------------------------------------------------------  variable_node **left_sockets = new variable_node*[E];  check_node **right_sockets = new check_node*[E];  edge **EdgeStackPointer = EdgeStack;         // Auxiliary pointer to stack  int node_index, socket_index, count_nodes_of_degree;    node_index = 0;  socket_index = 0;  for (int i = 0; lambda_degs[i] != -1; i++)                // Loop through all left-degrees    {      int count_nodes_of_degree = (int)floor(lambda_wts[i] * E / lambda_degs[i]); // No. nodes of required degree      for (int j = 0; j < count_nodes_of_degree; j++)    // Number of nodes with required left-degree	{	  for (int k = 0; k < lambda_degs[i]; k++)              // Number of sockets for each degree	    left_sockets[socket_index++] = &variable_nodes[node_index];	  variable_nodes[node_index].AllocateEdges(EdgeStackPointer, lambda_degs[i]);	  variable_nodes[node_index].SetMapInUse(MapInUse);
	  variable_nodes[node_index].SetID(node_index);	  node_index++;	}    }  // Record no. of left sockets, may be different than E  // due to the fact that lambda * E may not be whole numbers  int count_left_sockets = socket_index;        // Modify N for same reason  N = node_index;  // Generate right sockets  node_index = 0;  socket_index = 0;  for (int i = 0; rho_degs[i] != -1; i++)                  // Loop through all right-degrees    {      int CurrentDegree  = rho_degs[i];      count_nodes_of_degree = (int)floor(rho_wts[i] * E / 					 CurrentDegree );  // No of nodes of required degree      for (int j = 0; j < count_nodes_of_degree; j++)         	{	  for (int k = 0; k < CurrentDegree; k++)      // Number of sockets for each degree	    right_sockets[socket_index++] = &check_nodes[node_index];	  check_nodes[node_index].AllocateEdges( EdgeStackPointer, CurrentDegree );	  check_nodes[node_index].SetID(node_index);	  	  node_index++;	}    }  // Record no. of right sockets, may be different than E  // due to the fact that lambda * E may not be whole numbers  int count_right_sockets = socket_index;        // Modify M,E for same reason  M = node_index;  E = min(count_left_sockets, count_right_sockets);  //----------------------------------------------------------------------------------------  // Generate permutations  //----------------------------------------------------------------------------------------  srand(time(NULL)); // Init random seed so that each call to function returns different set of values  cout << "Starting bipartite graph...";  int left_index, right_index;  for (int i = 0; i < E; i++)    {      // Randomly select socket from first E - left_index (last left_index sockets represent      // sockets that have already been selected)      //      cout << " i = " << i << " E = " << E;      int attempts = 0;      do	{	  // It is important to select left_index randomly and not only right_index,	  // because there is a significance to the order of bits within a code, sometimes with 	  // first or last bits better protected.  If left_index is not selected randomly,	  // the result would be a random tree, but in which lower degree left-nodes are of	  // lower index within each constituent code, contrary to complete randomness.	  left_index = uniform_random(E - i);	  //left_index = i;	  right_index = uniform_random(E - i);	  if ((attempts++) > 100)	    {	      cout << "Warning: cycles\n";	      break;	    }	}    while (left_sockets[left_index]->IsRightConnectedTo(right_sockets[right_index]));      if (right_index >= (E-i))	{	  cout << "right index or left_index exceed range\n"	       << "right_index = " << right_index	       << " left_index = " << left_index               << " E = " << E                << " left_index = " << left_index << "\n";	  exit(1);	}      edges[i].set_nodes(left_sockets[left_index], right_sockets[right_index]);      // Overwrite current sockets with last sockets, so that they are not selected again      right_sockets[right_index] = right_sockets[E - i - 1];      left_sockets[left_index] = left_sockets[E - i - 1];    }  cout << "Done\n";  // Clean-up  delete left_sockets;  delete right_sockets;}/************************************************************************ * * LDPC code * ************************************************************************/void LDPC_Code::Init_Messages( vector &ChannelOutput ){  if (ChannelOutput.GetSize() != Variables.GetLength())  {     cout << "LDPC_Code::Init_Messages: Incompatible sizes\n";     exit(1);  }  for (int i = 0; i < Variables.GetLength(); i++)
     Variables[i].Initialize( *Channel, ChannelOutput[i] );
}

void LDPC_Code::GetZeroCodeword( vector &Codeword ){   Codeword.Allocate(Variables.GetLength());   for (int i = 0; i < Variables.GetLength(); i++)      Codeword[i] = Variables[i].GetZeroSignal();}void LDPC_Code::Leftbound_Iteration(){  for (int i = 0; i < Checks.GetLength(); i++)    Checks[i].CalcAllLeftboundMessages();}void LDPC_Code::Rightbound_Iteration(){  for (int i = 0; i < Variables.GetLength(); i++)     Variables[i].CalcAllRightboundMessages();}void LDPC_Code::FinalIteration(){  for (int i = 0; i < Variables.GetLength(); i++)     Variables[i].CalcFinalMessage();}double LDPC_Code::Calc_Symbol_Error_Rate(){  double acc_correct = 0;  for (int i = 0; i < Variables.GetLength(); i++)     acc_correct += Variables[i].FinalEstimate.Decision().IsZero();  return 1.0 - acc_correct / (double)Variables.GetLength();}double LDPC_Code::Calc_Rightbound_Symbol_Error_Rate(){  double acc_correct = 0;  for (int i = 0; i < Graph.E; i++)    acc_correct += Graph.edges[i].RightBoundMessage.Decision().IsZero();  return 1.0 - acc_correct / Graph.E;}double LDPC_Code::Belief_Propagation_Decoder(int Count_Iterations){  static char buffer[500];  double Func_RC;  double LastMin = INF;  int CountIncreaseIterations = 0;  cout << "Initial symbol error rate = " << Calc_Symbol_Error_Rate() << "\n";  for (int i = 0; i < Count_Iterations; i++)  {      Leftbound_Iteration( );      Rightbound_Iteration();      Func_RC = Calc_Rightbound_Symbol_Error_Rate();      sprintf(buffer, "%d: Rightbound SER = %1.10f, %s", i+1, Func_RC, CharTime());      cout << buffer;      // Stop when Func_RC doesn't fall for some consecutive iterations      if (Func_RC < LastMin)      {         LastMin = Func_RC;         CountIncreaseIterations = 0;      }      else      {         CountIncreaseIterations++;         if (CountIncreaseIterations > 50)            break;      }      if (Func_RC < 1e-7) break;    }   return Func_RC;}

⌨️ 快捷键说明

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