summaryrefslogtreecommitdiff
path: root/gr-fec/docs/fec.dox
diff options
context:
space:
mode:
Diffstat (limited to 'gr-fec/docs/fec.dox')
-rw-r--r--gr-fec/docs/fec.dox627
1 files changed, 627 insertions, 0 deletions
diff --git a/gr-fec/docs/fec.dox b/gr-fec/docs/fec.dox
new file mode 100644
index 000000000..436510025
--- /dev/null
+++ b/gr-fec/docs/fec.dox
@@ -0,0 +1,627 @@
+/*! \page page_fec Forward Error Correction
+
+\section fec_introduction Introduction
+
+This is the gr-fec package. It contains all of the forward error
+correction (FEC) blocks, utilities, and examples. To use the FEC
+blocks, the Python namespaces is in gnuradio.fec, which would be
+normally imported as:
+
+\code
+ from gnuradio import fec
+\endcode
+
+See the Doxygen documentation for details about the blocks available
+in this package.
+
+A quick listing of the details can be found in Python after importing
+by using:
+
+\code
+ help(fec)
+\endcode
+
+
+\section fec_using Using the FEC API
+
+FEC is a complex issue to implement in a generic, generally usable
+way. To help with these issues, the FEC API operates on two levels:
+the coder variables and the coder deployments. The variables implement
+the encoding and decoding methods whereas the deployments set up the
+variables, make sure the input data is formatted properly, run the
+coder variable, and then pass on the data for follow-on processing.
+
+In a GNU Radio flowgraph, the deployments are GNU Radio blocks that we
+insert into the flowgraph. The deployments use the API of the coder
+variables to interact with the scheduler and set up the input/output
+item buffers that move data between blocks. The intent of the API is
+to be able to build the coding variables that are general enough for
+easy use in multiple situations. We then construct deployments to
+control the interaction between the data and the variable. GNU Radio
+provides deployments for a number of situations, but these should not
+be considered the only ways to deploy the decoders.
+
+
+\subsection fec_deployments Deployments
+
+Generally speaking, encoder deployments take in bits and produce
+bits (i.e., unpacked bytes with 1 bit per byte). Decoder deployments
+take in floats and produce bits. The floats are generally meant to
+represent soft decisions. If the demodulator does not produce soft
+decisions, an easy alternative is to convert the hard decision 0's and
+1's to -1 and +1 floats. The main departure from this model is when
+using a PDU-based modulator or demodulator, for which we can look at
+using the asynchronous message passing system. In this instance,
+passing bits is not natural, so we need to create a deployment that
+can handle packed bytes. GNU Radio has the gr::fec::asycn_encoder and
+gr::fec::async_decoder deployments that work in this mode.
+
+Some coding variables handle inputs and outputs differently than the
+described deployments. Using the FEC API provides concepts of input
+and output conversion properties that help us create deployments to
+convert the data streams to the required format of the variable.
+
+\subsubsection fec_deploy_simple Streaming Deployments
+
+For the encoder deployments, the gr::fec::encoder block is a
+relatively simple deployment for the encoding variables. It uses the
+encoding object information about the input/output sizes and
+input/output item sizes to set up the interaction with the
+scheduler. Typically, a coder will add redundancy to the stream making
+the output longer by some amount than the input stream. This block
+simply takes in an encoder object, specifically an object that derives
+from gr::fec::generic_encoder. It also takes in the input and output
+items sizes that the encoder will expect, which we can just ask the
+encoder for. Typically, the encodes expect unpacked bytes in and
+unpacked bytes out.
+
+The gr::fec::decoder block is a similarly simple deployment for the
+decoding variables. It uses the decoding variable information about
+the input/output sizes and input/output item sizes to set up the
+interaction with the scheduler. Since a decoder typically uses the
+redundancy from the input stream to correct for errors, the input
+stream will be longer than the output stream by the rate of the
+code. This block simply takes in an decoder object, specifically an
+object that derives from gr::fec::generic_decoder. It also takes in
+the input and output items sizes that the decoder will expect, which
+we can just ask the encoder for. The deployment expects a floating
+point stream input, though the decoder variables may take a float
+input or a byte. If using a byte format, it could be a hard decision
+or a quantized soft decision, depending on how the decoder object
+behaves.
+
+Normally, though, we don't work directly with these simple encoder()
+or decoder() deployments but a wrapper around those blocks. GNU
+Radio's gr-fec package comes with two Python deployments to make
+things easier: fec.extended_encoder and fec.extended_decoder. For one
+thing, these extended hier_block2 blocks take care of the puncturing
+and depuncturing operations often found in FEC codes. The other thing
+that these blocks do for us is read the API of the encoder/decoder
+variables to properly convert the data in or out, depending on how the
+coding object works.
+
+For instance, a generic_decoder takes in floating point values (which
+should be soft decisions). However, a decoder might instead want to
+work on 8-bit quantized soft decisions and so expects unsigned
+chars. Specifying 'uchar' as the
+gr::fec::generic_decoder::get_input_conversion() of the decoder block tells the
+fec.extended_decoder to convert the float to a byte.
+
+In GRC, we would add an "FEC Extended Encoder" to our transmitter or
+an "FEC Extended Decoder" to the receiver. We would then use one of
+the encoder or decoder FEC variable blocks to define the parameters of
+the particular code we want to use. We can find these codes under the
+[Error Coding] category in GRC. The encoders are found under
+[Encoders] and similarly the decoders under the [Decoders]
+categories. Putting these onto the canvas creates a variable that we
+can then pass to the extended encoder or decoder deployment blocks.
+
+Most of the parameters of the encoder and decoder definitions should
+be fairly obvious based on the type of code. See the documentation for
+each coding object for more details. In the following section \ref
+fec_parallelism, we explain the Parallelism and Dimension properties.
+
+See fec/fecapi_encoders.grc and fec/fecapi_decoders.grc in the
+installed examples for an example of how to work with these
+deployments given the three initial FEC coders available.
+
+\subsubsection fec_deploy_tag_stream Tagged Stream Deployments
+
+GNU Radio's gr-fec also comes with simple deployments for \ref
+page_tagged_stream_blocks blocks. These deployments work similarly to
+the normal streaming deployments but fit into a tagged stream system
+by setting a tagged stream tag to control the frame size. Like all
+tagged stream blocks, they expect the tag to be located in the stream
+in order to properly function.
+
+The simplest form of the tagged stream deployments are just the C++
+blocks gr::fec::tagged_encoder and gr::fec::tagged_decoder. These do
+not handle any input or output conversion. They expect the inputs to
+be already properly formatted for the encoding/decoding variables, and
+the outputs will be whatever the variable naturally produce.
+
+In the tagged stream deployments, the frame size set for a variable is
+no longer the static frame size like we expected in the streaming data
+implementations. Instead, we look at the frame size of the
+encoder/decoder variable during construction of the deployment as the
+maximum frame size, or a maximum transmission unit (MTU). This allows
+us to set up some internal memory to handle up to the required maximum
+length. When a tagged stream comes into this block, the frame size is
+then set based on that tagged stream information. If the frame is
+larger than the established MTU, a warning is sent out and the
+deployment only handles up to the MTU of the given frame.
+
+The extended Python tagged deployments, fec.extended_tagged_encoder
+and fec.extended_tagged_decoder, offer additional handling of the FEC
+API like we saw with the fec.extended_encoder and
+fec.extended_decoder. These extended deployments wrap up the
+puncturing and depuncturing as well as use the FEC API to do any input
+and output translation for the formatting of data streams. The
+fec.extended_tagged_encoder expects unpacked bits in and produces
+unpacked bits out. The fec.extended_tagged_decoder takes in floats
+(generally soft decisions from -1 to 1) and produces unpacked bits.
+
+See fec/fecapi_tagged_encoders.grc and fec/fecapi_tagged_decoders.grc
+in the installed examples for an example of how to work with these
+deployments given the three initial FEC coders available.
+
+
+
+\subsubsection fec_deploy_async Asynchronous Deployments
+
+The final standard deployment shipped with GNU Radio is for
+asynchronous \ref page_msg_passing and handling PDUs:
+gr::fec::async_encoder and gr::fec::async_decoder.
+
+Unlike the other deployments, these C++ deployments do not also have
+an extended Python deployment. Because this deployment uses message
+passing, we cannot easily build up a hierarchical block of message
+passing blocks to satisfy the input/output translations like we've
+done with the other forms of deployment. Instead, the input/output
+formatting is taken care of inside this deployment itself. Further,
+because this form of moving data anticipates data being moved in
+packets, these deployments cannot work with any FEC code that requires
+a history (see generic_decoder::get_history). Right now, this means
+that the async message passing deployments cannot work with
+convolutional codes (gr::fec::code::cc_encoder and
+gr::fec::code::cc_decoder) in streaming mode because it would require
+data from the next frame to finish off decoding the current frame.
+
+These deployments also work in two distinct modes. They can work in
+unpacked mode where inputs are messages of bits, or they may work in
+packed mode where messages are PDUs. The distinction is that the
+packed mode PDU's are the standard protocol data units (PDUs) that
+encompass full packets of data. This allows these async deployments to
+be used easily within PDU-based applications, such as encoding a
+packet with a CRC attached.
+
+When in packed or PDU mode, the encoder deployment has the option of
+reversing the bits during unpacking and packing. Like the extended
+deployments for the other data modes, these deployments manipulate the
+input data to the format expected by the encoding or decoding
+variables using calls to the FEC API. Because most of the coders work
+off unpacked bits, the incoming PDUs must first be unpacked into bits
+and the repacked again into the original PDU. The
+gr::blocks::kernel::pack_k_bits and gr::blocks::kernel::unpack_k_bits
+kernels are used here, and they can change the direction on how to
+pack and unpack. Because different data processing blocks, framing,
+deframing, and other operations may arbitrarily set the format of the
+bits and the ordering, we provide the options of unpacking and packing
+directions in the deployments. However, the gr::fec::async_decoder
+still expects the input to be soft decisions with one decision per
+item, so we only say whether this deployment outputs packed PDUs or
+not and the packing direction.
+
+For an example of using the asynchronous in PDU mode, see
+fec/fecapi_async_packed_decoders.grc. See
+fec/fecapi_async_to_stream.grc for an example of mixing the packed PDU
+mode encoder with a tagged stream decoder. This example shows the PDU
+input having a CRC32 appended to the uncoded stream that is then
+checked after the packet is decoded.
+
+For an example of the async deployment using unpacked bits, see
+fec/fecapi_async_encoders.grc and fec/fecapi_async_decoders.grc.
+
+
+\subsection fec_coding_vars Encoding/Decoding Variables
+
+GNU Radio currently has a minor subset of coders available:
+
+
+Coders:
+
+\li gr::fec::code::dummy_encoder
+\li gr::fec::code::repetition_encoder
+\li gr::fec::code::cc_encoder
+\li gr::fec::code::ccsds_encoder
+\li gr::fec::code::polar_encoder
+\li gr::fec::code::ldpc_par_mtrx_encoder
+\li gr::fec::code::ldpc_gen_mtrx_encoder
+
+Decoders:
+\li gr::fec::code::dummy_decoder
+\li gr::fec::code::repetition_decoder
+\li gr::fec::code::cc_decoder
+\li gr::fec::code::polar_decoder_sc
+\li gr::fec::code::polar_decoder_sc_list
+\li gr::fec::ldpc_decoder
+\li gr::fec::code::ldpc_bit_flip_decoder
+
+
+\subsubsection fec_dummy Dummy Encoder/Decoder
+
+When building a new FECAPI encoder or decoder variable, the
+gr::fec::code::dummy_encoder / gr::fec::code::dummy_decoder blocks are a good
+place to start. This coding set does no processing on the data. For
+the encoder, each bit is simply passed through directly. For the dummy
+decoder, the input data are floats, so -1's become 0 and 1's stay as
+1, but nothing else is done to the data. Mainly, these blocks are used
+for references and to make it easy to compare implementations with and
+without codes by easily dropping in these objects instead of
+restructuring the entire flowgraph. The ber_curve_gen.grc example file
+uses the dummy codes to show the curve to compare against the actual
+codes.
+
+
+\subsubsection fec_repetition Repetition Encoder/Decoder
+
+The simplest example of FEC is the repetition code in
+gr::fec::code::repetition_encoder and
+gr::fec::code::repetition_decoder. The basic idea is to repeat the
+information several times so that even if parts of the received
+message are corrupted, the majority of the data is received correctly
+and the original message can be discerned. The repetition decoder is
+not particularly sophisticated and other coders offer better
+performance, but it is useful for comparison.
+
+
+\subsubsection fec_cc Convolutional Encoder/Decoder
+
+Although mentioned in the convolutional coder and decoder classes, it
+is worth another mention. The gr::fec::code::cc_encoder is a generic
+convolutional encoder that can take any value of K, rate, and
+polynomials to encode a data stream. However, the
+gr::fec::code::cc_decoder is not as general, even though it is
+technically parameterized as such. The gr::fec::code::cc_decoder block
+currently <i>only</i> uses K=7, rate=2, and two polynomials (because
+the rate is two). We can, in fact, alter the polynomials, but a
+default of [109, 79] is typically. Eventually, we will make this block
+more generic for different rates and constraint lengths and take this
+particular code implementation as the set CCSDS decoder, much like we
+have the gr::fec::code::ccsds_encoder class.
+
+
+
+
+
+\subsection fec_parallelism Parallelism
+
+The code variables in GNU Radio Companion have the ability to create
+multiple encoder/decoder variables by selecting the level of
+parallelism. It is up the encoder to understand how to handle the
+parallelism. The following discussion explains the difference between
+the two levels and how and when to use. Generally, normal applications
+will just use a single level of parallelism.
+
+The GRC variable declarations for the different coders has a setting
+for <i>Parallelism</i>, which can be either 1 or 2. If set to 1, then
+the resulting variable is a list of coder blocks with the same
+settings. If set to 2, then the resulting variable is a list of lists
+of coder blocks. The code that accepts these variables must understand
+how to handle the parallelism. Most applications would set this to 1.
+
+The standard fec.extended_encoder ("FEC Extended Encoder" in GRC) and
+fec.extended_decoder ("FEC Extended Decoder" in GRC) can handle a
+Parallelism of 1. They accept a list of coder variables as defined by
+Dimension 1 and can multithread the application based on the
+"Threading Type" setting:
+
+\li <b>None</b>: does no parallel threading of the coders. Even if
+Dimension 1 is > 1, the encoder/decoder will ignore this setting and
+only use the first object in the list.
+
+\li <b>Ordinary</b>: all "Dimension 1" number (N) of encoder/decoder
+blocks will be used in parallel. The hier_block2 will block
+deinterleave the packets into N streams (using
+gr::blocks::deinterleave with a value of blocksize as the frame length
+and no relative rate changes) and pass these to each of the N coders
+to process the frames in parallel. The output of each coder is then
+interleaved back together to make a single output stream.
+
+\li <b>Capillary</b>: all "Dimension 1" number (N) of encoder/decoder
+blocks will be used in parallel, much like in the <b>Ordinary</b>
+mode. In this mode, however, the frames get split up in a tree-like
+fashion, where each branch launches 2 more branches. This means that N
+must be a factor of 2 for this mode to work. It tends to handle the
+load of the encoders/decoders better than the <b>Ordinary</b> mode.
+
+Note that the threading modes only work when using constant-length
+frames. If using the coders in tagged stream mode where the frame
+lengths may change, the <b>Ordinary</b> and <b>Capillary</b> modes are
+not available.
+
+The GRC example "ber_curve_gen.grc" uses a Parallelism of 2. This
+creates a list of lists of coders. The first dimension of the list
+corresponds to the number of Es/N0 values being used in the BER
+simulation. This allows the application to process all values of Es/N0
+simultaneously. Dimension 2 in this case allows the same concept of
+parallelism discussed above with the <b>None</b>, <b>Ordinary</b>, and
+<b>Capillary</b> models of threading.
+
+
+
+\section fec_api The API of the FECAPI
+
+The FECAPI defined by the parent generic_encoder and generic_decoder
+classes defines a set of virtual functions, some pure virtual, to
+allow the encoders/decoders to interact with the GNU Radio blocks. See
+the associated documentation of the generic_encoder and
+generic_decoder classes to know more about each of the API functions,
+some of which a child class is <i>required</i> to implement.
+
+The functions of the encoder and decoder are:
+
+\li double gr::fec::generic_encoder::rate()
+\li int gr::fec::generic_encoder::get_input_size()
+\li int gr::fec::generic_encoder::get_output_size()
+\li int gr::fec::generic_encoder::get_history()
+\li float gr::fec::generic_encoder::get_shift()
+\li const char* gr::fec::generic_encoder::get_input_conversion()
+\li const char* gr::fec::generic_encoder::get_output_conversion()
+\li bool gr::fec::generic_encoder::set_frame_size(unsigned int frame_size)
+
+Note: there is no get_input_item_size (or output) as the encoders
+always expect to work on bits.
+
+\li double gr::fec::generic_decoder::rate()
+\li int gr::fec::generic_decoder::get_input_size()
+\li int gr::fec::generic_decoder::get_output_size()
+\li int gr::fec::generic_decoder::get_history()
+\li float gr::fec::generic_decoder::get_shift()
+\li int gr::fec::generic_decoder::get_input_item_size()
+\li int gr::fec::generic_decoder::get_output_item_size()
+\li const char* gr::fec::generic_decoder::get_input_conversion()
+\li const char* gr::fec::generic_decoder::get_output_conversion()
+\li bool gr::fec::generic_decoder::set_frame_size(unsigned int frame_size)
+
+Whenever an FECAPI object refers to the frame size, it always means
+the number of bits in the uncoded frame. This means the number of bits
+going into an encoder and the number of bits coming out of a decoder.
+
+\section fec_examples FEC Examples
+
+\li ber_curve_gen.grc
+\li ber_curve_gen_ldpc.grc
+\li ber_test.grc
+\li fecapi_decoders.grc
+\li fecapi_encoders.grc
+\li fecapi_tagged_decoders.grc
+\li fecapi_tagged_encoders.grc
+\li fecapi_async_decoders.grc
+\li fecapi_async_encoders.grc
+\li fecapi_async_to_stream.grc
+
+
+
+\section fec_ldpc LDPC Codes
+
+GNU Radio supports a few different ways of handling LDPC codes. There
+are many types of encoders and decoders available, and defining the
+code can come in many different flavors. GNU Radio has two encoders
+and two decoders.
+
+\subsection fec_alist Describing the alist Files
+
+We use an alist file format for storing the matrices in files. The
+alist format looks like:
+
+\verbatim
+ncolumns nrows
+max_col_weight max_row_weight
+list_col_weights
+list_row_weights
+column_1_indices
+row_1_indices
+\endverbatim
+
+The ncolumns is the number of column in the matrix and nrows is the
+number of rows, so this would define a (nrows x ncolumns) matrix. The
+column and row weights are how many 1's are in each column or row,
+respectively. The alist format tracks the maximum weight for all
+columns and all rows as well as lists all of the weights for each
+column one one line and each row on another. Then, the alist format
+lists the indices of all 1's in the columns followed by a list of the
+indices of all 1's in the rows. The matrix can be constructed using
+either the column or row indices lists, and a check would be to make
+sure they create the same matrix. Because LDPC deals with sparse
+matrices, the weights should be small relative to the number of
+columns/rows. All of the indices are 1 based, not 0.
+
+And example is the simple_g_matrix.alist file that comes with GNU
+Radio as a sample generator matrix. The generator matrix is in the
+form [I | P] where I is the (k x k) identity matrix and P is a (k x
+(n-k)) matrix representing the parity information. Together, G is a
+(k x n) matrix. The alist file looks like:
+
+\verbatim
+8 4
+3 4
+1 1 1 1 3 3 3 3
+4 4 4 4
+1
+2
+3
+4
+2 3 4
+1 3 4
+1 2 4
+1 2 3
+1 6 7 8
+2 5 7 8
+3 5 6 8
+4 5 6 7
+\endverbatim
+
+So it has 8 columns and 4 rows. The maximum number of 1's in any
+column is 3 and the maximum number of 1's in any row is 4. The next
+two lines are the weights for each column and each row. Then we have 8
+lines that are the indices of the 1's in the columns followed by
+4 lines that are the indices of the 1's in the rows. Note that the
+number of items in any of these rows matches up with the numbers in
+the column and matrix weight lists. Let's use the either the column or
+rows to construct the matrix.
+
+\verbatim
+1 0 0 0 0 1 1 1
+0 1 0 0 1 0 1 1
+0 0 1 0 1 1 0 1
+0 0 0 1 1 1 1 0
+\endverbatim
+
+Now go back and do it with the other set of of indices to
+verify. We can also count up the 1's along the columns and rows to
+verify the top few lines for even more check.
+
+Some info on the alist files online can be found here:
+
+\li http://www.inference.phy.cam.ac.uk/mackay/codes/alist.html
+\li http://www.inference.phy.cam.ac.uk/mackay/codes/
+
+
+
+
+\subsection fec_ldpc_encoders LDPC Encoders
+
+There are two LDPC encoder variables but a few ways to set them up. They are:
+
+\li gr::fec::code::ldpc_par_mtrx_encoder
+\li gr::fec::code::ldpc_gen_mtrx_encoder
+
+Both encoders take in a matrix, but there are two different forms of
+the matrix that they work with. The gr::fec::code::ldpc_par_mtrx_encoder takes a
+parity check matrix, H, which is in upper triangular form. The
+gr::fec::code::ldpc_gen_mtrx_encoder takes in a generator matrix, G.
+
+A third coder exsits, gr::fec::ldpc_encoder, but this is deprecated
+and should not be used. It's functionally equivalent to
+gr::fec::code::ldpc_par_mtrx_encoder and still exists for
+compatibility reasons.
+
+There are two constructors for
+gr::fec::code::ldpc_par_mtrx_encoder. The first one, 'make', takes in
+an alist file that represents the parity matrix in the alist format
+described above. The 'make_H' function makes an LDPC encoder using a
+prebuilt gr::fec::code::ldpc_H_matrix object. When using the alist
+file, we also need to tell it the gap size in the matrix, which is not
+represented in the alist file format, but it should be known or part
+of the file name itself.
+
+The format of the parity check matrix, H, in upper triangular form is
+described as:
+
+\verbatim
+[ T A B ]
+[ E C D ]
+
+T: (n - k - g) x (n - k - g)
+A: (n - k - g) x g
+B: (n - k - g) x k
+E: g x (n - k - g)
+C: g x g
+D: g x k
+\endverbatim
+
+Where n is the size of the codeword, k is the size of the information
+word, and g is the size of the gap. See "Open-source Forward Error
+Correction using GNU Radio" for more description about this matrix:
+
+\li http://arc.aiaa.org/doi/abs/10.2514/6.2015-4655
+
+
+The other encoder is gr::fec::code::ldpc_gen_mtrx_encoder. This takes
+a generator matrix in systematic form G=[I P] which is (k x n). The
+codeword x is generated from the information word s via simple matrix
+multiplication: \f$ x=G^T s \f$.
+
+Unlike the encoder using the H matrix, the
+gr::fec::code::ldpc_gen_mtrx_encoder only has a single make function
+that takes in a prebuilt generator matrix object from the class
+gr::fec::code::ldpc_G_matrix.
+
+In GRC, we have a handful of blocks for manipulating the LDPC encoders
+and matrices:
+
+\li LDPC Encoder Definition: creates a
+gr::fec::code::ldpc_par_mtrx_encoder FEC variable using a provided
+alist file and specified matrix gap.
+\li LDPC Encoder Definition (via Parity Check): receives a prebuilt H
+matrix from the "LDPC Parity Check Matrix".
+\li LDPC Encoder Definition (via Generator): receives a prebuilt G
+matrix from the "LDPC Generator Matrix".
+\li LDPC Parity Check Matrix: constructs a parity check matrix, H,
+from a given alist file and matrix gap.
+\li LDPC Generator Matrix: constructs a generator matrix, G, from a
+given alist file.
+
+The gr::fec::code::ldpc_par_mtrx_encoder uses a reduced complexity
+algorithm. Compared to the gr::fec::code::ldpc_gen_mtrx_encoder, this
+requires orders of magnitude fewer operations at each encoding
+step. This is accomplished by completing a significant amount of the
+complex matrix manipulation (including inverse, multiplication, and
+Gaussian elimination operations) during preprocessing. The
+disadvantage of this encoder is that it requires a specially formatted
+matrix. There are some Python tools available from GNU Radio to format
+a standard parity check matrix appropriately for this encoder, as well
+as a small library of encoding-ready matrices for use.
+
+NOTE: we need to document these tools better.
+
+For uses of these codes, see the FEC examples:
+
+\li fecapi_ldpc_encoders.grc
+\li fecapi_tagged_ldpc_encoders.grc
+\li fecapi_async_ldpc_encoders.grc
+
+Prebuilt alist files are also distributed and installed with GNU
+Radio. They can be found in $prefix/share/gnuradio/fec/ldpc. The files
+generally represent the H matrix and are specified with the number of
+rows and columns (n and k) and gap of the matrix. The files named
+"gen_matrix" or similar are the generator, G, matrices.
+
+
+
+\subsection fec_ldpc_decoder LDPC Decoders
+
+The simplest LDPC decoder is probably the
+gr::fec::code::ldpc_bit_flip_decoder, a hard decision decoding
+scheme. The decoder seeks to find the codeword that was most likely
+sent, which must satisfy Hx'= 0. If the received codeword does not
+satisfy this parity check, then the decoder computes the parity checks
+on all of the bits. The bit(s) associated with the most failed parity
+checks are flipped. The process repeats until a valid codeword is
+found, or a maximum number of iterations is reached, whichever comes
+first.
+
+The gr::fec::ldpc_decoder is a soft-decision decoder that uses belief
+propagation (also known as message passing). Designed for a memoryless
+AWGN channel, it assumes a noise variance entered in as 'Sigma' in the
+block. This is a suboptimal, yet efficient method of decoding LDPC
+codes.
+
+In GRC, we have the following blocks for doing LDPC decoding:
+
+\li LDPC Decoder Definition: constructs a gr::fec::ldpc_decoder
+variable given the alist file name of the H matrix.
+\li LDPC Bit Flip Decoder Definition: constructs a
+gr::fec::code::ldpc_bit_flip_decoder. This does not take in an alist file
+name but instead a predefined matrix object. This decoder is useful in
+that it can take either an H or a G matrix constructed by either the
+"LDPC Parity Check Matrix" or "LDPC Generator Matrix," respectively.
+
+For uses of these codes, see the FEC examples:
+
+\li fecapi_ldpc_decoders.grc
+\li fecapi_tagged_ldpc_decoders.grc
+\li fecapi_async_ldpc_decoders.grc
+
+*/