Communication

The Communication toolkit is designed to make digital communication using error control codes easy. It offers a generic interface that combines elements of communication such as the channel and LDPC-codes, and transparantly handles modulation and demodulation. Note that any binary code based on parity bits, such as hamming-codes and turbo-codes, can be seen as special cases of LDPC-codes.

In short, communication following the framework implemented in Communication is considered to be comprised to the following elements and events. Suppose a Alice wishes to send a message to Bob.

  1. Each message will have K bits. If Alice needs to communicate more than that, several messages have to be sent according to the same procedure.
  2. The message is first encoded with an LDPC-code to form a N-bit codeword, where N > K. One codeword is uniquely associated with each mesage.
  3. This codeword is then modulated, which means that it is mapped onto a vector of symbols of a given alphabet. Each symbol represents an equal and integer number of bits, which implies that the cardinality of the alphabet must be a power of two. This vector of symbols is the channel input. Individual symbols will be referred to as x, the entire vector will be denoted as x.
  4. Alice will then send the channel input over the channel. The channel is, in a mathematical sense, essentially a mathematical model of distortions introduced to the channel input. Alice has now completed her part.
  5. The channel output is the result of the process of introducing distortions to the codeword by the channel, that is, according to the mathematical model prescribed by the definition of the channel. The channel output is in effect a vector of measurements of what has appeared at the end of channel, obtained by Bob. For each input symbol, one measurement is produced. One measurement is denoted as y, the vector of all measurements is denoted as y. In this implementation, the channel is always assumed to be in the class of Discrete Memoryless Channels, see Channel for details.
  6. The channel output y is then de-modulated, meaning that is is mapped onto N probabilities. For each bit of the codeword, a probability is generated that that bit was one in the original codeword. Each measurement y is de-modulated independently, by the assumption of the discrete memoryless property of the channel.
  7. Bob then provides the vector of probabilities as input to a decoding algorithm, which will try to infer which codeword was sent over the channel, and hence which message was sent. The final output is an estimate of the sent message. If the code is correctly chosen given the channel, this estimate is with very high probability the message sent by Alice. Thus, Bob has received the message and the communication is complete.

Interface

The Communication toolkit offers a single class, Communicator to handle all the communication steps. Because the Communicator combines encoding, modulation, demodulation and decoding, is requires many template parameters:

template <std::size_t N, std::size_t K,
	  typename Input, typename Output, std::size_t N_SYMBOLS>
class Communicator;
The following table shows where the template parameters stem from:
 std::size_t N  
See LDPCCode.
 std::size_t K  
See LDPCCode.
 typename Input  
The type of the channel input symbols, must be an integer type.
 typename Output  
The type of the channel output.
 std::size_t N_SYMBOLS  
The number of different possible channel inputs, i.e. the cardinality of the channel input alphabet. Must be a power of two.

A Communicator needs to be instanciated before it can be used, and it uses several components: a code, a default channel, and a set of symbols that comprise the alphabet of the channel input after modulation. Each of this can be specified during construction of a Communicator. The main member functions offered by Communicator are encode(...) and decode(...). It is possible the specify another channel than the default channel during decoding.

To ease the use of this code, some rather complicated jobs can be done automagically by the Communication toolkit:

  • Modulation and de-modulation is handled transparantly in an optimal way assuming that bits in codeword appear are equally distributed.
  • The input alphabet can be generated uniformly distrubuted over the range provided by the type Input with maximal spacing.
  • When no code is provided, a code will be automatically generated, which requires N to be a multiple of K.
The only thing that cannot be handled automatically is the selection of a channel.

The class Communicator providef the following typedefs, constants and memebr functions:

  typedef GeneratorMatrix;  
Typedef for a generator-matrix for the selected N-K code. Such a code should be used with this Communicator. See LDPCCode.
  typedef ChannelPtr;  
Typedef for a shared-pointer to a Channel<Input, Output>. Such a channel should be used with this Communicator.
  typedef CodePtr;  
Typedef for a shared-pointer to a Code<N, K>.
  typedef InputArray;  
Typedef for an STL-compliant array of length N_SYMBOLS that can be used to hold all different channel input symbols.
  static const std::size_t LENGTH;  
The number of input symbols needed to represent one N-bit codeword derived from an K-bit message.
  Communicator();  
Default constructor that assumes a NoiselessChannel as the default channel, and generate a default code as well as the channel input alphabet automatically.
  Communicator(ChannelPtr defaultChannel);  
Assume defaultChannel as the default channel, and generate a code as well as the channel input alphabet automatically.
  Communicator(ChannelPtr defaultChannel,          
	       const GeneratorMatrix &generator);  
Assume defaultChannel as the default channel, and use generator to generate a code. The channel input alphabet is generated automatically.
  Communicator(ChannelPtr defaultChannel,
	       CodePtr code);  
Assume defaultChannel as the default channel and use LDPC-code code. The channel input alphabet is generated automatically.
  Communicator(ChannelPtr defaultChannel,
	       const InputArray &symbols);  
Assume defaultChannel as the default channel and use symbols as the channel input alphabet. A code is generated automatically.
  Communicator(ChannelPtr defaultChannel,
	       const GeneratorMatrix &generator,
	       const InputArray &symbols);  
Assume defaultChannel as the default channel, use generator to generate a code and use symbols as the channel input alphabet.
  Communicator(ChannelPtr defaultChannel,
	       CodePtr code,
	       const InputArray &symbols);  
Assume defaultChannel as the default channel, use LDPC-code code and use symbols as the channel input alphabet.
  template <typename InputIterator,
	    typename OutputIterator>
  bool encode(InputIterator first1,
	      OutputIterator first2);  
Encodes and modulates a message. Reads elements starting from first1 until at least K message bits have been read, then writes LENGTH symbols of type Input to first2.
  template <typename InputIterator,
	    typename OutputIterator>
  bool decode(InputIterator first1,
	      OutputIterator first2,
	      const ChannelPtr channel);  
Reads LENGTH symbols of type Output from first1. De-modulates and decodes using the code supplied in the constructor. Writes elements to the range starting at first2 until at least K bits have been written.
  template <typename InputIterator,
	    typename OutputIterator>
  bool decode(InputIterator first1,
	      OutputIterator first2);  
Uses the default channel model as given during construction to demodulate.
  const InputArray &symbols() const  
Returns a reference to an array of symbols used as channel inputs.
  void print() const;  
Print the code, see LDPCCode.

Generation of Input Alphabet

To automatically generate an input alphabet, the following function is used:

template <typename Input, std::size_t NInputs>
std::tr1::array<Input, NInputs> generateAlphabet();