A header-only C++17 library of forward-error-correction (FEC) codes, tracing the evolution of channel coding across cellular standards from 2G to 5G. The library has no external dependencies — it uses only the C++ standard library — which makes it easy to drop into any project or to study as a self-contained reference implementation.
Error-correcting codes are the backbone of every digital communication system. This library implements the major code families in a single, readable codebase and ties each one to the cellular standard that made it famous, so you can see how and why channel coding evolved:
| Code family | Introduced with | Standard config |
|---|---|---|
| Hamming | classic block code | — |
| Convolutional / Viterbi | 2G (GSM) | gsm.hpp |
| Turbo | 3G / 4G (LTE) | lte.hpp |
| Reed–Solomon | block code (storage, DVB) | — |
| LDPC | 5G data channel | nr.hpp |
| Polar | 5G control channel | nr.hpp |
- Header-only — just add
fec-cpp/include/to your include path. - C++17, STL-only — no third-party libraries, no build-system lock-in.
- Encoder + decoder for each code family.
- Standard-specific presets for GSM (2G), LTE (4G) and NR (5G).
- Test suite covering encode/decode round-trips and error-correction limits.
.
fec-cpp/ - the library and its tooling
include/fec/ - header-only library
block/ - Hamming, Reed-Solomon
polar/ - Polar codes (SC decoder)
turbo/ - Turbo encoder/decoder (BCJR)
... - convolutional, LDPC, common
standards/ - gsm.hpp, lte.hpp, nr.hpp presets
examples/ - demo programs (BER curves)
tests/ - test suite (test_all)
scripts/ - plot_ber.py
CMakeLists.txt
plots/ - sample BER curves (PNG)
LICENSE
README.md
- A C++17-capable compiler (MSVC, GCC 9+, or Clang).
- CMake 3.15+ (optional — only needed to build the tests and examples).
The library itself needs no build step; just include the headers. The CMake
project for the tests and examples lives in fec-cpp/.
Open the fec-cpp folder (File → Open → Folder). Visual Studio detects
CMakeLists.txt, configures the project with the MSVC toolchain automatically,
and lets you build with Build → Build All and run tests from the Test Explorer.
cmake -S fec-cpp -B build
cmake --build build
ctest --test-dir build --output-on-failureNote: plain CMake on Windows defaults to the MSVC ("NMake") generator, which requires running from a Developer Command Prompt for Visual Studio. If you prefer MinGW, pass
-G "MinGW Makefiles"with the MinGWbindirectory on yourPATH.
Add fec-cpp/include/ to your include path, then:
#include "fec/fec.hpp"
using namespace fec;
using namespace std;
// Example: Polar code with N = 8, K = 4.
// from_rate picks the K most reliable bit-channels as info positions.
int N=8, K=4;
auto enc = polar::PolarEncoder::from_rate(N, K);
auto dec = polar::SCDecoder::from_rate(N, K);
BitVec message = {1,0,1,1};
BitVec codeword = enc.encode(message); // N coded bits
// AWGN channel (BPSK), returns LLRs
AWGNChannel ch(3.0f); // snr_db
LLRVec llr = ch.transmit(codeword);
BitVec decoded = dec.decode(llr); // K recovered info bits(See fec-cpp/examples/ for runnable programs and fec-cpp/standards/ for
ready-made GSM/LTE/NR configurations.)
Each *_ber example prints a plain table to stdout. fec-cpp/scripts/plot_ber.py
turns that table into a chart (semilog-y for BER, linear for failure rates), so
you can pipe a program straight into it without the script needing to know where
the binaries live:
pip install matplotlib
./build/hamming_ber | python fec-cpp/scripts/plot_ber.py --title "Hamming(7,4)" --xlabel "SNR (dB)" -o plots/hamming.png
./build/viterbi_ber | python fec-cpp/scripts/plot_ber.py --title "Viterbi r=1/2" --xlabel "SNR (dB)" -o plots/viterbi.png
./build/ldpc_ber | python fec-cpp/scripts/plot_ber.py --title "LDPC (regular, R=1/2)" --xlabel "SNR (dB)" -o plots/ldpc.png
./build/turbo_ber | python fec-cpp/scripts/plot_ber.py --title "Turbo [7,5], R=1/3" --xlabel "Eb/N0 (dB)" -o plots/turbo.png
./build/polar_ber | python fec-cpp/scripts/plot_ber.py --title "Polar SC (N=1024)" --xlabel "Eb/N0 (dB)" -o plots/polar.png
./build/rs_ber | python fec-cpp/scripts/plot_ber.py --title "RS(255,239)" --xlabel "symbol errors/blk" --linear -o plots/rs.pngColumn labels are read from the table's header row automatically. The Hamming
demo also plots an uncoded reference curve so the coding gain is visible. The
generated charts live in plots/.
All 22 tests pass. The library implements working encoders and decoders for every listed code family, including a successive-cancellation (SC) decoder for Polar codes and full error correction for Reed–Solomon.
Released under the MIT License — see LICENSE.
Issues and pull requests are welcome. Please make sure the full test suite passes
(ctest) before submitting changes.