.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/coding/plot_02_hu2005_fig5.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_coding_plot_02_hu2005_fig5.py: Hu, Eleftheriou & Arnold 2005, Fig. 5: a regular PEG code of length 504 ======================================================================== Fig. 5 of X.-Y. Hu, E. Eleftheriou and D. M. Arnold, "Regular and irregular progressive edge-growth Tanner graphs", *IEEE Trans. Inf. Theory* 51(1), 2005, gives the bit and block error rates of a regular LDPC code built by progressive edge growth, with :math:`n = 504`, :math:`m = 252` parity checks, symbol-node degree :math:`d_s = 3` and check-node degree :math:`d_c = 6`, over the AWGN channel with BPSK and sum-product decoding, next to MacKay's code and a random graph of the same parameters. :meth:`comnum.LdpcCode.peg` builds a graph by the same algorithm; the unit test ``literature`` of ``comnum_fec::ldpc`` checks that it has the girth 8 and the check degrees of the paper's Sec. VI. The graph is not the paper's graph (the algorithm breaks its ties at random), so the curves are those of a PEG code of these parameters, decoded by the flooding sum-product algorithm with at most 100 iterations: open Fig. 5 of the paper next to this figure and compare the PEG curves, solid for the bit error rate and dashed for the block error rate. The dotted line is uncoded BPSK. .. GENERATED FROM PYTHON SOURCE LINES 22-75 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from _gallery_utils import bpsk_awgn_decisions import comnum from comnum.plot import BACKGROUND, GREY code = comnum.LdpcCode.peg(504, 252, var_degree=3, seed=1) code.set_decoder("sum_product", layered=False, max_iterations=100) print(code, "rate", code.rate) def error_rates(ebn0_db, seed, min_block_errors=100, max_blocks=40_000, batch=500): """Bit and block error rates over AWGN with BPSK, until `min_block_errors` block errors or `max_blocks` codewords.""" bit_errors = block_errors = blocks = 0 t = 0 while block_errors < min_block_errors and blocks < max_blocks: rng = comnum.Rng.stream(seed, "peg504", int(10 * ebn0_db), t) b = comnum.bits(code.k * batch, rng) e = (bpsk_awgn_decisions(code, b, ebn0_db, rng) != b).reshape(batch, -1) bit_errors += int(e.sum()) block_errors += int(e.any(axis=1).sum()) blocks += batch t += 1 return bit_errors / (blocks * code.k), block_errors / blocks points = np.arange(1.0, 3.76, 0.25) rates = np.array([error_rates(e, seed=5) for e in points]) rates[rates == 0] = np.nan # no error observed: nothing to draw fig, ax = plt.subplots() fine = np.linspace(0, 4, 81) ax.semilogy(fine, comnum.theory_ber(2, fine, "psk"), ":", color=GREY, linewidth=1.4, label="uncoded BPSK") # fmt: skip ax.semilogy( points, rates[:, 0], "o-", markeredgecolor=BACKGROUND, label="PEG (504, 252), bit error rate" ) ax.semilogy( points, rates[:, 1], "s--", markeredgecolor=BACKGROUND, label="PEG (504, 252), block error rate" ) ax.set( xlim=(0, 4), ylim=(1e-6, 1), xlabel="$E_b/N_0$ (dB)", ylabel="error rate", title="Regular (3, 6) PEG code, n = 504 (Hu et al. 2005, Fig. 5)", ) ax.legend(loc="lower left") fig.tight_layout() .. image-sg:: /auto_examples/coding/images/sphx_glr_plot_02_hu2005_fig5_001.png :alt: Regular (3, 6) PEG code, n = 504 (Hu et al. 2005, Fig. 5) :srcset: /auto_examples/coding/images/sphx_glr_plot_02_hu2005_fig5_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none LdpcCode(n=504, k=252) rate 0.5 .. GENERATED FROM PYTHON SOURCE LINES 76-79 The waterfall of a regular (3, 6) code of this length lies about 1.5 dB from the Shannon limit of rate 1/2 (0.19 dB); the paper's Fig. 5 shows the PEG code below MacKay's code and the random graph at every SNR. .. GENERATED FROM PYTHON SOURCE LINES 79-82 .. code-block:: Python print(f"Shannon limit at rate 1/2: {comnum.theory_shannon_limit_ebn0_db(0.5):.2f} dB") for e, (ber, bler) in zip(points, rates, strict=True): print(f"Eb/N0 = {e:.2f} dB: BER {ber:.2e}, BLER {bler:.2e}") .. rst-class:: sphx-glr-script-out .. code-block:: none Shannon limit at rate 1/2: 0.19 dB Eb/N0 = 1.00 dB: BER 5.97e-02, BLER 6.64e-01 Eb/N0 = 1.25 dB: BER 4.43e-02, BLER 5.08e-01 Eb/N0 = 1.50 dB: BER 2.23e-02, BLER 2.94e-01 Eb/N0 = 1.75 dB: BER 1.07e-02, BLER 1.41e-01 Eb/N0 = 2.00 dB: BER 4.81e-03, BLER 6.45e-02 Eb/N0 = 2.25 dB: BER 1.47e-03, BLER 2.00e-02 Eb/N0 = 2.50 dB: BER 3.81e-04, BLER 5.41e-03 Eb/N0 = 2.75 dB: BER 7.60e-05, BLER 1.22e-03 Eb/N0 = 3.00 dB: BER 2.11e-05, BLER 2.75e-04 Eb/N0 = 3.25 dB: BER 2.98e-06, BLER 5.00e-05 Eb/N0 = 3.50 dB: BER 1.69e-06, BLER 2.50e-05 Eb/N0 = 3.75 dB: BER nan, BLER nan .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 10.244 seconds) .. _sphx_glr_download_auto_examples_coding_plot_02_hu2005_fig5.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_hu2005_fig5.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_hu2005_fig5.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_hu2005_fig5.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_