├── lib ├── a.out ├── random_generator.py ├── qa_ldpc.cc ├── qa_ldpc.h ├── copy_bb_impl.h ├── test_ldpc.cc ├── lh_detector_fb_impl.h ├── bsc_bb_impl.h ├── ldpc_encoder_bb_impl.h ├── ldpc_encoder_bf_impl.h ├── ldpc_decoder_bb_impl.h ├── ldpc_decoder_fb_impl.h ├── xtest.cc ├── gf2vec.h ├── lh_detector_fb_impl.cc ├── copy_bb_impl.cc ├── awgn_test.cc ├── gf2vec.cc ├── CMakeLists.txt ├── bsc_bb_impl.cc ├── ldpc_encoder_bb_impl.cc ├── ldpc_encoder_bf_impl.cc ├── ldpc_decoder_bb_impl.cc ├── ldpc_decoder_fb_impl.cc ├── gf2mat.h ├── cldpc.cc ├── cldpc.h ├── alist.h ├── gf2mat.cc ├── awgn_bp.h ├── xbp.h ├── alist.cc └── awgn_bp.cc ├── python ├── fileread.py ├── test_hier.py ├── ldpc_hier_encoder_bb.py ├── ldpc_hier_decoder_fb.py ├── CMakeLists.txt ├── __init__.py ├── test_bsc.py ├── qa_copy_bb.py └── test_awgn.py ├── docs ├── doxygen │ ├── other │ │ ├── group_defs.dox │ │ └── main_page.dox │ ├── doxyxml │ │ ├── generated │ │ │ ├── __init__.py │ │ │ └── index.py │ │ ├── text.py │ │ └── __init__.py │ └── CMakeLists.txt ├── README.ldpc └── CMakeLists.txt ├── cmake ├── Modules │ ├── FindGnuradioRuntime.cmake │ ├── FindCppUnit.cmake │ ├── GrPlatform.cmake │ ├── GrTest.cmake │ └── CMakeParseArgumentsCopy.cmake └── cmake_uninstall.cmake.in ├── gr-ldpc.lwr ├── apps ├── CMakeLists.txt ├── find_smallest.py ├── top_block.py ├── example1.py ├── rs_ldpc.py ├── peg.py ├── gf.py └── example2.grc ├── swig ├── ldpc_swig.i └── CMakeLists.txt ├── grc ├── ldpc_lh_detector_fb.xml ├── ldpc_ldpc_hier_encoder_bb.xml ├── CMakeLists.txt ├── ldpc_copy_bb.xml ├── ldpc_bsc_bb.xml ├── ldpc_ldpc_encoder_bb.xml ├── ldpc_ldpc_encoder_bf.xml ├── ldpc_ldpc_decoder_bb.xml ├── ldpc_ldpc_decoder_fb.xml └── ldpc_ldpc_hier_decoder_fb.xml ├── include └── ldpc │ ├── api.h │ ├── CMakeLists.txt │ ├── bsc_bb.h │ ├── copy_bb.h │ ├── lh_detector_fb.h │ ├── ldpc_encoder_bf.h │ ├── ldpc_encoder_bb.h │ ├── ldpc_decoder_bb.h │ └── ldpc_decoder_fb.h ├── README └── CMakeLists.txt /lib/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manuts/gr-ldpc/HEAD/lib/a.out -------------------------------------------------------------------------------- /lib/random_generator.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | f = open("randoms", "w") 4 | for i in range(100000): 5 | X = random.gauss(0, 0.6) 6 | f.write(str(X) + "\n") 7 | -------------------------------------------------------------------------------- /python/fileread.py: -------------------------------------------------------------------------------- 1 | import scipy as sp 2 | import numpy as np 3 | 4 | f = sp.fromfile(open("encout"), dtype=sp.int8) 5 | 6 | for i in range(10000): 7 | print int(f[i]), 8 | -------------------------------------------------------------------------------- /docs/doxygen/other/group_defs.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * \defgroup block GNU Radio LDPC C++ Signal Processing Blocks 3 | * \brief All C++ blocks that can be used from the LDPC GNU Radio 4 | * module are listed here or in the subcategories below. 5 | * 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains generated files produced by generateDS.py. 3 | 4 | These do the real work of parsing the doxygen xml files but the 5 | resultant classes are not very friendly to navigate so the rest of the 6 | doxyxml module processes them further. 7 | """ 8 | -------------------------------------------------------------------------------- /docs/doxygen/other/main_page.dox: -------------------------------------------------------------------------------- 1 | /*! \mainpage 2 | 3 | Welcome to the GNU Radio LDPC Block 4 | 5 | This is the intro page for the Doxygen manual generated for the LDPC 6 | block (docs/doxygen/other/main_page.dox). Edit it to add more detailed 7 | documentation about the new GNU Radio modules contained in this 8 | project. 9 | 10 | */ 11 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioRuntime.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(GNURADIO_RUNTIME gnuradio-runtime) 3 | 4 | INCLUDE(FindPackageHandleStandardArgs) 5 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) 6 | MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) 7 | -------------------------------------------------------------------------------- /docs/README.ldpc: -------------------------------------------------------------------------------- 1 | This is the ldpc-write-a-block package meant as a guide to building 2 | out-of-tree packages. To use the ldpc blocks, the Python namespaces 3 | is in 'ldpc', which is imported as: 4 | 5 | import ldpc 6 | 7 | See the Doxygen documentation for details about the blocks available 8 | in this package. A quick listing of the details can be found in Python 9 | after importing by using: 10 | 11 | help(ldpc) 12 | -------------------------------------------------------------------------------- /gr-ldpc.lwr: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 IIT Bombay. 3 | # 4 | # This is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3, or (at your option) 7 | # any later version. 8 | # 9 | # This software is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this software; see the file COPYING. If not, write to 16 | # the Free Software Foundation, Inc., 51 Franklin Street, 17 | # Boston, MA 02110-1301, USA. 18 | # 19 | 20 | category: common 21 | depends: gnuradio 22 | source: git://https://github.com/manuts/gr-ldpc.git 23 | gitbranch: master 24 | inherit: cmake 25 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | include(GrPython) 21 | 22 | GR_PYTHON_INSTALL( 23 | PROGRAMS 24 | DESTINATION bin 25 | ) 26 | -------------------------------------------------------------------------------- /swig/ldpc_swig.i: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | 3 | #define LDPC_API 4 | 5 | %include "gnuradio.i" // the common stuff 6 | 7 | //load generated python docstrings 8 | %include "ldpc_swig_doc.i" 9 | 10 | %{ 11 | #include "ldpc/copy_bb.h" 12 | #include "ldpc/ldpc_encoder_bb.h" 13 | #include "ldpc/ldpc_decoder_bb.h" 14 | #include "ldpc/bsc_bb.h" 15 | #include "ldpc/ldpc_encoder_bf.h" 16 | #include "ldpc/ldpc_decoder_fb.h" 17 | #include "ldpc/lh_detector_fb.h" 18 | %} 19 | 20 | 21 | %include "ldpc/copy_bb.h" 22 | GR_SWIG_BLOCK_MAGIC2(ldpc, copy_bb); 23 | %include "ldpc/ldpc_encoder_bb.h" 24 | GR_SWIG_BLOCK_MAGIC2(ldpc, ldpc_encoder_bb); 25 | %include "ldpc/ldpc_decoder_bb.h" 26 | GR_SWIG_BLOCK_MAGIC2(ldpc, ldpc_decoder_bb); 27 | %include "ldpc/bsc_bb.h" 28 | GR_SWIG_BLOCK_MAGIC2(ldpc, bsc_bb); 29 | %include "ldpc/ldpc_encoder_bf.h" 30 | GR_SWIG_BLOCK_MAGIC2(ldpc, ldpc_encoder_bf); 31 | %include "ldpc/ldpc_decoder_fb.h" 32 | GR_SWIG_BLOCK_MAGIC2(ldpc, ldpc_decoder_fb); 33 | %include "ldpc/lh_detector_fb.h" 34 | GR_SWIG_BLOCK_MAGIC2(ldpc, lh_detector_fb); 35 | -------------------------------------------------------------------------------- /cmake/Modules/FindCppUnit.cmake: -------------------------------------------------------------------------------- 1 | # http://www.cmake.org/pipermail/cmake/2006-October/011446.html 2 | # Modified to use pkg config and use standard var names 3 | 4 | # 5 | # Find the CppUnit includes and library 6 | # 7 | # This module defines 8 | # CPPUNIT_INCLUDE_DIR, where to find tiff.h, etc. 9 | # CPPUNIT_LIBRARIES, the libraries to link against to use CppUnit. 10 | # CPPUNIT_FOUND, If false, do not try to use CppUnit. 11 | 12 | INCLUDE(FindPkgConfig) 13 | PKG_CHECK_MODULES(PC_CPPUNIT "cppunit") 14 | 15 | FIND_PATH(CPPUNIT_INCLUDE_DIRS 16 | NAMES cppunit/TestCase.h 17 | HINTS ${PC_CPPUNIT_INCLUDE_DIR} 18 | PATHS 19 | /usr/local/include 20 | /usr/include 21 | ) 22 | 23 | FIND_LIBRARY(CPPUNIT_LIBRARIES 24 | NAMES cppunit 25 | HINTS ${PC_CPPUNIT_LIBDIR} 26 | PATHS 27 | ${CPPUNIT_INCLUDE_DIRS}/../lib 28 | /usr/local/lib 29 | /usr/lib 30 | ) 31 | 32 | LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS}) 33 | 34 | INCLUDE(FindPackageHandleStandardArgs) 35 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 36 | MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 37 | -------------------------------------------------------------------------------- /grc/ldpc_lh_detector_fb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | lh_detector_fb 4 | ldpc_lh_detector_fb 5 | ldpc 6 | import ldpc 7 | ldpc.lh_detector_fb() 8 | 18 | 19 | 24 | 25 | in 26 | float 27 | 28 | 29 | 34 | 35 | out 36 | byte 37 | 38 | 39 | -------------------------------------------------------------------------------- /include/ldpc/api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_LDPC_API_H 23 | #define INCLUDED_LDPC_API_H 24 | 25 | #include 26 | 27 | #ifdef gnuradio_ldpc_EXPORTS 28 | # define LDPC_API __GR_ATTR_EXPORT 29 | #else 30 | # define LDPC_API __GR_ATTR_IMPORT 31 | #endif 32 | 33 | #endif /* INCLUDED_LDPC_API_H */ 34 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_hier_encoder_bb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_hier_encoder_bb 4 | ldpc_ldpc_hier_encoder_bb 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_hier_encoder_bb($alist_file) 8 | 13 | 14 | File 15 | alist_file 16 | file_open 17 | 18 | 19 | 24 | 25 | in 26 | byte 27 | 28 | 29 | 34 | 35 | out 36 | byte 37 | 38 | 39 | -------------------------------------------------------------------------------- /grc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | install(FILES 20 | ldpc_copy_bb.xml 21 | ldpc_ldpc_encoder_bb.xml 22 | ldpc_ldpc_decoder_bb.xml 23 | ldpc_bsc_bb.xml 24 | ldpc_ldpc_encoder_bf.xml 25 | ldpc_ldpc_decoder_fb.xml 26 | ldpc_ldpc_hier_encoder_bb.xml 27 | ldpc_ldpc_hier_decoder_fb.xml 28 | ldpc_lh_detector_fb.xml DESTINATION share/gnuradio/grc/blocks 29 | ) 30 | -------------------------------------------------------------------------------- /python/test_hier.py: -------------------------------------------------------------------------------- 1 | from gnuradio import gr, blocks 2 | import ldpc 3 | 4 | class my_tb(gr.top_block): 5 | def __init__(self, fname, sigma, max_iterations): 6 | gr.top_block.__init__(self) 7 | 8 | encoder = ldpc.ldpc_hier_encoder_bf(fname) 9 | decoder = ldpc.ldpc_hier_decoder_fb(fname, 10 | sigma, max_iterations) 11 | 12 | unpack2pack = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) 13 | pack2unpack = blocks.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) 14 | 15 | inFile = "/home/manu/Downloads/in.flac" 16 | outFile = "/home/manu/Downloads/out.flac" 17 | source = blocks.file_source(1, inFile, False) 18 | sink = blocks.file_sink(1, outFile) 19 | 20 | self.connect(source, pack2unpack, encoder, decoder, unpack2pack, sink) 21 | 22 | def main(): 23 | fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963" 24 | sigma = 0.3 25 | max_iterations = 100 26 | tb = my_tb(fname, sigma, max_iterations) 27 | print "tb initialized" 28 | tb.start() 29 | tb.wait() 30 | 31 | if __name__ == '__main__': 32 | try: 33 | main() 34 | except KeyboardInterrupt: 35 | pass 36 | -------------------------------------------------------------------------------- /grc/ldpc_copy_bb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | copy_bb 4 | ldpc_copy_bb 5 | ldpc 6 | import ldpc 7 | ldpc.copy_bb($vlen) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /grc/ldpc_bsc_bb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bsc_bb 4 | ldpc_bsc_bb 5 | ldpc 6 | import ldpc 7 | ldpc.bsc_bb($vlen, $epsilon) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/qa_ldpc.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | /* 23 | * This class gathers together all the test cases for the gr-filter 24 | * directory into a single test suite. As you create new test cases, 25 | * add them here. 26 | */ 27 | 28 | #include "qa_ldpc.h" 29 | 30 | CppUnit::TestSuite * 31 | qa_ldpc::suite() 32 | { 33 | CppUnit::TestSuite *s = new CppUnit::TestSuite("ldpc"); 34 | 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_encoder_bb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_encoder_bb 4 | ldpc_ldpc_encoder_bb 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_encoder_bb($alist_file) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_encoder_bf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_encoder_bf 4 | ldpc_ldpc_encoder_bf 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_encoder_bf($alist_file) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /include/ldpc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Install public header files 22 | ######################################################################## 23 | install(FILES 24 | api.h 25 | copy_bb.h 26 | ldpc_encoder_bb.h 27 | ldpc_decoder_bb.h 28 | bsc_bb.h 29 | ldpc_encoder_bf.h 30 | ldpc_decoder_fb.h 31 | lh_detector_fb.h DESTINATION include/ldpc 32 | ) 33 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_decoder_bb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_decoder_bb 4 | ldpc_ldpc_decoder_bb 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_decoder_bb($alist_file, $epsilon, $max_iterations) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_decoder_fb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_decoder_fb 4 | ldpc_ldpc_decoder_fb 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_decoder_fb($alist_file, $sigma, $max_iterations) 8 | 13 | 14 | ... 15 | ... 16 | ... 17 | 18 | 19 | 24 | 25 | in 26 | 27 | 28 | 29 | 34 | 35 | out 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/qa_ldpc.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2012 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifndef _QA_LDPC_H_ 24 | #define _QA_LDPC_H_ 25 | 26 | #include 27 | #include 28 | 29 | //! collect all the tests for the gr-filter directory 30 | 31 | class __GR_ATTR_EXPORT qa_ldpc 32 | { 33 | public: 34 | //! return suite of tests for all of gr-filter directory 35 | static CppUnit::TestSuite *suite(); 36 | }; 37 | 38 | #endif /* _QA_LDPC_H_ */ 39 | -------------------------------------------------------------------------------- /apps/find_smallest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013 IIT Bombay. 4 | # Author: Manu T S 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | def find_smallest(array): 23 | if len(array) == 1: 24 | return 0 25 | elif len(array) == 2: 26 | if array[0] <= array[1]: 27 | return 0 28 | else: 29 | return 1 30 | else: 31 | arrayA = array[:len(array)/2] 32 | arrayB = array[(len(array)/2):] 33 | smallA = find_smallest(arrayA) 34 | smallB = find_smallest(arrayB) 35 | if arrayA[smallA] <= arrayB[smallB]: 36 | return smallA 37 | else: 38 | return len(arrayA) + smallB 39 | -------------------------------------------------------------------------------- /grc/ldpc_ldpc_hier_decoder_fb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ldpc_hier_decoder_fb 4 | ldpc_ldpc_hier_decoder_fb 5 | ldpc 6 | import ldpc 7 | ldpc.ldpc_hier_decoder_fb($alist_file, $sigma, $max_iterations) 8 | 13 | 14 | Alist File 15 | alist_file 16 | file_open 17 | 18 | 19 | Sigma 20 | sigma 21 | float 22 | 23 | 24 | Max iterations 25 | max_iterations 26 | int 27 | 28 | 29 | 34 | 35 | in 36 | float 37 | 38 | 39 | 44 | 45 | out 46 | byte 47 | 48 | 49 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 2 | 3 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 5 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 6 | 7 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 8 | STRING(REGEX REPLACE "\n" ";" files "${files}") 9 | FOREACH(file ${files}) 10 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 11 | IF(EXISTS "$ENV{DESTDIR}${file}") 12 | EXEC_PROGRAM( 13 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 14 | OUTPUT_VARIABLE rm_out 15 | RETURN_VALUE rm_retval 16 | ) 17 | IF(NOT "${rm_retval}" STREQUAL 0) 18 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 19 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 20 | ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") 21 | EXEC_PROGRAM( 22 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 23 | OUTPUT_VARIABLE rm_out 24 | RETURN_VALUE rm_retval 25 | ) 26 | IF(NOT "${rm_retval}" STREQUAL 0) 27 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 28 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 29 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 30 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 31 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 32 | ENDFOREACH(file) 33 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Setup dependencies 22 | ######################################################################## 23 | find_package(Doxygen) 24 | 25 | ######################################################################## 26 | # Begin conditional configuration 27 | ######################################################################## 28 | if(ENABLE_DOXYGEN) 29 | 30 | ######################################################################## 31 | # Add subdirectories 32 | ######################################################################## 33 | add_subdirectory(doxygen) 34 | 35 | endif(ENABLE_DOXYGEN) 36 | -------------------------------------------------------------------------------- /lib/copy_bb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_COPY_BB_IMPL_H 22 | #define INCLUDED_LDPC_COPY_BB_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace ldpc { 28 | 29 | class copy_bb_impl : public copy_bb 30 | { 31 | private: 32 | size_t d_vlen; 33 | 34 | public: 35 | copy_bb_impl(size_t vlen); 36 | ~copy_bb_impl(); 37 | size_t get_vlen(); 38 | 39 | // Where all the action really happens 40 | int work(int noutput_items, 41 | gr_vector_const_void_star &input_items, 42 | gr_vector_void_star &output_items); 43 | }; 44 | 45 | } // namespace ldpc 46 | } // namespace gr 47 | 48 | #endif /* INCLUDED_LDPC_COPY_BB_IMPL_H */ 49 | 50 | -------------------------------------------------------------------------------- /lib/test_ldpc.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2012 Free Software Foundation, Inc. 4 | * 5 | * This file is part of GNU Radio 6 | * 7 | * GNU Radio is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3, or (at your option) 10 | * any later version. 11 | * 12 | * GNU Radio is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with GNU Radio; see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | #include "config.h" 25 | #endif 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | #include "qa_ldpc.h" 32 | #include 33 | 34 | int 35 | main (int argc, char **argv) 36 | { 37 | CppUnit::TextTestRunner runner; 38 | std::ofstream xmlfile(get_unittest_path("ldpc.xml").c_str()); 39 | CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); 40 | 41 | runner.addTest(qa_ldpc::suite()); 42 | runner.setOutputter(xmlout); 43 | 44 | bool was_successful = runner.run("", false); 45 | 46 | return was_successful ? 0 : 1; 47 | } 48 | -------------------------------------------------------------------------------- /lib/lh_detector_fb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_LH_DETECTOR_FB_IMPL_H 22 | #define INCLUDED_LDPC_LH_DETECTOR_FB_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace ldpc { 28 | 29 | class lh_detector_fb_impl : public lh_detector_fb 30 | { 31 | private: 32 | // Nothing to declare in this block. 33 | 34 | public: 35 | lh_detector_fb_impl(); 36 | ~lh_detector_fb_impl(); 37 | 38 | // Where all the action really happens 39 | int work(int noutput_items, 40 | gr_vector_const_void_star &input_items, 41 | gr_vector_void_star &output_items); 42 | }; 43 | 44 | } // namespace ldpc 45 | } // namespace gr 46 | 47 | #endif /* INCLUDED_LDPC_LH_DETECTOR_FB_IMPL_H */ 48 | 49 | -------------------------------------------------------------------------------- /lib/bsc_bb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_BSC_BB_IMPL_H 22 | #define INCLUDED_LDPC_BSC_BB_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace ldpc { 28 | 29 | class bsc_bb_impl : public bsc_bb 30 | { 31 | private: 32 | float d_epsilon; 33 | int nerr; 34 | int d_vlen; 35 | float limit; 36 | int X; 37 | 38 | public: 39 | bsc_bb_impl(int vlen, float epsilon); 40 | ~bsc_bb_impl(); 41 | int get_nerr(); 42 | 43 | // Where all the action really happens 44 | int work(int noutput_items, 45 | gr_vector_const_void_star &input_items, 46 | gr_vector_void_star &output_items); 47 | }; 48 | 49 | } // namespace ldpc 50 | } // namespace gr 51 | 52 | #endif /* INCLUDED_LDPC_BSC_BB_IMPL_H */ 53 | 54 | -------------------------------------------------------------------------------- /python/ldpc_hier_encoder_bb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2013 IIT Bombay. 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | from gnuradio import gr, blocks 23 | import ldpc 24 | 25 | class ldpc_hier_encoder_bb(gr.hier_block2): 26 | """ 27 | docstring for block ldpc_hier_encoder_bb 28 | """ 29 | def __init__(self, alist_file): 30 | gr.hier_block2.__init__(self, 31 | "ldpc_hier_encoder_bb", 32 | gr.io_signature(1, 1, gr.sizeof_char), # Input signature 33 | gr.io_signature(1, 1, gr.sizeof_char)) # Output signature 34 | 35 | # Define blocks and connect them 36 | encoder = ldpc.ldpc_encoder_bb(alist_file) 37 | K = encoder.get_K() 38 | N = encoder.get_N() 39 | str2Kvec = blocks.stream_to_vector(1, K) 40 | Nvec2str = blocks.vector_to_stream(1, N) 41 | 42 | self.connect(self, str2Kvec, encoder, Nvec2str, self) 43 | -------------------------------------------------------------------------------- /python/ldpc_hier_decoder_fb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2013 IIT Bombay. 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | from gnuradio import gr, blocks 23 | import ldpc 24 | 25 | class ldpc_hier_decoder_fb(gr.hier_block2): 26 | """ 27 | docstring for block ldpc_hier_decoder_fb 28 | """ 29 | def __init__(self, alist_file, sigma, max_iterations): 30 | gr.hier_block2.__init__(self, 31 | "ldpc_hier_decoder_fb", 32 | gr.io_signature(1, 1, gr.sizeof_float), # Input signature 33 | gr.io_signature(1, 1, gr.sizeof_char)) # Output signature 34 | 35 | # Define blocks and connect them 36 | decoder = ldpc.ldpc_decoder_fb(alist_file, 37 | sigma, max_iterations) 38 | K = decoder.get_K() 39 | N = decoder.get_N() 40 | str2Nvec = blocks.stream_to_vector(4, N) 41 | Kvec2str = blocks.vector_to_stream(1, K) 42 | 43 | self.connect(self, str2Nvec, decoder, Kvec2str, self) 44 | -------------------------------------------------------------------------------- /lib/ldpc_encoder_bb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_LDPC_ENCODER_BB_IMPL_H 22 | #define INCLUDED_LDPC_LDPC_ENCODER_BB_IMPL_H 23 | 24 | #include 25 | #include "cldpc.h" 26 | #include "alist.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | class ldpc_encoder_bb_impl : public ldpc_encoder_bb 32 | { 33 | private: 34 | alist d_list; 35 | cldpc d_code; 36 | int K; 37 | int N; 38 | 39 | public: 40 | ldpc_encoder_bb_impl(const char * alist_file); 41 | ~ldpc_encoder_bb_impl(); 42 | int get_K(); 43 | int get_N(); 44 | 45 | // Where all the action really happens 46 | int work(int noutput_items, 47 | gr_vector_const_void_star &input_items, 48 | gr_vector_void_star &output_items); 49 | }; 50 | 51 | } // namespace ldpc 52 | } // namespace gr 53 | 54 | #endif /* INCLUDED_LDPC_LDPC_ENCODER_BB_IMPL_H */ 55 | 56 | -------------------------------------------------------------------------------- /lib/ldpc_encoder_bf_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_LDPC_ENCODER_BF_IMPL_H 22 | #define INCLUDED_LDPC_LDPC_ENCODER_BF_IMPL_H 23 | 24 | #include 25 | #include "cldpc.h" 26 | #include "alist.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | class ldpc_encoder_bf_impl : public ldpc_encoder_bf 32 | { 33 | private: 34 | alist d_list; 35 | cldpc d_code; 36 | int K; 37 | int N; 38 | 39 | public: 40 | ldpc_encoder_bf_impl(const char * alist_file); 41 | ~ldpc_encoder_bf_impl(); 42 | int get_K(); 43 | int get_N(); 44 | 45 | // Where all the action really happens 46 | int work(int noutput_items, 47 | gr_vector_const_void_star &input_items, 48 | gr_vector_void_star &output_items); 49 | }; 50 | 51 | } // namespace ldpc 52 | } // namespace gr 53 | 54 | #endif /* INCLUDED_LDPC_LDPC_ENCODER_BF_IMPL_H */ 55 | 56 | -------------------------------------------------------------------------------- /cmake/Modules/GrPlatform.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PLATFORM_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup additional defines for OS types 27 | ######################################################################## 28 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 29 | set(LINUX TRUE) 30 | endif() 31 | 32 | if(LINUX AND EXISTS "/etc/debian_version") 33 | set(DEBIAN TRUE) 34 | endif() 35 | 36 | if(LINUX AND EXISTS "/etc/redhat-release") 37 | set(REDHAT TRUE) 38 | endif() 39 | 40 | ######################################################################## 41 | # when the library suffix should be 64 (applies to redhat linux family) 42 | ######################################################################## 43 | if(NOT DEFINED LIB_SUFFIX AND REDHAT AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$") 44 | set(LIB_SUFFIX 64) 45 | endif() 46 | set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix") 47 | -------------------------------------------------------------------------------- /include/ldpc/bsc_bb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_BSC_BB_H 23 | #define INCLUDED_LDPC_BSC_BB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API bsc_bb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual int get_nerr() = 0; 41 | 42 | /*! 43 | * \brief Return a shared_ptr to a new instance of ldpc::bsc_bb. 44 | * 45 | * To avoid accidental use of raw pointers, ldpc::bsc_bb's 46 | * constructor is in a private implementation 47 | * class. ldpc::bsc_bb::make is the public interface for 48 | * creating new instances. 49 | */ 50 | static sptr make(int vlen, float epsilon); 51 | }; 52 | 53 | } // namespace ldpc 54 | } // namespace gr 55 | 56 | #endif /* INCLUDED_LDPC_BSC_BB_H */ 57 | 58 | -------------------------------------------------------------------------------- /include/ldpc/copy_bb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_COPY_BB_H 23 | #define INCLUDED_LDPC_COPY_BB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API copy_bb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual size_t get_vlen() = 0; 41 | 42 | /*! 43 | * \brief Return a shared_ptr to a new instance of ldpc::copy_bb. 44 | * 45 | * To avoid accidental use of raw pointers, ldpc::copy_bb's 46 | * constructor is in a private implementation 47 | * class. ldpc::copy_bb::make is the public interface for 48 | * creating new instances. 49 | */ 50 | static sptr make(size_t vlen); 51 | }; 52 | 53 | } // namespace ldpc 54 | } // namespace gr 55 | 56 | #endif /* INCLUDED_LDPC_COPY_BB_H */ 57 | 58 | -------------------------------------------------------------------------------- /include/ldpc/lh_detector_fb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_LH_DETECTOR_FB_H 23 | #define INCLUDED_LDPC_LH_DETECTOR_FB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API lh_detector_fb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | 41 | /*! 42 | * \brief Return a shared_ptr to a new instance of ldpc::lh_detector_fb. 43 | * 44 | * To avoid accidental use of raw pointers, ldpc::lh_detector_fb's 45 | * constructor is in a private implementation 46 | * class. ldpc::lh_detector_fb::make is the public interface for 47 | * creating new instances. 48 | */ 49 | static sptr make(); 50 | }; 51 | 52 | } // namespace ldpc 53 | } // namespace gr 54 | 55 | #endif /* INCLUDED_LDPC_LH_DETECTOR_FB_H */ 56 | 57 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Include python install macros 22 | ######################################################################## 23 | include(GrPython) 24 | if(NOT PYTHONINTERP_FOUND) 25 | return() 26 | endif() 27 | 28 | ######################################################################## 29 | # Install python sources 30 | ######################################################################## 31 | GR_PYTHON_INSTALL( 32 | FILES 33 | __init__.py 34 | ldpc_hier_encoder_bb.py 35 | ldpc_hier_decoder_fb.py 36 | DESTINATION ${GR_PYTHON_DIR}/ldpc 37 | ) 38 | 39 | ######################################################################## 40 | # Handle the unit tests 41 | ######################################################################## 42 | include(GrTest) 43 | 44 | set(GR_TEST_TARGET_DEPS gnuradio-ldpc) 45 | set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) 46 | GR_ADD_TEST(qa_copy_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_copy_bb.py) 47 | -------------------------------------------------------------------------------- /lib/ldpc_decoder_bb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_LDPC_DECODER_BB_IMPL_H 22 | #define INCLUDED_LDPC_LDPC_DECODER_BB_IMPL_H 23 | 24 | #include 25 | #include "alist.h" 26 | #include "cldpc.h" 27 | #include "xbp.h" 28 | 29 | namespace gr { 30 | namespace ldpc { 31 | 32 | class ldpc_decoder_bb_impl : public ldpc_decoder_bb 33 | { 34 | private: 35 | alist d_list; 36 | cldpc d_code; 37 | xbp d_spa; 38 | int N; 39 | int K; 40 | int n_iterations; 41 | 42 | public: 43 | ldpc_decoder_bb_impl(const char * alist_file, float epsilon, int max_iterations); 44 | ~ldpc_decoder_bb_impl(); 45 | int get_K(); 46 | int get_N(); 47 | int get_niterations(); 48 | 49 | // Where all the action really happens 50 | int work(int noutput_items, 51 | gr_vector_const_void_star &input_items, 52 | gr_vector_void_star &output_items); 53 | }; 54 | 55 | } // namespace ldpc 56 | } // namespace gr 57 | 58 | #endif /* INCLUDED_LDPC_LDPC_DECODER_BB_IMPL_H */ 59 | 60 | -------------------------------------------------------------------------------- /lib/ldpc_decoder_fb_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef INCLUDED_LDPC_LDPC_DECODER_FB_IMPL_H 22 | #define INCLUDED_LDPC_LDPC_DECODER_FB_IMPL_H 23 | 24 | #include 25 | #include "alist.h" 26 | #include "cldpc.h" 27 | #include "awgn_bp.h" 28 | 29 | namespace gr { 30 | namespace ldpc { 31 | 32 | class ldpc_decoder_fb_impl : public ldpc_decoder_fb 33 | { 34 | private: 35 | alist d_list; 36 | cldpc d_code; 37 | awgn_bp d_spa; 38 | int N; 39 | int K; 40 | int n_iterations; 41 | 42 | public: 43 | ldpc_decoder_fb_impl(const char * alist_file, float sigma, int max_iterations); 44 | ~ldpc_decoder_fb_impl(); 45 | int get_K(); 46 | int get_N(); 47 | int get_niterations(); 48 | 49 | // Where all the action really happens 50 | int work(int noutput_items, 51 | gr_vector_const_void_star &input_items, 52 | gr_vector_void_star &output_items); 53 | }; 54 | 55 | } // namespace ldpc 56 | } // namespace gr 57 | 58 | #endif /* INCLUDED_LDPC_LDPC_DECODER_FB_IMPL_H */ 59 | 60 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 IIT Bombay. 3 | # 4 | # This is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3, or (at your option) 7 | # any later version. 8 | # 9 | # This software is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this software; see the file COPYING. If not, write to 16 | # the Free Software Foundation, Inc., 51 Franklin Street, 17 | # Boston, MA 02110-1301, USA. 18 | # 19 | 20 | This software is a GNU Radio Out of Tree module implementing 21 | generinc encoder and decoder for LDPC codes. This module is 22 | developed as part of Google Summer of Code 2013, by Manu T S, 23 | under the mentorship of Dr-Ing. Jens Elsner. 24 | 25 | In case of bugs please report with the author. Author can be 26 | contacted through his email. 27 | 28 | - manu.t.sree@gmail.com 29 | 30 | ----------------------------------------------------------- 31 | 32 | Build Instructions 33 | 34 | ----------------------------------------------------------- 35 | 36 | (A) Using PyBOMBS 37 | ------------------- 38 | 39 | This assumes that you have installed GNU Radio using PyBOMBS 40 | 41 | Please get the pybombs recipe from 42 | - https://github.com/manuts/gr-ldpc/blob/master/gr-ldpc.lwr 43 | 44 | Run ./pybombs install gr-ldpc 45 | 46 | 47 | (B) Using cmake 48 | ------------------- 49 | 50 | Make sure that you have installed GNU Radio 51 | Run the following commands 52 | 53 | $ mkdir $(builddir) 54 | $ cd $(builddir) 55 | $ cmake [OPTIONS] $(srcdir) 56 | $ make 57 | $ make test 58 | $ sudo make install 59 | -------------------------------------------------------------------------------- /include/ldpc/ldpc_encoder_bf.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_LDPC_ENCODER_BF_H 23 | #define INCLUDED_LDPC_LDPC_ENCODER_BF_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API ldpc_encoder_bf : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual int get_K() = 0; 41 | virtual int get_N() = 0; 42 | 43 | /*! 44 | * \brief Return a shared_ptr to a new instance of ldpc::ldpc_encoder_bf. 45 | * 46 | * To avoid accidental use of raw pointers, ldpc::ldpc_encoder_bf's 47 | * constructor is in a private implementation 48 | * class. ldpc::ldpc_encoder_bf::make is the public interface for 49 | * creating new instances. 50 | */ 51 | static sptr make(const char * alist_file); 52 | }; 53 | 54 | } // namespace ldpc 55 | } // namespace gr 56 | 57 | #endif /* INCLUDED_LDPC_LDPC_ENCODER_BF_H */ 58 | 59 | -------------------------------------------------------------------------------- /include/ldpc/ldpc_encoder_bb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_LDPC_ENCODER_BB_H 23 | #define INCLUDED_LDPC_LDPC_ENCODER_BB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API ldpc_encoder_bb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual int get_K() = 0; 41 | virtual int get_N() = 0; 42 | 43 | /*! 44 | * \brief Return a shared_ptr to a new instance of ldpc::ldpc_encoder_bb. 45 | * 46 | * To avoid accidental use of raw pointers, ldpc::ldpc_encoder_bb's 47 | * constructor is in a private implementation 48 | * class. ldpc::ldpc_encoder_bb::make is the public interface for 49 | * creating new instances. 50 | */ 51 | static sptr make(const char * alist_file); 52 | }; 53 | 54 | } // namespace ldpc 55 | } // namespace gr 56 | 57 | #endif /* INCLUDED_LDPC_LDPC_ENCODER_BB_H */ 58 | 59 | -------------------------------------------------------------------------------- /include/ldpc/ldpc_decoder_bb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_LDPC_DECODER_BB_H 23 | #define INCLUDED_LDPC_LDPC_DECODER_BB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API ldpc_decoder_bb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual int get_K() = 0; 41 | virtual int get_N() = 0; 42 | virtual int get_niterations() = 0; 43 | 44 | /*! 45 | * \brief Return a shared_ptr to a new instance of ldpc::ldpc_decoder_bb. 46 | * 47 | * To avoid accidental use of raw pointers, ldpc::ldpc_decoder_bb's 48 | * constructor is in a private implementation 49 | * class. ldpc::ldpc_decoder_bb::make is the public interface for 50 | * creating new instances. 51 | */ 52 | static sptr make(const char * alist_file, float epsilon, int max_iterations); 53 | }; 54 | 55 | } // namespace ldpc 56 | } // namespace gr 57 | 58 | #endif /* INCLUDED_LDPC_LDPC_DECODER_BB_H */ 59 | 60 | -------------------------------------------------------------------------------- /include/ldpc/ldpc_decoder_fb.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | #ifndef INCLUDED_LDPC_LDPC_DECODER_FB_H 23 | #define INCLUDED_LDPC_LDPC_DECODER_FB_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | /*! 32 | * \brief <+description of block+> 33 | * \ingroup ldpc 34 | * 35 | */ 36 | class LDPC_API ldpc_decoder_fb : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | virtual int get_K() = 0; 41 | virtual int get_N() = 0; 42 | virtual int get_niterations() = 0; 43 | 44 | /*! 45 | * \brief Return a shared_ptr to a new instance of ldpc::ldpc_decoder_fb. 46 | * 47 | * To avoid accidental use of raw pointers, ldpc::ldpc_decoder_fb's 48 | * constructor is in a private implementation 49 | * class. ldpc::ldpc_decoder_fb::make is the public interface for 50 | * creating new instances. 51 | */ 52 | static sptr make(const char * alist_file, float sigma, int max_iterations); 53 | }; 54 | 55 | } // namespace ldpc 56 | } // namespace gr 57 | 58 | #endif /* INCLUDED_LDPC_LDPC_DECODER_FB_H */ 59 | 60 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/text.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Utilities for extracting text from generated classes. 23 | """ 24 | 25 | def is_string(txt): 26 | if isinstance(txt, str): 27 | return True 28 | try: 29 | if isinstance(txt, unicode): 30 | return True 31 | except NameError: 32 | pass 33 | return False 34 | 35 | def description(obj): 36 | if obj is None: 37 | return None 38 | return description_bit(obj).strip() 39 | 40 | def description_bit(obj): 41 | if hasattr(obj, 'content'): 42 | contents = [description_bit(item) for item in obj.content] 43 | result = ''.join(contents) 44 | elif hasattr(obj, 'content_'): 45 | contents = [description_bit(item) for item in obj.content_] 46 | result = ''.join(contents) 47 | elif hasattr(obj, 'value'): 48 | result = description_bit(obj.value) 49 | elif is_string(obj): 50 | return obj 51 | else: 52 | raise StandardError('Expecting a string or something with content, content_ or value attribute') 53 | # If this bit is a paragraph then add one some line breaks. 54 | if hasattr(obj, 'name') and obj.name == 'para': 55 | result += "\n\n" 56 | return result 57 | -------------------------------------------------------------------------------- /python/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2008,2009 Free Software Foundation, Inc. 3 | # 4 | # This application is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3, or (at your option) 7 | # any later version. 8 | # 9 | # This application is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License along 15 | # with this program; if not, write to the Free Software Foundation, Inc., 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | 19 | # The presence of this file turns this directory into a Python package 20 | 21 | ''' 22 | This is the GNU Radio LDPC module. Place your Python package 23 | description here (python/__init__.py). 24 | ''' 25 | 26 | # ---------------------------------------------------------------- 27 | # Temporary workaround for ticket:181 (swig+python problem) 28 | import sys 29 | _RTLD_GLOBAL = 0 30 | try: 31 | from dl import RTLD_GLOBAL as _RTLD_GLOBAL 32 | except ImportError: 33 | try: 34 | from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL 35 | except ImportError: 36 | pass 37 | 38 | if _RTLD_GLOBAL != 0: 39 | _dlopenflags = sys.getdlopenflags() 40 | sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) 41 | # ---------------------------------------------------------------- 42 | 43 | 44 | # import swig generated symbols into the ldpc namespace 45 | from ldpc_swig import * 46 | 47 | # import any pure python here 48 | from ldpc_hier_encoder_bb import ldpc_hier_encoder_bb 49 | from ldpc_hier_decoder_fb import ldpc_hier_decoder_fb 50 | 51 | 52 | # 53 | 54 | # ---------------------------------------------------------------- 55 | # Tail of workaround 56 | if _RTLD_GLOBAL != 0: 57 | sys.setdlopenflags(_dlopenflags) # Restore original flags 58 | # ---------------------------------------------------------------- 59 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Generated Mon Feb 9 19:08:05 2009 by generateDS.py. 5 | """ 6 | 7 | from xml.dom import minidom 8 | 9 | import os 10 | import sys 11 | import compound 12 | 13 | import indexsuper as supermod 14 | 15 | class DoxygenTypeSub(supermod.DoxygenType): 16 | def __init__(self, version=None, compound=None): 17 | supermod.DoxygenType.__init__(self, version, compound) 18 | 19 | def find_compounds_and_members(self, details): 20 | """ 21 | Returns a list of all compounds and their members which match details 22 | """ 23 | 24 | results = [] 25 | for compound in self.compound: 26 | members = compound.find_members(details) 27 | if members: 28 | results.append([compound, members]) 29 | else: 30 | if details.match(compound): 31 | results.append([compound, []]) 32 | 33 | return results 34 | 35 | supermod.DoxygenType.subclass = DoxygenTypeSub 36 | # end class DoxygenTypeSub 37 | 38 | 39 | class CompoundTypeSub(supermod.CompoundType): 40 | def __init__(self, kind=None, refid=None, name='', member=None): 41 | supermod.CompoundType.__init__(self, kind, refid, name, member) 42 | 43 | def find_members(self, details): 44 | """ 45 | Returns a list of all members which match details 46 | """ 47 | 48 | results = [] 49 | 50 | for member in self.member: 51 | if details.match(member): 52 | results.append(member) 53 | 54 | return results 55 | 56 | supermod.CompoundType.subclass = CompoundTypeSub 57 | # end class CompoundTypeSub 58 | 59 | 60 | class MemberTypeSub(supermod.MemberType): 61 | 62 | def __init__(self, kind=None, refid=None, name=''): 63 | supermod.MemberType.__init__(self, kind, refid, name) 64 | 65 | supermod.MemberType.subclass = MemberTypeSub 66 | # end class MemberTypeSub 67 | 68 | 69 | def parse(inFilename): 70 | 71 | doc = minidom.parse(inFilename) 72 | rootNode = doc.documentElement 73 | rootObj = supermod.DoxygenType.factory() 74 | rootObj.build(rootNode) 75 | 76 | return rootObj 77 | 78 | -------------------------------------------------------------------------------- /docs/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Create the doxygen configuration file 22 | ######################################################################## 23 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) 24 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) 25 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir) 26 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) 27 | 28 | set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) 29 | set(enable_html_docs YES) 30 | set(enable_latex_docs NO) 31 | set(enable_xml_docs YES) 32 | 33 | configure_file( 34 | ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 35 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 36 | @ONLY) 37 | 38 | set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html) 39 | 40 | ######################################################################## 41 | # Make and install doxygen docs 42 | ######################################################################## 43 | add_custom_command( 44 | OUTPUT ${BUILT_DIRS} 45 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 46 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 47 | COMMENT "Generating documentation with doxygen" 48 | ) 49 | 50 | add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS}) 51 | 52 | install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR}) 53 | -------------------------------------------------------------------------------- /lib/xtest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "cldpc.h" 7 | #include "alist.h" 8 | #include "xbp.h" 9 | #include 10 | 11 | int main () { 12 | std::string fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/my_peg2"; 13 | alist a(fname.c_str()); 14 | srand(time(NULL)); 15 | std::ifstream random("randoms"); 16 | float trans_prob = 0.07; 17 | cldpc code(a); 18 | xbp spa(a, trans_prob); 19 | spa.set_max_iterations(100); 20 | int K = code.dimension(); 21 | spa.set_K(K); 22 | int N = code.get_N(); 23 | std::cout << K << std::endl; 24 | std::vector in; 25 | in.resize(K); 26 | std::cout << std::endl; 27 | std::vector out, rx, data, tx; 28 | std::vector llr, rx_llr; 29 | std::stringstream ss; 30 | int niterations, nerr; 31 | bool match; 32 | int mat = 0; 33 | float X; 34 | std::string line; 35 | tx.resize(N); 36 | for ( int count = 0; count < 100; count++ ) { 37 | for ( int i = 0; i < K; i++ ) { 38 | in[i] = char(rand()%2); 39 | } 40 | nerr = 0; 41 | out = code.encode(in); 42 | float lim = trans_prob*10000; 43 | for ( int i = 0; i < N; i++ ) { 44 | X = rand()%10000; 45 | if ( X < lim ) { 46 | nerr++; 47 | if (out[i] == char(0)) 48 | tx[i] = char(1); 49 | else 50 | tx[i] = char(0); 51 | } 52 | else 53 | tx[i] = out[i]; 54 | } 55 | rx = spa.decode(tx, &niterations); 56 | data = code.get_systematic_bits(rx); 57 | match = true; 58 | for ( int i = 0; i < K; i++ ) { 59 | if ( data[i] != in[i] ) { 60 | match = false; 61 | break; 62 | } 63 | } 64 | if ( match ){ 65 | std::cout << count << "\t\tmat"; 66 | mat++; 67 | } 68 | else { 69 | std::cout << count << "\t**" <<"\tmis"; 70 | } 71 | std::cout << "\tnerr = " << nerr; 72 | std::cout << "\tniterations = " << niterations << std::endl; 73 | } 74 | std::cout << mat << std::endl; 75 | } 76 | -------------------------------------------------------------------------------- /lib/gf2vec.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class for GF2 vector algebra 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This is a class for handling GF2 vectors. 28 | * 29 | */ 30 | 31 | #ifndef GF2VEC_H 32 | #define GF2VEC_H 33 | #include 34 | 35 | class GF2Vec 36 | { 37 | //! The vector vec 38 | std::vector vec; 39 | 40 | //! Resize the vector 41 | void resize(int size); 42 | 43 | public: 44 | 45 | //! Default constructor 46 | GF2Vec() {} 47 | 48 | //! Constructs a vector of length "size" with all 0 entries 49 | GF2Vec(int size); 50 | 51 | //! Returns the vector 52 | std::vector get_vec(); 53 | 54 | //! Returns the size of the vector 55 | int size(); 56 | 57 | //! Resets the vector with the given input 58 | void set_vec(std::vector); 59 | 60 | //! Access the ith element 61 | char & operator [](int i); 62 | 63 | //! Overloading the operator '=' 64 | void operator=(GF2Vec x); 65 | 66 | //! Obtain a subvector between the indices i to j 67 | GF2Vec sub_vector(int i, int j); 68 | 69 | //! Overloading the operator '+' 70 | friend GF2Vec operator+(GF2Vec a, GF2Vec b); 71 | 72 | //! Overloading the operator '*' 73 | friend char operator*(GF2Vec a, GF2Vec b); 74 | 75 | //! Prints the vector 76 | void print_vec(); 77 | }; 78 | 79 | #endif // #ifndef GF2VEC_H 80 | -------------------------------------------------------------------------------- /swig/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Include swig generation macros 22 | ######################################################################## 23 | find_package(SWIG) 24 | find_package(PythonLibs) 25 | if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) 26 | return() 27 | endif() 28 | include(GrSwig) 29 | include(GrPython) 30 | 31 | ######################################################################## 32 | # Setup swig generation 33 | ######################################################################## 34 | foreach(incdir ${GNURADIO_RUNTIME_INCLUDE_DIRS}) 35 | list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gnuradio/swig) 36 | endforeach(incdir) 37 | 38 | set(GR_SWIG_LIBRARIES gnuradio-ldpc) 39 | set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/ldpc_swig_doc.i) 40 | set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include) 41 | 42 | GR_SWIG_MAKE(ldpc_swig ldpc_swig.i) 43 | 44 | ######################################################################## 45 | # Install the build swig module 46 | ######################################################################## 47 | GR_SWIG_INSTALL(TARGETS ldpc_swig DESTINATION ${GR_PYTHON_DIR}/ldpc) 48 | 49 | ######################################################################## 50 | # Install swig .i files for development 51 | ######################################################################## 52 | install( 53 | FILES 54 | ldpc_swig.i 55 | ${CMAKE_CURRENT_BINARY_DIR}/ldpc_swig_doc.i 56 | DESTINATION ${GR_INCLUDE_DIR}/ldpc/swig 57 | ) 58 | -------------------------------------------------------------------------------- /lib/lh_detector_fb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "lh_detector_fb_impl.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | lh_detector_fb::sptr 32 | lh_detector_fb::make() 33 | { 34 | return gnuradio::get_initial_sptr 35 | (new lh_detector_fb_impl()); 36 | } 37 | 38 | /* 39 | * The private constructor 40 | */ 41 | lh_detector_fb_impl::lh_detector_fb_impl() 42 | : gr::sync_block("lh_detector_fb", 43 | gr::io_signature::make(1, 1, sizeof(float)), 44 | gr::io_signature::make(1, 1, sizeof(char))) 45 | {} 46 | 47 | /* 48 | * Our virtual destructor. 49 | */ 50 | lh_detector_fb_impl::~lh_detector_fb_impl() 51 | { 52 | } 53 | 54 | int 55 | lh_detector_fb_impl::work(int noutput_items, 56 | gr_vector_const_void_star &input_items, 57 | gr_vector_void_star &output_items) 58 | { 59 | const float *in = (const float *) input_items[0]; 60 | char *out = (char *) output_items[0]; 61 | 62 | // Do <+signal processing+> 63 | for (int i = 0; i < noutput_items; i++) { 64 | if (in[i] < 0.0) { 65 | out[i] = char(1); 66 | } 67 | else { 68 | out[i] = char(0); 69 | } 70 | } 71 | 72 | // Tell runtime system how many output items we produced. 73 | return noutput_items; 74 | } 75 | 76 | } /* namespace ldpc */ 77 | } /* namespace gr */ 78 | 79 | -------------------------------------------------------------------------------- /lib/copy_bb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "copy_bb_impl.h" 27 | #include 28 | 29 | namespace gr { 30 | namespace ldpc { 31 | 32 | copy_bb::sptr 33 | copy_bb::make(size_t vlen) 34 | { 35 | return gnuradio::get_initial_sptr 36 | (new copy_bb_impl(vlen)); 37 | } 38 | 39 | /* 40 | * The private constructor 41 | */ 42 | copy_bb_impl::copy_bb_impl(size_t vlen) 43 | : gr::sync_block("copy_bb", 44 | gr::io_signature::make(0, 0, 0), 45 | gr::io_signature::make(0, 0, 0)), d_vlen(vlen) 46 | { 47 | set_input_signature(gr::io_signature::make(1, 1, sizeof(char) * d_vlen)); 48 | set_output_signature(gr::io_signature::make(1, 1, sizeof(char) * d_vlen)); 49 | } 50 | 51 | /* 52 | * Our virtual destructor. 53 | */ 54 | copy_bb_impl::~copy_bb_impl() 55 | { 56 | } 57 | 58 | size_t 59 | copy_bb_impl::get_vlen() { 60 | return d_vlen; 61 | } 62 | 63 | int 64 | copy_bb_impl::work(int noutput_items, 65 | gr_vector_const_void_star &input_items, 66 | gr_vector_void_star &output_items) 67 | { 68 | const char *in = (const char *) input_items[0]; 69 | char *out = (char *) output_items[0]; 70 | 71 | memcpy(out, in, noutput_items * d_vlen); 72 | 73 | // Tell runtime system how many output items we produced. 74 | return noutput_items; 75 | } 76 | 77 | } /* namespace ldpc */ 78 | } /* namespace gr */ 79 | 80 | -------------------------------------------------------------------------------- /lib/awgn_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "cldpc.h" 7 | #include "alist.h" 8 | #include "awgn_bp.h" 9 | #include 10 | 11 | int main () { 12 | std::string fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963"; 13 | alist a(fname.c_str()); 14 | srand(time(NULL)); 15 | std::ifstream random("randoms"); 16 | float trans_prob = 0.6; 17 | cldpc code(a); 18 | awgn_bp spa(a, trans_prob); 19 | spa.set_max_iterations(100); 20 | int K = code.dimension(); 21 | spa.set_K(K); 22 | int N = code.get_N(); 23 | std::cout << K << std::endl; 24 | std::vector in; 25 | in.resize(K); 26 | std::cout << std::endl; 27 | std::vector out, rx, data; 28 | std::vector llr, rx_llr, tx; 29 | std::stringstream ss; 30 | int niterations, nerr; 31 | bool match; 32 | int mat = 0; 33 | float X; 34 | std::string line; 35 | tx.resize(N); 36 | for ( int count = 0; count < 100; count++ ) { 37 | for ( int i = 0; i < K; i++ ) { 38 | in[i] = char(rand()%2); 39 | } 40 | nerr = 0; 41 | out = code.encode(in); 42 | for ( int i = 0; i < N; i++ ) { 43 | getline(random, line); 44 | ss << line; 45 | ss >> X; 46 | ss.seekg(0, std::ios::end); 47 | ss.clear(); 48 | if (out[i] == char(0)) { 49 | tx[i] = 1.0 + X; 50 | if ( X < -1.0) 51 | nerr++; 52 | } 53 | else { 54 | tx[i] = -1.0 + X; 55 | if ( X > 1.0) 56 | nerr++; 57 | } 58 | } 59 | rx = spa.decode(tx, &niterations); 60 | data = code.get_systematic_bits(rx); 61 | match = true; 62 | for ( int i = 0; i < K; i++ ) { 63 | if ( data[i] != in[i] ) { 64 | match = false; 65 | break; 66 | } 67 | } 68 | if ( match ){ 69 | std::cout << count << "\t\tmat"; 70 | mat++; 71 | } 72 | else { 73 | std::cout << count << "\t**" <<"\tmis"; 74 | } 75 | std::cout << "\tnerr = " << nerr; 76 | std::cout << "\tniterations = " << niterations << std::endl; 77 | } 78 | std::cout << mat << std::endl; 79 | } 80 | -------------------------------------------------------------------------------- /lib/gf2vec.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Implementation of a class for GF2 vector algebra 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | */ 27 | 28 | #include "gf2vec.h" 29 | #include 30 | 31 | GF2Vec::GF2Vec(int size) { 32 | vec.resize(size); 33 | for( int i = 0; i < size; i++) { 34 | vec[i] = char(0); 35 | } 36 | } 37 | 38 | void GF2Vec::set_vec(const std::vector in) { 39 | resize(in.size()); 40 | for ( int i = 0; i < vec.size(); i++ ) { 41 | vec[i] = in[i]; 42 | } 43 | } 44 | 45 | std::vector GF2Vec::get_vec(){ 46 | return vec; 47 | } 48 | 49 | int GF2Vec::size() { 50 | return vec.size(); 51 | } 52 | 53 | char & GF2Vec::operator[](int i) { 54 | return vec[i]; 55 | } 56 | 57 | GF2Vec operator+(GF2Vec a, GF2Vec b) { 58 | GF2Vec sum(a.size()); 59 | for( int i = 0; i < sum.size(); i++) { 60 | sum[i] = a[i] ^ b[i]; 61 | } 62 | return sum; 63 | } 64 | 65 | GF2Vec GF2Vec::sub_vector(int from, int to) { 66 | int len = to - from; 67 | GF2Vec x(len); 68 | for ( int i = 0; i < len; i++ ) { 69 | x[i] = vec[i + from]; 70 | } 71 | return x; 72 | } 73 | 74 | char operator*(GF2Vec a, GF2Vec b) { 75 | char sum; 76 | sum = char(0); 77 | for (int i = 0; i < a.size(); i++) { 78 | sum = sum ^ ( a[i] & b[i] ); 79 | } 80 | return sum; 81 | } 82 | 83 | void GF2Vec::print_vec() { 84 | for (int i = 0; i < size(); i++ ) { 85 | std::cout << int(vec[i]) << " "; 86 | } 87 | std::cout << '\n'; 88 | } 89 | 90 | void GF2Vec::resize(int size) { 91 | vec.resize(size); 92 | } 93 | 94 | void GF2Vec::operator=(GF2Vec x) { 95 | set_vec(x.get_vec()); 96 | } 97 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Python interface to contents of doxygen xml documentation. 23 | 24 | Example use: 25 | See the contents of the example folder for the C++ and 26 | doxygen-generated xml used in this example. 27 | 28 | >>> # Parse the doxygen docs. 29 | >>> import os 30 | >>> this_dir = os.path.dirname(globals()['__file__']) 31 | >>> xml_path = this_dir + "/example/xml/" 32 | >>> di = DoxyIndex(xml_path) 33 | 34 | Get a list of all top-level objects. 35 | 36 | >>> print([mem.name() for mem in di.members()]) 37 | [u'Aadvark', u'aadvarky_enough', u'main'] 38 | 39 | Get all functions. 40 | 41 | >>> print([mem.name() for mem in di.in_category(DoxyFunction)]) 42 | [u'aadvarky_enough', u'main'] 43 | 44 | Check if an object is present. 45 | 46 | >>> di.has_member(u'Aadvark') 47 | True 48 | >>> di.has_member(u'Fish') 49 | False 50 | 51 | Get an item by name and check its properties. 52 | 53 | >>> aad = di.get_member(u'Aadvark') 54 | >>> print(aad.brief_description) 55 | Models the mammal Aadvark. 56 | >>> print(aad.detailed_description) 57 | Sadly the model is incomplete and cannot capture all aspects of an aadvark yet. 58 | 59 | This line is uninformative and is only to test line breaks in the comments. 60 | >>> [mem.name() for mem in aad.members()] 61 | [u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness'] 62 | >>> aad.get_member(u'print').brief_description 63 | u'Outputs the vital aadvark statistics.' 64 | 65 | """ 66 | 67 | from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther 68 | 69 | def _test(): 70 | import os 71 | this_dir = os.path.dirname(globals()['__file__']) 72 | xml_path = this_dir + "/example/xml/" 73 | di = DoxyIndex(xml_path) 74 | # Get the Aadvark class 75 | aad = di.get_member('Aadvark') 76 | aad.brief_description 77 | import doctest 78 | return doctest.testmod() 79 | 80 | if __name__ == "__main__": 81 | _test() 82 | 83 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Setup library 22 | ######################################################################## 23 | include(GrPlatform) #define LIB_SUFFIX 24 | 25 | include_directories(${Boost_INCLUDE_DIR}) 26 | link_directories(${Boost_LIBRARY_DIRS}) 27 | 28 | list(APPEND ldpc_sources 29 | gf2mat.cc 30 | gf2vec.cc 31 | cldpc.cc 32 | alist.cc 33 | xbp.cc 34 | awgn_bp.cc 35 | copy_bb_impl.cc 36 | ldpc_encoder_bb_impl.cc 37 | ldpc_decoder_bb_impl.cc 38 | bsc_bb_impl.cc 39 | ldpc_encoder_bf_impl.cc 40 | ldpc_decoder_fb_impl.cc 41 | lh_detector_fb_impl.cc 42 | ) 43 | 44 | add_library(gnuradio-ldpc SHARED ${ldpc_sources}) 45 | target_link_libraries(gnuradio-ldpc ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) 46 | set_target_properties(gnuradio-ldpc PROPERTIES DEFINE_SYMBOL "gnuradio_ldpc_EXPORTS") 47 | 48 | ######################################################################## 49 | # Install built library files 50 | ######################################################################## 51 | install(TARGETS gnuradio-ldpc 52 | LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file 53 | ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file 54 | RUNTIME DESTINATION bin # .dll file 55 | ) 56 | 57 | ######################################################################## 58 | # Build and register unit test 59 | ######################################################################## 60 | include(GrTest) 61 | 62 | include_directories(${CPPUNIT_INCLUDE_DIRS}) 63 | 64 | list(APPEND test_ldpc_sources 65 | ${CMAKE_CURRENT_SOURCE_DIR}/test_ldpc.cc 66 | ${CMAKE_CURRENT_SOURCE_DIR}/qa_ldpc.cc 67 | ) 68 | 69 | add_executable(test-ldpc ${test_ldpc_sources}) 70 | 71 | target_link_libraries( 72 | test-ldpc 73 | ${GNURADIO_RUNTIME_LIBRARIES} 74 | ${Boost_LIBRARIES} 75 | ${CPPUNIT_LIBRARIES} 76 | gnuradio-ldpc 77 | ) 78 | 79 | GR_ADD_TEST(test_ldpc test-ldpc) 80 | -------------------------------------------------------------------------------- /python/test_bsc.py: -------------------------------------------------------------------------------- 1 | from gnuradio import gr, digital, blocks, analog 2 | import ldpc 3 | import numpy as np 4 | import random, array, copy 5 | 6 | class my_tb(gr.top_block): 7 | def __init__(self, fname, epsilon, max_iterations): 8 | gr.top_block.__init__(self) 9 | self.src = blocks.vector_source_b(()) 10 | print "initializing encoder" 11 | self.encoder = ldpc.ldpc_encoder_bb(fname) 12 | print "encoder initialized" 13 | self.K = self.encoder.get_K() 14 | self.N = self.encoder.get_N() 15 | print self.K 16 | print self.N 17 | str2Kvec = blocks.stream_to_vector(1, self.K) 18 | chk2symb = digital.chunks_to_symbols_bf(([1, -1]), 1) 19 | str2Nvec = blocks.stream_to_vector(4, self.N) 20 | self.channel = ldpc.bsc_bb(self.N, epsilon) 21 | self.decoder = ldpc.ldpc_decoder_bb(fname, epsilon, max_iterations) 22 | print "decoder initialized" 23 | self.noise = analog.noise_source_f(analog.GR_GAUSSIAN, epsilon, 0) 24 | self.adder = blocks.add_vff(1) 25 | Kvec2str = blocks.vector_to_stream(1, self.K) 26 | Nvec2str = blocks.vector_to_stream(4, self.N) 27 | self.dst = blocks.vector_sink_b() 28 | self.connect(self.src, str2Kvec, self.encoder, self.channel, 29 | self.decoder, Kvec2str, self.dst) 30 | 31 | def main(): 32 | fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963" 33 | epsilon = 0.06 34 | max_iterations = 100 35 | print "initializing top block" 36 | tb = my_tb(fname, epsilon, max_iterations) 37 | K = tb.K 38 | N = tb.N 39 | match = 0 40 | mismatch = 0 41 | datatpl = array.array('B') 42 | for i in range(K): 43 | datatpl.append(0) 44 | f = open('output', 'w') 45 | g = open('data', 'w') 46 | for i in range(100): 47 | txdata = () 48 | for i in range(K): 49 | X = random.randint(0, 1) 50 | if X == 1: 51 | datatpl[i] = 1 52 | txdata = txdata + (1, ) 53 | else: 54 | datatpl[i] = 0 55 | txdata = txdata + (0, ) 56 | g.write("tx data\n") 57 | g.write(str(datatpl) + "\n") 58 | tb.src.set_data(datatpl) 59 | tb.run() 60 | rx_tpl = tb.dst.data() 61 | tb.dst.reset() 62 | g.write("rx data\n") 63 | g.write(str(rx_tpl) + "\n") 64 | if np.array_equal(txdata, rx_tpl): 65 | match += 1 66 | else: 67 | mismatch += 1 68 | _str = str(np.array_equal(txdata, rx_tpl)) 69 | _str = _str + "\t" + str(tb.channel.get_nerr()) + "\t" + str(tb.decoder.get_niterations()) + "\n" 70 | f.write(_str) 71 | 72 | if __name__ == '__main__': 73 | try: 74 | main() 75 | except KeyboardInterrupt: 76 | pass 77 | -------------------------------------------------------------------------------- /lib/bsc_bb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 <+YOU OR YOUR COMPANY+>. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "bsc_bb_impl.h" 27 | #include 28 | #include 29 | 30 | namespace gr { 31 | namespace ldpc { 32 | 33 | bsc_bb::sptr 34 | bsc_bb::make(int vlen, float epsilon) 35 | { 36 | return gnuradio::get_initial_sptr 37 | (new bsc_bb_impl(vlen, epsilon)); 38 | } 39 | 40 | /* 41 | * The private constructor 42 | */ 43 | bsc_bb_impl::bsc_bb_impl(int vlen, float epsilon) 44 | : gr::sync_block("bsc_bb", 45 | gr::io_signature::make(1, 1, sizeof(char) * vlen), 46 | gr::io_signature::make(1, 1, sizeof(char) * vlen)), d_vlen(vlen) 47 | { 48 | limit = 100000*epsilon; 49 | } 50 | 51 | /* 52 | * Our virtual destructor. 53 | */ 54 | bsc_bb_impl::~bsc_bb_impl() 55 | { 56 | } 57 | 58 | int 59 | bsc_bb_impl::get_nerr() { 60 | return nerr; 61 | } 62 | 63 | int 64 | bsc_bb_impl::work(int noutput_items, 65 | gr_vector_const_void_star &input_items, 66 | gr_vector_void_star &output_items) 67 | { 68 | const char *in = (const char *) input_items[0]; 69 | char *out = (char *) output_items[0]; 70 | 71 | // Do <+signal processing+> 72 | srand(time(NULL)); 73 | nerr = 0; 74 | for ( int i = 0; i < d_vlen; i++ ) { 75 | X = rand()%100000; 76 | if ( X > limit ) { 77 | out[i] = in[i]; 78 | } 79 | else { 80 | nerr++; 81 | if ( in[i] == char(0) ) { 82 | out[i] = char(1); 83 | } 84 | else { 85 | out[i] = char(0); 86 | } 87 | } 88 | } 89 | 90 | // Tell runtime system how many output items we produced. 91 | return noutput_items; 92 | } 93 | 94 | } /* namespace ldpc */ 95 | } /* namespace gr */ 96 | 97 | -------------------------------------------------------------------------------- /lib/ldpc_encoder_bb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "ldpc_encoder_bb_impl.h" 27 | #include 28 | 29 | namespace gr { 30 | namespace ldpc { 31 | 32 | ldpc_encoder_bb::sptr 33 | ldpc_encoder_bb::make(const char * alist_file) 34 | { 35 | return gnuradio::get_initial_sptr 36 | (new ldpc_encoder_bb_impl(alist_file)); 37 | } 38 | 39 | /* 40 | * The private constructor 41 | */ 42 | ldpc_encoder_bb_impl::ldpc_encoder_bb_impl(const char * alist_file) 43 | : gr::sync_block("ldpc_encoder_bb", 44 | gr::io_signature::make(0, 0, 0), 45 | gr::io_signature::make(0, 0, 0)) 46 | { 47 | d_list.read(alist_file); 48 | d_code.set_alist(d_list); 49 | K = d_code.dimension(); 50 | N = d_code.get_N(); 51 | set_input_signature(gr::io_signature::make(1, 1, sizeof(char) * K)); 52 | set_output_signature(gr::io_signature::make(1, 1, sizeof(char) * N)); 53 | } 54 | 55 | /* 56 | * Our virtual destructor. 57 | */ 58 | ldpc_encoder_bb_impl::~ldpc_encoder_bb_impl() 59 | { 60 | } 61 | 62 | int 63 | ldpc_encoder_bb_impl::get_K() { 64 | return K; 65 | } 66 | 67 | int 68 | ldpc_encoder_bb_impl::get_N() { 69 | return N; 70 | } 71 | 72 | int 73 | ldpc_encoder_bb_impl::work(int noutput_items, 74 | gr_vector_const_void_star &input_items, 75 | gr_vector_void_star &output_items) 76 | { 77 | const char *in = (const char *) input_items[0]; 78 | char *out = (char *) output_items[0]; 79 | 80 | // Do <+signal processing+> 81 | std::vector data, code; 82 | data.resize(K); 83 | 84 | for (int j = 0; j < noutput_items; j++) { 85 | 86 | for ( int i = 0; i < K; i++ ) { 87 | data[i] = in[i + (j*K)]; 88 | } 89 | 90 | code = d_code.encode(data); 91 | for ( int i = 0; i < N; i++ ) { 92 | out[i + (j*N)] = code[i]; 93 | } 94 | } 95 | // Tell runtime system how many output items we produced. 96 | return noutput_items; 97 | } 98 | 99 | } /* namespace ldpc */ 100 | } /* namespace gr */ 101 | 102 | -------------------------------------------------------------------------------- /lib/ldpc_encoder_bf_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "ldpc_encoder_bf_impl.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | ldpc_encoder_bf::sptr 32 | ldpc_encoder_bf::make(const char * alist_file) 33 | { 34 | return gnuradio::get_initial_sptr 35 | (new ldpc_encoder_bf_impl(alist_file)); 36 | } 37 | 38 | /* 39 | * The private constructor 40 | */ 41 | ldpc_encoder_bf_impl::ldpc_encoder_bf_impl(const char * alist_file) 42 | : gr::sync_block("ldpc_encoder_bb", 43 | gr::io_signature::make(0, 0, 0), 44 | gr::io_signature::make(0, 0, 0)) 45 | { 46 | d_list.read(alist_file); 47 | d_code.set_alist(d_list); 48 | K = d_code.dimension(); 49 | N = d_code.get_N(); 50 | set_input_signature(gr::io_signature::make(1, 1, sizeof(char) * K)); 51 | set_output_signature(gr::io_signature::make(1, 1, sizeof(float) * N)); 52 | } 53 | 54 | /* 55 | * Our virtual destructor. 56 | */ 57 | ldpc_encoder_bf_impl::~ldpc_encoder_bf_impl() 58 | { 59 | } 60 | 61 | int 62 | ldpc_encoder_bf_impl::get_K() { 63 | return K; 64 | } 65 | 66 | int 67 | ldpc_encoder_bf_impl::get_N() { 68 | return N; 69 | } 70 | 71 | int 72 | ldpc_encoder_bf_impl::work(int noutput_items, 73 | gr_vector_const_void_star &input_items, 74 | gr_vector_void_star &output_items) 75 | { 76 | const char *in = (const char *) input_items[0]; 77 | float *out = (float *) output_items[0]; 78 | 79 | // Do <+signal processing+> 80 | std::vector data, code; 81 | data.resize(K); 82 | for (int j = 0; j < noutput_items; j++) { 83 | for ( int i = 0; i < K; i++ ) { 84 | data[i] = in[i + (j*K)]; 85 | } 86 | code = d_code.encode(data); 87 | for ( int i = 0; i < N; i++ ) { 88 | if ( code[i] == char(0) ) { 89 | out[i + (j*N)] = 1.0; 90 | } 91 | else { 92 | out[i + (j*N)] = -1.0; 93 | } 94 | } 95 | } 96 | 97 | // Tell runtime system how many output items we produced. 98 | return noutput_items; 99 | } 100 | 101 | } /* namespace ldpc */ 102 | } /* namespace gr */ 103 | 104 | -------------------------------------------------------------------------------- /lib/ldpc_decoder_bb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "ldpc_decoder_bb_impl.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | ldpc_decoder_bb::sptr 32 | ldpc_decoder_bb::make(const char * alist_file, float epsilon, int max_iterations) 33 | { 34 | return gnuradio::get_initial_sptr 35 | (new ldpc_decoder_bb_impl(alist_file, epsilon, max_iterations)); 36 | } 37 | 38 | /* 39 | * The private constructor 40 | */ 41 | ldpc_decoder_bb_impl::ldpc_decoder_bb_impl(const char * alist_file, float epsilon, int max_iterations) 42 | : gr::sync_block("ldpc_decoder_bb", 43 | gr::io_signature::make(0, 0, 0), 44 | gr::io_signature::make(0, 0, 0)) 45 | { 46 | d_list.read(alist_file); 47 | d_code.set_alist(d_list); 48 | d_spa.set_alist_sigma(d_list, epsilon); 49 | K = d_code.dimension(); 50 | N = d_code.get_N(); 51 | d_spa.set_K(K); 52 | d_spa.set_max_iterations(max_iterations); 53 | set_input_signature(gr::io_signature::make(1, 1, sizeof(char) * N)); 54 | set_output_signature(gr::io_signature::make(1, 1, sizeof(char) * K)); 55 | } 56 | 57 | /* 58 | * Our virtual destructor. 59 | */ 60 | ldpc_decoder_bb_impl::~ldpc_decoder_bb_impl() 61 | { 62 | } 63 | 64 | int 65 | ldpc_decoder_bb_impl::get_K() { 66 | return K; 67 | } 68 | 69 | int 70 | ldpc_decoder_bb_impl::get_N() { 71 | return N; 72 | } 73 | 74 | int 75 | ldpc_decoder_bb_impl::get_niterations () { 76 | return n_iterations; 77 | } 78 | 79 | int 80 | ldpc_decoder_bb_impl::work(int noutput_items, 81 | gr_vector_const_void_star &input_items, 82 | gr_vector_void_star &output_items) 83 | { 84 | const char *in = (const char *) input_items[0]; 85 | char *out = (char *) output_items[0]; 86 | 87 | // Do <+signal processing+> 88 | std::vector rx; 89 | std::vector estimate, data; 90 | rx.resize(N); 91 | for (int j = 0; j < noutput_items; j++) { 92 | for ( int i = 0; i < N; i++ ) { 93 | rx[i] = in[i + (j*N)]; 94 | } 95 | estimate = d_spa.decode(rx, &n_iterations); 96 | data = d_code.get_systematic_bits(estimate); 97 | for ( int i = 0; i < K; i++ ) { 98 | out[i + (j*K)] = data[i]; 99 | } 100 | } 101 | 102 | // Tell runtime system how many output items we produced. 103 | return noutput_items; 104 | } 105 | 106 | } /* namespace ldpc */ 107 | } /* namespace gr */ 108 | 109 | -------------------------------------------------------------------------------- /lib/ldpc_decoder_fb_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2013 IIT Bombay. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * This software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this software; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "ldpc_decoder_fb_impl.h" 27 | 28 | namespace gr { 29 | namespace ldpc { 30 | 31 | ldpc_decoder_fb::sptr 32 | ldpc_decoder_fb::make(const char * alist_file, float sigma, int max_iterations) 33 | { 34 | return gnuradio::get_initial_sptr 35 | (new ldpc_decoder_fb_impl(alist_file, sigma, max_iterations)); 36 | } 37 | 38 | /* 39 | * The private constructor 40 | */ 41 | ldpc_decoder_fb_impl::ldpc_decoder_fb_impl(const char * alist_file, float sigma, int max_iterations) 42 | : gr::sync_block("ldpc_decoder_fb", 43 | gr::io_signature::make(0, 0, 0), 44 | gr::io_signature::make(0, 0, 0)) 45 | { 46 | d_list.read(alist_file); 47 | d_code.set_alist(d_list); 48 | d_spa.set_alist_sigma(d_list, sigma); 49 | K = d_code.dimension(); 50 | N = d_code.get_N(); 51 | d_spa.set_K(K); 52 | d_spa.set_max_iterations(max_iterations); 53 | set_input_signature(gr::io_signature::make(1, 1, sizeof(float) * N)); 54 | set_output_signature(gr::io_signature::make(1, 1, sizeof(char) * K)); 55 | } 56 | 57 | /* 58 | * Our virtual destructor. 59 | */ 60 | ldpc_decoder_fb_impl::~ldpc_decoder_fb_impl() 61 | { 62 | } 63 | 64 | int 65 | ldpc_decoder_fb_impl::get_K() { 66 | return K; 67 | } 68 | 69 | int 70 | ldpc_decoder_fb_impl::get_N() { 71 | return N; 72 | } 73 | 74 | int 75 | ldpc_decoder_fb_impl::get_niterations () { 76 | return n_iterations; 77 | } 78 | 79 | int 80 | ldpc_decoder_fb_impl::work(int noutput_items, 81 | gr_vector_const_void_star &input_items, 82 | gr_vector_void_star &output_items) 83 | { 84 | const float *in = (const float *) input_items[0]; 85 | char *out = (char *) output_items[0]; 86 | 87 | // Do <+signal processing+> 88 | std::vector rx; 89 | std::vector estimate, data; 90 | rx.resize(N); 91 | for (int j = 0; j < noutput_items; j++) { 92 | for ( int i = 0; i < N; i++ ) { 93 | rx[i] = in[i + (j*N)]; 94 | } 95 | estimate = d_spa.decode(rx, &n_iterations); 96 | data = d_code.get_systematic_bits(estimate); 97 | for ( int i = 0; i < K; i++ ) { 98 | out[i + (j*K)] = data[i]; 99 | } 100 | } 101 | 102 | // Tell runtime system how many output items we produced. 103 | return noutput_items; 104 | } 105 | 106 | } /* namespace ldpc */ 107 | } /* namespace gr */ 108 | 109 | -------------------------------------------------------------------------------- /lib/gf2mat.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class for GF2 matrix algebra 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This is a class for handling GF2 matrices. 28 | * 29 | */ 30 | 31 | #ifndef GF2MAT_H 32 | #define GF2MAT_H 33 | #include 34 | #include "gf2vec.h" 35 | #include "alist.h" 36 | 37 | class GF2Mat 38 | { 39 | //! The matrix H 40 | std::vector < std::vector > H; 41 | 42 | //! Number of rows in H 43 | int M; 44 | 45 | //! Number of columns in H 46 | int N; 47 | 48 | public: 49 | //! Default constructor 50 | GF2Mat() {}; 51 | 52 | //! Construct an M x N matrix with all 0 entries 53 | GF2Mat(int m, int n); 54 | 55 | //! Loads the matrix from alist _list 56 | GF2Mat(alist _list); 57 | 58 | //! Initializes the class from a 2-D vector X 59 | GF2Mat(std::vector > X); 60 | 61 | //! Returns the variable M 62 | int get_M(); 63 | 64 | //! Returns the variable N 65 | int get_N(); 66 | 67 | //! Set the element at (i, j) coordinate to val 68 | void set_element(int i, int j, char val); 69 | 70 | //! Returns the element at coordinate (i, j) 71 | char get_element(int i, int j); 72 | 73 | //! Returns the ith row 74 | GF2Vec get_row(int i); 75 | 76 | //! Returns the ith column 77 | GF2Vec get_col(int i); 78 | 79 | //! Returns the ith row 80 | GF2Vec operator[](int i); 81 | 82 | //! Prints the matrix H 83 | void print_matrix(); 84 | 85 | //! Sets the ith column with the given vector 86 | void set_col(int i, GF2Vec vec); 87 | 88 | //! Sets the ith row with the given vector 89 | void set_row(int i, GF2Vec vec); 90 | 91 | //! Swaps columns i and j 92 | void swap_cols(int i, int j); 93 | 94 | //! Adds column j to i and replace i with the sum 95 | void add_cols(int i, int j); 96 | 97 | //! Add row j to i and replace j with the sum 98 | void add_rows(int i, int j); 99 | 100 | //! Returns the variable H 101 | std::vector > get_H(); 102 | 103 | /*! 104 | \brief Obtains an equivalent representation of H for encoding 105 | 106 | For encoding a G matrix in the form [I P] is obtained from the 107 | parity matrix H, by (a) Column permutations, (b) Row additions 108 | and (c) Row permutations. Details of encoding is given in 109 | section A.1 of the reference given below. 110 | - "Modern Coding Theory", T Richardson and R Urbanke. 111 | 112 | \param p is the column permutation during this operation 113 | \ 114 | */ 115 | GF2Mat get_G(std::vector & p, int & rank); 116 | 117 | }; 118 | 119 | #endif // #ifndef GF2MAT_H 120 | -------------------------------------------------------------------------------- /lib/cldpc.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Implementation of a class holding an LDPC code 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | */ 27 | 28 | #include "cldpc.h" 29 | 30 | cldpc::cldpc(const GF2Mat X) { 31 | H = X; 32 | M = H.get_M(); 33 | N = H.get_N(); 34 | G = H.get_G(permute, rank_H); 35 | K = N - rank_H; 36 | } 37 | 38 | cldpc::cldpc(const alist _list) { 39 | H = GF2Mat(_list); 40 | M = H.get_M(); 41 | N = H.get_N(); 42 | G = H.get_G(permute, rank_H); 43 | K = N - rank_H; 44 | } 45 | 46 | void cldpc::set_alist(const alist _list) { 47 | H = GF2Mat(_list); 48 | M = H.get_M(); 49 | N = H.get_N(); 50 | G = H.get_G(permute, rank_H); 51 | K = N - rank_H; 52 | } 53 | 54 | std::vector cldpc::get_systematic_bits(std::vector in) { 55 | std::vector data; 56 | data.resize(K); 57 | int index; 58 | for ( int i = 0; i < K; i++ ) { 59 | index = permute[i + rank_H]; 60 | data[i] = in[index]; 61 | } 62 | return data; 63 | } 64 | 65 | void cldpc::print_permute() { 66 | for ( int i = 0; i < permute.size(); i++ ) { 67 | std::cout << permute[i] << ", "; 68 | } 69 | std::cout << "\n"; 70 | } 71 | 72 | std::vector cldpc::syndrome(const std::vector in) { 73 | std::vector synd; 74 | synd.resize(rank_H); 75 | GF2Vec in_bvec; 76 | in_bvec.set_vec(in); 77 | for ( int i = 0; i < rank_H; i++ ) { 78 | synd[i] = H[i]*in_bvec; 79 | } 80 | return synd; 81 | } 82 | 83 | bool cldpc::is_codeword(const std::vector in) { 84 | std::vector synd; 85 | synd = syndrome(in); 86 | bool is_code; 87 | is_code = true; 88 | for ( int i = 0; i < rank_H; i++ ) { 89 | if ( synd[i] != char(0) ) { 90 | is_code = false; 91 | } 92 | } 93 | return is_code; 94 | } 95 | 96 | std::vector cldpc::encode(std::vector dataword) { 97 | if (dataword.size() == K) { 98 | GF2Vec x(N); 99 | GF2Vec data(K); 100 | data.set_vec(dataword); 101 | for ( int i = rank_H; i < N; i++ ) { 102 | x[i] = dataword[i - rank_H]; 103 | } 104 | for ( int i = 0; i < rank_H; i++ ) { 105 | x[i] = G[i].sub_vector(N-K, N)*data; 106 | } 107 | GF2Vec y(N); 108 | for ( int i = 0; i < N; i++ ) { 109 | y[permute[i]] = x[i]; 110 | } 111 | return y.get_vec(); 112 | } 113 | } 114 | 115 | int cldpc::dimension() { 116 | return K; 117 | } 118 | 119 | int cldpc::get_M() { 120 | return M; 121 | } 122 | 123 | int cldpc::get_N() { 124 | return N; 125 | } 126 | 127 | GF2Mat cldpc::get_H() { 128 | return H; 129 | } 130 | 131 | GF2Mat cldpc::get_G() { 132 | return G; 133 | } 134 | -------------------------------------------------------------------------------- /lib/cldpc.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class holding an LDPC code 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This class defined various functions and variables needed to 28 | * implement an LDPC code class. 29 | * 30 | */ 31 | 32 | #ifndef LDPC_H 33 | #define LDPC_H 34 | 35 | #include 36 | #include 37 | 38 | #include "gf2vec.h" 39 | #include "gf2mat.h" 40 | #include "alist.h" 41 | 42 | class cldpc 43 | { 44 | public: 45 | //! Default constructor 46 | cldpc() {}; 47 | 48 | //! Constructs the LDPC class from given GF2mat X 49 | cldpc(const GF2Mat X); 50 | 51 | //! Constructs the class from the given alist _list 52 | cldpc(const alist _list); 53 | 54 | //! Prints the variable permute 55 | void print_permute(); 56 | 57 | /*! 58 | \brief Encode the given vector dataword. 59 | 60 | dataword is of length K where K is the dimension of the code. 61 | The function returns a vector of length N where N is the 62 | block-length of the code. 63 | 64 | For encoding a G matrix in the form [I P] is obtained from the 65 | parity matrix H, by (a) Column permutations, (b) Row additions 66 | and (c) Row permutations. Details of encoding is given in 67 | section A.1 of the reference given below. 68 | - "Modern Coding Theory", T Richardson and R Urbanke. 69 | */ 70 | std::vector encode(std::vector dataword); 71 | 72 | //! Returns the dimension of the code 73 | int dimension(); 74 | 75 | //! Returns the parity check matrix H 76 | GF2Mat get_H(); 77 | 78 | //! Returns the matrix G used in encoding 79 | GF2Mat get_G(); 80 | 81 | //! Returns the variable M 82 | int get_M(); 83 | 84 | //! Returns the variable N 85 | int get_N(); 86 | 87 | //! Returns the syndrome for a given vector "in" 88 | std::vector syndrome(const std::vector in); 89 | 90 | //! Returns true if "in" is a codeword, else false 91 | bool is_codeword(const std::vector in); 92 | 93 | //! Set the variable _list 94 | void set_alist(const alist _list); 95 | 96 | //! Obtain systematic bits from "in" 97 | std::vector get_systematic_bits(std::vector in); 98 | 99 | private: 100 | //! The parity check matrix 101 | GF2Mat H; 102 | 103 | //! An equivalent matrix obtained from H used for encoding 104 | GF2Mat G; 105 | 106 | //! Stores the column permutation in obtaining G from H 107 | std::vector permute; 108 | 109 | //! Rank of the H matrix 110 | int rank_H; 111 | 112 | //! The number of check nodes in the Tanner-graph 113 | int M; 114 | 115 | //! The number of variable nodes in the Tanner-graph 116 | int N; 117 | 118 | //! The dimension of the code 119 | int K; 120 | }; 121 | 122 | #endif // ifndef LDPC_H 123 | -------------------------------------------------------------------------------- /lib/alist.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class to hold sparse matrices in alist-format 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This class handles sparse matrices specified in alist-format. 28 | * For details about alist format please visit the link below. 29 | * - http://www.inference.phy.cam.ac.uk/mackay/codes/alist.html 30 | * 31 | * Alist class is an efficient way of representing a sparse matrix 32 | * the parity check matrix H of an LDPC code for instance. 33 | * 34 | */ 35 | 36 | #ifndef ALIST_H 37 | #define ALIST_H 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | class alist 46 | { 47 | public: 48 | 49 | //! Default Constructor 50 | alist() : data_ok(false) {} 51 | 52 | //! Constructor which loads alist class from an alist-file 53 | alist(const char * fname); 54 | 55 | //! Read alist data from a file 56 | void read(const char * fname); 57 | 58 | //! Write alist data to a file 59 | void write(const char * fname) const; 60 | 61 | //! Retuns N, the number of variable nodes 62 | int get_N(); 63 | 64 | //! Return M, the number of check nodes 65 | int get_M(); 66 | 67 | //! Return the m_list variable 68 | std::vector< std::vector > get_mlist(); 69 | 70 | //! Returns the n_list variable 71 | std::vector< std::vector > get_nlist(); 72 | 73 | //! Returns the num_mlist variable 74 | std::vector get_num_mlist(); 75 | 76 | //! Returns the num_nlist variable 77 | std::vector get_num_nlist(); 78 | 79 | //! Returns the max_num_nlist variable 80 | int get_max_num_nlist(); 81 | 82 | //! Returns the max_num_mlist variable 83 | int get_max_num_mlist(); 84 | 85 | //! Prints the nlist[i] variable 86 | void print_nlist_i(int i); 87 | 88 | //! Prints the mlist[i] variable 89 | void print_mlist_i(int i); 90 | 91 | //! Returns the corresponding H matrix 92 | std::vector > get_matrix(); 93 | 94 | protected: 95 | //! A variable indicating if data has been read from alist-file 96 | bool data_ok; 97 | 98 | //! Number of variable nodes 99 | int N; 100 | 101 | //! Number of check nodes 102 | int M; 103 | 104 | //! Maximum weight of rows 105 | int max_num_mlist; 106 | 107 | //! Maximum weight of columns 108 | int max_num_nlist; 109 | 110 | //! Weight of each column n 111 | std::vector num_nlist; 112 | 113 | //! Weight of each row m 114 | std::vector num_mlist; 115 | 116 | //! List of integer coordinates along each rows with non-zero entries 117 | std::vector< std::vector > mlist; 118 | 119 | //! List of integer coordinates along each column with non-zero entries 120 | std::vector< std::vector > nlist; 121 | }; 122 | #endif // ifndef ALIST_H 123 | -------------------------------------------------------------------------------- /apps/top_block.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ################################################## 3 | # Gnuradio Python Flow Graph 4 | # Title: Top Block 5 | # Generated: Wed Sep 25 17:08:31 2013 6 | ################################################## 7 | 8 | from gnuradio import analog 9 | from gnuradio import blocks 10 | from gnuradio import digital 11 | from gnuradio import eng_notation 12 | from gnuradio import gr 13 | from gnuradio.eng_option import eng_option 14 | from gnuradio.filter import firdes 15 | from grc_gnuradio import wxgui as grc_wxgui 16 | from optparse import OptionParser 17 | import ldpc 18 | import wx 19 | 20 | class top_block(grc_wxgui.top_block_gui): 21 | 22 | def __init__(self): 23 | grc_wxgui.top_block_gui.__init__(self, title="Top Block") 24 | _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" 25 | self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) 26 | 27 | ################################################## 28 | # Variables 29 | ################################################## 30 | self.sigma = sigma = 0.3 31 | self.samp_rate = samp_rate = 32000 32 | self.max_iterations = max_iterations = 50 33 | 34 | ################################################## 35 | # Blocks 36 | ################################################## 37 | self.ldpc_lh_detector_fb_0 = ldpc.lh_detector_fb() 38 | self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf(([1.0, -1.0]), 1) 39 | self.blocks_unpacked_to_packed_xx_0 = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) 40 | self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) 41 | self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/home/manu/Downloads/in.flac", False) 42 | self.blocks_file_sink_2 = blocks.file_sink(gr.sizeof_char*1, "/home/manu/val") 43 | self.blocks_file_sink_2.set_unbuffered(False) 44 | self.blocks_file_sink_1 = blocks.file_sink(gr.sizeof_char*1, "/home/manu/ref") 45 | self.blocks_file_sink_1.set_unbuffered(False) 46 | self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_char*1, "/home/manu/out") 47 | self.blocks_file_sink_0.set_unbuffered(False) 48 | self.blocks_add_xx_0 = blocks.add_vff(1) 49 | self.analog_noise_source_x_0 = analog.noise_source_f(analog.GR_GAUSSIAN, sigma, 1) 50 | 51 | ################################################## 52 | # Connections 53 | ################################################## 54 | self.connect((self.blocks_file_source_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) 55 | self.connect((self.blocks_unpacked_to_packed_xx_0, 0), (self.blocks_file_sink_0, 0)) 56 | self.connect((self.analog_noise_source_x_0, 0), (self.blocks_add_xx_0, 1)) 57 | self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.blocks_add_xx_0, 0)) 58 | self.connect((self.blocks_add_xx_0, 0), (self.ldpc_lh_detector_fb_0, 0)) 59 | self.connect((self.ldpc_lh_detector_fb_0, 0), (self.blocks_file_sink_2, 0)) 60 | self.connect((self.ldpc_lh_detector_fb_0, 0), (self.blocks_unpacked_to_packed_xx_0, 0)) 61 | self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.blocks_file_sink_1, 0)) 62 | self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.digital_chunks_to_symbols_xx_0, 0)) 63 | 64 | 65 | # QT sink close method reimplementation 66 | 67 | def get_sigma(self): 68 | return self.sigma 69 | 70 | def set_sigma(self, sigma): 71 | self.sigma = sigma 72 | self.analog_noise_source_x_0.set_amplitude(self.sigma) 73 | 74 | def get_samp_rate(self): 75 | return self.samp_rate 76 | 77 | def set_samp_rate(self, samp_rate): 78 | self.samp_rate = samp_rate 79 | 80 | def get_max_iterations(self): 81 | return self.max_iterations 82 | 83 | def set_max_iterations(self, max_iterations): 84 | self.max_iterations = max_iterations 85 | 86 | if __name__ == '__main__': 87 | parser = OptionParser(option_class=eng_option, usage="%prog: [options]") 88 | (options, args) = parser.parse_args() 89 | tb = top_block() 90 | tb.Start(True) 91 | tb.Wait() 92 | 93 | -------------------------------------------------------------------------------- /python/qa_copy_bb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013 IIT Bombay. 4 | # 5 | # This is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # This software is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this software; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | # 20 | 21 | from gnuradio import gr, gr_unittest, blocks, digital 22 | import ldpc_swig as ldpc 23 | import random, array, copy 24 | 25 | class qa_copy_bb (gr_unittest.TestCase): 26 | 27 | def setUp (self): 28 | self.tb = gr.top_block () 29 | 30 | def tearDown (self): 31 | self.tb = None 32 | 33 | def test_001_t (self): 34 | # set up fg 35 | blk_len = 100 36 | encoder = ldpc.copy_bb(blk_len) 37 | datatpl = array.array('B') 38 | txdata = () 39 | for i in range(blk_len): 40 | X = random.randint(0, 1) 41 | if X == 1: 42 | datatpl.append(1) 43 | txdata = txdata + (1, ) 44 | else: 45 | datatpl.append(0) 46 | txdata = txdata + (0, ) 47 | src = blocks.vector_source_b(datatpl) 48 | str2vec = blocks.stream_to_vector(1, blk_len) 49 | vec2str = blocks.vector_to_stream(1, blk_len) 50 | dst = blocks.vector_sink_b() 51 | self.tb.connect(src, str2vec, encoder, vec2str, dst) 52 | self.tb.run () 53 | rxtpl = dst.data() 54 | self.assertTupleEqual(txdata, rxtpl) 55 | # check data 56 | 57 | def test_002_t (self): 58 | # set up fg 59 | fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963" 60 | epsilon = 0.5 61 | max_iterations = 100 62 | encoder = ldpc.ldpc_encoder_bf(fname) 63 | decoder = ldpc.ldpc_decoder_fb(fname, epsilon, max_iterations) 64 | blk_len = encoder.get_K() 65 | datatpl = array.array('B') 66 | txdata = () 67 | for i in range(blk_len): 68 | X = random.randint(0, 1) 69 | if X == 1: 70 | datatpl.append(1) 71 | txdata = txdata + (1, ) 72 | else: 73 | datatpl.append(0) 74 | txdata = txdata + (0, ) 75 | src = blocks.vector_source_b(datatpl) 76 | str2vec = blocks.stream_to_vector(1, blk_len) 77 | vec2str = blocks.vector_to_stream(1, blk_len) 78 | dst = blocks.vector_sink_b() 79 | self.tb.connect(src, str2vec, encoder, decoder, vec2str, dst) 80 | self.tb.run () 81 | rxtpl = dst.data() 82 | self.assertTupleEqual(txdata, rxtpl) 83 | # check data 84 | 85 | def test_003_t (self): 86 | # set up fg 87 | fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963" 88 | epsilon = 0.04 89 | max_iterations = 100 90 | encoder = ldpc.ldpc_encoder_bb(fname) 91 | N = encoder.get_N() 92 | channel = ldpc.bsc_bb(N, epsilon) 93 | decoder = ldpc.ldpc_decoder_bb(fname, epsilon, max_iterations) 94 | blk_len = encoder.get_K() 95 | datatpl = array.array('B') 96 | txdata = () 97 | for i in range(blk_len): 98 | X = random.randint(0, 1) 99 | if X == 1: 100 | datatpl.append(1) 101 | txdata = txdata + (1, ) 102 | else: 103 | datatpl.append(0) 104 | txdata = txdata + (0, ) 105 | src = blocks.vector_source_b(datatpl) 106 | str2vec = blocks.stream_to_vector(1, blk_len) 107 | vec2str = blocks.vector_to_stream(1, blk_len) 108 | dst = blocks.vector_sink_b() 109 | self.tb.connect(src, str2vec, encoder, channel, decoder, vec2str, dst) 110 | self.tb.run () 111 | rxtpl = dst.data() 112 | self.assertTupleEqual(txdata, rxtpl) 113 | # check data 114 | 115 | if __name__ == '__main__': 116 | gr_unittest.run(qa_copy_bb, "qa_copy_bb.xml") 117 | -------------------------------------------------------------------------------- /python/test_awgn.py: -------------------------------------------------------------------------------- 1 | from gnuradio import gr, digital, blocks, analog 2 | import ldpc 3 | import numpy as np 4 | import random, array, copy 5 | 6 | class my_tb(gr.top_block): 7 | def __init__(self, fname, epsilon, max_iterations): 8 | gr.top_block.__init__(self) 9 | 10 | self.src = blocks.vector_source_b(()) 11 | # self.encoder = ldpc.ldpc_encoder_bf(fname) 12 | # self.decoder = ldpc.ldpc_decoder_fb(fname, epsilon, max_iterations) 13 | # self.encoder = ldpc.ldpc_encoder_bb(fname) 14 | # self.decoder = ldpc.ldpc_decoder_bb(fname, epsilon, max_iterations) 15 | # self.K = self.encoder.get_K() 16 | # self.N = self.encoder.get_N() 17 | self.K = 100 18 | self.N = 100 19 | print self.K 20 | print self.N 21 | copy = ldpc.copy_bb(self.K) 22 | self.dst = blocks.vector_sink_b() 23 | fsink1 = blocks.file_sink(gr.sizeof_char*self.K, "in") 24 | fsink1.set_unbuffered(False) 25 | fsink2 = blocks.file_sink(gr.sizeof_char*self.K, "out") 26 | fsink2.set_unbuffered(False) 27 | # fsink3 = blocks.file_sink(gr.sizeof_float*1, "encout") 28 | # fsink3.set_unbuffered(False) 29 | fsink3 = blocks.file_sink(gr.sizeof_char*self.N, "encout") 30 | fsink3.set_unbuffered(False) 31 | 32 | inFile = "/home/manu/Downloads/in.flac" 33 | outFile = "/home/manu/out.flac" 34 | source = blocks.file_source(gr.sizeof_char*self.K, inFile, False) 35 | sink = blocks.file_sink(gr.sizeof_char*self.K, outFile) 36 | unpack2pack = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) 37 | pack2unpack = blocks.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) 38 | rsource= blocks.vector_source_b(map(int, np.random.randint(0x00, 0x02, 1000)), True) 39 | 40 | 41 | # str2Kvec = blocks.stream_to_vector(1, self.K) 42 | # str2Nvec = blocks.stream_to_vector(4, self.N) 43 | # Kvec2str = blocks.vector_to_stream(1, self.K) 44 | # Nvec2str = blocks.vector_to_stream(4, self.N) 45 | str2Kvec = blocks.stream_to_vector(1, self.K) 46 | str2Nvec = blocks.stream_to_vector(1, self.N) 47 | Kvec2str = blocks.vector_to_stream(1, self.K) 48 | Nvec2str = blocks.vector_to_stream(1, self.N) 49 | 50 | self.noise = analog.noise_source_f(analog.GR_GAUSSIAN, epsilon, 0) 51 | self.adder = blocks.add_vff(1) 52 | 53 | self.connect(source, copy, sink) 54 | # self.connect(source, pack2unpack, str2Kvec, fsink1) 55 | # self.connect(str2Kvec, self.encoder, self.decoder, fsink2) 56 | # self.connect(self.encoder, fsink3) 57 | 58 | # self.connect(self.src, str2Kvec, self.encoder, 59 | # Nvec2str) 60 | # self.connect(Nvec2str, (self.adder, 0)) 61 | # self.connect(self.noise, (self.adder, 1)) 62 | # self.connect(self.adder, str2Nvec, 63 | # self.decoder, Kvec2str, self.dst) 64 | 65 | def main(): 66 | fname = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files/96.3.963" 67 | epsilon = 0.6 68 | max_iterations = 100 69 | print "initializing top block" 70 | tb = my_tb(fname, epsilon, max_iterations) 71 | tb.start() 72 | tb.wait() 73 | # K = tb.K 74 | # N = tb.N 75 | # match = 0 76 | # mismatch = 0 77 | # datatpl = array.array('B') 78 | # for i in range(K): 79 | # datatpl.append(0) 80 | # f = open('output', 'w') 81 | # g = open('data', 'w') 82 | # for i in range(100): 83 | # txdata = () 84 | # for i in range(K): 85 | # X = random.randint(0, 1) 86 | # if X == 1: 87 | # datatpl[i] = 1 88 | # txdata = txdata + (1, ) 89 | # else: 90 | # datatpl[i] = 0 91 | # txdata = txdata + (0, ) 92 | # g.write("tx data\n") 93 | # g.write(str(datatpl) + "\n") 94 | # tb.src.set_data(datatpl) 95 | # tb.run() 96 | # rx_tpl = tb.dst.data() 97 | # tb.dst.reset() 98 | # g.write("rx data\n") 99 | # g.write(str(rx_tpl) + "\n") 100 | # if np.array_equal(txdata, rx_tpl): 101 | # match += 1 102 | # else: 103 | # mismatch += 1 104 | # _str = str(np.array_equal(txdata, rx_tpl)) 105 | # _str = _str + "\t" + str(tb.decoder.get_niterations()) + "\n" 106 | # f.write(_str) 107 | # print _str 108 | 109 | if __name__ == '__main__': 110 | try: 111 | main() 112 | except KeyboardInterrupt: 113 | pass 114 | -------------------------------------------------------------------------------- /apps/example1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ################################################## 3 | # Gnuradio Python Flow Graph 4 | # Title: Example1 5 | # Author: Manu T S 6 | # Generated: Wed Apr 9 01:36:34 2014 7 | ################################################## 8 | 9 | from gnuradio import analog 10 | from gnuradio import blocks 11 | from gnuradio import digital 12 | from gnuradio import eng_notation 13 | from gnuradio import gr 14 | from gnuradio.eng_option import eng_option 15 | from gnuradio.filter import firdes 16 | from grc_gnuradio import wxgui as grc_wxgui 17 | from optparse import OptionParser 18 | import ldpc 19 | import wx 20 | 21 | class example1(grc_wxgui.top_block_gui): 22 | 23 | def __init__(self): 24 | grc_wxgui.top_block_gui.__init__(self, title="Example1") 25 | _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" 26 | self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) 27 | 28 | ################################################## 29 | # Variables 30 | ################################################## 31 | self.sigma = sigma = 0.5 32 | self.samp_rate = samp_rate = 32000 33 | self.max_iterations = max_iterations = 50 34 | self.alist_file = alist_file = "/home/manu/repos/ldpc/gr-ldpc/python/alist-files" 35 | 36 | ################################################## 37 | # Blocks 38 | ################################################## 39 | self.ldpc_ldpc_hier_encoder_bb_0 = ldpc.ldpc_hier_encoder_bb("/home/manu/1920.1280.3.303/H1920.1280.3.303") 40 | self.ldpc_ldpc_hier_decoder_fb_0 = ldpc.ldpc_hier_decoder_fb("/home/manu/1920.1280.3.303/H1920.1280.3.303", sigma, max_iterations) 41 | self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf(([1.0, -1.0]), 1) 42 | self.blocks_unpacked_to_packed_xx_0 = blocks.unpacked_to_packed_bb(1, gr.GR_LSB_FIRST) 43 | self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb(1, gr.GR_LSB_FIRST) 44 | self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/home/manu/Downloads/06 - Coming Back To Life.flac", False) 45 | self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_char*1, "/home/manu/Downloads/out", False) 46 | self.blocks_file_sink_0.set_unbuffered(False) 47 | self.blocks_add_xx_0 = blocks.add_vff(1) 48 | self.analog_noise_source_x_0 = analog.noise_source_f(analog.GR_GAUSSIAN, sigma, 0) 49 | 50 | ################################################## 51 | # Connections 52 | ################################################## 53 | self.connect((self.blocks_file_source_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) 54 | self.connect((self.ldpc_ldpc_hier_decoder_fb_0, 0), (self.blocks_unpacked_to_packed_xx_0, 0)) 55 | self.connect((self.blocks_unpacked_to_packed_xx_0, 0), (self.blocks_file_sink_0, 0)) 56 | self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.ldpc_ldpc_hier_encoder_bb_0, 0)) 57 | self.connect((self.ldpc_ldpc_hier_encoder_bb_0, 0), (self.digital_chunks_to_symbols_xx_0, 0)) 58 | self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.blocks_add_xx_0, 0)) 59 | self.connect((self.analog_noise_source_x_0, 0), (self.blocks_add_xx_0, 1)) 60 | self.connect((self.blocks_add_xx_0, 0), (self.ldpc_ldpc_hier_decoder_fb_0, 0)) 61 | 62 | 63 | # QT sink close method reimplementation 64 | 65 | def get_sigma(self): 66 | return self.sigma 67 | 68 | def set_sigma(self, sigma): 69 | self.sigma = sigma 70 | self.analog_noise_source_x_0.set_amplitude(self.sigma) 71 | 72 | def get_samp_rate(self): 73 | return self.samp_rate 74 | 75 | def set_samp_rate(self, samp_rate): 76 | self.samp_rate = samp_rate 77 | 78 | def get_max_iterations(self): 79 | return self.max_iterations 80 | 81 | def set_max_iterations(self, max_iterations): 82 | self.max_iterations = max_iterations 83 | 84 | def get_alist_file(self): 85 | return self.alist_file 86 | 87 | def set_alist_file(self, alist_file): 88 | self.alist_file = alist_file 89 | 90 | if __name__ == '__main__': 91 | import ctypes 92 | import sys 93 | if sys.platform.startswith('linux'): 94 | try: 95 | x11 = ctypes.cdll.LoadLibrary('libX11.so') 96 | x11.XInitThreads() 97 | except: 98 | print "Warning: failed to XInitThreads()" 99 | parser = OptionParser(option_class=eng_option, usage="%prog: [options]") 100 | (options, args) = parser.parse_args() 101 | tb = example1() 102 | tb.Start(True) 103 | tb.Wait() 104 | 105 | -------------------------------------------------------------------------------- /apps/rs_ldpc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013 IIT Bombay. 4 | # Author: Manu T S 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | import numpy 23 | import sys 24 | 25 | """ 26 | Generation of LDPC matrices based on Reed-Solomon codes [1] 27 | """ 28 | 29 | def swap_columns(i, j, M): 30 | n = M.shape[1] 31 | I = numpy.zeros(shape=(n, n)) 32 | for k in range(n): 33 | I[k, k] = 1 34 | I[i, i] = 0 35 | I[j, j] = 0 36 | I[i, j] = 1 37 | I[j, i] = 1 38 | return M*I 39 | 40 | def swap_index(i, j, index): 41 | temp = index[0, i] 42 | index[0, i] = index[0, j] 43 | index[0, j] = temp 44 | return index 45 | def add_rows(i, j, M): 46 | n = M.shape[0] 47 | I = numpy.zeros(shape=(n, n)) 48 | for k in range(n): 49 | I[k, k] = 1 50 | I[j, i] = 1 51 | return I*M 52 | 53 | def regular_check(H, rho, gamma): 54 | right_regular = True 55 | left_regular = True 56 | for i in range(H.shape[0]): 57 | weight = 0 58 | for j in range(H.shape[1]): 59 | weight += H[i, j] 60 | if weight != rho: 61 | right_regular = False 62 | for j in range(H.shape[1]): 63 | weight = 0 64 | for i in range(H.shape[0]): 65 | weight += H[i, j] 66 | if weight != gamma: 67 | left_regular = False 68 | return left_regular, right_regular 69 | 70 | def generate_H(rho, gamma, gf): 71 | q = gf.q 72 | gen = gf.rs_gen_poly(rho) 73 | coset_base = [] 74 | exp_matrix = numpy.zeros((gamma*q, rho), dtype = int) 75 | for i in range(gamma): 76 | multiplier = i 77 | curnt_word = [] 78 | curnt_word.append(gen[0]) 79 | for j in range(1, len(gen)): 80 | _prdct = gf.mul_exp(gen[j], multiplier) 81 | _sum = gf.add_exp(_prdct, gen[j - 1]) 82 | curnt_word.append(_sum) 83 | curnt_word.append(0) 84 | coset_base.append(curnt_word) 85 | subspace_base = coset_base[0] 86 | for i in range(gamma): 87 | row = i*q 88 | for j in range(rho): 89 | exp_matrix[row, j] = coset_base[i][j] 90 | for k in range(1, q): 91 | for j in range(rho): 92 | _prdct = gf.mul_exp(k, subspace_base[j]) 93 | _sum = gf.add_exp(_prdct, coset_base[i][j]) 94 | exp_matrix[row + k, j] = _sum 95 | 96 | H = numpy.zeros((gamma*q, q*rho), dtype = int) 97 | for row in range(gamma*q): 98 | for col in range(rho): 99 | if (exp_matrix[row, col] == -1*sys.maxint): 100 | H[row, col*q] = 1 101 | else: 102 | exp = exp_matrix[row, col] 103 | H[row, col*q + exp + 1] = 1 104 | return H 105 | 106 | def convert_binary(H): 107 | n = H.shape[1] 108 | m = H.shape[0] 109 | for i in range(m): 110 | for j in range(n): 111 | H[i, j] = H[i, j]%2 112 | return H 113 | 114 | def triangulate_H(H): # TODO There are errors in this routine 115 | n = H.shape[1] 116 | m = H.shape[0] 117 | index = numpy.zeros(shape=(1, n)) 118 | for i in range(n): 119 | index[0, i] = i 120 | for i in range(m): 121 | j = i 122 | while j < n: 123 | if H[i, j] == 1: 124 | print "swapping column ", 125 | print i, j 126 | H = swap_columns(i, j, H) 127 | index = swap_index(i, j, index) 128 | print H 129 | print index 130 | break 131 | j += 1 132 | for k in range(i+1, m): 133 | if H[k, i] == 1: 134 | print "adding ", 135 | print i, k 136 | H = add_rows(i, k, H) 137 | print H 138 | H = convert_binary(H) 139 | print H 140 | return index, H 141 | 142 | """ 143 | References 144 | 145 | "A Class of Low-Density Parity-Check Codes Constructed Based on 146 | Reed-Solomon Codes With Two Information Symbols", 147 | Ivana Djurdjevic, Jun Xu, Khaled Abdel-Ghaffer and Shu Lin 148 | IEEE Communications Letters, July 2000. 149 | """ 150 | -------------------------------------------------------------------------------- /apps/peg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013 IIT Bombay. 4 | # Author: Manu T S 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | import numpy as np 23 | from find_smallest import find_smallest 24 | import copy 25 | 26 | class peg(): 27 | 28 | """ 29 | Progressive edge growth algorithm for generating 30 | LDPC matrices. The algorithm is obtained from [1] 31 | """ 32 | 33 | def __init__(self, nvar, nchk, degree_sequence): 34 | self.degree_sequence = degree_sequence 35 | self.nvar = nvar 36 | self.nchk = nchk 37 | self.H = np.zeros((nchk, nvar), dtype = np.int32) 38 | self.sym_degrees = np.zeros(nvar, dtype = np.int32) 39 | self.chk_degrees = np.zeros(nchk, dtype = np.int32) 40 | self.I_edge_chk2var = [] 41 | self.I_edge_var2chk = [] 42 | for chk in range(nchk): 43 | self.I_edge_chk2var.append([]) 44 | for var in range(nvar): 45 | self.I_edge_chk2var[chk].append(0) 46 | for var in range(nvar): 47 | self.I_edge_var2chk.append([]) 48 | for chk in range(nchk): 49 | self.I_edge_var2chk[var].append(0) 50 | 51 | def grow_edge(self, var, chk): 52 | self.I_edge_chk2var[chk][var] = 1 53 | self.I_edge_var2chk[var][chk] = 1 54 | self.H[chk, var] = 1 55 | self.sym_degrees[var] += 1 56 | self.chk_degrees[chk] += 1 57 | 58 | def bfs(self, var): 59 | var_list = np.zeros(self.nvar, dtype = np.int32) 60 | var_list[var] = 1 61 | cur_chk_list = [] 62 | new_chk_list = [] 63 | for i in range(self.nchk): 64 | cur_chk_list.append(0) 65 | new_chk_list.append(0) 66 | chk_Q = [] 67 | var_Q = [] 68 | var_Q.append(var) 69 | while(True): 70 | for _vars in var_Q: 71 | for i in range(self.nchk): 72 | if self.H[i, _vars] == 1: 73 | if cur_chk_list[i] == 0: 74 | new_chk_list[i] = 1 75 | chk_Q.append(i) 76 | var_Q = [] 77 | for _chks in chk_Q: 78 | for j in range(self.nvar): 79 | if self.H[_chks, j] == 1: 80 | if var_list[j] == 0: 81 | var_list[j] = 1 82 | var_Q.append(j) 83 | chk_Q = [] 84 | if new_chk_list.count(1) == self.nchk: 85 | new_chk = self.find_smallest_chk(cur_chk_list) 86 | return new_chk 87 | elif np.array_equal(new_chk_list, cur_chk_list): 88 | new_chk = self.find_smallest_chk(cur_chk_list) 89 | return new_chk 90 | else: 91 | cur_chk_list = copy.copy(new_chk_list) 92 | 93 | def find_smallest_chk(self, cur_chk_list): 94 | index = [] 95 | degree = [] 96 | for i in range(len(cur_chk_list)): 97 | if cur_chk_list[i] == 0: 98 | index.append(i) 99 | degree.append(self.chk_degrees[i]) 100 | return index[find_smallest(degree)] 101 | 102 | def _print(self): 103 | print "I_edge_chk2var" 104 | for i in range(len(self.I_edge_chk2var)): 105 | print self.I_edge_chk2var[i] 106 | print "I_edge_var2chk" 107 | for i in range(len(self.I_edge_var2chk)): 108 | print self.I_edge_var2chk[i] 109 | 110 | def progressive_edge_growth(self): 111 | for var in range(self.nvar): 112 | print "edge growth at var", var 113 | for k in range(self.degree_sequence[var]): 114 | if k == 0: 115 | smallest_degree_chk = find_smallest(self.chk_degrees) 116 | self.grow_edge(var, smallest_degree_chk) 117 | else: 118 | chk = self.bfs(var) 119 | self.grow_edge(var, chk) 120 | 121 | """ 122 | References 123 | 124 | "Regular and Irregular Progressive-Edge Growth Tanner Graphs", 125 | Xiao-Yu Hu, Evangelos Eleftheriou and Dieter M. Arnold. 126 | IEEE Transactions on Information Theory, January 2005. 127 | """ 128 | -------------------------------------------------------------------------------- /lib/gf2mat.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Implementation of a class for GF2 matrix algebra 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | */ 27 | 28 | #include "gf2mat.h" 29 | #include 30 | 31 | GF2Mat::GF2Mat(int m, int n) { 32 | M = m; 33 | N = n; 34 | H.resize(M); 35 | for ( int i = 0; i < M; i++ ) { 36 | H[i].resize(N); 37 | for ( int j = 0; j < N; j++ ) { 38 | H[i][j] = char(0); 39 | } 40 | } 41 | } 42 | 43 | GF2Mat::GF2Mat(std::vector > X) { 44 | M = X.size(); 45 | N = X[0].size(); 46 | H.resize(M); 47 | for ( int i = 0; i < M; i++ ) { 48 | H[i].resize(N); 49 | for ( int j = 0; j < N; j++ ){ 50 | H[i][j] = X[i][j]; 51 | } 52 | } 53 | } 54 | 55 | GF2Mat::GF2Mat(alist _list) { 56 | int m, n; 57 | M = _list.get_M(); 58 | N = _list.get_N(); 59 | H.resize(M); 60 | for ( int i = 0; i < M; i++ ) { 61 | H[i].resize(N); 62 | for ( int j = 0; j < N; j++ ) { 63 | H[i][j] = char(0); 64 | } 65 | } 66 | H = _list.get_matrix(); 67 | } 68 | 69 | int GF2Mat::get_M() { 70 | return M; 71 | } 72 | 73 | int GF2Mat::get_N() { 74 | return N; 75 | } 76 | 77 | void GF2Mat::set_element(int i, int j, char val) { 78 | H[i][j] = val; 79 | } 80 | 81 | char GF2Mat::get_element(int i, int j) { 82 | return H[i][j]; 83 | } 84 | 85 | void GF2Mat::print_matrix() { 86 | for (int i = 0; i < M; i++) { 87 | for (int j = 0; j < N; j++) { 88 | std::cout << int(H[i][j]) << " "; 89 | } 90 | std::cout << '\n'; 91 | } 92 | } 93 | 94 | GF2Vec GF2Mat::operator[](int i) { 95 | GF2Vec row(N); 96 | row.set_vec(H[i]); 97 | return row; 98 | } 99 | 100 | GF2Vec GF2Mat::get_row(int i) { 101 | GF2Vec row(N); 102 | for ( int j = 0; j < N; j++ ){ 103 | row[j] = H[i][j]; 104 | } 105 | return row; 106 | } 107 | 108 | GF2Vec GF2Mat::get_col(int i) { 109 | GF2Vec col(M); 110 | for ( int j = 0; j < M; j++ ) { 111 | col[j] = H[j][i]; 112 | } 113 | return col; 114 | } 115 | 116 | void GF2Mat::add_cols(int i, int j) { 117 | for ( int row = 0; row < M; row++ ) { 118 | H[row][i] = H[row][i] xor H[row][j]; 119 | } 120 | } 121 | 122 | void GF2Mat::add_rows(int i, int j) { 123 | for ( int col = 0; col < N; col++ ) { 124 | H[i][col] = H[i][col] xor H[j][col]; 125 | } 126 | } 127 | 128 | void GF2Mat::set_row(int row, GF2Vec vec) { 129 | for ( int j = 0; j < N; j++ ) { 130 | H[row][j] = vec[j]; 131 | } 132 | } 133 | 134 | void GF2Mat::set_col(int col, GF2Vec vec) { 135 | for ( int j = 0; j < M; j++ ) { 136 | H[j][col] = vec[j]; 137 | } 138 | } 139 | 140 | void GF2Mat::swap_cols(int i, int j) { 141 | GF2Vec tmp; 142 | tmp = get_col(i); 143 | set_col(i, get_col(j)); 144 | set_col(j, tmp); 145 | } 146 | 147 | GF2Mat GF2Mat::get_G(std::vector & permute, 148 | int & rank) { 149 | permute.resize(N); 150 | rank = 0; 151 | for ( int col = 0; col < N; col++ ) { 152 | permute[col] = col; 153 | } 154 | GF2Mat G(H); 155 | int diag = 0; 156 | int limit = M; 157 | int temp; 158 | while (diag < limit) { 159 | bool non_zero = false; 160 | for ( int col = diag; col < N; col++ ) { 161 | if ( G.get_element(diag, col) == char(1) ) { 162 | non_zero = true; 163 | rank++; 164 | G.swap_cols(diag, col); 165 | temp = permute[diag]; 166 | permute[diag] = permute[col]; 167 | permute[col] = temp; 168 | break; 169 | } 170 | } 171 | if (non_zero) { 172 | for ( int row = 0; row < diag; row++ ) { 173 | if (G.get_element(row, diag) == char(1)){ 174 | G.add_rows(row, diag); 175 | } 176 | } 177 | for ( int row = diag + 1; row < M; row++ ) { 178 | if (G.get_element(row, diag) == char(1)) { 179 | G.add_rows(row, diag); 180 | } 181 | } 182 | diag++; 183 | } 184 | else{ 185 | GF2Vec current_row; 186 | current_row = G.get_row(diag); 187 | for ( int row = diag; row < limit - 1; row++ ) { 188 | G.set_row(row, G.get_row(row + 1)); 189 | } 190 | G.set_row(limit - 1, current_row); 191 | limit--; 192 | } 193 | } 194 | return G; 195 | } 196 | 197 | std::vector > GF2Mat::get_H() { 198 | return H; 199 | } 200 | -------------------------------------------------------------------------------- /apps/gf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013 IIT Bombay. 4 | # Author: Manu T S 5 | # 6 | # This is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # This software is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this software; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | import math 23 | import sys 24 | 25 | class GF: 26 | 27 | def __init__(self, prime, poly): 28 | self.prime = prime 29 | self.mod_poly = poly 30 | self.dimension = len(self.mod_poly) - 1 31 | self.q = int(math.pow(self.prime, self.dimension)) 32 | self.exp_2_pol = [] 33 | self.pol_2_exp = [0]*self.q 34 | self.pol_2_exp[0] = -1*sys.maxint 35 | self.zero_exp = -1*sys.maxint 36 | for i in range(1, self.q): 37 | pol = [0]*i 38 | pol.pop() 39 | pol.append(1) 40 | poly = self.divide_poly(pol) 41 | ind = 0 42 | for j in range(len(poly)): 43 | ind += poly[j]*(self.prime**j) 44 | self.pol_2_exp[ind] = i - 1 45 | self.exp_2_pol.append(poly) 46 | 47 | def divide_poly(self, poly): 48 | if len(poly) >= len(self.mod_poly): 49 | mul_index = len(poly) - len(self.mod_poly) 50 | prod = [] 51 | for i in range(mul_index): 52 | prod.append(0) 53 | for i in range(mul_index, len(self.mod_poly) + mul_index): 54 | prod.append( 55 | (self.mod_poly[i - mul_index]*poly[-1]) % self.prime) 56 | bal = self.sub_poly(poly, prod) 57 | return self.divide_poly(bal) 58 | else: 59 | return poly 60 | 61 | def mul_exp(self, exp1, exp2): 62 | if exp1 == self.zero_exp: 63 | return exp2 64 | elif exp2 == self.zero_exp: 65 | return exp1 66 | else: 67 | return ((exp1 + exp2) % (self.q - 1)) 68 | 69 | def pol_2_indx(self, poly): 70 | ind = 0 71 | for i in range(len(poly)): 72 | ind += poly[i]*(self.prime**i) 73 | return ind 74 | 75 | def mul_poly(self, poly1, poly2): 76 | ind1 = self.pol_2_indx(poly1) 77 | ind2 = self.pol_2_indx(poly2) 78 | exp1 = self.pol_2_exp[ind1] 79 | exp2 = self.pol_2_exp[ind2] 80 | return self.exp_2_pol[self.mul_exp(exp1, exp2)] 81 | 82 | def div_poly(self, poly1, poly2): 83 | ind0 = 0 84 | for i in range(len(poly1)): 85 | ind0 += poly1[i]*(self.prime**i) 86 | ind1 = 0 87 | for i in range(len(poly2)): 88 | ind1 += poly2[i]*(self.prime**i) 89 | return self.exp_2_pol[self.div_exp(ind0, ind1)] 90 | 91 | def div_exp(self, exp1, exp2): 92 | inv_exp2 = m_inv_exp(self, exp2) 93 | return self.mul_exp(exp1, inv_exp2) 94 | 95 | def m_inv_exp(self, exp): 96 | return (self.q - 1) - (exp % self.q - 1) 97 | 98 | def add_exp(self, exp1, exp2): 99 | if exp1 == -1*sys.maxint: 100 | pol1 = [] 101 | else: 102 | pol1 = self.exp_2_pol[exp1] 103 | if exp2 == -1*sys.maxint: 104 | pol2 = [] 105 | else: 106 | pol2 = self.exp_2_pol[exp2] 107 | _sum = self.add_poly(pol1, pol2) 108 | ind = self.pol_2_indx(_sum) 109 | return self.pol_2_exp[ind] 110 | 111 | def sub_poly(self, poly1, poly2): 112 | inv_poly2 = self.a_inv_poly(poly2) 113 | return self.add_poly(poly1, inv_poly2) 114 | 115 | def add_poly(self, poly1, poly2): 116 | if len(poly1) >= len(poly2): 117 | _sum = [] 118 | for i in range(len(poly2)): 119 | _sum.append((poly1[i] + poly2[i]) % self.prime) 120 | for i in range(len(poly2), len(poly1)): 121 | _sum.append(poly1[i]) 122 | if len(_sum) == 0: 123 | return _sum 124 | while(_sum[-1] == 0): 125 | _sum.pop() 126 | if len(_sum) == 0: 127 | break 128 | return _sum 129 | else: 130 | return self.add_poly(poly2, poly1) 131 | 132 | def a_inv_poly(self, poly): 133 | inv = [] 134 | for i in range(len(poly)): 135 | inv.append((self.prime - poly[i]) % self.prime) 136 | return inv 137 | 138 | def a_inv_exp(self, exp): 139 | poly = self.exp_2_pol[exp] 140 | inv = self.a_inv_poly(poly) 141 | ind = self.pol_2_indx(inv) 142 | return self.pol_2_exp[ind] 143 | 144 | def rs_gen_poly(self, rho): 145 | gen_poly = [self.a_inv_exp(1), 0] 146 | comp = 1 147 | while comp < rho - 2: 148 | gen_poly = self.rs_gen_add_degree(gen_poly) 149 | comp += 1 150 | return gen_poly 151 | 152 | def rs_gen_add_degree(self, pol): 153 | new_degree = len(pol) 154 | new_gen = [] 155 | g_0 = self.mul_exp(self.a_inv_exp(new_degree), pol[0]) 156 | new_gen.append(g_0) 157 | new_comp = self.a_inv_exp(new_degree) 158 | for i in range(1, new_degree): 159 | _prdct = self.mul_exp(pol[i], new_comp) 160 | _sum = self.add_exp(_prdct, pol[i-1]) 161 | new_gen.append(_sum) 162 | new_gen.append(0) 163 | return new_gen 164 | -------------------------------------------------------------------------------- /lib/awgn_bp.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class for message passing for AWGN channel 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This class defines functions for message passing mechanism for a 28 | * AWGN channel. Message passing (also known as belief propagation) 29 | * is used for decoding LDPC codes. Details of how LDPC codes are 30 | * decoded is available in the link below 31 | * - http://www.cs.utoronto.ca/~radford/ftp/LDPC-2012-02-11/decoding.html 32 | * 33 | * Belief propagation decoding is a suboptimal but efficient method of 34 | * decoding LDPC codes. 35 | * 36 | */ 37 | 38 | #ifndef AWGN_BP_H 39 | #define AWGN_BP_H 40 | 41 | #include 42 | #include 43 | #include 44 | #include "gf2mat.h" 45 | #include "alist.h" 46 | 47 | class awgn_bp 48 | { 49 | public: 50 | //! Default constructor 51 | awgn_bp () {}; 52 | 53 | //! A constructor for given GF2Mat and sigma 54 | awgn_bp (const GF2Mat X, float sgma); 55 | 56 | //! A constructor for given alist and sigma 57 | awgn_bp (alist _list, float sgma); 58 | 59 | //! Initializes the class using given alist and sigma 60 | void set_alist_sigma(alist _list, float sgma); 61 | 62 | //! Returns the variable Q 63 | std::vector< std::vector > get_Q(); 64 | 65 | //! Returns the variable R 66 | std::vector< std::vector > get_R(); 67 | 68 | //! Returns the variable H 69 | GF2Mat get_H(); 70 | 71 | //! Calculates the likelihood ratios given an input vector 72 | void rx_lr_calc(std::vector codeword); 73 | 74 | //! Returns the variable rx_lr 75 | std::vector get_rx_lr(); 76 | 77 | //! Returns the variable lr 78 | std::vector get_lr(); 79 | 80 | //! Initializes the sum product algorithm set-up 81 | void spa_initialize(); 82 | 83 | //! Updates the check-nodes based on messages from variable nodes 84 | void update_chks(); 85 | 86 | //! Updates the variable-nodes based on messages from check nodes 87 | void update_vars(); 88 | 89 | //! Returns the current estimate 90 | std::vector get_estimate(); 91 | 92 | //! Computes initial estimate based on the vector rx_word 93 | void compute_init_estimate(std::vector rx_word); 94 | 95 | //! Computes the estimate based on current likelihood-ratios lr 96 | void decision(); 97 | 98 | //! Returns the syndrome for the current estimate 99 | std::vector get_syndrome(); 100 | 101 | //! Returns the syndrome for the input codeword 102 | std::vector get_syndrome(const std::vector codeword); 103 | 104 | //! Checks if the current estimate is a codeword 105 | bool is_codeword(); 106 | 107 | //! Checks if the input is a codeword 108 | bool is_codeword(const std::vector codeword); 109 | 110 | //! Sets the variable K 111 | void set_K(int k); 112 | 113 | //! Returns the variable K 114 | int get_K(); 115 | 116 | //! Sets the variable max_iterations 117 | void set_max_iterations(int k); 118 | 119 | //! Returns the variable max_iterations 120 | int get_max_iterations(); 121 | 122 | /*! 123 | \brief Decodes the given vector rx_word by message passing. 124 | 125 | \param *niterations is the number of message passing iterations 126 | done to decode this codeword 127 | */ 128 | std::vector decode (std::vector rx_word, 129 | int *niterations); 130 | private: 131 | //! The number of check nodes in the tanner-graph 132 | int M; 133 | 134 | //! The number of variable nodes in the tanner-graph 135 | int N; 136 | 137 | //! The dimension of the code used 138 | int K; 139 | 140 | //! The maximum number of message passing iterations allowed 141 | int max_iterations; 142 | 143 | //! The parity check matrix of the LDPC code 144 | GF2Mat H; 145 | 146 | //! The standard-deviation of the AWGN channel 147 | float sigma; 148 | 149 | //! Matrix holding messages from check nodes to variable nodes 150 | std::vector< std::vector > R; 151 | 152 | //! Matrix holding messages from variable nodes to check nodes 153 | std::vector< std::vector > Q; 154 | 155 | //! The array of likelihood computed from the channel output 156 | std::vector rx_lr; 157 | 158 | //! The array for holding likelihoods computed on BP decoding 159 | std::vector lr; 160 | 161 | //! List of integer coordinates along each column with non-zero entries 162 | std::vector < std::vector > nlist; 163 | 164 | //! List of integer coordinates along each row with non-zero entries 165 | std::vector < std::vector > mlist; 166 | 167 | //! Weight of each column n 168 | std::vector num_nlist; 169 | 170 | //! Weight of each row m 171 | std::vector num_mlist; 172 | 173 | //! The array for holding estimate computed on BP decoding 174 | std::vector estimate; 175 | }; 176 | #endif // ifndef AWGN_BP_H 177 | -------------------------------------------------------------------------------- /cmake/Modules/GrTest.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_TEST_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_TEST_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Add a unit test and setup the environment for a unit test. 27 | # Takes the same arguments as the ADD_TEST function. 28 | # 29 | # Before calling set the following variables: 30 | # GR_TEST_TARGET_DEPS - built targets for the library path 31 | # GR_TEST_LIBRARY_DIRS - directories for the library path 32 | # GR_TEST_PYTHON_DIRS - directories for the python path 33 | ######################################################################## 34 | function(GR_ADD_TEST test_name) 35 | 36 | if(WIN32) 37 | #Ensure that the build exe also appears in the PATH. 38 | list(APPEND GR_TEST_TARGET_DEPS ${ARGN}) 39 | 40 | #In the land of windows, all libraries must be in the PATH. 41 | #Since the dependent libraries are not yet installed, 42 | #we must manually set them in the PATH to run tests. 43 | #The following appends the path of a target dependency. 44 | foreach(target ${GR_TEST_TARGET_DEPS}) 45 | get_target_property(location ${target} LOCATION) 46 | if(location) 47 | get_filename_component(path ${location} PATH) 48 | string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) 49 | list(APPEND GR_TEST_LIBRARY_DIRS ${path}) 50 | endif(location) 51 | endforeach(target) 52 | 53 | #SWIG generates the python library files into a subdirectory. 54 | #Therefore, we must append this subdirectory into PYTHONPATH. 55 | #Only do this for the python directories matching the following: 56 | foreach(pydir ${GR_TEST_PYTHON_DIRS}) 57 | get_filename_component(name ${pydir} NAME) 58 | if(name MATCHES "^(swig|lib|src)$") 59 | list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE}) 60 | endif() 61 | endforeach(pydir) 62 | endif(WIN32) 63 | 64 | file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) 65 | file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? 66 | file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list? 67 | 68 | set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}") 69 | 70 | #http://www.cmake.org/pipermail/cmake/2009-May/029464.html 71 | #Replaced this add test + set environs code with the shell script generation. 72 | #Its nicer to be able to manually run the shell script to diagnose problems. 73 | #ADD_TEST(${ARGV}) 74 | #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") 75 | 76 | if(UNIX) 77 | set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") 78 | #set both LD and DYLD paths to cover multiple UNIX OS library paths 79 | list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH") 80 | list(APPEND pypath "$PYTHONPATH") 81 | 82 | #replace list separator with the path separator 83 | string(REPLACE ";" ":" libpath "${libpath}") 84 | string(REPLACE ";" ":" pypath "${pypath}") 85 | list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}") 86 | 87 | #generate a bat file that sets the environment and runs the test 88 | find_program(SHELL sh) 89 | set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) 90 | file(WRITE ${sh_file} "#!${SHELL}\n") 91 | #each line sets an environment variable 92 | foreach(environ ${environs}) 93 | file(APPEND ${sh_file} "export ${environ}\n") 94 | endforeach(environ) 95 | #load the command to run with its arguments 96 | foreach(arg ${ARGN}) 97 | file(APPEND ${sh_file} "${arg} ") 98 | endforeach(arg) 99 | file(APPEND ${sh_file} "\n") 100 | 101 | #make the shell file executable 102 | execute_process(COMMAND chmod +x ${sh_file}) 103 | 104 | add_test(${test_name} ${SHELL} ${sh_file}) 105 | 106 | endif(UNIX) 107 | 108 | if(WIN32) 109 | list(APPEND libpath ${DLL_PATHS} "%PATH%") 110 | list(APPEND pypath "%PYTHONPATH%") 111 | 112 | #replace list separator with the path separator (escaped) 113 | string(REPLACE ";" "\\;" libpath "${libpath}") 114 | string(REPLACE ";" "\\;" pypath "${pypath}") 115 | list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}") 116 | 117 | #generate a bat file that sets the environment and runs the test 118 | set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) 119 | file(WRITE ${bat_file} "@echo off\n") 120 | #each line sets an environment variable 121 | foreach(environ ${environs}) 122 | file(APPEND ${bat_file} "SET ${environ}\n") 123 | endforeach(environ) 124 | #load the command to run with its arguments 125 | foreach(arg ${ARGN}) 126 | file(APPEND ${bat_file} "${arg} ") 127 | endforeach(arg) 128 | file(APPEND ${bat_file} "\n") 129 | 130 | add_test(${test_name} ${bat_file}) 131 | endif(WIN32) 132 | 133 | endfunction(GR_ADD_TEST) 134 | -------------------------------------------------------------------------------- /lib/xbp.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Definition of a class for message passing for BSC channel 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | * 27 | * This class defines functions for message passing mechanism for a 28 | * BSC channel. Message passing (also known as belief propagation) 29 | * is used for decoding LDPC codes. Details of how LDPC codes are 30 | * decoded is available in the link below 31 | * - http://www.cs.utoronto.ca/~radford/ftp/LDPC-2012-02-11/decoding.html 32 | * 33 | * Belief propagation decoding is a suboptimal but efficient method of 34 | * decoding LDPC codes. 35 | * 36 | */ 37 | 38 | #ifndef XBP_H 39 | #define XBP_H 40 | 41 | #include 42 | #include 43 | #include 44 | #include "gf2mat.h" 45 | #include "alist.h" 46 | 47 | class xbp 48 | { 49 | public: 50 | //! Default constructor 51 | xbp () {}; 52 | 53 | //! A constructor for given GF2Mat and sigma 54 | xbp (const GF2Mat X, float sgma); 55 | 56 | //! A constructor for given alist and sigma 57 | xbp (alist _list, float sgma); 58 | 59 | //! Initializes the class using given alist and sigma 60 | void set_alist_sigma(alist _list, float sgma); 61 | 62 | //! Returns the variable Q 63 | std::vector< std::vector > get_Q(); 64 | 65 | //! Returns the variable R 66 | std::vector< std::vector > get_R(); 67 | 68 | //! Returns the variable H 69 | GF2Mat get_H(); 70 | 71 | //! Calculates the likelihood ratios given an input vector 72 | void rx_lr_calc(std::vector codeword); 73 | 74 | //! Returns the variable rx_lr 75 | std::vector get_rx_lr(); 76 | 77 | //! Returns the variable lr 78 | std::vector get_lr(); 79 | 80 | //! Initializes the sum product algorithm set-up 81 | void spa_initialize(); 82 | 83 | //! Updates the check-nodes based on messages from variable nodes 84 | void update_chks(); 85 | 86 | //! Updates the variable-nodes based on messages from check nodes 87 | void update_vars(); 88 | 89 | //! Returns the current estimate 90 | std::vector get_estimate(); 91 | 92 | //! Computes the estimate based on current likelihood-ratios lr 93 | void decision(); 94 | 95 | //! Returns the syndrome for the current estimate 96 | std::vector get_syndrome(); 97 | 98 | //! Returns the syndrome for the input codeword 99 | std::vector get_syndrome(const std::vector codeword); 100 | 101 | //! Checks if the current estimate is a codeword 102 | bool is_codeword(); 103 | 104 | //! Checks if the input is a codeword 105 | bool is_codeword(const std::vector codeword); 106 | 107 | //! Sets the variable K 108 | void set_K(int k); 109 | 110 | //! Returns the variable K 111 | int get_K(); 112 | 113 | //! Sets the variable max_iterations 114 | void set_max_iterations(int k); 115 | 116 | //! Returns the variable max_iterations 117 | int get_max_iterations(); 118 | 119 | /*! 120 | \brief Decodes the given vector rx_word by message passing. 121 | 122 | \param *niterations is the number of message passing iterations 123 | done to decode this codeword 124 | */ 125 | std::vector decode (std::vector rx_word, 126 | int *niterations); 127 | 128 | private: 129 | //! The number of check nodes in the tanner-graph 130 | int M; 131 | 132 | //! The number of variable nodes in the tanner-graph 133 | int N; 134 | 135 | //! The dimension of the code used 136 | int K; 137 | 138 | //! The maximum number of message passing iterations allowed 139 | int max_iterations; 140 | 141 | //! The parity check matrix of the LDPC code 142 | GF2Mat H; 143 | 144 | //! The standard-deviation of the AWGN channel 145 | float sigma; 146 | 147 | //! Matrix holding messages from check nodes to variable nodes 148 | std::vector< std::vector > R; 149 | 150 | //! Matrix holding messages from variable nodes to check nodes 151 | std::vector< std::vector > Q; 152 | 153 | //! The array of likelihood computed from the channel output 154 | std::vector rx_lr; 155 | 156 | //! The array for holding likelihoods computed on BP decoding 157 | std::vector lr; 158 | 159 | //! List of integer coordinates along each column with non-zero entries 160 | std::vector < std::vector > nlist; 161 | 162 | //! List of integer coordinates along each row with non-zero entries 163 | std::vector < std::vector > mlist; 164 | 165 | //! Weight of each column n 166 | std::vector num_nlist; 167 | 168 | //! Weight of each row m 169 | std::vector num_mlist; 170 | 171 | //! The array for holding estimate computed on BP decoding 172 | std::vector estimate; 173 | 174 | /* 175 | int M, N, K, max_iterations; 176 | GF2Mat H; 177 | float sigma; 178 | std::vector< std::vector > Q, R; 179 | std::vector rx_lr; 180 | std::vector lr; 181 | std::vector < std::vector > mlist, nlist; 182 | std::vector num_mlist, num_nlist; 183 | std::vector estimate;*/ 184 | }; 185 | #endif // ifndef XBP_H 186 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | 21 | ######################################################################## 22 | # Project setup 23 | ######################################################################## 24 | cmake_minimum_required(VERSION 2.6) 25 | project(gr-ldpc CXX C) 26 | enable_testing() 27 | 28 | #select the release build type by default to get optimization flags 29 | if(NOT CMAKE_BUILD_TYPE) 30 | set(CMAKE_BUILD_TYPE "Release") 31 | message(STATUS "Build type not specified: defaulting to release.") 32 | endif(NOT CMAKE_BUILD_TYPE) 33 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 34 | 35 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) 36 | 37 | ######################################################################## 38 | # Compiler specific setup 39 | ######################################################################## 40 | if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) 41 | #http://gcc.gnu.org/wiki/Visibility 42 | add_definitions(-fvisibility=hidden) 43 | endif() 44 | 45 | ######################################################################## 46 | # Find boost 47 | ######################################################################## 48 | if(UNIX AND EXISTS "/usr/lib64") 49 | list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix 50 | endif(UNIX AND EXISTS "/usr/lib64") 51 | set(Boost_ADDITIONAL_VERSIONS 52 | "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" 53 | "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" 54 | "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49" 55 | "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54" 56 | "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" 57 | "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" 58 | "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" 59 | ) 60 | find_package(Boost "1.35" COMPONENTS filesystem system) 61 | 62 | if(NOT Boost_FOUND) 63 | message(FATAL_ERROR "Boost required to compile ldpc") 64 | endif() 65 | 66 | ######################################################################## 67 | # Install directories 68 | ######################################################################## 69 | include(GrPlatform) #define LIB_SUFFIX 70 | set(GR_RUNTIME_DIR bin) 71 | set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) 72 | set(GR_INCLUDE_DIR include/ldpc) 73 | set(GR_DATA_DIR share) 74 | set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) 75 | set(GR_DOC_DIR ${GR_DATA_DIR}/doc) 76 | set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) 77 | set(GR_CONF_DIR etc) 78 | set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) 79 | set(GR_LIBEXEC_DIR libexec) 80 | set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) 81 | set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) 82 | 83 | ######################################################################## 84 | # Find gnuradio build dependencies 85 | ######################################################################## 86 | find_package(GnuradioRuntime) 87 | find_package(CppUnit) 88 | 89 | # To run a more advanced search for GNU Radio and it's components and 90 | # versions, use the following. Add any components required to the list 91 | # of GR_REQUIRED_COMPONENTS (in all caps) and change "version" to the 92 | # minimum API compatible version required. 93 | # 94 | # set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER ...) 95 | # find_package(Gnuradio "version") 96 | 97 | if(NOT GNURADIO_RUNTIME_FOUND) 98 | message(FATAL_ERROR "GnuRadio Runtime required to compile ldpc") 99 | endif() 100 | if(NOT CPPUNIT_FOUND) 101 | message(FATAL_ERROR "CppUnit required to compile ldpc") 102 | endif() 103 | 104 | ######################################################################## 105 | # Setup the include and linker paths 106 | ######################################################################## 107 | include_directories( 108 | ${CMAKE_SOURCE_DIR}/include 109 | ${Boost_INCLUDE_DIRS} 110 | ${CPPUNIT_INCLUDE_DIRS} 111 | ${GNURADIO_RUNTIME_INCLUDE_DIRS} 112 | ) 113 | 114 | link_directories( 115 | ${Boost_LIBRARY_DIRS} 116 | ${CPPUNIT_LIBRARY_DIRS} 117 | ${GNURADIO_RUNTIME_LIBRARY_DIRS} 118 | ) 119 | 120 | # Set component parameters 121 | set(GR_LDPC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE) 122 | set(GR_LDPC_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE) 123 | 124 | ######################################################################## 125 | # Create uninstall target 126 | ######################################################################## 127 | configure_file( 128 | ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in 129 | ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 130 | @ONLY) 131 | 132 | add_custom_target(uninstall 133 | ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 134 | ) 135 | 136 | ######################################################################## 137 | # Add subdirectories 138 | ######################################################################## 139 | add_subdirectory(include/ldpc) 140 | add_subdirectory(lib) 141 | add_subdirectory(swig) 142 | add_subdirectory(python) 143 | add_subdirectory(grc) 144 | add_subdirectory(apps) 145 | add_subdirectory(docs) 146 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArgumentsCopy.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE_PARSE_ARGUMENTS( args...) 2 | # 3 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 4 | # parsing the arguments given to that macro or function. 5 | # It processes the arguments and defines a set of variables which hold the 6 | # values of the respective options. 7 | # 8 | # The argument contains all options for the respective macro, 9 | # i.e. keywords which can be used when calling the macro without any value 10 | # following, like e.g. the OPTIONAL keyword of the install() command. 11 | # 12 | # The argument contains all keywords for this macro 13 | # which are followed by one value, like e.g. DESTINATION keyword of the 14 | # install() command. 15 | # 16 | # The argument contains all keywords for this macro 17 | # which can be followed by more than one value, like e.g. the TARGETS or 18 | # FILES keywords of the install() command. 19 | # 20 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 21 | # keywords listed in , and 22 | # a variable composed of the given 23 | # followed by "_" and the name of the respective keyword. 24 | # These variables will then hold the respective value from the argument list. 25 | # For the keywords this will be TRUE or FALSE. 26 | # 27 | # All remaining arguments are collected in a variable 28 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 29 | # your macro was called with unrecognized parameters. 30 | # 31 | # As an example here a my_install() macro, which takes similar arguments as the 32 | # real install() command: 33 | # 34 | # function(MY_INSTALL) 35 | # set(options OPTIONAL FAST) 36 | # set(oneValueArgs DESTINATION RENAME) 37 | # set(multiValueArgs TARGETS CONFIGURATIONS) 38 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 39 | # ... 40 | # 41 | # Assume my_install() has been called like this: 42 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 43 | # 44 | # After the cmake_parse_arguments() call the macro will have set the following 45 | # variables: 46 | # MY_INSTALL_OPTIONAL = TRUE 47 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 48 | # MY_INSTALL_DESTINATION = "bin" 49 | # MY_INSTALL_RENAME = "" (was not used) 50 | # MY_INSTALL_TARGETS = "foo;bar" 51 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 52 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 53 | # 54 | # You can the continue and process these variables. 55 | # 56 | # Keywords terminate lists of values, e.g. if directly after a one_value_keyword 57 | # another recognized keyword follows, this is interpreted as the beginning of 58 | # the new option. 59 | # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 60 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 61 | # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 62 | 63 | #============================================================================= 64 | # Copyright 2010 Alexander Neundorf 65 | # 66 | # Distributed under the OSI-approved BSD License (the "License"); 67 | # see accompanying file Copyright.txt for details. 68 | # 69 | # This software is distributed WITHOUT ANY WARRANTY; without even the 70 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 71 | # See the License for more information. 72 | #============================================================================= 73 | # (To distribute this file outside of CMake, substitute the full 74 | # License text for the above reference.) 75 | 76 | 77 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 78 | return() 79 | endif() 80 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 81 | 82 | 83 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 84 | # first set all result variables to empty/FALSE 85 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 86 | set(${prefix}_${arg_name}) 87 | endforeach(arg_name) 88 | 89 | foreach(option ${_optionNames}) 90 | set(${prefix}_${option} FALSE) 91 | endforeach(option) 92 | 93 | set(${prefix}_UNPARSED_ARGUMENTS) 94 | 95 | set(insideValues FALSE) 96 | set(currentArgName) 97 | 98 | # now iterate over all arguments and fill the result variables 99 | foreach(currentArg ${ARGN}) 100 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 101 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 102 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 103 | 104 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 105 | if(insideValues) 106 | if("${insideValues}" STREQUAL "SINGLE") 107 | set(${prefix}_${currentArgName} ${currentArg}) 108 | set(insideValues FALSE) 109 | elseif("${insideValues}" STREQUAL "MULTI") 110 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 111 | endif() 112 | else(insideValues) 113 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 114 | endif(insideValues) 115 | else() 116 | if(NOT ${optionIndex} EQUAL -1) 117 | set(${prefix}_${currentArg} TRUE) 118 | set(insideValues FALSE) 119 | elseif(NOT ${singleArgIndex} EQUAL -1) 120 | set(currentArgName ${currentArg}) 121 | set(${prefix}_${currentArgName}) 122 | set(insideValues "SINGLE") 123 | elseif(NOT ${multiArgIndex} EQUAL -1) 124 | set(currentArgName ${currentArg}) 125 | set(${prefix}_${currentArgName}) 126 | set(insideValues "MULTI") 127 | endif() 128 | endif() 129 | 130 | endforeach(currentArg) 131 | 132 | # propagate the result variables to the caller: 133 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 134 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 135 | endforeach(arg_name) 136 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 137 | 138 | endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) 139 | -------------------------------------------------------------------------------- /lib/alist.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Implementation of a class to hold sparse matrices in alist-format 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | */ 27 | 28 | #include "alist.h" 29 | 30 | alist::alist(const char * fname) 31 | : data_ok(false) { 32 | read(fname); 33 | } 34 | 35 | std::vector > alist::get_matrix() { 36 | std::vector > mat; 37 | mat.resize(M); 38 | for ( int i = 0; i < M; i++ ) { 39 | mat[i].resize(N); 40 | for ( int j = 0; j < N; j++ ) { 41 | mat[i][j] = char(0); 42 | } 43 | for ( int k = 0; k < num_mlist[i]; k++ ) { 44 | mat[i][mlist[i][k] - 1] = char(1); 45 | } 46 | } 47 | return mat; 48 | } 49 | 50 | std::vector< std::vector > alist::get_mlist() { 51 | return mlist; 52 | } 53 | 54 | std::vector< std::vector > alist::get_nlist() { 55 | return nlist; 56 | } 57 | 58 | std::vector alist::get_num_mlist() { 59 | return num_mlist; 60 | } 61 | 62 | std::vector alist::get_num_nlist() { 63 | return num_nlist; 64 | } 65 | 66 | void alist::read(const char * fname) { 67 | std::ifstream file; 68 | std::string line; 69 | std::stringstream ss; 70 | 71 | file.open(fname); 72 | if(!(file.is_open())) { 73 | std::cout << "Could not open the file" << std::endl; 74 | } 75 | 76 | // Parse N and M 77 | std::getline(file, line); 78 | ss << line; 79 | ss >> N >> M; 80 | num_nlist.resize(N); 81 | num_mlist.resize(M); 82 | nlist.resize(N); 83 | mlist.resize(M); 84 | ss.seekg(0, std::ios::end); 85 | ss.clear(); 86 | 87 | // parse max_num_n and max_num_m 88 | std::getline(file, line); 89 | ss << line; 90 | ss >> max_num_nlist >> max_num_mlist; 91 | ss.seekg(0, std::ios::end); 92 | ss.clear(); 93 | 94 | // Parse weight of each column n 95 | std::getline(file, line); 96 | ss << line; 97 | for (int i = 0; i < N; i++ ) { 98 | ss >> num_nlist[i]; 99 | nlist[i].resize(num_nlist[i]); 100 | } 101 | ss.seekg(0, std::ios::end); 102 | ss.clear(); 103 | 104 | // Parse weight of each row m 105 | std::getline(file, line); 106 | ss << line; 107 | for (int i = 0; i < M; i++ ) { 108 | ss >> num_mlist[i]; 109 | mlist[i].resize(num_mlist[i]); 110 | } 111 | ss.seekg(0, std::ios::end); 112 | ss.clear(); 113 | 114 | // Parse indices with non zero entries in ith column 115 | for (int column = 0; column < N; column++) { 116 | std::getline(file, line); 117 | ss << line; 118 | for (int entry = 0; entry < num_nlist[column]; entry++) { 119 | ss >> nlist[column][entry]; 120 | } 121 | ss.seekg(0, std::ios::end); 122 | ss.clear(); 123 | } 124 | 125 | // Parse indices with non zero entries in ith row 126 | for (int row = 0; row < M; row++) { 127 | std::getline(file, line); 128 | ss << line; 129 | for (int entry = 0; entry < num_mlist[row]; entry++) { 130 | ss >> mlist[row][entry]; 131 | } 132 | ss.seekg(0, std::ios::end); 133 | ss.clear(); 134 | } 135 | 136 | file.close(); 137 | data_ok = true; 138 | } 139 | 140 | void alist::write(const char * fname) const 141 | { 142 | if (!data_ok) { 143 | std::cout << "Data not ok, exiting" << std::endl; 144 | exit(1); 145 | } 146 | // Else 147 | std::ofstream file(fname, std::ofstream::out); 148 | // Write N and M 149 | file << N << " " << M << std::endl; 150 | file << max_num_nlist << " " << max_num_mlist << std::endl; 151 | // Write column weights 152 | for (int i = 0; i < num_nlist.size() - 1; i++) { 153 | file << num_nlist[i] << " "; 154 | } 155 | file << num_nlist[num_nlist.size() - 1] << std::endl; 156 | // Write row weights 157 | for (int i = 0; i < num_mlist.size() - 1; i++) { 158 | file << num_mlist[i] << " "; 159 | } 160 | file << num_mlist[num_mlist.size() - 1] << std::endl; 161 | // Write non zero indices in the ith column 162 | for (int i = 0; i < N; i++) { 163 | for (int j = 0; j < num_nlist[i] - 1; j++) { 164 | file << nlist[i][j] << "\t"; 165 | } 166 | file << nlist[i][num_nlist[i] - 1]; 167 | file << std::endl; 168 | } 169 | // Write non zero indices in the ith row 170 | for (int i = 0; i < M; i++) { 171 | for (int j = 0; j < num_mlist[i] - 1; j++) { 172 | file << mlist[i][j] << "\t"; 173 | } 174 | file << mlist[i][num_mlist[i] - 1]; 175 | file << std::endl; 176 | } 177 | file.close(); 178 | } 179 | 180 | int alist::get_N() { 181 | return N; 182 | } 183 | 184 | int alist::get_M() { 185 | return M; 186 | } 187 | 188 | int alist::get_max_num_nlist() { 189 | return max_num_nlist; 190 | } 191 | 192 | int alist::get_max_num_mlist() { 193 | return max_num_mlist; 194 | } 195 | 196 | void alist::print_nlist_i(int column) { 197 | std::cout << "Indices in column " << column << std::endl; 198 | for (int i = 0; i < num_nlist[column] - 1; i++) { 199 | std::cout << nlist[column][i] << ", "; 200 | } 201 | std::cout << nlist[column][num_nlist[column] - 1] << std::endl; 202 | } 203 | 204 | void alist::print_mlist_i(int row) { 205 | std::cout << "Indices in row " << row << std::endl; 206 | for (int i = 0; i < num_mlist[row] - 1; i++) { 207 | std::cout << mlist[row][i] << ", "; 208 | } 209 | std::cout << mlist[row][num_mlist[row] - 1] << std::endl; 210 | } 211 | -------------------------------------------------------------------------------- /apps/example2.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mon Sep 23 15:08:19 2013 4 | 5 | options 6 | 7 | id 8 | top_block 9 | 10 | 11 | _enabled 12 | True 13 | 14 | 15 | title 16 | 17 | 18 | 19 | author 20 | 21 | 22 | 23 | description 24 | 25 | 26 | 27 | window_size 28 | 1280, 1024 29 | 30 | 31 | generate_options 32 | wx_gui 33 | 34 | 35 | category 36 | Custom 37 | 38 | 39 | run_options 40 | prompt 41 | 42 | 43 | run 44 | True 45 | 46 | 47 | max_nouts 48 | 0 49 | 50 | 51 | realtime_scheduling 52 | 53 | 54 | 55 | _coordinate 56 | (10, 10) 57 | 58 | 59 | _rotation 60 | 0 61 | 62 | 63 | 64 | variable 65 | 66 | id 67 | alist_file 68 | 69 | 70 | _enabled 71 | True 72 | 73 | 74 | value 75 | "/home/manu/repos/ldpc/gr-ldpc/python/alist-files" 76 | 77 | 78 | _coordinate 79 | (242, 23) 80 | 81 | 82 | _rotation 83 | 0 84 | 85 | 86 | 87 | variable 88 | 89 | id 90 | samp_rate 91 | 92 | 93 | _enabled 94 | True 95 | 96 | 97 | value 98 | 32000 99 | 100 | 101 | _coordinate 102 | (10, 170) 103 | 104 | 105 | _rotation 106 | 0 107 | 108 | 109 | 110 | analog_random_source_x 111 | 112 | id 113 | analog_random_source_x_0 114 | 115 | 116 | _enabled 117 | True 118 | 119 | 120 | type 121 | byte 122 | 123 | 124 | min 125 | 0x00 126 | 127 | 128 | max 129 | 0x02 130 | 131 | 132 | num_samps 133 | 1000 134 | 135 | 136 | repeat 137 | True 138 | 139 | 140 | affinity 141 | 142 | 143 | 144 | minoutbuf 145 | 0 146 | 147 | 148 | _coordinate 149 | (295, 287) 150 | 151 | 152 | _rotation 153 | 0 154 | 155 | 156 | 157 | ldpc_ldpc_hier_encoder_bf 158 | 159 | id 160 | ldpc_ldpc_hier_encoder_bf_0 161 | 162 | 163 | _enabled 164 | True 165 | 166 | 167 | alist_file 168 | alist_file 169 | 170 | 171 | affinity 172 | 173 | 174 | 175 | minoutbuf 176 | 0 177 | 178 | 179 | _coordinate 180 | (557, 192) 181 | 182 | 183 | _rotation 184 | 0 185 | 186 | 187 | 188 | wxgui_scopesink2 189 | 190 | id 191 | wxgui_scopesink2_0 192 | 193 | 194 | _enabled 195 | True 196 | 197 | 198 | type 199 | float 200 | 201 | 202 | title 203 | Scope Plot 204 | 205 | 206 | samp_rate 207 | samp_rate 208 | 209 | 210 | v_scale 211 | 0 212 | 213 | 214 | v_offset 215 | 0 216 | 217 | 218 | t_scale 219 | 0 220 | 221 | 222 | ac_couple 223 | False 224 | 225 | 226 | xy_mode 227 | False 228 | 229 | 230 | num_inputs 231 | 1 232 | 233 | 234 | win_size 235 | 236 | 237 | 238 | grid_pos 239 | 240 | 241 | 242 | notebook 243 | 244 | 245 | 246 | trig_mode 247 | wxgui.TRIG_MODE_AUTO 248 | 249 | 250 | y_axis_label 251 | Counts 252 | 253 | 254 | affinity 255 | 256 | 257 | 258 | _coordinate 259 | (814, 306) 260 | 261 | 262 | _rotation 263 | 0 264 | 265 | 266 | 267 | analog_random_source_x_0 268 | ldpc_ldpc_hier_encoder_bf_0 269 | 0 270 | 0 271 | 272 | 273 | ldpc_ldpc_hier_encoder_bf_0 274 | wxgui_scopesink2_0 275 | 0 276 | 0 277 | 278 | 279 | -------------------------------------------------------------------------------- /lib/awgn_bp.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file 3 | * \brief Implementation of a class for message passing for AWGN channel 4 | * \author Manu T S 5 | * 6 | * ----------------------------------------------------------------- 7 | * 8 | * Copyright 2013 IIT Bombay. 9 | * 10 | * This is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3, or (at your option) 13 | * any later version. 14 | * 15 | * This software is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this software; see the file COPYING. If not, write to 22 | * the Free Software Foundation, Inc., 51 Franklin Street, 23 | * Boston, MA 02110-1301, USA. 24 | * 25 | * ----------------------------------------------------------------- 26 | */ 27 | 28 | #include "awgn_bp.h" 29 | 30 | awgn_bp::awgn_bp ( const GF2Mat X, float sgma) { 31 | H = X; 32 | M = H.get_M(); 33 | N = H.get_N(); 34 | Q.resize(M); 35 | R.resize(M); 36 | sigma = sgma; 37 | for (int i = 0; i < M; i++) { 38 | Q[i].resize(N); 39 | R[i].resize(N); 40 | } 41 | lr.resize(N); 42 | estimate.resize(N); 43 | } 44 | 45 | awgn_bp::awgn_bp ( alist _list, float sgma) { 46 | H = GF2Mat(_list); 47 | mlist = _list.get_mlist(); 48 | nlist = _list.get_nlist(); 49 | num_mlist = _list.get_num_mlist(); 50 | num_nlist = _list.get_num_nlist(); 51 | M = H.get_M(); 52 | N = H.get_N(); 53 | Q.resize(M); 54 | R.resize(M); 55 | sigma = sgma; 56 | for (int i = 0; i < M; i++) { 57 | Q[i].resize(N); 58 | R[i].resize(N); 59 | } 60 | lr.resize(N); 61 | estimate.resize(N); 62 | } 63 | 64 | void awgn_bp::set_alist_sigma(alist _list, float sgma) { 65 | H = GF2Mat(_list); 66 | mlist = _list.get_mlist(); 67 | nlist = _list.get_nlist(); 68 | num_mlist = _list.get_num_mlist(); 69 | num_nlist = _list.get_num_nlist(); 70 | M = H.get_M(); 71 | N = H.get_N(); 72 | Q.resize(M); 73 | R.resize(M); 74 | sigma = sgma; 75 | for (int i = 0; i < M; i++) { 76 | Q[i].resize(N); 77 | R[i].resize(N); 78 | } 79 | lr.resize(N); 80 | estimate.resize(N); 81 | } 82 | 83 | std::vector< std::vector > awgn_bp::get_Q() { 84 | return Q; 85 | } 86 | 87 | std::vector< std::vector > awgn_bp::get_R() { 88 | return R; 89 | } 90 | 91 | GF2Mat awgn_bp::get_H() { 92 | return H; 93 | } 94 | 95 | void awgn_bp::rx_lr_calc(std::vector codeword) { 96 | rx_lr.resize(N); 97 | float y; 98 | for ( int i = 0; i < N; i++){ 99 | y = codeword[i]; 100 | rx_lr[i] = exp((-1*y)/(2*sigma*sigma)); 101 | } 102 | } 103 | 104 | std::vector awgn_bp::get_rx_lr() { 105 | return rx_lr; 106 | } 107 | 108 | std::vector awgn_bp::get_lr() { 109 | return lr; 110 | } 111 | 112 | void awgn_bp::spa_initialize() { 113 | int row; 114 | for ( int var = 0; var < N; var++ ) { 115 | for ( int i = 0; i < num_nlist[var]; i++ ) { 116 | row = nlist[var][i] - 1; 117 | Q[row][var] = rx_lr[var]; 118 | } 119 | } 120 | } 121 | 122 | void awgn_bp::update_chks() { 123 | double product, _prdct; 124 | int v; 125 | for ( int chk = 0; chk < M; chk++ ) { 126 | product = double(1.0); 127 | for (int i = 0; i < num_mlist[chk]; i++) { 128 | v = mlist[chk][i] - 1; 129 | product = product*double( 2/(1 + Q[chk][v]) - 1 ); 130 | } 131 | for ( int i = 0; i < num_mlist[chk]; i++ ) { 132 | v = mlist[chk][i] - 1; 133 | _prdct = product/double( 2/(1 + Q[chk][v]) - 1); 134 | R[chk][v] = double((1 - _prdct)/(1 + _prdct)); 135 | } 136 | } 137 | } 138 | 139 | void awgn_bp::update_vars() { 140 | double _sum, __sum; 141 | int c; 142 | for ( int var = 0; var < N; var++ ) { 143 | _sum = rx_lr[var]; 144 | for ( int i = 0; i < num_nlist[var]; i++ ) { 145 | c = nlist[var][i] - 1; 146 | _sum = _sum * double(R[c][var]); 147 | } 148 | lr[var] = _sum; 149 | for ( int i = 0; i < num_nlist[var]; i++ ) { 150 | c = nlist[var][i] - 1; 151 | __sum = _sum/R[c][var]; 152 | Q[c][var] = __sum; 153 | } 154 | } 155 | } 156 | 157 | std::vector awgn_bp::get_estimate() { 158 | return estimate; 159 | } 160 | 161 | void awgn_bp::compute_init_estimate(std::vector rx_word) { 162 | for ( int i = 0; i < rx_word.size(); i++ ) { 163 | if (rx_word[i] < 0) 164 | estimate[i] = char(1); 165 | else 166 | estimate[i] = char(0); 167 | } 168 | } 169 | 170 | void awgn_bp::decision() { 171 | for ( int i = 0; i < N; i++ ){ 172 | if ( lr[i] > 1 ) 173 | estimate[i] = char(1); 174 | else 175 | estimate[i] = char(0); 176 | } 177 | } 178 | 179 | void awgn_bp::set_K(int k) { 180 | K = k; 181 | } 182 | 183 | int awgn_bp::get_K() { 184 | return K; 185 | } 186 | 187 | std::vector awgn_bp::get_syndrome(std::vector codeword) { 188 | std::vector synd; 189 | synd.resize(N - K); 190 | GF2Vec in_bvec; 191 | in_bvec.set_vec(codeword); 192 | for ( int i = 0; i < N - K; i++ ) { 193 | synd[i] = H[i]*in_bvec; 194 | } 195 | return synd; 196 | } 197 | 198 | std::vector awgn_bp::get_syndrome() { 199 | std::vector synd; 200 | synd.resize(N - K); 201 | GF2Vec in_bvec; 202 | in_bvec.set_vec(estimate); 203 | for ( int i = 0; i < N - K; i++ ) { 204 | synd[i] = H[i]*in_bvec; 205 | } 206 | return synd; 207 | } 208 | 209 | bool awgn_bp::is_codeword(std::vector codeword) { 210 | std::vector synd; 211 | synd = get_syndrome(codeword); 212 | bool is_code; 213 | is_code = true; 214 | for ( int i = 0; i < N - K; i++ ) { 215 | if ( synd[i] != char(0) ) { 216 | is_code = false; 217 | } 218 | } 219 | return is_code; 220 | } 221 | 222 | bool awgn_bp::is_codeword() { 223 | std::vector synd; 224 | synd = get_syndrome(); 225 | bool is_code; 226 | is_code = true; 227 | for ( int i = 0; i < N - K; i++ ) { 228 | if ( synd[i] != char(0) ) { 229 | is_code = false; 230 | } 231 | } 232 | return is_code; 233 | } 234 | 235 | void awgn_bp::set_max_iterations(int k) { 236 | max_iterations = k; 237 | } 238 | 239 | int awgn_bp::get_max_iterations() { 240 | return max_iterations; 241 | } 242 | 243 | std::vector awgn_bp::decode(std::vector rx_word, 244 | int *niteration) { 245 | *niteration = 0; 246 | compute_init_estimate(rx_word); 247 | if (is_codeword()) { 248 | return estimate; 249 | } 250 | else { 251 | rx_lr_calc(rx_word); 252 | spa_initialize(); 253 | while (*niteration < max_iterations) { 254 | *niteration += 1; 255 | update_chks(); 256 | update_vars(); 257 | decision(); 258 | if (is_codeword()) { 259 | break; 260 | } 261 | } 262 | return estimate; 263 | } 264 | } 265 | --------------------------------------------------------------------------------