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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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();
|