├── .cproject ├── .gitignore ├── .project ├── .pydevproject ├── LICENSE ├── Makefile.am ├── bindings ├── Makefile.am ├── __init__.py ├── channels.i ├── codes │ ├── Makefile.am │ ├── __init__.py │ ├── codes.i │ ├── codes_workaround.i │ ├── fountain.i │ ├── ldpc.i │ ├── null.i │ ├── spinal │ │ ├── Makefile.am │ │ ├── __init__.py │ │ └── spinal.i │ ├── strider.i │ └── turbo.i ├── common.i ├── demappers.i ├── demappers_workaround.i ├── general.i ├── itpp │ ├── Makefile.am │ ├── __init__.py │ ├── base_sparse.i │ ├── base_vec.i │ ├── ldpc.i │ ├── llr.i │ └── modulator.i ├── mappers.i ├── mappers_workaround.i ├── misc.i ├── numpy.i ├── protocols.i └── util │ ├── Makefile.am │ ├── __init__.py │ ├── config.i │ ├── hashes.i │ └── inference.i ├── build-aux └── m4 │ ├── m4_ax_check_compile_flag.m4 │ ├── m4_ax_pkg_swig.m4 │ ├── m4_ax_python_devel.m4 │ ├── m4_ax_swig_enable_cxx.m4 │ └── m4_ax_swig_python.m4 ├── configure.ac ├── data ├── Makefile.am └── ldpc │ ├── LDPC_1024.it │ ├── LDPC_2048.it │ ├── LDPC_256.it │ ├── LDPC_256_rate0.5.it │ ├── LDPC_256_rate0.74.it │ ├── LDPC_3072.it │ ├── LDPC_4096.it │ └── LDPC_9500.it ├── doc ├── .gitignore ├── Doxyfile ├── doxygen-footer.html └── modules.h ├── include ├── CodeBench.h ├── ComposedTransformation.h ├── CrcDetector.h ├── CrcPacketGenerator.h ├── Makefile.am ├── OracleDetector.h ├── PacketGenerator.h ├── TransformationAdaptor.h ├── channels │ ├── AwgnChannel.h │ ├── AwgnChannel.hh │ ├── AwgnNoiseGenerator.h │ ├── BscChannel.h │ ├── CoherenceCoeffGenerator.h │ ├── CoherenceFading.h │ ├── CoherenceFading.hh │ ├── CompositeChannel.h │ ├── CompositeChannel.hh │ ├── MimoChannel.h │ ├── TransparentCoherenceFading.h │ └── TransparentCoherenceFading.hh ├── codes │ ├── DecodeResult.h │ ├── EncoderMultiplexer.h │ ├── IDecoder.h │ ├── IEncoder.h │ ├── ILLRDecoder.h │ ├── IMultiStreamDecoder.h │ ├── IMultiStreamEncoder.h │ ├── InterleavedDecoder.h │ ├── InterleavedDecoder.hh │ ├── InterleavedEncoder.h │ ├── MultiToSingleStreamDecoder.h │ ├── MultiToSingleStreamDecoder.hh │ ├── MultiToSingleStreamEncoder.h │ ├── RandomPermutationGenerator.h │ ├── SymbolToLLRDecoderAdaptor.h │ ├── SymbolToLLRDecoderAdaptor.hh │ ├── archive │ │ ├── CachedEncoder.h │ │ ├── CachedEncoder.hh │ │ ├── CachedMultiDecoder.h │ │ ├── CachedMultiDecoder.hh │ │ ├── IMultiDecoder.h │ │ ├── IMultiEncoder.h │ │ ├── LinearCheckNodeUpdater.cpp │ │ └── LinearCheckNodeUpdater.h │ ├── fountain │ │ ├── LTDecoder.h │ │ ├── LTParityNeighborGenerator.h │ │ ├── ParityEncoder.h │ │ ├── RaptorDecoder.h │ │ └── RaptorEncoder.h │ ├── ldpc │ │ ├── LinearCheckNodeUpdater.h │ │ ├── MatrixLDPCCode.h │ │ ├── MatrixLDPCDecoder.h │ │ ├── MatrixLDPCEncoder.h │ │ ├── MatrixLDPCNeighborGenerator.h │ │ ├── SparseMatrix.h │ │ ├── SparseMatrix.hh │ │ ├── WifiLDPC.h │ │ ├── WordWidthTransformer.h │ │ └── WordWidthTransformer.hh │ ├── null │ │ ├── NullDecoder.h │ │ └── NullEncoder.h │ ├── puncturing │ │ ├── IPuncturingSchedule.h │ │ ├── RepeatingPuncturingSchedule.h │ │ ├── RoundRobinPuncturingSchedule.h │ │ ├── StaticPuncturingSchedule.h │ │ └── StridedPuncturingSchedule.h │ ├── spinal │ │ ├── CodeFactory.h │ │ ├── Composites.h │ │ ├── FlatSymbolStorage.h │ │ ├── FlatSymbolStorage.hh │ │ ├── HashDecoder.h │ │ ├── HashDecoder.hh │ │ ├── HashEncoder.h │ │ ├── HashEncoder.hh │ │ ├── IHashDecoder.h │ │ ├── SpinalBranchEvaluator.h │ │ ├── StubHashDecoder.h │ │ └── protocols │ │ │ ├── SequentialProtocol.h │ │ │ ├── SequentialProtocol.hh │ │ │ └── StridedProtocol.h │ ├── strider │ │ ├── LayerManipulator.h │ │ ├── LayerSuperposition.h │ │ ├── LayeredDecoder.h │ │ ├── LayeredDecoder.hh │ │ ├── LayeredEncoder.h │ │ ├── StriderFactory.h │ │ ├── StriderGeneratorMatrix.h │ │ ├── StriderInterleaver.h │ │ └── StriderTurboCode.h │ └── turbo │ │ ├── TurboCodec.h │ │ ├── TurboDecoder.h │ │ └── TurboEncoder.h ├── demappers │ ├── BitwiseDemapper.h │ ├── BitwiseDemapper.hh │ ├── BscDemapper.h │ ├── IDemapper.h │ ├── ItppDemapper.h │ ├── ItppDemapper.hh │ └── NullDemapper.h ├── mappers │ ├── ComplexLinearMapper.h │ ├── GaussianMapper.h │ ├── GrayMapper.h │ ├── IMapper.h │ ├── LinearMapper.h │ ├── NormalDistribution.h │ ├── QPSKMapper.h │ ├── QamMapper.h │ ├── SoftMapper.h │ └── TruncatedNormalDistribution.h ├── protocols │ ├── OneTryProtocol.h │ └── RateApproxProtocol.h └── util │ ├── BitStatCounter.h │ ├── BlockStatCounter.h │ ├── ItppUtils.h │ ├── MTRand.h │ ├── Utils.h │ ├── crc.h │ ├── hashes │ ├── BitwiseXor.h │ ├── Lookup3Hash.h │ ├── OneAtATimeHash.h │ ├── SWIGHash.h │ ├── SalsaHash.h │ ├── ShiftRegisterAdaptorHash.h │ ├── SingleSymbolFunction.h │ ├── UnlimitedHash.h │ ├── UnlimitedHash.hh │ ├── ecrypt-config.h │ ├── ecrypt-machine.h │ ├── ecrypt-portable.h │ └── salsa20.h │ └── inference │ ├── bp │ ├── BPMessage.h │ ├── BipartiteBP.h │ ├── BipartiteGraph.h │ ├── ElementHeap.h │ ├── LinearVariableNodeUpdater.h │ ├── MessagePassingDecoder.h │ ├── MessagePassingDecoder.hh │ ├── MultiStack.h │ ├── MultiVector.h │ └── NodeUpdater.h │ └── hmm │ ├── Backtracker.h │ ├── BeamSearch.h │ ├── BestK.h │ ├── DualPool.h │ ├── IPruner.h │ ├── LookaheadAdaptor.h │ ├── LookaheadBeamSearch.h │ └── ParallelBestK.h ├── lablog ├── .project ├── .pydevproject ├── Makefile.am ├── configure.ac ├── python │ ├── Distribute.py │ ├── ExperimentRepository.py │ ├── Results.py │ ├── SqliteExperimentRepository.py │ └── __init__.py └── test │ ├── DistributeTests.py │ ├── ExperimentRepositoryTests.py │ └── ResultsTests.py ├── python ├── Makefile.am ├── codes │ ├── __init__.py │ └── spinal │ │ ├── __init__.py │ │ └── reference │ │ ├── Decoder.py │ │ ├── Encoder.py │ │ ├── Example1.py │ │ ├── Hash.py │ │ ├── Lookup3Hash.py │ │ ├── RNG.py │ │ ├── SalsaHash.py │ │ ├── SymbolMapper.py │ │ └── __init__.py ├── protocols │ ├── MultipleTryProtocol.py │ └── __init__.py ├── simulator │ ├── FactoryCollection.py │ ├── SanityTest.py │ ├── Simulator.py │ ├── __init__.py │ ├── default_configuration.py │ └── factories │ │ ├── ChannelFactory.py │ │ ├── DemapFactory.py │ │ ├── DetectorFactory.py │ │ ├── MapFactory.py │ │ ├── PacketGenFactory.py │ │ ├── ProtocolFactory.py │ │ ├── StatisticsFactory.py │ │ ├── __init__.py │ │ └── codes │ │ ├── FadingStriderFactory.py │ │ ├── LTFactory.py │ │ ├── LdpcFactory.py │ │ ├── MultiplexedFactory.py │ │ ├── NullFactory.py │ │ ├── RaptorFactory.py │ │ ├── SpinalFactory.py │ │ ├── StriderFactory.py │ │ ├── TurboFactory.py │ │ └── __init__.py ├── statistics │ ├── ErrorLocationStatistics.py │ ├── ErrorRateStatistics.py │ ├── FirstErrorStatistics.py │ └── __init__.py └── util │ └── serialization │ ├── __init__.py │ └── results.proto ├── src ├── CrcPacketGenerator.cpp ├── Makefile.am ├── PacketGenerator.cpp ├── channels │ ├── BscChannel.cpp │ ├── CoherenceCoeffGenerator.cpp │ └── MimoChannel.cpp ├── codes │ ├── EncoderMultiplexer.cpp │ ├── InterleavedEncoder.cpp │ ├── MultiToSingleStreamEncoder.cpp │ ├── RandomPermutationGenerator.cpp │ ├── fountain │ │ ├── LTDecoder.cpp │ │ ├── LTParityNeighborGenerator.cpp │ │ ├── RaptorDecoder.cpp │ │ └── RaptorEncoder.cpp │ ├── ldpc │ │ ├── LinearCheckNodeUpdater.cpp │ │ ├── MatrixLDPCCode.cpp │ │ ├── MatrixLDPCDecoder.cpp │ │ ├── MatrixLDPCEncoder.cpp │ │ ├── MatrixLDPCNeighborGenerator.cpp │ │ └── WifiLDPC.cpp │ ├── null │ │ ├── NullDecoder.cpp │ │ └── NullEncoder.cpp │ ├── puncturing │ │ ├── RepeatingPuncturingSchedule.cpp │ │ ├── RoundRobinPuncturingSchedule.cpp │ │ ├── StaticPuncturingSchedule.cpp │ │ └── StridedPuncturingSchedule.cpp │ ├── spinal │ │ ├── CodeFactory.cpp │ │ ├── SpinalBranchEvaluator.cpp │ │ ├── StubHashDecoder.cpp │ │ └── protocols │ │ │ └── StridedProtocol.cpp │ ├── strider │ │ ├── LayerManipulator.cpp │ │ ├── LayerSuperposition.cpp │ │ ├── LayeredEncoder.cpp │ │ ├── StriderFactory.cpp │ │ ├── StriderGeneratorMatrix.cpp │ │ ├── StriderInterleaver.cpp │ │ └── StriderTurboCode.cpp │ └── turbo │ │ ├── TurboCodec.cpp │ │ ├── TurboDecoder.cpp │ │ └── TurboEncoder.cpp ├── demappers │ ├── BscDemapper.cpp │ └── NullDemapper.cpp ├── mappers │ ├── ComplexLinearMapper.cpp │ ├── GaussianMapper.cpp │ ├── GrayMapper.cpp │ ├── LinearMapper.cpp │ ├── NormalDistribution.cpp │ ├── QPSKMapper.cpp │ ├── QamMapper.cpp │ ├── SoftMapper.cpp │ └── TruncatedNormalDistribution.cpp ├── protocols │ ├── OneTryProtocol.cpp │ └── RateApproxProtocol.cpp └── util │ ├── BitStatCounter.cpp │ ├── BlockStatCounter.cpp │ ├── ItppUtils.cpp │ ├── Utils.cpp │ ├── crc.cpp │ ├── hashes │ ├── BitwiseXor.cpp │ ├── Lookup3Hash.cpp │ ├── OneAtATimeHash.cpp │ ├── SalsaHash.cpp │ └── salsa20.cpp │ └── inference │ └── bp │ ├── BipartiteBP.cpp │ └── LinearVariableNodeUpdater.cpp ├── test ├── UtilsTests.py ├── codes │ ├── InterleavedEncoderTests.py │ ├── fountain │ │ └── ParityEncoderTests.py │ ├── ldpc │ │ ├── MatrixLDPCDecodingTests.py │ │ ├── MatrixLDPCNeighborGeneratorTests.py │ │ └── WordWidthTransformerTests.py │ ├── spinal │ │ ├── CachedHashEncoderTests.py │ │ ├── EncoderDecoderTests.py │ │ ├── PuncturedEncoderTests.py │ │ ├── PuncturingScheduleTests.py │ │ ├── RepeatingPuncturingScheduleTests.py │ │ ├── StridedProtocolTests.py │ │ └── StridedPuncturingScheduleTests.py │ ├── strider │ │ ├── LayerSuperpositionTests.py │ │ ├── StriderEncoderTests.py │ │ ├── StriderTurboTests.py │ │ ├── strider-message.dat │ │ ├── strider_packets_doubles_imag.dat │ │ ├── strider_packets_doubles_real.dat │ │ ├── turbo-interleaved-1530.dat │ │ └── turbo-message-1530.dat │ └── turbo │ │ ├── TurboCodecTests.py │ │ ├── test-codeword-1530.dat │ │ └── test-message-1530.dat └── demappers │ └── BitwiseDemapperTests.py └── util ├── GenerateCrcCode.py ├── GenerateRaptorLDPC.py ├── MatrixLDPC.py └── TurboPuncturing.py /.gitignore: -------------------------------------------------------------------------------- 1 | aclocal.m4 2 | config.h.in 3 | configure 4 | Makefile.in 5 | MANIFEST.in 6 | autom4te.cache 7 | build-aux 8 | install-sh 9 | missing 10 | py-compile 11 | release/ 12 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | wireless 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.ui.externaltools.ExternalToolBuilder 15 | full,incremental, 16 | 17 | 18 | LaunchConfigHandle 19 | <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder (1).launch 20 | 21 | 22 | 23 | 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 25 | full,incremental, 26 | 27 | 28 | 29 | 30 | 31 | org.eclipse.cdt.core.cnature 32 | org.eclipse.cdt.core.ccnature 33 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 34 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 35 | org.python.pydev.pythonNature 36 | 37 | 38 | -------------------------------------------------------------------------------- /.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Default 6 | python 2.7 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | With some exceptions, the contents are licensed under the following license (the MIT license): 2 | 3 | Copyright (c) 2012 Jonathan Perry 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | 12 | Notable exceptions: 13 | ==================== 14 | include/util/MTRand.h 15 | based on a "BSD New"-licensed file by Makoto Matsumoto, Takuji Nishimura, and Richard J. Wagner. 16 | see the source code for more information. 17 | 18 | src/util/crc.cpp 19 | based on a CRC implementation generated by the MIT-licensed crcmod 20 | 21 | src/util/salsa20.cpp 22 | Based on D.J.Bernstein's salsa in the public domain; modifications also in the public domain. 23 | include/util/ecrypt-config.h 24 | include/util/ecrypt-machine.h 25 | include/util/ecrypt-portable.h 26 | From eSTREAM software performance testing platform, used for Salsa implementation 27 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = python src bindings data lablog include 2 | 3 | ACLOCAL_AMFLAGS = -I build-aux/m4 4 | 5 | EXTRA_DIST = LICENSE 6 | -------------------------------------------------------------------------------- /bindings/__init__.py: -------------------------------------------------------------------------------- 1 | import util 2 | 3 | import general 4 | import channels 5 | import mappers 6 | import demappers 7 | import codes 8 | import codes.strider 9 | import codes.turbo 10 | import codes.ldpc 11 | import codes.fountain 12 | import codes.spinal 13 | import codes.null 14 | 15 | import misc 16 | import statistics 17 | import protocols 18 | 19 | from general import * 20 | from misc import * 21 | 22 | -------------------------------------------------------------------------------- /bindings/codes/Makefile.am: -------------------------------------------------------------------------------- 1 | # bindings/codes Makefile 2 | 3 | SUBDIRS = spinal 4 | 5 | ## Flags and commands 6 | # use python flags; add project-wide include directory; only shared libraries are required. 7 | AM_CPPFLAGS += $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/include 8 | AM_CXXFLAGS += -shared 9 | AM_LDFLAGS += $(PYTHON_EXTRA_LDFLAGS) -module 10 | SWIG_CMD = $(SWIG) $(AX_SWIG_PYTHON_OPT) $(AX_SWIG_PYTHON_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/.. -DHAVE_CONFIG_H 11 | 12 | # Libraries made in this directory 13 | codes_execdir = ${pkgpyexecdir}/codes 14 | codes_pythondir = ${pkgpythondir}/codes 15 | 16 | codes_exec_LTLIBRARIES = _codes.la _fountain.la _strider.la _turbo.la _ldpc.la _null.la 17 | 18 | codes_python_PYTHON = __init__.py 19 | 20 | codes_python_PYTHON += codes.py 21 | _codes_la_SOURCES = codes.i 22 | _codes_la_LIBADD = -L../../src -lwireless 23 | 24 | codes_python_PYTHON += fountain.py 25 | _fountain_la_SOURCES = fountain.i 26 | _fountain_la_LIBADD = -L../../src -lwireless 27 | 28 | codes_python_PYTHON += strider.py 29 | _strider_la_SOURCES = strider.i 30 | _strider_la_LIBADD = -L../../src -lwireless 31 | 32 | codes_python_PYTHON += turbo.py 33 | _turbo_la_SOURCES = turbo.i 34 | _turbo_la_LIBADD = -L../../src -lwireless 35 | 36 | codes_python_PYTHON += ldpc.py 37 | _ldpc_la_SOURCES = ldpc.i 38 | _ldpc_la_LIBADD = -L../../src -lwireless 39 | 40 | codes_python_PYTHON += null.py 41 | _null_la_SOURCES = null.i 42 | _null_la_LIBADD = -L../../src -lwireless 43 | 44 | .i.cpp: 45 | $(SWIG_CMD) -o $@ $< 46 | -------------------------------------------------------------------------------- /bindings/codes/__init__.py: -------------------------------------------------------------------------------- 1 | from codes import * 2 | -------------------------------------------------------------------------------- /bindings/codes/codes_workaround.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | %{ 7 | #include "codes/SymbolToLLRDecoderAdaptor.h" 8 | #include "codes/InterleavedEncoder.h" 9 | #include "codes/EncoderMultiplexer.h" 10 | #include "codes/puncturing/IPuncturingSchedule.h" 11 | #include "codes/puncturing/StridedPuncturingSchedule.h" 12 | #include "codes/puncturing/StaticPuncturingSchedule.h" 13 | #include "codes/puncturing/RepeatingPuncturingSchedule.h" 14 | #include "codes/puncturing/RoundRobinPuncturingSchedule.h" 15 | #include "codes/MultiToSingleStreamEncoder.h" 16 | #include "codes/MultiToSingleStreamDecoder.h" 17 | 18 | // demappers: 19 | #include 20 | using namespace itpp; 21 | #include "demappers/ItppDemapper.h" 22 | 23 | // mappers: 24 | #include "mappers/QPSKMapper.h" 25 | #include "mappers/QamMapper.h" 26 | 27 | %} 28 | -------------------------------------------------------------------------------- /bindings/codes/fountain.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.codes") fountain 6 | 7 | %include "common.i" 8 | %include "codes/codes_workaround.i" 9 | %import "codes/codes.i" 10 | 11 | // Fix import problem in hashes 12 | %include "carrays.i" 13 | %array_class(unsigned int, uint32_Array) 14 | %import "util/hashes.i" 15 | 16 | 17 | %shared_ptr(LTDecoder) 18 | %shared_ptr(RaptorDecoder) 19 | 20 | %{ 21 | #include "util/hashes/BitwiseXor.h" 22 | 23 | #include "codes/fountain/LTParityNeighborGenerator.h" 24 | #include "codes/fountain/ParityEncoder.h" 25 | #include "codes/fountain/LTDecoder.h" 26 | #include "codes/fountain/RaptorEncoder.h" 27 | #include "codes/fountain/RaptorDecoder.h" 28 | 29 | %} 30 | 31 | %include "codes/fountain/LTParityNeighborGenerator.h" 32 | %include "codes/fountain/ParityEncoder.h" 33 | %include "codes/fountain/LTDecoder.h" 34 | %include "codes/fountain/RaptorEncoder.h" 35 | %include "codes/fountain/RaptorDecoder.h" 36 | 37 | %template(LTEncoder) ParityEncoder; 38 | -------------------------------------------------------------------------------- /bindings/codes/ldpc.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.codes") ldpc 6 | 7 | %include "common.i" 8 | %include "codes/codes_workaround.i" 9 | %import "codes/codes.i" 10 | 11 | ///////////////// 12 | // Smart pointers 13 | ///////////////// 14 | %shared_ptr(MatrixLDPCEncoder) 15 | 16 | 17 | %{ 18 | #include "codes/ldpc/WordWidthTransformer.h" 19 | #include "codes/ldpc/SparseMatrix.h" 20 | #include "codes/ldpc/MatrixLDPCCode.h" 21 | #include "codes/ldpc/MatrixLDPCEncoder.h" 22 | #include "codes/ldpc/MatrixLDPCDecoder.h" 23 | #include "codes/ldpc/WifiLDPC.h" 24 | %} 25 | 26 | %include "codes/ldpc/WordWidthTransformer.h" 27 | %include "codes/ldpc/SparseMatrix.h" 28 | %include "codes/ldpc/MatrixLDPCCode.h" 29 | %include "codes/ldpc/MatrixLDPCEncoder.h" 30 | %include "codes/ldpc/MatrixLDPCDecoder.h" 31 | %include "codes/ldpc/WifiLDPC.h" 32 | 33 | %template(UcharSparseMatrix) SparseMatrix; 34 | -------------------------------------------------------------------------------- /bindings/codes/null.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.codes") null 6 | 7 | %include "common.i" 8 | %include "codes/codes_workaround.i" 9 | %import "codes/codes.i" 10 | 11 | // Fix import problem in hashes 12 | %include "carrays.i" 13 | %array_class(unsigned int, uint32_Array) 14 | %import "util/hashes.i" 15 | 16 | 17 | %shared_ptr(NullEncoder) 18 | %shared_ptr(NullDecoder) 19 | 20 | %{ 21 | #include "codes/null/NullEncoder.h" 22 | #include "codes/null/NullDecoder.h" 23 | %} 24 | 25 | %include "codes/null/NullEncoder.h" 26 | %include "codes/null/NullDecoder.h" 27 | -------------------------------------------------------------------------------- /bindings/codes/spinal/Makefile.am: -------------------------------------------------------------------------------- 1 | # bindings/codes/spinal Makefile 2 | 3 | ## Flags and commands 4 | # use python flags; add project-wide include directory; only shared libraries are required. 5 | AM_CPPFLAGS += $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/include 6 | AM_CXXFLAGS += -shared 7 | AM_LDFLAGS += $(PYTHON_EXTRA_LDFLAGS) -module 8 | SWIG_CMD = $(SWIG) $(AX_SWIG_PYTHON_OPT) $(AX_SWIG_PYTHON_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/../.. -DHAVE_CONFIG_H 9 | 10 | # Libraries made in this directory 11 | spinal_execdir = ${pkgpyexecdir}/codes/spinal 12 | spinal_pythondir = ${pkgpythondir}/codes/spinal 13 | 14 | spinal_exec_LTLIBRARIES = _spinal.la 15 | 16 | spinal_python_PYTHON = __init__.py 17 | 18 | spinal_python_PYTHON += spinal.py 19 | _spinal_la_SOURCES = spinal.i 20 | _spinal_la_LIBADD = -L../../../src -lspinal 21 | 22 | .i.cpp: 23 | $(SWIG_CMD) -o $@ $< 24 | -------------------------------------------------------------------------------- /bindings/codes/spinal/__init__.py: -------------------------------------------------------------------------------- 1 | from spinal import * 2 | import reference 3 | -------------------------------------------------------------------------------- /bindings/codes/strider.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.codes") strider 6 | 7 | %include "common.i" 8 | %include "codes/codes_workaround.i" 9 | %import "codes/codes.i" 10 | %include "mappers_workaround.i" 11 | %import "mappers.i" 12 | 13 | ///////////////// 14 | // numpy 15 | //////////////// 16 | 17 | %numpy_typemaps(std::complex, NPY_CDOUBLE , int); 18 | %apply (std::complex* IN_ARRAY2, int DIM1, int DIM2) {(std::complex* matrixG, 19 | int rowsG, 20 | int colsG)} 21 | %apply (std::complex* INPLACE_ARRAY2, int DIM1, int DIM2) {(std::complex* outMatrixG, 22 | int rowsG, 23 | int colsG)} 24 | 25 | ///////////////// 26 | // Smart pointers 27 | ///////////////// 28 | %shared_ptr(LayeredEncoder) 29 | %shared_ptr(LayeredDecoder) 30 | 31 | 32 | %{ 33 | #include "codes/strider/LayeredEncoder.h" 34 | #include "codes/strider/LayerSuperposition.h" 35 | #include "codes/strider/StriderTurboCode.h" 36 | #include "codes/strider/LayeredDecoder.h" 37 | #include "codes/strider/StriderGeneratorMatrix.h" 38 | #include "codes/strider/StriderFactory.h" 39 | %} 40 | 41 | %include "codes/strider/LayeredEncoder.h" 42 | %include "codes/strider/LayerSuperposition.h" 43 | %include "codes/strider/StriderTurboCode.h" 44 | %include "codes/strider/LayeredDecoder.h" 45 | %include "codes/strider/StriderGeneratorMatrix.h" 46 | %include "codes/strider/StriderFactory.h" 47 | 48 | 49 | %template(ComplexLayeredDecoder) LayeredDecoder; 50 | -------------------------------------------------------------------------------- /bindings/codes/turbo.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.codes") turbo 6 | 7 | %include "common.i" 8 | %include "codes/codes_workaround.i" 9 | %import "codes/codes.i" 10 | 11 | %shared_ptr(TurboEncoder) 12 | %shared_ptr(TurboDecoder) 13 | %shared_ptr(InterleavedDecoder) 14 | 15 | %{ 16 | #include "codes/turbo/TurboEncoder.h" 17 | #include "codes/turbo/TurboDecoder.h" 18 | #include "codes/InterleavedDecoder.h" 19 | %} 20 | 21 | %include "codes/turbo/TurboEncoder.h" 22 | %include "codes/turbo/TurboDecoder.h" 23 | %include "codes/InterleavedDecoder.h" 24 | 25 | %template(InterleavedTurboDecoder) InterleavedDecoder; -------------------------------------------------------------------------------- /bindings/common.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | /////////////////////// 7 | // Exception handling 8 | /////////////////////// 9 | %include exception.i 10 | 11 | %{ 12 | #include 13 | %} 14 | 15 | %exception { 16 | try { 17 | $function 18 | } catch(const std::exception& err) { 19 | SWIG_exception(SWIG_RuntimeError, err.what()); 20 | } catch(...) { 21 | SWIG_exception(SWIG_RuntimeError, "Unknown exception"); 22 | } 23 | } 24 | 25 | ///////////////// 26 | // numpy 27 | //////////////// 28 | %{ 29 | // numpy initialization 30 | #define SWIG_FILE_WITH_INIT 31 | %} 32 | %include "numpy.i" 33 | 34 | %init %{ 35 | import_array(); 36 | %} 37 | 38 | ///////////////// 39 | // Smart pointers 40 | ///////////////// 41 | #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 42 | %include 43 | %{ 44 | #include 45 | %} 46 | 47 | -------------------------------------------------------------------------------- /bindings/demappers.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless") demappers 6 | 7 | %include "common.i" 8 | %import "general.i" 9 | %import "mappers.i" 10 | %include "mappers_workaround.i" 11 | %import "itpp/modulator.i" 12 | 13 | ///////////////// 14 | // numpy 15 | //////////////// 16 | 17 | %apply (unsigned int* INPLACE_ARRAY1, int DIM1) {(unsigned int* const seed, 18 | int seedSize)} 19 | 20 | 21 | %{ 22 | #include "demappers/IDemapper.h" 23 | #include "demappers/BitwiseDemapper.h" 24 | #include "demappers/BscDemapper.h" 25 | #include "demappers/NullDemapper.h" 26 | #include "demappers/ItppDemapper.h" 27 | 28 | // For GrayDemapper typedef 29 | #include "mappers/GrayMapper.h" 30 | 31 | // Workaround for %import problem 32 | using namespace itpp; 33 | %} 34 | 35 | %include "demappers/IDemapper.h" 36 | %include "demappers/BitwiseDemapper.h" 37 | %include "demappers/BscDemapper.h" 38 | %include "demappers/NullDemapper.h" 39 | %include "demappers/ItppDemapper.h" 40 | 41 | %shared_ptr(IDemapper) 42 | %template(template_IDemapper_Symbol) IDemapper; 43 | 44 | %shared_ptr(IDemapper) 45 | %template(template_IDemapper_ComplexSymbol) IDemapper; 46 | %template(GrayDemapper) BitwiseDemapper; 47 | 48 | %shared_ptr(ItppDemapper) 49 | %template(ItppComplexDemapper) ItppDemapper; 50 | -------------------------------------------------------------------------------- /bindings/demappers_workaround.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | %include "mappers_workaround.i" 7 | 8 | %{ 9 | #include 10 | #include "demappers/ItppDemapper.h" 11 | %} -------------------------------------------------------------------------------- /bindings/general.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless") general 6 | 7 | %include "common.i" 8 | 9 | ////////////////// 10 | // STL 11 | ////////////////// 12 | %include "std_string.i" 13 | %include "std_vector.i" 14 | %include "std_complex.i" 15 | %include "stdint.i" 16 | 17 | %{ 18 | #include 19 | #include 20 | #include 21 | #include "CodeBench.h" 22 | #include "util/MTRand.h" 23 | %} 24 | 25 | %include "CodeBench.h" 26 | %include "util/MTRand.h" 27 | 28 | %pythoncode %{ 29 | Symbol = int 30 | SoftSymbol = float 31 | N0_t = float 32 | FadingMagnitude = float 33 | LLRValue = float 34 | ComplexSymbol = complex 35 | %} 36 | 37 | 38 | %template(FadingSymbol) FadingSymbolTuple; 39 | %template(FadingComplexSymbol) FadingSymbolTuple; 40 | 41 | 42 | // VECTOR TYPES 43 | namespace std { 44 | %template(vectori) vector; 45 | %template(vectorcf) vector< std::complex >; 46 | %template(vectorcd) vector< std::complex >; 47 | %template(vectorui) vector; 48 | %template(vectorus) vector; 49 | %template(vectors) vector; 50 | %template(vectorul) vector; 51 | %template(vectorull) vector; 52 | %template(vectorb) vector; 53 | %template(vectorf) vector; 54 | %template(vectorstr) vector; 55 | 56 | %template(vector_fadingsymbol) vector; 57 | %template(vector_fading_csymbol) vector; 58 | }; 59 | 60 | 61 | %pythoncode %{ 62 | vector_csymbol = vectorcd 63 | vector_symbol = vectori 64 | vector_softsymbol = vectorf 65 | vector_llr = vectorf 66 | %} -------------------------------------------------------------------------------- /bindings/itpp/Makefile.am: -------------------------------------------------------------------------------- 1 | # bindings/itpp Makefile 2 | 3 | ## Flags and commands 4 | # use python flags; add project-wide include directory; only shared libraries are required. 5 | AM_CPPFLAGS += $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/include 6 | AM_CXXFLAGS += -shared 7 | AM_LDFLAGS += $(PYTHON_EXTRA_LDFLAGS) -module 8 | SWIG_CMD = $(SWIG) $(AX_SWIG_PYTHON_OPT) $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/.. -DHAVE_CONFIG_H 9 | 10 | # Directories 11 | itpp_execdir = ${pkgpyexecdir}/itpp 12 | itpp_pythondir = ${pkgpythondir}/itpp 13 | 14 | # Libraries made in this directory 15 | itpp_exec_LTLIBRARIES = _base_sparse.la _base_vec.la _ldpc.la _llr.la _modulator.la 16 | itpp_python_PYTHON = __init__.py 17 | 18 | itpp_python_PYTHON += base_sparse.py 19 | _base_sparse_la_SOURCES = base_sparse.i 20 | _base_sparse_la_LIBADD = $(ITPP_LIBS) 21 | 22 | itpp_python_PYTHON += base_vec.py 23 | _base_vec_la_SOURCES = base_vec.i 24 | _base_vec_la_LIBADD = $(ITPP_LIBS) 25 | 26 | itpp_python_PYTHON += ldpc.py 27 | _ldpc_la_SOURCES = ldpc.i 28 | _ldpc_la_LIBADD = $(ITPP_LIBS) 29 | 30 | itpp_python_PYTHON += llr.py 31 | _llr_la_SOURCES = llr.i 32 | _llr_la_LIBADD = $(ITPP_LIBS) 33 | 34 | itpp_python_PYTHON += modulator.py 35 | _modulator_la_SOURCES = modulator.i 36 | _modulator_la_LIBADD = $(ITPP_LIBS) 37 | 38 | .i.cpp: 39 | $(SWIG_CMD) -o $@ $< 40 | -------------------------------------------------------------------------------- /bindings/itpp/__init__.py: -------------------------------------------------------------------------------- 1 | from base_vec import * 2 | from base_sparse import * 3 | from modulator import * 4 | from ldpc import * 5 | from llr import * -------------------------------------------------------------------------------- /bindings/itpp/ldpc.i: -------------------------------------------------------------------------------- 1 | %module(package="wireless.itpp") ldpc 2 | 3 | /////////////////////// 4 | // Exception handling 5 | /////////////////////// 6 | %include exception.i 7 | 8 | %exception { 9 | try { 10 | $action 11 | } 12 | SWIG_CATCH_STDEXCEPT 13 | catch (...) { 14 | SWIG_exception(SWIG_UnknownError, "Unknown exception"); 15 | } 16 | } 17 | 18 | ///////////////// 19 | // Smart pointers 20 | ///////////////// 21 | #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 22 | %include 23 | %{ 24 | #include 25 | %} 26 | 27 | 28 | ////////////////// 29 | // General code-related 30 | ////////////////// 31 | %{ 32 | #include 33 | #include 34 | using namespace itpp; 35 | %} 36 | 37 | %import "base_vec.i" 38 | %import "base_sparse.i" 39 | 40 | %include 41 | 42 | 43 | %ignore operator<<(std::ostream &os, const LDPC_Code &C); 44 | 45 | %include 46 | -------------------------------------------------------------------------------- /bindings/itpp/llr.i: -------------------------------------------------------------------------------- 1 | %module(package="wireless.itpp") llr 2 | 3 | /////////////////////// 4 | // Exception handling 5 | /////////////////////// 6 | %include exception.i 7 | 8 | %exception { 9 | try { 10 | $action 11 | } 12 | SWIG_CATCH_STDEXCEPT 13 | catch (...) { 14 | SWIG_exception(SWIG_UnknownError, "Unknown exception"); 15 | } 16 | } 17 | 18 | ///////////////// 19 | // Smart pointers 20 | ///////////////// 21 | #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 22 | %include 23 | %{ 24 | #include 25 | %} 26 | 27 | 28 | ////////////////// 29 | // General code-related 30 | ////////////////// 31 | %{ 32 | #include 33 | using namespace itpp; 34 | %} 35 | 36 | 37 | %ignore operator<<(std::ostream &os, const LLR_calc_unit &l); 38 | %include 39 | 40 | 41 | -------------------------------------------------------------------------------- /bindings/mappers.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless") mappers 6 | 7 | %include "common.i" 8 | %import "general.i" 9 | 10 | ///////////////// 11 | // numpy 12 | //////////////// 13 | 14 | ///////////////// 15 | // Smart pointers 16 | ///////////////// 17 | %shared_ptr(IMapper) 18 | %shared_ptr(QPSKMapper) 19 | %shared_ptr(QamMapper) 20 | %shared_ptr(LinearMapper) 21 | 22 | 23 | %{ 24 | #include "mappers/IMapper.h" 25 | #include "mappers/LinearMapper.h" 26 | #include "mappers/GrayMapper.h" 27 | #include "mappers/GaussianMapper.h" 28 | #include "mappers/NormalDistribution.h" 29 | #include "mappers/TruncatedNormalDistribution.h" 30 | #include "mappers/QPSKMapper.h" 31 | #include "mappers/SoftMapper.h" 32 | #include "mappers/ComplexLinearMapper.h" 33 | #include "mappers/QamMapper.h" 34 | %} 35 | 36 | %include "mappers/IMapper.h" 37 | %template(IComplexMapper) IMapper; 38 | 39 | %include "mappers/LinearMapper.h" 40 | %include "mappers/GrayMapper.h" 41 | %include "mappers/GaussianMapper.h" 42 | %include "mappers/TruncatedNormalDistribution.h" 43 | %include "mappers/NormalDistribution.h" 44 | %include "mappers/QPSKMapper.h" 45 | %include "mappers/SoftMapper.h" 46 | %include "mappers/ComplexLinearMapper.h" 47 | %include "mappers/QamMapper.h" 48 | 49 | -------------------------------------------------------------------------------- /bindings/mappers_workaround.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | %{ 7 | #include "mappers/QPSKMapper.h" 8 | #include "mappers/QamMapper.h" 9 | %} 10 | 11 | -------------------------------------------------------------------------------- /bindings/misc.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless") misc 6 | 7 | %include "common.i" 8 | %import "general.i" 9 | %include "codes/codes_workaround.i" 10 | %import "codes/codes.i" 11 | 12 | ///////////////// 13 | // numpy 14 | //////////////// 15 | 16 | %apply (unsigned int* INPLACE_ARRAY1, int DIM1) {(unsigned int* const seed, 17 | int seedSize)} 18 | 19 | 20 | %{ 21 | #include "PacketGenerator.h" 22 | #include "CrcPacketGenerator.h" 23 | 24 | #include "OracleDetector.h" 25 | #include "CrcDetector.h" 26 | #include "ComposedTransformation.h" 27 | 28 | // For DefaultOracleDetector 29 | #include "codes/IDecoder.h" 30 | %} 31 | 32 | %include "PacketGenerator.h" 33 | %include "CrcPacketGenerator.h" 34 | 35 | %include "OracleDetector.h" 36 | %include "CrcDetector.h" 37 | %include "ComposedTransformation.h" 38 | 39 | %template(DefaultOracleDetector) OracleDetector; 40 | %template(DefaultCrcDetector) CrcDetector; 41 | 42 | 43 | // Utils class 44 | %{ 45 | #include "util/Utils.h" 46 | %} 47 | %include "util/Utils.h" 48 | %template(BlockifyUint32) Utils::blockify; 49 | 50 | // Extra utils: 51 | %{ 52 | #include "util/BitStatCounter.h" 53 | #include "util/BlockStatCounter.h" 54 | %} 55 | %include "util/BitStatCounter.h" 56 | %include "util/BlockStatCounter.h" 57 | -------------------------------------------------------------------------------- /bindings/protocols.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.protocols") protocols 6 | 7 | %include "common.i" 8 | %import "general.i" 9 | %include "codes/codes_workaround.i" 10 | %import "codes/codes.i" 11 | 12 | ///////////////// 13 | // numpy 14 | //////////////// 15 | 16 | %apply (unsigned int* INPLACE_ARRAY1, int DIM1) {(unsigned int* const seed, 17 | int seedSize)} 18 | 19 | ////////////////// 20 | // General code-related 21 | ////////////////// 22 | %{ 23 | #include "protocols/RateApproxProtocol.h" 24 | #include "protocols/OneTryProtocol.h" 25 | %} 26 | 27 | %include "protocols/RateApproxProtocol.h" 28 | %include "protocols/OneTryProtocol.h" 29 | -------------------------------------------------------------------------------- /bindings/util/Makefile.am: -------------------------------------------------------------------------------- 1 | # bindings/util Makefile 2 | 3 | ## Flags and commands 4 | # use python flags; add project-wide include directory; only shared libraries are required. 5 | AM_CPPFLAGS += $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/include 6 | AM_CXXFLAGS += -shared -DDATA_PATH='"$(datadir)"' 7 | AM_LDFLAGS += $(PYTHON_EXTRA_LDFLAGS) -module 8 | SWIG_CMD = $(SWIG) $(AX_SWIG_PYTHON_OPT) $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/.. -I${top_builddir} -DHAVE_CONFIG_H 9 | 10 | # Directories 11 | util_execdir = ${pkgpyexecdir}/util 12 | util_pythondir = ${pkgpythondir}/util 13 | 14 | # Libraries made in this directory 15 | util_exec_LTLIBRARIES = _hashes.la _inference.la _config.la 16 | util_python_PYTHON = __init__.py 17 | 18 | util_python_PYTHON += hashes.py 19 | _hashes_la_SOURCES = hashes.i 20 | _hashes_la_LIBADD = -L../../src -lwireless 21 | 22 | util_python_PYTHON += inference.py 23 | _inference_la_SOURCES = inference.i 24 | _inference_la_LIBADD = -L../../src -lwireless 25 | 26 | util_python_PYTHON += config.py 27 | _config_la_SOURCES = config.i 28 | _config_la_LIBADD = -L../../src -lwireless 29 | 30 | .i.cpp: 31 | $(SWIG_CMD) -o $@ $< 32 | -------------------------------------------------------------------------------- /bindings/util/__init__.py: -------------------------------------------------------------------------------- 1 | import hashes 2 | import inference 3 | import config 4 | -------------------------------------------------------------------------------- /bindings/util/config.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.util") config 6 | 7 | %include "std_string.i" 8 | 9 | %{ 10 | #include "config.h" 11 | 12 | std::string get_data_dir() { 13 | return DATA_PATH; 14 | } 15 | %} 16 | 17 | %include "config.h" 18 | 19 | std::string get_data_dir(); -------------------------------------------------------------------------------- /bindings/util/hashes.i: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | %module(package="wireless.util") hashes 6 | 7 | %include exception.i 8 | %include stdint.i 9 | 10 | /////////////////////// 11 | // Exception handling 12 | /////////////////////// 13 | 14 | %{ 15 | #include 16 | %} 17 | 18 | %exception { 19 | try { 20 | $function 21 | } catch(const std::exception& err) { 22 | SWIG_exception(SWIG_RuntimeError, err.what()); 23 | } catch(...) { 24 | SWIG_exception(SWIG_RuntimeError, "Unknown exception"); 25 | } 26 | } 27 | 28 | 29 | %{ 30 | #include "util/hashes/salsa20.h" 31 | #include "util/hashes/SalsaHash.h" 32 | #include "util/hashes/Lookup3Hash.h" 33 | #include "util/hashes/OneAtATimeHash.h" 34 | #include "util/hashes/UnlimitedHash.h" 35 | #include "util/hashes/BitwiseXor.h" 36 | #include "util/hashes/SingleSymbolFunction.h" 37 | #include "util/hashes/SWIGHash.h" 38 | 39 | #include "util/hashes/ShiftRegisterAdaptorHash.h" 40 | %} 41 | 42 | %include "util/hashes/salsa20.h" 43 | %include "util/hashes/SalsaHash.h" 44 | %include "util/hashes/Lookup3Hash.h" 45 | %include "util/hashes/OneAtATimeHash.h" 46 | %include "util/hashes/UnlimitedHash.h" 47 | %include "util/hashes/BitwiseXor.h" 48 | %include "util/hashes/SingleSymbolFunction.h" 49 | %include "util/hashes/SWIGHash.h" 50 | 51 | //%include "util/hashes/ShiftRegisterAdaptorHash.h" 52 | 53 | %template(BitwiseXorSymbolFunction) SingleSymbolFunction; 54 | 55 | %template(Lookup3UnlimitedHash) UnlimitedHash; 56 | %template(SalsaUnlimitedHash) UnlimitedHash; 57 | 58 | %template(Lookup3) SWIGHash; 59 | 60 | // Make types available 61 | %include "carrays.i" 62 | 63 | %array_class(unsigned int, uint32_Array) 64 | 65 | %pythoncode %{ 66 | # SALSA TYPES 67 | def SalsaState(): 68 | return uint32_Array(16) 69 | %} 70 | -------------------------------------------------------------------------------- /data/Makefile.am: -------------------------------------------------------------------------------- 1 | # data/ Makefile.am 2 | 3 | # distribute contents of data directory 4 | nobase_dist_data_DATA = \ 5 | ./ldpc/LDPC_3072.it \ 6 | ./ldpc/LDPC_9500.it \ 7 | ./ldpc/LDPC_256_rate0.5.it \ 8 | ./ldpc/LDPC_2048.it \ 9 | ./ldpc/LDPC_1024.it \ 10 | ./ldpc/LDPC_4096.it \ 11 | ./ldpc/LDPC_256_rate0.74.it \ 12 | ./ldpc/LDPC_256.it 13 | -------------------------------------------------------------------------------- /data/ldpc/LDPC_1024.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_1024.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_2048.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_2048.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_256.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_256.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_256_rate0.5.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_256_rate0.5.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_256_rate0.74.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_256_rate0.74.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_3072.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_3072.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_4096.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_4096.it -------------------------------------------------------------------------------- /data/ldpc/LDPC_9500.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/data/ldpc/LDPC_9500.it -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | html/ 2 | -------------------------------------------------------------------------------- /doc/doxygen-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /include/CodeBench.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | 14 | // IMPORTANT: Remember to change all reference in pyCoding.i if changing 15 | // the type of Symbol. 16 | typedef int Symbol; 17 | typedef float SoftSymbol; 18 | typedef double ComplexBaseType; 19 | typedef std::complex ComplexSymbol; 20 | typedef std::complex ComplexNumber; 21 | 22 | typedef float N0_t; 23 | typedef float FadingMagnitude; 24 | typedef float LLRValue; 25 | 26 | #define SYMBOL_MAX INT_MAX 27 | #define SYMBOL_MIN INT_MIN 28 | 29 | /** 30 | * Container for a symbol together with fading information 31 | */ 32 | template 33 | struct FadingSymbolTuple { 34 | // Symbol 35 | SymbolType symbol; 36 | 37 | // the fading magnitude 38 | FadingMagnitude fading; 39 | }; 40 | 41 | typedef FadingSymbolTuple FadingSymbol; 42 | typedef FadingSymbolTuple FadingComplexSymbol; 43 | -------------------------------------------------------------------------------- /include/CrcDetector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "util/Utils.h" 10 | 11 | /** 12 | * \ingroup detectors 13 | * \brief Detects whether the packet's CRC checks out 14 | */ 15 | template 16 | class CrcDetector { 17 | public: 18 | CrcDetector(unsigned int numPackets); 19 | 20 | /** 21 | * @param packetInd the index of the packet 22 | * @param packet the packet data 23 | */ 24 | void setPacket(unsigned int packetInd, const std::string& packet); 25 | 26 | /** 27 | * @return True if the decoded result is equal to the set packet 28 | */ 29 | bool isFinished(unsigned int packetInd, const DecodeResult& result); 30 | }; 31 | 32 | template 33 | inline CrcDetector::CrcDetector(unsigned int numPackets) 34 | {} 35 | 36 | template 37 | inline void CrcDetector::setPacket( 38 | unsigned int packetInd, 39 | const std::string & packet) 40 | { 41 | // nothing to be done; this class only relies on received CRC, thus doesn't need the real packet 42 | // to decide whether transmission is complete. 43 | } 44 | 45 | template 46 | inline bool CrcDetector::isFinished( 47 | unsigned int packetInd, 48 | const DecodeResult & result) 49 | { 50 | uint16_t crc = Utils::getArrCRC16((const uint8_t*)result.packet.data() + 2, 51 | result.packet.size() - 2); 52 | return (crc == *(uint16_t*)result.packet.data()); 53 | } 54 | -------------------------------------------------------------------------------- /include/CrcPacketGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "util/MTRand.h" 11 | 12 | using std::string; 13 | using std::vector; 14 | 15 | /** 16 | * \ingroup packetgen 17 | * \brief Generates packets with CRC32 18 | */ 19 | class CrcPacketGenerator 20 | { 21 | public: 22 | /** 23 | * C'tor 24 | * @param packetLengthBits the length of the packet, in bits. Must be not smaller than 40. 25 | */ 26 | CrcPacketGenerator(unsigned int packetLengthBits); 27 | 28 | /** 29 | * Seed the pseudo-random number generator 30 | * @param seedValue the seed 31 | */ 32 | void seed(unsigned int* const seed, int seedSize); 33 | 34 | /** 35 | * Generates a packet. 36 | * 37 | * The produced packets have CRC32 as first 4 bytes. 38 | */ 39 | string get(); 40 | 41 | private: 42 | // packet length, in bytes, of the desired packet 43 | unsigned int m_packetLengthBits; 44 | 45 | // random number generator 46 | MTRand m_random; 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /include/OracleDetector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | /** 11 | * \ingroup detectors 12 | * \brief Determines whether packet was decoded successfully by comparing to ground truth 13 | */ 14 | template 15 | class OracleDetector { 16 | public: 17 | OracleDetector(unsigned int numPackets); 18 | 19 | /** 20 | * @param packetInd the index of the packet 21 | * @param packet the packet data 22 | */ 23 | void setPacket(unsigned int packetInd, const std::string& packet); 24 | 25 | /** 26 | * @return True if the decoded result is equal to the set packet 27 | */ 28 | bool isFinished(unsigned int packetInd, const DecodeResult& result); 29 | private: 30 | // The packets 31 | std::vector m_packets; 32 | }; 33 | 34 | template 35 | inline OracleDetector::OracleDetector(unsigned int numPackets) 36 | : m_packets(numPackets) 37 | {} 38 | 39 | template 40 | inline void OracleDetector::setPacket( 41 | unsigned int packetInd, 42 | const std::string & packet) 43 | { 44 | m_packets[packetInd] = packet; 45 | } 46 | 47 | 48 | 49 | template 50 | inline bool OracleDetector::isFinished( 51 | unsigned int packetInd, 52 | const DecodeResult & result) 53 | { 54 | return result.packet == m_packets[packetInd]; 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /include/PacketGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "util/MTRand.h" 11 | 12 | using std::string; 13 | using std::vector; 14 | 15 | /** 16 | * \ingroup packetgen 17 | * \brief Generates random packets 18 | */ 19 | class PacketGenerator 20 | { 21 | public: 22 | /** 23 | * C'tor 24 | * @param packetLengthBits the length of the packet, in bits. Must be a 25 | * multiple of 8. 26 | */ 27 | PacketGenerator(unsigned int packetLengthBits); 28 | 29 | /** 30 | * Seed the pseudo-random number generator 31 | * @param seedValue the seed 32 | */ 33 | void seed(unsigned int* const seed, int seedSize); 34 | 35 | /** 36 | * Generates a packet. 37 | */ 38 | string get(); 39 | 40 | private: 41 | // packet length, in bytes, of the desired packet 42 | unsigned int m_packetLengthBits; 43 | 44 | // random number generator 45 | MTRand m_random; 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /include/channels/AwgnChannel.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../CodeBench.h" 11 | #include "AwgnNoiseGenerator.h" 12 | 13 | template 14 | inline AwgnChannel::AwgnChannel(N0_t n0) 15 | : m_stddevPerDimension(sqrt(n0 / 2.0)), 16 | m_random(0u) 17 | {} 18 | 19 | template 20 | inline void AwgnChannel::seed( 21 | unsigned int *const seed, 22 | int seedSize) 23 | { 24 | m_random.seed(seed, seedSize); 25 | } 26 | 27 | template 28 | inline void AwgnChannel::process( 29 | const std::vector & inSymbols, 30 | std::vector & outSymbols) 31 | { 32 | unsigned int symbolsSize = inSymbols.size(); 33 | outSymbols.clear(); 34 | outSymbols.resize(symbolsSize); 35 | for (unsigned int i = 0; i < symbolsSize; i++) { 36 | outSymbols[i] = noisify(inSymbols[i], m_stddevPerDimension); 37 | } 38 | } 39 | 40 | template 41 | inline unsigned int AwgnChannel::forecast(unsigned int numOutputs) 42 | { 43 | return numOutputs; 44 | } 45 | 46 | template 47 | inline double AwgnChannel::getStddevPerDimension() 48 | { 49 | return m_stddevPerDimension; 50 | } 51 | 52 | template 53 | inline ChannelSymbol AwgnChannel::noisify( 54 | ChannelSymbol x, 55 | double stddevPerDimension) 56 | { 57 | return AwgnNoiseGenerator::noisify(m_random, x, stddevPerDimension); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /include/channels/BscChannel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | 8 | #include 9 | #include "../CodeBench.h" 10 | #include "../util/MTRand.h" 11 | 12 | using std::vector; 13 | 14 | /** 15 | * \ingroup channels 16 | * \brief Simulates the Binary Symmetric Channel 17 | */ 18 | class BscChannel 19 | { 20 | public: 21 | typedef Symbol InputType; 22 | typedef Symbol OutputType; 23 | 24 | /** 25 | * C'tor 26 | * @param p: probability of a flip (ie 1-prob(remain same)) 27 | */ 28 | BscChannel(float p); 29 | 30 | /** 31 | * Seed the pseudo-random number generator 32 | * @param seedValue the seed 33 | */ 34 | void seed(unsigned int* const seed, int seedSize); 35 | 36 | /** 37 | * Adds noise to given symbols. 38 | * bits are flipped with probability p. 39 | */ 40 | void process(const std::vector& inSymbols, 41 | std::vector& outSymbols); 42 | 43 | /** 44 | * @return the number of input items needed to generate numOutputs output 45 | * items 46 | */ 47 | unsigned int forecast(unsigned int numOutputs); 48 | 49 | private: 50 | // probability of error 51 | float m_p; 52 | 53 | // random generator 54 | MTRand m_random; 55 | }; 56 | -------------------------------------------------------------------------------- /include/channels/CoherenceCoeffGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "../CodeBench.h" 10 | #include "../util/MTRand.h" 11 | 12 | /** 13 | * \ingroup channels 14 | * \brief Generates fading coefficients for coherence-time based fading 15 | */ 16 | class CoherenceCoeffGenerator { 17 | public: 18 | /** 19 | * C'tor 20 | * @param coherenceInterval: the number of symbols between re-randomization 21 | * of the fading coefficient 22 | */ 23 | CoherenceCoeffGenerator(uint32_t coherenceInterval); 24 | 25 | /** 26 | * Seed the pseudo-random number generator 27 | * @param seedValue the seed 28 | */ 29 | void seed(uint32_t* const seed, int seedSize); 30 | 31 | /** 32 | * @return the next fading coefficient 33 | */ 34 | FadingMagnitude next(); 35 | 36 | private: 37 | /** 38 | * Re-randomizes the fading coefficient 39 | */ 40 | void randomizeCoefficient(); 41 | 42 | // The coherence interval, in symbols 43 | const uint32_t m_coherenceInterval; 44 | 45 | // 1/sqrt(2) for randomization of fading coefficient 46 | const double m_sqrt2inv; 47 | 48 | // The random number generator 49 | MTRand m_random; 50 | 51 | // The current channel coefficient 52 | FadingMagnitude m_fadingCoeff; 53 | 54 | // Number of remaining symbols at the current coefficient before 55 | // re-randomization 56 | uint32_t m_remaining; 57 | }; 58 | -------------------------------------------------------------------------------- /include/channels/CoherenceFading.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | inline CoherenceFading::CoherenceFading( 11 | uint32_t coherenceInterval) 12 | : m_coeffGenerator(coherenceInterval) 13 | {} 14 | 15 | template 16 | void CoherenceFading::seed(uint32_t *const seed, int seedSize) 17 | { 18 | m_coeffGenerator.seed(seed, seedSize); 19 | } 20 | 21 | template 22 | inline void CoherenceFading::process( 23 | const std::vector & inSymbols, 24 | std::vector & outSymbols) 25 | { 26 | uint32_t numSymbols = inSymbols.size(); 27 | 28 | outSymbols.resize(numSymbols); 29 | 30 | for(uint32_t i = 0; i < numSymbols; i++) { 31 | FadingMagnitude fading = m_coeffGenerator.next(); 32 | outSymbols[i].fading = fading; 33 | outSymbols[i].symbol = inSymbols[i] * ComplexBaseType(fading); 34 | } 35 | } 36 | 37 | 38 | template 39 | unsigned int CoherenceFading::forecast(unsigned int numOutputs) { 40 | return numOutputs; 41 | } 42 | 43 | template 44 | inline void CoherenceFading::transform( 45 | const std::vector & inSymbols, 46 | const std::vector & observedSymbols, 47 | std::vector & outSymbols) const 48 | { 49 | uint32_t numSymbols = std::min(inSymbols.size(), observedSymbols.size()); 50 | 51 | outSymbols.resize(numSymbols); 52 | 53 | for(uint32_t i = 0; i < numSymbols; i++) { 54 | FadingMagnitude fading = observedSymbols[i].fading; 55 | outSymbols[i].fading = fading; 56 | outSymbols[i].symbol = inSymbols[i] * ComplexBaseType(fading); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /include/channels/CompositeChannel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include "../CodeBench.h" 11 | #include "../util/MTRand.h" 12 | 13 | /** 14 | * \ingroup channels 15 | * \brief Concatenates two channels, to make a new channel 16 | */ 17 | template 18 | class CompositeChannel 19 | { 20 | public: 21 | typedef typename Channel1::InputType InputType; 22 | typedef typename Channel2::OutputType OutputType; 23 | 24 | /** 25 | * C'tor 26 | */ 27 | CompositeChannel(const Channel1& channel1, 28 | const Channel2& channel2, 29 | uint32_t numOutputSymbolsToReserve); 30 | 31 | /** 32 | * Seed the pseudo-random number generator 33 | * @param seedValue the seed 34 | */ 35 | void seed(unsigned int* const seed, int seedSize); 36 | 37 | /** 38 | * Transforms the given symbols through both channels 39 | */ 40 | void process(const std::vector& inSymbols, 41 | std::vector& outSymbols); 42 | 43 | /** 44 | * @return the number of input items needed to generate numOutputs output 45 | * items 46 | */ 47 | unsigned int forecast(unsigned int numOutputs); 48 | 49 | private: 50 | 51 | // The channels 52 | Channel1 m_channel1; 53 | Channel2 m_channel2; 54 | 55 | // Random number generator, to seed both channels 56 | MTRand m_random; 57 | 58 | // buffer to hold the outputs of channel1 before feeding into channel2 59 | std::vector m_intermediateBuffer; 60 | }; 61 | 62 | #include "CompositeChannel.hh" 63 | -------------------------------------------------------------------------------- /include/codes/DecodeResult.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | 9 | /** 10 | * \ingroup codes 11 | * \brief The result of a decode attempt 12 | */ 13 | struct DecodeResult { 14 | DecodeResult(const std::string& _packet, float _logProbError) 15 | : packet(_packet), logProbError(_logProbError) {} 16 | DecodeResult() {}; 17 | 18 | // The decoded packet 19 | std::string packet; 20 | 21 | // The log of the probability of error as appears from decoding process 22 | float logProbError; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /include/codes/IDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../CodeBench.h" 12 | #include "DecodeResult.h" 13 | 14 | /** 15 | * \ingroup codes 16 | * \brief Interface for a decoder 17 | */ 18 | template 19 | class IDecoder { 20 | public: 21 | typedef DecodeResult Result; 22 | typedef std::tr1::shared_ptr > Ptr; 23 | 24 | /** 25 | * D'tor 26 | */ 27 | virtual ~IDecoder() {} 28 | 29 | /** 30 | * Resets the decoder, so a different packet can be decoded 31 | */ 32 | virtual void reset() = 0; 33 | 34 | /** 35 | * Adds more symbol information to the packet. 36 | * Assumes the noise power is constant accross all symbols 37 | * 38 | * @param symbols: the symbols to add 39 | */ 40 | virtual void add(const std::vector& symbols, 41 | N0_t n0) = 0; 42 | 43 | /** 44 | * Adds more symbol information to the packet. 45 | * Assumes a fading channel (where noise power is constant but 46 | * received power changes). 47 | * 48 | * @param symbols: the symbols to add 49 | * @param fadingMagnitude: the scaling factor that the symbols underwent 50 | * when transmitted on the channel 51 | * @param n0: channel noise power 52 | */ 53 | virtual void add(const std::vector& symbols, 54 | const std::vector& fadingMagnitude, 55 | N0_t n0) = 0; 56 | 57 | /** 58 | * Performs a full decode of the given symbols, returning the most likely 59 | * candidate for the packet. 60 | */ 61 | virtual DecodeResult decode() = 0; 62 | }; 63 | -------------------------------------------------------------------------------- /include/codes/IEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class IEncoder; 13 | typedef std::tr1::shared_ptr IEncoderPtr; 14 | 15 | /** 16 | * \ingroup codes 17 | * \brief Interface of an encoder 18 | */ 19 | class IEncoder 20 | { 21 | public: 22 | /** 23 | * d'tor 24 | */ 25 | virtual ~IEncoder() {} 26 | 27 | /** 28 | * Sets the packet to be encoded 29 | * @param packet: the packet to be encoded 30 | */ 31 | virtual void setPacket(const std::string& packet) = 0; 32 | 33 | /** 34 | * Gets the next encoded symbols into outSymbols 35 | * @param numSymbols: the number of symbols to emit 36 | * @param outSymbols: [out] where symbols will be written 37 | */ 38 | virtual void encode( 39 | unsigned int numSymbols, 40 | std::vector& outSymbols) = 0; 41 | }; 42 | -------------------------------------------------------------------------------- /include/codes/ILLRDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "../CodeBench.h" 11 | #include "DecodeResult.h" 12 | 13 | /** 14 | * \ingroup codes 15 | * \brief A decoder that uses Log Likelihood Ratio estimates of bits as its information 16 | */ 17 | class ILLRDecoder { 18 | public: 19 | typedef DecodeResult Result; 20 | typedef std::tr1::shared_ptr Ptr; 21 | 22 | /** 23 | * D'tor 24 | */ 25 | virtual ~ILLRDecoder() {} 26 | 27 | /** 28 | * Resets the decoder, so a different packet can be decoded 29 | */ 30 | virtual void reset() = 0; 31 | 32 | /** 33 | * Adds log likelihood information. This decoder only supports contiguous 34 | * likelihoods, starting with bit 0. 35 | * @param llrs: the log-likelihood ratios to add 36 | */ 37 | virtual void add(const std::vector& llrs) = 0; 38 | 39 | /** 40 | * Performs a full decode of the given symbols, returning the most likely 41 | * candidate for the packet. 42 | */ 43 | virtual DecodeResult decode() = 0; 44 | }; 45 | -------------------------------------------------------------------------------- /include/codes/IMultiStreamDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "IDecoder.h" 12 | 13 | /** 14 | * \ingroup codes 15 | * \brief Interface for decoders for punctured codes 16 | */ 17 | template 18 | class IMultiStreamDecoder { 19 | public: 20 | typedef std::tr1::shared_ptr< IMultiStreamDecoder > Ptr; 21 | 22 | /** 23 | * Virtual D'tor 24 | */ 25 | virtual ~IMultiStreamDecoder() {}; 26 | 27 | /** 28 | * Resets the decoder, so a different packet can be decoded 29 | */ 30 | virtual void reset() = 0; 31 | 32 | /** 33 | * Sets the symbols for the packet. 34 | * @param streamIndices: for each symbol, which stream it came from 35 | * @param symbols: the symbols to add 36 | */ 37 | virtual void add(const std::vector& streamIndices, 38 | const std::vector& symbols, 39 | N0_t n0) = 0; 40 | 41 | /** 42 | * Performs a full decode of the given symbols, returning the most likely 43 | * candidate for the packet. 44 | */ 45 | virtual DecodeResult decode() = 0; 46 | }; 47 | -------------------------------------------------------------------------------- /include/codes/IMultiStreamEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../CodeBench.h" 12 | 13 | /** 14 | * \ingroup codes 15 | * \brief Interface for puncture-able encoders 16 | * 17 | * The IMultiStreamEncoder interface is suitable for codes where values can be generated from 18 | * different "locations" or "streams". These kind of encoders can be punctured easily, by 19 | * requesting outputs from specific streams. 20 | * 21 | * A IMultiStreamEncoder instance allows explicit access to the different streams. If combined with 22 | * a puncturing strategy, the result is an encoder that produces a single stream (an IEncoder). 23 | */ 24 | class IMultiStreamEncoder { 25 | public: 26 | typedef std::tr1::shared_ptr Ptr; 27 | 28 | /** 29 | * Virtual d'tor 30 | */ 31 | virtual ~IMultiStreamEncoder() {} 32 | 33 | /** 34 | * Sets the packet to be encoded 35 | * @param packet: the packet to be encoded 36 | */ 37 | virtual void setPacket(const std::string& packet) = 0; 38 | 39 | /** 40 | * Encodes symbols from requested spine values 41 | * @param streamIndices: the sequence of streams from which values should be emitted 42 | * @param outSymbols: [out] where symbols will be written 43 | */ 44 | virtual void encode( 45 | const std::vector& streamIndices, 46 | std::vector& outSymbols) = 0; 47 | }; 48 | -------------------------------------------------------------------------------- /include/codes/InterleavedDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "IDecoder.h" 11 | 12 | /** 13 | * \ingroup codes 14 | * \brief Decodes an interleaved code: de-interleaves, then decodes. 15 | */ 16 | template 17 | class InterleavedDecoder : public ILLRDecoder { 18 | public: 19 | /** 20 | * C'tor 21 | * @param decoder: the internal decoder 22 | * @param interleaveSequence: the interleaving sequence 23 | */ 24 | InterleavedDecoder(const Decoder& decoder, 25 | const std::vector& interleaveSequence); 26 | 27 | /** 28 | * D'tor 29 | */ 30 | virtual ~InterleavedDecoder() {} 31 | 32 | /** 33 | * Resets the decoder, so a different packet can be decoded 34 | */ 35 | virtual void reset(); 36 | 37 | /** 38 | * Sets the symbols for the packet. This decoder only supports contiguous 39 | * symbols, starting with symbol 0. 40 | * @param symbols: the symbols to add 41 | */ 42 | virtual void add(const std::vector& symbols); 43 | 44 | /** 45 | * Performs a full decode of the given symbols, returning the most likely 46 | * candidate for the packet. 47 | */ 48 | virtual DecodeResult decode(); 49 | 50 | private: 51 | // The decoder we're interleaving into 52 | Decoder m_decoder; 53 | 54 | // The interleaving sequence 55 | std::vector m_interleavingSequence; 56 | 57 | // The next symbol we're expecting 58 | unsigned int m_next; 59 | }; 60 | 61 | #include "InterleavedDecoder.hh" 62 | -------------------------------------------------------------------------------- /include/codes/InterleavedDecoder.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include 6 | 7 | template 8 | inline InterleavedDecoder::InterleavedDecoder( 9 | const Decoder& decoder, 10 | const std::vector & interleaveSequence) 11 | : m_decoder(decoder), 12 | m_interleavingSequence(interleaveSequence), 13 | m_next(0) 14 | {} 15 | 16 | template 17 | inline void InterleavedDecoder::reset() { 18 | m_decoder.reset(); 19 | m_next = 0; 20 | } 21 | 22 | template 23 | inline void InterleavedDecoder::add( 24 | const std::vector & symbols) 25 | { 26 | assert(m_next + symbols.size() <= m_interleavingSequence.size()); 27 | 28 | for(unsigned int i = 0; i < symbols.size(); i++) { 29 | m_decoder.addLLR(m_interleavingSequence[m_next++], symbols[i]); 30 | } 31 | } 32 | 33 | template 34 | inline DecodeResult InterleavedDecoder::decode() { 35 | return m_decoder.decode(); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /include/codes/MultiToSingleStreamDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../CodeBench.h" 12 | #include "IDecoder.h" 13 | #include "IMultiStreamDecoder.h" 14 | 15 | 16 | /** 17 | * \ingroup codes 18 | * \brief Decodes a punctured code by rearranging received symbols according to where they were 19 | * generated 20 | */ 21 | template 22 | class MultiToSingleStreamDecoder : public IDecoder { 23 | public: 24 | typedef std::tr1::shared_ptr< MultiToSingleStreamDecoder > Ptr; 25 | 26 | /** 27 | * C'tor 28 | */ 29 | MultiToSingleStreamDecoder(typename IMultiStreamDecoder::Ptr& decoder, 30 | IPuncturingSchedulePtr& puncturing); 31 | 32 | /** 33 | * @see IDecoder 34 | */ 35 | virtual void reset(); 36 | virtual void add(const std::vector& symbols, 37 | N0_t n0); 38 | virtual void add(const std::vector& symbols, 39 | const std::vector& fadingMagnitude, 40 | N0_t n0); 41 | virtual DecodeResult decode(); 42 | 43 | /** 44 | * Performs a full decode of the given symbols, returning the most likely 45 | * candidate for the packet. 46 | * 47 | * This version returns an extended result 48 | */ 49 | //SpinalDecodeResult decodeExtended(); 50 | 51 | private: 52 | // The decoder 53 | typename IMultiStreamDecoder::Ptr m_decoder; 54 | 55 | // The puncturing schedule 56 | IPuncturingSchedulePtr m_puncturing; 57 | 58 | // Sequence of streams where symbols come from 59 | std::vector m_streamIndicesWorkArr; 60 | }; 61 | 62 | #include "MultiToSingleStreamDecoder.hh" 63 | -------------------------------------------------------------------------------- /include/codes/MultiToSingleStreamDecoder.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "MultiToSingleStreamDecoder.h" 8 | 9 | 10 | template 11 | inline MultiToSingleStreamDecoder::MultiToSingleStreamDecoder( 12 | typename IMultiStreamDecoder::Ptr & decoder, 13 | IPuncturingSchedulePtr & puncturing) 14 | : m_decoder(decoder), 15 | m_puncturing(puncturing) 16 | {} 17 | 18 | 19 | 20 | template 21 | inline void MultiToSingleStreamDecoder::reset() 22 | { 23 | m_decoder->reset(); 24 | m_puncturing->reset(); 25 | } 26 | 27 | 28 | template 29 | inline void MultiToSingleStreamDecoder::add( 30 | const std::vector & symbols, 31 | N0_t n0) { 32 | // Get which spine values need to be computed 33 | m_puncturing->batchNext(symbols.size(), m_streamIndicesWorkArr); 34 | 35 | // Encode all requested spine values 36 | m_decoder->add(m_streamIndicesWorkArr, symbols, n0); 37 | } 38 | 39 | template 40 | inline void MultiToSingleStreamDecoder::add( 41 | const std::vector & symbols, 42 | const std::vector& fadingMagnitude, 43 | N0_t n0) 44 | { 45 | throw(std::runtime_error("Not currently supported")); 46 | } 47 | 48 | template 49 | inline DecodeResult MultiToSingleStreamDecoder::decode() 50 | { 51 | return m_decoder->decode(); 52 | } 53 | 54 | //template 55 | //inline SpinalDecodeResult MultiToSingleStreamDecoder::decodeExtended() 56 | //{ 57 | // return m_decoder->decodeExtended(); 58 | //} 59 | 60 | -------------------------------------------------------------------------------- /include/codes/MultiToSingleStreamEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "IEncoder.h" 10 | 11 | #include "IMultiStreamEncoder.h" 12 | #include "puncturing/IPuncturingSchedule.h" 13 | 14 | /** 15 | * \ingroup codes 16 | * \brief Punctures a puncture-able code, can produce a stream of symbols. 17 | */ 18 | class MultiToSingleStreamEncoder : public IEncoder { 19 | public: 20 | MultiToSingleStreamEncoder(IMultiStreamEncoder::Ptr& encoder, 21 | IPuncturingSchedulePtr& puncturing); 22 | 23 | /** 24 | * Sets the packet to be encoded 25 | * @param packet: the packet to be encoded 26 | */ 27 | virtual void setPacket(const std::string& packet); 28 | 29 | /** 30 | * Gets the next encoded symbols into outSymbols 31 | * @param numSymbols: the number of symbols to emit 32 | * @param outSymbols: [out] where symbols will be written 33 | */ 34 | virtual void encode( 35 | unsigned int numSymbols, 36 | std::vector& outSymbols); 37 | 38 | private: 39 | // The encoder 40 | IMultiStreamEncoder::Ptr m_encoder; 41 | 42 | // The puncturing schedule 43 | IPuncturingSchedulePtr m_puncturing; 44 | 45 | // A working array that keeps stream indices from which to take symbols, for encode() 46 | std::vector m_streamIndicesWorkArr; 47 | }; 48 | -------------------------------------------------------------------------------- /include/codes/SymbolToLLRDecoderAdaptor.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | template 7 | inline SymbolToLLRDecoderAdaptor::SymbolToLLRDecoderAdaptor( 8 | typename IDemapper::Ptr & demapper, 9 | ILLRDecoder::Ptr & decoder) 10 | : m_demapper(demapper), 11 | m_decoder(decoder) 12 | {} 13 | 14 | template 15 | inline void SymbolToLLRDecoderAdaptor::reset() { 16 | m_decoder->reset(); 17 | } 18 | 19 | template 20 | inline void SymbolToLLRDecoderAdaptor::add( 21 | const std::vector & symbols, 22 | N0_t n0) 23 | { 24 | m_demapper->process(symbols, n0, m_llrs); 25 | m_decoder->add(m_llrs); 26 | } 27 | 28 | template 29 | inline void SymbolToLLRDecoderAdaptor::add( 30 | const std::vector & symbols, 31 | const std::vector& fadingMagnitude, 32 | N0_t n0) 33 | { 34 | m_demapper->process(symbols, fadingMagnitude, n0, m_llrs); 35 | m_decoder->add(m_llrs); 36 | } 37 | 38 | template 39 | inline DecodeResult SymbolToLLRDecoderAdaptor::decode() { 40 | return m_decoder->decode(); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /include/codes/archive/IMultiDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include "IDecoder.h" 11 | 12 | template 13 | class IMultiDecoder { 14 | public: 15 | // DecodeResult is defined in IDecoder 16 | typedef DecodeResult Result; 17 | 18 | /** 19 | * D'tor 20 | */ 21 | virtual ~IMultiDecoder() {} 22 | 23 | /** 24 | * Removes packet 'packetInd' from the decoder, so a different packet 25 | * would be able to use the same packetInd. 26 | */ 27 | virtual void resetPacket(unsigned int packetInd) = 0; 28 | 29 | /** 30 | * Sets the symbols for the packet. This decoder only supports contiguous 31 | * symbols, starting with passInd == 0. 32 | * @param packetInd: the packet whose pass is supplied 33 | * @param symbols: the symbols of the pass 34 | */ 35 | virtual void addSymbols( 36 | unsigned int packetInd, 37 | const std::vector& symbols) = 0; 38 | 39 | /** 40 | * Starts a decode for the given packetInd. The result is then read using 41 | * getDecodeResult. 42 | */ 43 | virtual void decode(unsigned int packetInd) = 0; 44 | 45 | /** 46 | * @return the ML packet decoded by existing packetInd symbols. 47 | * @note that a decode must be run before calling getDecodeResult. 48 | */ 49 | virtual DecodeResult getDecodeResult(unsigned int packetInd) = 0; 50 | }; 51 | -------------------------------------------------------------------------------- /include/codes/archive/IMultiEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class IMultiEncoder; 13 | typedef std::tr1::shared_ptr IMultiEncoderPtr; 14 | 15 | 16 | class IMultiEncoder 17 | { 18 | public: 19 | /** 20 | * d'tor 21 | */ 22 | virtual ~IMultiEncoder() {} 23 | 24 | /** 25 | * Sets the packet to be encoded 26 | * @param packetInd: the index of the packet (0 to numPackets-1) 27 | * @param packet: the packet to be encoded 28 | */ 29 | virtual void setPacket(unsigned int packetInd, const std::string& packet) = 0; 30 | 31 | /** 32 | * Removes the packet from the cache 33 | * Note that this might not actually free memory, in order to save on 34 | * new/delete overhead 35 | * @param packetInd: the index of the packet to be removed 36 | */ 37 | virtual void removePacket(unsigned int packetInd) = 0; 38 | 39 | /** 40 | * @return True if packet exists, False otherwise. 41 | * @param packetInd: the index of the packet queried. 42 | */ 43 | virtual bool hasPacket(unsigned int packetInd) = 0; 44 | 45 | /** 46 | * Copies the specified encoded symbols into outSymbols 47 | * @param packetInd: the index of the packet whose symbols are requested 48 | * @param numSymbols: the number of symbols to emit 49 | * @param outSymbols: [out] where symbols will be written 50 | */ 51 | virtual void encode( 52 | unsigned int packetInd, 53 | unsigned int numSymbols, 54 | std::vector& outSymbols) = 0; 55 | }; 56 | -------------------------------------------------------------------------------- /include/codes/ldpc/MatrixLDPCCode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "SparseMatrix.h" 8 | 9 | /** 10 | * \ingroup ldpc 11 | * \brief Specification of a Quasi-Cyclic LDPC code 12 | */ 13 | struct MatrixLDPCCode { 14 | MatrixLDPCCode(unsigned int _n, 15 | unsigned int _Z, 16 | unsigned int _rateNumerator, 17 | unsigned int _rateDenominator, 18 | const unsigned int* rowPtrs, 19 | unsigned int numValues, 20 | const unsigned char* vals, 21 | const unsigned int* cols); 22 | 23 | // Size of codeword 24 | unsigned int n; 25 | 26 | // Size of cyclic-permutation submatrices 27 | unsigned int Z; 28 | 29 | // the numerator of the rate 30 | unsigned int rateNumerator; 31 | // the denominator of the rate 32 | unsigned int rateDenominator; 33 | 34 | // matrix of the message bits each check node xors (this does not include 35 | // how parity bits are xored in check nodes - we assume the almost-diagonal 36 | // structure in 802.11n-2009 37 | SparseMatrix matrix; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /include/codes/ldpc/MatrixLDPCDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "MatrixLDPCCode.h" 11 | #include "../IDecoder.h" 12 | #include "../../OracleDetector.h" 13 | #include "../../util/inference/bp/MessagePassingDecoder.h" 14 | 15 | using namespace std; 16 | 17 | /** 18 | * \ingroup ldpc 19 | * \brief Decoder for Quasi-Cyclic LDPC codes 20 | */ 21 | class MatrixLDPCDecoder 22 | { 23 | public: 24 | MatrixLDPCDecoder(const MatrixLDPCCode& code, 25 | unsigned int numIters); 26 | 27 | /** 28 | * Resets the decoder, so a different packet can be decoded 29 | */ 30 | void reset(); 31 | 32 | /** 33 | * Sets the symbols for the packet. This decoder only supports contiguous 34 | * symbols, starting with symbol 0. 35 | * @param symbols: the symbols to add 36 | */ 37 | void add(const std::vector& floats); 38 | 39 | /** 40 | * Performs a full decode of the given symbols, returning the most likely 41 | * candidate for the packet. 42 | */ 43 | DecodeResult decode(); 44 | 45 | private: 46 | // Decoder 47 | MatrixLDPCCode m_code; 48 | 49 | // The number of iterations of message passing to perform 50 | unsigned int m_numIter; 51 | 52 | // The received codeword's log likelihoods (one per bit) 53 | std::vector m_LLRs; 54 | }; 55 | -------------------------------------------------------------------------------- /include/codes/ldpc/MatrixLDPCNeighborGenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "SparseMatrix.h" 8 | #include "MatrixLDPCCode.h" 9 | 10 | /** 11 | * \ingroup ldpc 12 | * \brief Outputs graphical structure of LDPC code, for belief propagation. 13 | */ 14 | class MatrixLDPCNeighborGenerator { 15 | public: 16 | MatrixLDPCNeighborGenerator(const MatrixLDPCCode& code); 17 | 18 | /** 19 | * restart at the beginning 20 | */ 21 | void reset(); 22 | 23 | /** 24 | * Sets the observed node we're getting neighbors for to 'observedBitIndex' 25 | */ 26 | void set(unsigned long observedBitIndex); 27 | 28 | /** 29 | * Advances to next check node 30 | */ 31 | void nextNode(); 32 | 33 | /** 34 | * @return the number of neighbors for the specific message bit 35 | */ 36 | unsigned int count(); 37 | 38 | /** 39 | * @return the next neighbor 40 | */ 41 | unsigned int next(); 42 | 43 | /** 44 | * @return true if there are more neighbors, false otherwise 45 | * 46 | * It will return true before count() calls to next() had been performed. 47 | **/ 48 | bool hasMore(); 49 | 50 | private: 51 | MatrixLDPCCode m_code; 52 | 53 | // the index of the first parity bit 54 | unsigned int m_firstParityBitIndex; 55 | 56 | // current matrix row 57 | unsigned int m_row; 58 | 59 | // current bitIndex in 0..Z-1 60 | unsigned int m_bitIndex; 61 | 62 | // current index into neighbors 63 | unsigned int m_neighborIndex; 64 | }; 65 | -------------------------------------------------------------------------------- /include/codes/ldpc/SparseMatrix.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include 6 | 7 | template 8 | inline SparseMatrix::SparseMatrix(int numRows, 9 | const unsigned int *rowPtrs, 10 | unsigned int numValues, 11 | const ValueType *values, 12 | const unsigned int *colInd) 13 | : m_rowPtr(rowPtrs, rowPtrs + numRows), 14 | m_value(values, values + numValues), 15 | m_columnInd(colInd, colInd + numValues) 16 | { 17 | m_rowPtr.push_back(numValues); 18 | } 19 | 20 | 21 | template 22 | inline unsigned int SparseMatrix::dim() const { 23 | return m_rowPtr.size() - 1; 24 | } 25 | 26 | 27 | template 28 | inline unsigned int SparseMatrix::degree() const { 29 | return m_value.size(); 30 | } 31 | 32 | 33 | template 34 | inline unsigned int SparseMatrix::rowDegree(unsigned int rowInd) const 35 | { 36 | return (m_rowPtr[rowInd + 1] - m_rowPtr[rowInd]); 37 | } 38 | 39 | 40 | template 41 | inline unsigned int SparseMatrix::rowPtr(unsigned int rowInd) const { 42 | if(rowInd >= dim()) { 43 | throw(std::runtime_error("row index out of range")); 44 | } 45 | 46 | return m_rowPtr[rowInd]; 47 | } 48 | 49 | 50 | template 51 | inline unsigned int SparseMatrix::colInd(unsigned int ptr) const { 52 | return m_columnInd[ptr]; 53 | } 54 | 55 | 56 | template 57 | inline ValueType SparseMatrix::val(unsigned int ptr) const { 58 | return m_value[ptr]; 59 | } 60 | -------------------------------------------------------------------------------- /include/codes/ldpc/WifiLDPC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | #pragma once 7 | 8 | #include "MatrixLDPCCode.h" 9 | 10 | /** 11 | * \ingroup ldpc 12 | * \brief factory for 802.11n LDPC codes with n=648 13 | */ 14 | MatrixLDPCCode getWifiLDPC648(unsigned int rateNumerator, 15 | unsigned int rateDenominator); 16 | 17 | /** 18 | * \ingroup ldpc 19 | * \brief factory for 802.11n LDPC codes with n=1296 20 | */ 21 | MatrixLDPCCode getWifiLDPC1296(unsigned int rateNumerator, 22 | unsigned int rateDenominator); 23 | 24 | /** 25 | * \ingroup ldpc 26 | * \brief factory for 802.11n LDPC codes with n=1944 27 | */ 28 | MatrixLDPCCode getWifiLDPC1944(unsigned int rateNumerator, 29 | unsigned int rateDenominator); 30 | 31 | -------------------------------------------------------------------------------- /include/codes/null/NullDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../ILLRDecoder.h" 8 | #include 9 | 10 | /** 11 | * \ingroup codes 12 | * \brief A decoder that simply hard-decodes its given LLRs 13 | */ 14 | class NullDecoder: public ILLRDecoder { 15 | public: 16 | /** 17 | * C'tor 18 | * @param packetLength: the length of the packet 19 | */ 20 | NullDecoder(uint32_t packetLength); 21 | 22 | /** 23 | * @see ILLRDecoder 24 | */ 25 | virtual void reset(); 26 | virtual void add(const std::vector& llrs); 27 | virtual DecodeResult decode(); 28 | 29 | private: 30 | // The packet length this decoder is built for 31 | uint32_t m_packetLength; 32 | 33 | // The packet estimates 34 | std::vector m_packetVector; 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /include/codes/null/NullEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../IEncoder.h" 8 | #include 9 | 10 | /** 11 | * \ingroup codes 12 | * \brief An encoder that does not modify the input bits to the output. 13 | * Each input bit is copied to an output symbol 14 | */ 15 | class NullEncoder: public IEncoder { 16 | public: 17 | /** 18 | * C'tor 19 | * @param packetLength: the length of the packet 20 | */ 21 | NullEncoder(uint32_t packetLength); 22 | 23 | /** 24 | * @see IEncoder 25 | */ 26 | virtual void setPacket(const std::string& packet); 27 | 28 | virtual void encode(unsigned int numSymbols, 29 | std::vector& outSymbols); 30 | 31 | private: 32 | // The length of packets this encoder handles. 33 | const uint32_t m_packetLength; 34 | 35 | // The number of remaining symbols to decode 36 | uint32_t m_numRemaining; 37 | 38 | // The bits from the current packet 39 | std::vector m_packetVector; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /include/codes/puncturing/IPuncturingSchedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // forward declaration 13 | class IPuncturingSchedule; 14 | 15 | typedef std::tr1::shared_ptr IPuncturingSchedulePtr; 16 | 17 | /** 18 | * \ingroup puncturing 19 | * \brief Interface for classes that specify puncturing schedules 20 | * 21 | * The IPuncturingSchedule specifies what sequence of streams of an IMultiStreamEncoder is used 22 | * to produce a codeword. 23 | */ 24 | class IPuncturingSchedule { 25 | public: 26 | /** 27 | * Virtual D'tor 28 | */ 29 | virtual ~IPuncturingSchedule() {} 30 | 31 | /** 32 | * Resets the instance to the beginning of the puncturing schedule 33 | */ 34 | virtual void reset() = 0; 35 | 36 | /** 37 | * Returns next stream indices from which a symbol is derived 38 | */ 39 | virtual void batchNext(unsigned int numSymbols, 40 | std::vector& streamIndices) = 0; 41 | }; 42 | -------------------------------------------------------------------------------- /include/codes/puncturing/RepeatingPuncturingSchedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include "IPuncturingSchedule.h" 9 | 10 | /** 11 | * \ingroup puncturing 12 | * \brief Repeats each stream index of another puncturing schedule several (numRepetitions) times 13 | */ 14 | class RepeatingPuncturingSchedule : public IPuncturingSchedule 15 | { 16 | public: 17 | /** 18 | * @param innerSchedule: puncturing schedule whose indices are repeated 19 | * @param numRepetitions: the number of times each index in innerSchedule should be repeated 20 | * before moving to the next symbol 21 | */ 22 | RepeatingPuncturingSchedule(IPuncturingSchedulePtr& innerSchedule, 23 | unsigned int numRepetitions); 24 | 25 | /** 26 | * @see IPuncturingSchedule 27 | */ 28 | virtual void reset(); 29 | 30 | /** 31 | * @see IPuncturingSchedule 32 | */ 33 | virtual void batchNext(unsigned int numSymbols, 34 | std::vector& streamIndices); 35 | 36 | private: 37 | // The schedule producing the spine values 38 | IPuncturingSchedulePtr m_innerSchedule; 39 | 40 | // number of repetitions of each spine value from the inner schedule 41 | const unsigned int m_numRepetitions; 42 | 43 | // The repeated spine value, last obtained from innerSchedule 44 | uint16_t m_cachedIndex; 45 | 46 | // Number of remaining repetitions for the cached index 47 | unsigned int m_remainingRepetitions; 48 | 49 | // A cache used by batchNext 50 | std::vector m_tempCache; 51 | }; 52 | -------------------------------------------------------------------------------- /include/codes/puncturing/RoundRobinPuncturingSchedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "IPuncturingSchedule.h" 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup puncturing 13 | * \brief Gets symbols from index 0 to last index and wraps around 14 | * 15 | * Chooses streams in order 0,1,2.. and wraps around when reaching the highest stream 16 | */ 17 | class RoundRobinPuncturingSchedule : public IPuncturingSchedule { 18 | public: 19 | /** 20 | * c'tor 21 | * @param numStreams: the number of streams to puncture. class will produce indices 22 | * 0, 1, ... numStreams-1, 0, 1, ... 23 | */ 24 | RoundRobinPuncturingSchedule(uint32_t numStreams); 25 | 26 | /** 27 | * @see IPuncturingSchedule 28 | */ 29 | virtual void reset(); 30 | 31 | /** 32 | * @see IPuncturingSchedule 33 | */ 34 | virtual void batchNext(unsigned int numSymbols, 35 | std::vector& streamIndices); 36 | 37 | private: 38 | // The total number of streams to puncture from 39 | const uint32_t m_numStreams; 40 | 41 | // The next stream where symbols should be taken from 42 | uint32_t m_nextStream; 43 | }; 44 | -------------------------------------------------------------------------------- /include/codes/puncturing/StaticPuncturingSchedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "IPuncturingSchedule.h" 10 | 11 | /** 12 | * \ingroup puncturing 13 | * \brief Punctures according to a given vector 14 | * 15 | * Instances are given a vector with the puncturing schedule they provide. 16 | * 17 | * There is support for changing the schedule while running. 18 | */ 19 | class StaticPuncturingSchedule : public IPuncturingSchedule 20 | { 21 | public: 22 | /** 23 | * C'tor. 24 | * 25 | * Starts with an empty schedule. 26 | */ 27 | StaticPuncturingSchedule(); 28 | 29 | /** 30 | * @see IPuncturingSchedule 31 | */ 32 | virtual void reset(); 33 | 34 | /** 35 | * @see IPuncturingSchedule 36 | */ 37 | virtual void batchNext(unsigned int numSymbols, 38 | std::vector& streamIndices); 39 | 40 | /** 41 | * Returns next spine value from which a symbol is derived 42 | */ 43 | uint16_t next(); 44 | 45 | /** 46 | * Sets the puncturing schedule 47 | */ 48 | void set(const std::vector& schedule); 49 | 50 | private: 51 | // List of locations to return as a puncturing schedule 52 | std::vector m_schedule; 53 | 54 | // The index into m_schedule where the next puncturing location is. 55 | unsigned int m_nextIndex; 56 | }; 57 | -------------------------------------------------------------------------------- /include/codes/spinal/Composites.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../puncturing/StridedPuncturingSchedule.h" 8 | #include "protocols/SequentialProtocol.h" 9 | 10 | 11 | // Puncturing 12 | typedef SequentialProtocol StridedSequentialProtocol; 13 | 14 | -------------------------------------------------------------------------------- /include/codes/spinal/IHashDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../IMultiStreamDecoder.h" 12 | 13 | /** 14 | * \ingroup spinal 15 | * \brief Result of a spinal decode attempt 16 | */ 17 | struct SpinalDecodeResult : public DecodeResult { 18 | SpinalDecodeResult(const std::string& _packet, float _logProbError) 19 | : DecodeResult(_packet,_logProbError) {} 20 | SpinalDecodeResult() {}; 21 | 22 | // The weights associated with the decode attempt. 23 | // There should be exactly 6 weights: 24 | // index 0: the total path weight of the most likely result 25 | // index 1: the edge weight of the most likely result 26 | // index 2: the total path weight of the second most likely result 27 | // index 3: the edge weight of the second most likely result 28 | // index 4: the total path weight of a random result from third..last 29 | // index 5: the edge weight of a random result from third..last 30 | std::vector weights; 31 | }; 32 | 33 | /** 34 | * \ingroup spinal 35 | * \brief Decoder for spinal codes. 36 | */ 37 | template 38 | class IHashDecoder : public IMultiStreamDecoder { 39 | public: 40 | typedef std::tr1::shared_ptr< IHashDecoder > Ptr; 41 | 42 | /** 43 | * @see IMultiStreamDecoder 44 | * functions reset, add, decode 45 | *****/ 46 | 47 | /** 48 | * Performs a full decode of the given symbols, returning the most likely 49 | * candidate for the packet. 50 | * 51 | * This version returns an extended result 52 | */ 53 | virtual SpinalDecodeResult decodeExtended() = 0; 54 | }; 55 | -------------------------------------------------------------------------------- /include/codes/spinal/StubHashDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "../../CodeBench.h" 11 | #include "../IDecoder.h" 12 | using namespace std; 13 | 14 | 15 | /** 16 | * \ingroup spinal 17 | * \brief A stub of a decoder, for testing purposes. The inputs to the decode function 18 | * are saved and can be accessed. 19 | */ 20 | class StubHashDecoder 21 | { 22 | public: 23 | typedef DecodeResult Result; 24 | 25 | StubHashDecoder(unsigned int numSymbolsPerPass); 26 | 27 | /** 28 | * Stub for the decoder. 29 | * - numPasses is saved into this->lastCallNumPasses 30 | * - symbols are copied into this->lastCallSymbols 31 | * 32 | * @return empty string 33 | */ 34 | Result decode(unsigned int numPasses, 35 | const Symbol* symbols, 36 | int symbolsSize); 37 | 38 | /** 39 | * @return the number of symbols per pass. 40 | * @note The construction of the puncturing means all passes have the same 41 | * number of symbols. 42 | */ 43 | unsigned int numSymbolsPerPass(); 44 | 45 | // member where numPasses will be saved 46 | unsigned int lastCallNumPasses; 47 | 48 | // member that will contain the symbols that are passed. 49 | vector lastCallSymbols; 50 | 51 | private: 52 | unsigned int m_numSymbolsPerPass; 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /include/codes/strider/LayerSuperposition.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include "../../CodeBench.h" 11 | 12 | /** 13 | * \ingroup strider 14 | * \brief Composes linear combinations of layers using a given matrix, to produce symbols 15 | */ 16 | class LayerSuperposition { 17 | public: 18 | /** 19 | * C'tor 20 | * 21 | * @param layerLength: number of symbols in each layer 22 | * @param G: generator matrix for the code 23 | */ 24 | LayerSuperposition(unsigned int layerLength, 25 | std::complex* matrixG, 26 | int rowsG, 27 | int colsG); 28 | 29 | /** 30 | * Sets the packet to be encoded 31 | */ 32 | void setLayer(unsigned int layerInd, 33 | const std::vector< ComplexSymbol >& layer); 34 | 35 | /** 36 | * Resets the encoder to start from the first symbol of first pass 37 | */ 38 | void reset(); 39 | 40 | /** 41 | * Gets the next encoded symbol 42 | */ 43 | ComplexSymbol next(); 44 | 45 | private: 46 | // The generator matrix, G 47 | boost::numeric::ublas::matrix< ComplexSymbol, 48 | boost::numeric::ublas::row_major > m_G; 49 | 50 | // The layer symbols. Each layer is stored in a row. 51 | boost::numeric::ublas::matrix< ComplexSymbol, 52 | boost::numeric::ublas::column_major > m_layerSymbols; 53 | 54 | // The next symbol to be output within current pass 55 | unsigned int m_nextSymbol; 56 | 57 | // The current pass that is output (which row of m_G) 58 | unsigned int m_currentPass; 59 | }; 60 | -------------------------------------------------------------------------------- /include/codes/strider/StriderFactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "LayeredEncoder.h" 8 | #include "../IDecoder.h" 9 | 10 | /** 11 | * \ingroup strider 12 | * \brief Factory for strider encoders and decoders 13 | */ 14 | class StriderFactory { 15 | public: 16 | /** 17 | * Creates the standard strider encoder 18 | * @param fragmentLengthBits: the length of each fragment, in bits, 19 | * including the CRC bits. 20 | * 21 | * @note: fragmentLengthBits must be an even number 22 | */ 23 | static LayeredEncoder::Ptr createEncoder(uint32_t fragmentLengthBits); 24 | 25 | /** 26 | * Creates the standard strider decoder 27 | * @param fragmentLengthBits: the length of each fragment, in bits, 28 | * including the CRC bits. 29 | */ 30 | static IDecoder::Ptr createDecoder(uint32_t fragmentLengthBits); 31 | 32 | /** 33 | * Creates the strider decoder for a fading channel 34 | */ 35 | static IDecoder::Ptr createFadingDecoder(uint32_t fragmentLengthBits); 36 | 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /include/codes/strider/StriderGeneratorMatrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | 9 | /** 10 | * \ingroup strider 11 | * \brief Loads strider's 27x33 generator matrix. 12 | * 13 | * @param outMatrixG: where values will be written 14 | * @param rowsG: must be 27 15 | * @param colsG: must be 33 16 | */ 17 | void getStriderGeneratorMatrix(std::complex* outMatrixG, 18 | int rowsG, 19 | int colsG); 20 | -------------------------------------------------------------------------------- /include/codes/strider/StriderInterleaver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | 9 | /** 10 | * \ingroup strider 11 | * \brief Default strider interleaving sequence 12 | */ 13 | extern uint16_t striderInterleaver[]; 14 | 15 | -------------------------------------------------------------------------------- /include/codes/strider/StriderTurboCode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../IEncoder.h" 8 | #include "../ILLRDecoder.h" 9 | 10 | /** 11 | * \ingroup strider 12 | * \brief Factory for turbo encoder and decoder used internally within Strider 13 | */ 14 | class StriderTurboCode { 15 | public: 16 | /** 17 | * Creates a new strider turbo encoder 18 | * @param lengthBits: the number of message bits the turbo code should 19 | * handle 20 | */ 21 | static IEncoderPtr createEncoder(uint32_t lengthBits); 22 | 23 | /** 24 | * Creates a new strider turbo decoder 25 | * @param lengthBits: the number of message bits the turbo code should 26 | * handle 27 | */ 28 | static ILLRDecoder::Ptr createDecoder(uint32_t lengthBits); 29 | 30 | private: 31 | /** 32 | * Returns a pseudo-random interleaver for strider 33 | * @param lengthBits: the number of message bits the turbo code should 34 | * handle 35 | */ 36 | static void getInterleaver(uint32_t lengthBits, 37 | std::vector& interleavingSequence); 38 | }; 39 | -------------------------------------------------------------------------------- /include/codes/turbo/TurboCodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | 9 | /** 10 | * \ingroup turbo 11 | * \brief Factory for bit-interleavings for turbo 12 | */ 13 | class TurboCodec { 14 | public: 15 | /** 16 | * Returns an interleaver for the given message length 17 | */ 18 | static void getInterleaver(uint32_t messageLength, itpp::ivec& interleaver); 19 | 20 | private: 21 | TurboCodec() {}; 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /include/codes/turbo/TurboDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "../ILLRDecoder.h" 14 | #include "../InterleavedDecoder.h" 15 | 16 | /** 17 | * \ingroup turbo 18 | * \brief Turbo decoder 19 | */ 20 | class TurboDecoder : public ILLRDecoder { 21 | public: 22 | TurboDecoder(uint32_t messageLength); 23 | 24 | /** 25 | * D'tor 26 | */ 27 | virtual ~TurboDecoder() {} 28 | 29 | /** 30 | * Resets the decoder, so a different packet can be decoded 31 | */ 32 | virtual void reset(); 33 | 34 | /** 35 | * Sets the symbols for the packet. This decoder only supports contiguous 36 | * symbols, starting with symbol 0. 37 | * @param symbols: the symbols to add 38 | */ 39 | virtual void add(const std::vector& symbols); 40 | 41 | /** 42 | * Adds the LLR to the specific bit. 43 | * Can be used to implement decoding for punctured or interleaved 44 | * sequences 45 | * @param location: the bit of the original turbo encoder that the LLR 46 | * corresponds to 47 | * @param llr: the log-likelihood-ratio value 48 | */ 49 | void addLLR(unsigned int location, float llr); 50 | 51 | /** 52 | * Performs a full decode of the given symbols, returning the most likely 53 | * candidate for the packet. 54 | */ 55 | virtual DecodeResult decode(); 56 | 57 | private: 58 | itpp::Turbo_Codec m_codec; 59 | 60 | // Vector where log likelihood estimates are saved 61 | itpp::vec m_llr; 62 | 63 | // Next symbol to be added using add() 64 | unsigned int m_next; 65 | }; 66 | 67 | typedef InterleavedDecoder InterleavedTurboDecoder; 68 | -------------------------------------------------------------------------------- /include/codes/turbo/TurboEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "../IEncoder.h" 14 | 15 | /** 16 | * \ingroup turbo 17 | * \brief Turbo encoder 18 | */ 19 | class TurboEncoder : public IEncoder 20 | { 21 | public: 22 | TurboEncoder(uint32_t messageLength); 23 | 24 | /** 25 | * d'tor 26 | */ 27 | virtual ~TurboEncoder() {} 28 | 29 | /** 30 | * Sets the packet to be encoded 31 | * @param packet: the packet to be encoded 32 | */ 33 | virtual void setPacket(const std::string& packet); 34 | 35 | /** 36 | * Gets the next encoded symbols into outSymbols 37 | * @param numSymbols: the number of symbols to emit 38 | * @param outSymbols: [out] where symbols will be written 39 | */ 40 | virtual void encode( 41 | unsigned int numSymbols, 42 | std::vector& outSymbols); 43 | 44 | private: 45 | itpp::Turbo_Codec m_codec; 46 | 47 | // The number of input bytes for a single message block 48 | unsigned int m_packetLengthBytes; 49 | itpp::bvec m_packetBits; 50 | itpp::bvec m_encodedBits; 51 | }; 52 | -------------------------------------------------------------------------------- /include/demappers/BscDemapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | 10 | /** 11 | * \ingroup demappers 12 | * \brief Produces LLRs from bits distorted by the Binary Symmetric Channel 13 | */ 14 | class BscDemapper { 15 | public: 16 | typedef float OutputType; 17 | 18 | /** 19 | * C'tor 20 | * @param flipProb: the probability (in [0,1]) of a bit flip 21 | * (ie 1-prob(remain same)) 22 | */ 23 | BscDemapper(float flipProb); 24 | 25 | /** 26 | * Demaps symbols to soft bit values 27 | * @param symbols: the symbols to be mapped 28 | * @param n0: ignored in this case. 29 | * @param llrs: log-likelihood ratios 30 | */ 31 | void process(const std::vector& symbols, 32 | N0_t n0, 33 | std::vector& llrs); 34 | 35 | /** 36 | * @return the number of input items needed to generate numOutputs output 37 | * items 38 | */ 39 | unsigned int forecast(unsigned int numOutputs); 40 | 41 | private: 42 | 43 | // LLR of getting a 1 over getting a 0, given the bit, ie 44 | // m_llr[i] = log( prob(1 given observed i) / prob(0 given obs. i) ) 45 | float m_llr[2]; 46 | }; 47 | -------------------------------------------------------------------------------- /include/demappers/IDemapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup demappers 13 | * \brief Interface for a demapper 14 | */ 15 | template 16 | class IDemapper { 17 | public: 18 | typedef LLRValue OutputType; 19 | typedef std::tr1::shared_ptr > Ptr; 20 | 21 | /** 22 | * virtual d'tor 23 | */ 24 | virtual ~IDemapper() {} 25 | 26 | /** 27 | * Demaps symbols to soft bit values 28 | * @param symbols: the symbols to be mapped 29 | * @param n0: channel noise power 30 | * @param llrs: [out] the soft values 31 | */ 32 | virtual void process(const std::vector& symbols, 33 | N0_t n0, 34 | std::vector& llrs) = 0; 35 | 36 | /** 37 | * Demaps symbols to soft bit values, given different noise for each symbol 38 | * @param symbols: the symbols to be mapped 39 | * @param fadingMagnitude: the scaling factor that the symbols underwent 40 | * when transmitted on the channel 41 | * @param n0: channel noise power 42 | * @param llrs: [out] the soft values 43 | */ 44 | virtual void process(const std::vector& symbols, 45 | const std::vector& fadingMagnitude, 46 | N0_t n0, 47 | std::vector& llrs) = 0; 48 | 49 | /** 50 | * @return the number of input items needed to generate numOutputs output 51 | * items 52 | */ 53 | virtual unsigned int forecast(unsigned int numOutputs) = 0; 54 | }; 55 | -------------------------------------------------------------------------------- /include/demappers/NullDemapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | using namespace std; 10 | 11 | /** 12 | * \ingroup demappers 13 | * \brief Performs no transformation on the symbols 14 | */ 15 | class NullDemapper { 16 | public: 17 | typedef Symbol OutputType; 18 | 19 | /** 20 | * maps a group of symbols. NOP 21 | */ 22 | void process(const std::vector& inSymbols, 23 | std::vector& outSymbols); 24 | 25 | /** 26 | * Maps a single symbol. NOP 27 | */ 28 | Symbol map(Symbol sym); 29 | 30 | vector createOutputVector() { 31 | std::vector a; 32 | a.push_back(4); 33 | a.push_back(12412); 34 | return a;} 35 | }; 36 | -------------------------------------------------------------------------------- /include/mappers/ComplexLinearMapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup mappers 13 | * \brief Maps integers to complex numbers 14 | */ 15 | class ComplexLinearMapper { 16 | public: 17 | typedef uint16_t InputType; 18 | typedef ComplexSymbol OutputType; 19 | 20 | /** 21 | * C'tor 22 | * @param numBitsPerDim: the number of data bits to take for each of the 23 | * I and Q parts 24 | */ 25 | ComplexLinearMapper(unsigned int numBitsPerDim); 26 | 27 | /** 28 | * Maps symbols to the complex domain. 29 | * LSB's taken for real part, next bits for imaginary 30 | * 31 | * @param inSymbols: the inputs to be mapped 32 | * @param outSymbols: the mapped outputs 33 | */ 34 | void process(const std::vector& inSymbols, 35 | std::vector& outSymbols); 36 | 37 | /** 38 | * Maps a single symbol to the complex domain 39 | */ 40 | ComplexSymbol map(uint16_t sym); 41 | 42 | /** 43 | * @return the average signal power, assuming input is uniformly distributed 44 | */ 45 | float getAveragePower(); 46 | 47 | /** 48 | * @return the number of input items needed to generate numOutputs output 49 | * items 50 | */ 51 | unsigned int forecast(unsigned int numOutputs); 52 | 53 | private: 54 | // Number of bits from each input to take for each dimension 55 | const unsigned int m_numBitsPerDim; 56 | 57 | // A mask to apply to the input to extract only LSB bits for one dimension 58 | const uint16_t m_symbolMask; 59 | }; 60 | -------------------------------------------------------------------------------- /include/mappers/IMapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | #include 10 | #include 11 | 12 | /** 13 | * \ingroup mappers 14 | * \brief Interface of a mapper 15 | */ 16 | template 17 | class IMapper { 18 | public: 19 | typedef uint16_t InputType; 20 | typedef ChannelSymbol OutputType; 21 | typedef std::tr1::shared_ptr< IMapper > Ptr; 22 | 23 | /** 24 | * Virtual d'tor 25 | */ 26 | virtual ~IMapper() {} 27 | 28 | /** 29 | * Maps symbols to the (larger) precision, linearly 30 | * @param symbols: the symbols to be mapped 31 | */ 32 | virtual void process(const std::vector& inSymbols, 33 | std::vector& outSymbols) = 0; 34 | 35 | /** 36 | * @return the average signal power, assuming input is uniformly distributed 37 | */ 38 | virtual float getAveragePower() = 0; 39 | 40 | /** 41 | * @return the number of input items needed to generate numOutputs output 42 | * items 43 | */ 44 | virtual unsigned int forecast(unsigned int numOutputs) = 0; 45 | }; 46 | -------------------------------------------------------------------------------- /include/mappers/NormalDistribution.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * \ingroup mappers 9 | * \brief Helper functions to compute Normal Distribution. 10 | * 11 | * Numerical calculations of properties of the normal distribution. 12 | * 13 | * Implementation from http://home.online.no/~pjacklam/notes/invnorm/ 14 | * The C++ source file implemented by Jeremy Lea, and supposedly freely 15 | * available to "Use them as you wish, for whatever purpose" as stated on 16 | * http://home.online.no/~pjacklam/notes/invnorm/ 17 | * 18 | * This implementation is suitable for the standard normal distribution 19 | * (ie mu=0, sigma^2=1) 20 | */ 21 | class NormalDistribution { 22 | public: 23 | /** 24 | * Returns the Probability Density Function at point u 25 | * 26 | * Based on Jeremy Lea's stdnormal_pdf 27 | */ 28 | static double pdf(double u); 29 | 30 | /** 31 | * Returns the Cumulative Distribution Function at point u 32 | * 33 | * Based on Jeremy Lea's stdnormal_cdf, which also includes the notice: 34 | * 35 | * The standard normal CDF, for one random variable. 36 | * 37 | * Author: W. J. Cody 38 | * URL: http://www.netlib.org/specfun/erf 39 | * 40 | * This is the erfc() routine only, adapted by the 41 | * transform stdnormal_cdf(u)=(erfc(-u/sqrt(2))/2; 42 | */ 43 | static double cdf(double u); 44 | 45 | /** 46 | * Returns the Percentage Point Function for p in (0,1) 47 | * 48 | * Based on Jeremy Lea's stdnormal_inv 49 | */ 50 | static double ppf(double p); 51 | }; 52 | -------------------------------------------------------------------------------- /include/mappers/QPSKMapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../CodeBench.h" 12 | #include "IMapper.h" 13 | 14 | /** 15 | * \ingroup mappers 16 | * \brief Maps bits to QPSK (using ITPP) 17 | */ 18 | class QPSKMapper : public IMapper { 19 | public: 20 | /** 21 | * Virtual d'tor 22 | */ 23 | virtual ~QPSKMapper() {} 24 | 25 | /** 26 | * Maps symbols to the (larger) precision, linearly 27 | * @param symbols: the symbols to be mapped 28 | */ 29 | virtual void process(const std::vector& inSymbols, 30 | std::vector& outSymbols); 31 | 32 | /** 33 | * @return the average signal power, assuming input is uniformly distributed 34 | */ 35 | virtual float getAveragePower(); 36 | 37 | /** 38 | * @return the number of input items needed to generate numOutputs output 39 | * items 40 | */ 41 | virtual unsigned int forecast(unsigned int numOutputs); 42 | 43 | private: 44 | // QPSK modulator from ITPP 45 | itpp::QPSK m_qpsk; 46 | }; 47 | -------------------------------------------------------------------------------- /include/mappers/QamMapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../CodeBench.h" 12 | #include "IMapper.h" 13 | 14 | /** 15 | * \ingroup mappers 16 | * \brief Maps bits to arbitrary QAM-2^k (using ITPP) 17 | */ 18 | class QamMapper : public IMapper { 19 | public: 20 | /** 21 | * C'tor 22 | * @param k: this will be QAM-2^k 23 | * @note k must be even 24 | */ 25 | QamMapper(uint32_t k); 26 | 27 | /** 28 | * Virtual d'tor 29 | */ 30 | virtual ~QamMapper() {} 31 | 32 | /** 33 | * Maps symbols to the (larger) precision, linearly 34 | * @param symbols: the symbols to be mapped 35 | */ 36 | virtual void process(const std::vector& inSymbols, 37 | std::vector& outSymbols); 38 | 39 | /** 40 | * @return the average signal power, assuming input is uniformly distributed 41 | */ 42 | virtual float getAveragePower(); 43 | 44 | /** 45 | * @return the number of input items needed to generate numOutputs output 46 | * items 47 | */ 48 | virtual unsigned int forecast(unsigned int numOutputs); 49 | 50 | private: 51 | // The k such that we are doing QAM-2^k 52 | const uint32_t m_k; 53 | 54 | // Qam modulator from ITPP 55 | itpp::QAM m_qam; 56 | }; 57 | -------------------------------------------------------------------------------- /include/mappers/SoftMapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "../CodeBench.h" 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup mappers 13 | * \brief Maps several bits of an integer to a float 14 | */ 15 | class SoftMapper { 16 | public: 17 | typedef uint16_t InputType; 18 | typedef SoftSymbol OutputType; 19 | 20 | /** 21 | * C'tor 22 | * @param symbolSizeBits: the number of data bits each element contains 23 | */ 24 | SoftMapper(unsigned int symbolSizeBits); 25 | 26 | /** 27 | * Maps symbols to the (larger) precision, linearly 28 | * @param symbols: the symbols to be mapped 29 | */ 30 | void process(const std::vector& inSymbols, 31 | std::vector& outSymbols); 32 | 33 | /** 34 | * Maps a single symbol to the (larger) precision, linearly 35 | */ 36 | SoftSymbol map(uint16_t sym); 37 | 38 | /** 39 | * @return the average signal power, assuming input is uniformly distributed 40 | */ 41 | float getAveragePower(); 42 | 43 | /** 44 | * @return the number of input items needed to generate numOutputs output 45 | * items 46 | */ 47 | unsigned int forecast(unsigned int numOutputs); 48 | 49 | private: 50 | const unsigned int m_symbolSizeBits; 51 | 52 | // A mask to apply to the input to extract only relevant bits 53 | const uint16_t m_symbolMask; 54 | }; 55 | -------------------------------------------------------------------------------- /include/mappers/TruncatedNormalDistribution.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * \ingroup mappers 9 | * \brief Produces a elements from gaussian distribution, limited to a range (a,b). 10 | * 11 | * Calculates values associated with the Truncated Normal Distribution, 12 | * see http://en.wikipedia.org/wiki/Truncated_normal_distribution 13 | * 14 | * This implementation only deals with truncations of the standard normal 15 | * mu = 0, sigma^2 = 1. 16 | */ 17 | class TruncatedNormalDistribution { 18 | public: 19 | /** 20 | * C'tor 21 | * @param a the lower truncation point 22 | * @param b the upper truncation point 23 | */ 24 | TruncatedNormalDistribution(double a, double b); 25 | 26 | /** 27 | * @return the Percentage Point Function for p in (0,1) 28 | */ 29 | double ppf(double p); 30 | 31 | /** 32 | * @return the variance of the truncated normal 33 | */ 34 | double variance(); 35 | 36 | private: 37 | // The lower truncation point 38 | double m_a; 39 | 40 | // The upper truncation point 41 | double m_b; 42 | 43 | // The CDF of point a on a standard normal variable 44 | double m_cdfOfA; 45 | 46 | // The probability of a standard normal to fall between a and b 47 | double m_weightGivenAB; 48 | }; 49 | -------------------------------------------------------------------------------- /include/protocols/OneTryProtocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | /** 13 | * \ingroup protocols 14 | * \brief Transmits exactly a single burst of symbols, numSymbols symbols long. 15 | */ 16 | class OneTryProtocol { 17 | public: 18 | /** 19 | * @param numPackets: the number of packets the protocol keeps in memory in 20 | * parallel 21 | * @param numSymbols: the number of symbols to transmit 22 | */ 23 | OneTryProtocol(unsigned int numPackets, unsigned int numSymbols); 24 | 25 | /** 26 | * @param packetInd: the packet referred to 27 | * @return the number of symbols that the decoder should possess before 28 | * the protocol makes the next choice 29 | */ 30 | unsigned int numSymbolsNextDecode(unsigned int packetInd); 31 | 32 | /** 33 | * Update the protocol with the results of a decode attempt. 34 | * 35 | * The protocol bases its decision on how many passes to require next 36 | * based on this information. 37 | */ 38 | void setResult(unsigned int packetInd, 39 | unsigned int numSymbols, 40 | bool isFinished); 41 | 42 | /** 43 | * The packet is done; Clean up and prepare for next packet. 44 | * @param packetInd: the index of the packet that is done. 45 | */ 46 | void resetPacket(unsigned int packetInd); 47 | 48 | private: 49 | // The maximum number of passes for protocol 50 | unsigned int m_numSymbols; 51 | 52 | vector m_nextDecode; 53 | }; 54 | -------------------------------------------------------------------------------- /include/util/BitStatCounter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup util 13 | * \brief Counts statistics of individual bits in a series of strings. 14 | * 15 | * The user processes multiple strings, then queries for different bits i how many times bit i was 1. 16 | */ 17 | class BitStatCounter { 18 | public: 19 | /** 20 | * C'tor 21 | * @param num_bits: The length of strings whose statistics are gathered. 22 | */ 23 | BitStatCounter(uint32_t num_bits); 24 | 25 | /** 26 | * Processes the string, keeping statistics 27 | * @param s: the string whose bits should be processed. 28 | */ 29 | void process(const std::string& s); 30 | 31 | /** 32 | * Queries the statistics of a bit 33 | * @param bit_index: statistics of which bit to get (must be 0 <= bit_index < m_num_bits) 34 | * @returns: the number of processed string where bit bit_index was 1. 35 | */ 36 | uint32_t query(uint32_t bit_index); 37 | 38 | private: 39 | // The number of bits to get statistics for 40 | const uint32_t m_num_bits; 41 | 42 | // The number of 1 occurences for each bit 43 | std::vector m_stats; 44 | }; 45 | -------------------------------------------------------------------------------- /include/util/BlockStatCounter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup util 13 | * \brief Counts statistics of k-bit blocks in a series of strings. 14 | * 15 | * The user processes multiple strings, then queries for different blocks i how many times block i 16 | * was != 0. 17 | */ 18 | class BlockStatCounter { 19 | public: 20 | /** 21 | * C'tor 22 | * @param num_bits: The length of strings whose statistics are gathered. 23 | * @param k: The block length. 24 | * @note num_bits must be divisible by k 25 | */ 26 | BlockStatCounter(uint32_t num_bits, uint32_t k); 27 | 28 | /** 29 | * Processes the string, keeping statistics 30 | * @param s: the string whose bits should be processed. 31 | */ 32 | void process(const std::string& s); 33 | 34 | /** 35 | * Queries the statistics of a block 36 | * @param block_index: statistics of which block to get (must be 37 | * 0 <= block_index < m_num_bits / m_k) 38 | * @returns: the number of processed string where block block_index was != 0. 39 | */ 40 | uint32_t query(uint32_t block_index); 41 | 42 | private: 43 | // The number of bits to get statistics for 44 | const uint32_t m_num_bits; 45 | 46 | // The block size 47 | const uint32_t m_k; 48 | 49 | // The number of blocks in each string 50 | const uint32_t m_num_blocks; 51 | 52 | // The number of 1 occurences for each bit 53 | std::vector m_stats; 54 | 55 | // A temp vector to blockify strings into. 56 | std::vector m_tmp_blocks; 57 | }; 58 | -------------------------------------------------------------------------------- /include/util/ItppUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * \ingroup util 13 | * \brief Conversion utils to/from IT++ vectors 14 | */ 15 | class ItppUtils { 16 | public: 17 | /** 18 | * Converts a string into an itpp bvec. 19 | * bvec must be of the appropriate size to the string. 20 | */ 21 | static void stringToVector(const std::string& src, itpp::bvec& dst); 22 | 23 | /** 24 | * Converts an itpp bvec to a string. 25 | * The string is resized to the appropriate size. 26 | */ 27 | static void vectorToString(const itpp::bvec& src, std::string& dst); 28 | 29 | private: 30 | ItppUtils() {}; 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /include/util/crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | 9 | // See crc.c file for more information 10 | 11 | uint16_t crc16r(const uint8_t *data, int len, uint16_t crc); 12 | uint32_t crc32r(const uint8_t *data, int len, uint32_t crc); 13 | -------------------------------------------------------------------------------- /include/util/hashes/BitwiseXor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "SingleSymbolFunction.h" 8 | 9 | /** 10 | * \ingroup hashes 11 | * \brief Implementation of a simple bitwise XOR of uint32 12 | */ 13 | class BitwiseXor { 14 | public: 15 | // The hash's output 16 | typedef unsigned int Digest; 17 | 18 | // The internal state of the hash 19 | typedef unsigned int State; 20 | 21 | static void init(Digest digest, State& state); 22 | 23 | static void update(State& state, unsigned int data); 24 | 25 | static Digest digest(const State& state); 26 | }; 27 | 28 | /** 29 | * \ingroup hashes 30 | * \brief Produces symbols from the digest of a BitwiseXor 31 | */ 32 | typedef SingleSymbolFunction BitwiseXorSymbolFunction; 33 | 34 | -------------------------------------------------------------------------------- /include/util/hashes/Lookup3Hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "UnlimitedHash.h" 10 | 11 | /** 12 | * \ingroup hashes 13 | * \brief Implementation of Bob Jenkin's lookup3 hash function. 14 | * 15 | * Source code partially derived from: 16 | * http://www.burtleburtle.net/bob/c/lookup3.c 17 | */ 18 | class Lookup3Hash { 19 | public: 20 | // The hash's output 21 | typedef uint32_t Digest; 22 | 23 | // The internal state of the hash 24 | typedef uint32_t State[3]; 25 | 26 | static void init(Digest digest, State& state); 27 | 28 | static void update(State& state, unsigned int data); 29 | 30 | static Digest digest(const State& state); 31 | 32 | static uint64_t digest_extended(const State& state); 33 | }; 34 | 35 | /** 36 | * \ingroup hashes 37 | * \brief Produces symbols from the digest of a Lookup3Hash 38 | */ 39 | class Lookup3SymbolFunction{ 40 | public: 41 | typedef Lookup3Hash Hash; 42 | static const unsigned int NUM_SYMBOLS_PER_STATE = 2; 43 | 44 | static void getSymbols(const Hash::State& state, 45 | uint16_t* symbols); 46 | 47 | }; 48 | 49 | typedef UnlimitedHash Lookup3UnlimitedHash; 50 | -------------------------------------------------------------------------------- /include/util/hashes/OneAtATimeHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "SingleSymbolFunction.h" 8 | #include "UnlimitedHash.h" 9 | 10 | /** 11 | * \ingroup hashes 12 | * \brief Implementation of Bob Jenkin's One-At-A-Time hash function. 13 | * 14 | * code and discussion at: 15 | * http://www.burtleburtle.net/bob/hash/doobs.html 16 | */ 17 | class OneAtATimeHash { 18 | public: 19 | // The hash's output 20 | typedef unsigned int Digest; 21 | 22 | // The internal state of the hash 23 | typedef unsigned int State; 24 | 25 | static void init(Digest digest, State& state); 26 | 27 | static void update(State& state, unsigned int data); 28 | 29 | static Digest digest(const State& state); 30 | }; 31 | 32 | /** 33 | * \ingroup hashes 34 | * \brief Produces symbols from the digest of a SalsaHash 35 | * 36 | * @Note: one at a time hash produces one symbol per hash application. 37 | */ 38 | typedef SingleSymbolFunction OneAtATimeSymbolFunction; 39 | 40 | typedef UnlimitedHash OneAtATimeUnlimitedHash; 41 | -------------------------------------------------------------------------------- /include/util/hashes/SWIGHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * \ingroup hashes 9 | * \brief Python wrapper for hash functions 10 | */ 11 | template 12 | class SWIGHash { 13 | public: 14 | typedef typename HashFunctionT::Digest Digest; 15 | typedef typename HashFunctionT::State State; 16 | 17 | /** 18 | * C'tor 19 | * @param digest: the digest to initialize from 20 | */ 21 | SWIGHash(Digest digest); 22 | 23 | /** 24 | * Returns the current State 25 | */ 26 | State& getState(); 27 | 28 | /** 29 | * Updates the hash with 'data' 30 | */ 31 | void update(unsigned int data); 32 | 33 | /** 34 | * Returns the digest 35 | */ 36 | Digest digest(); 37 | 38 | private: 39 | // The internal state 40 | State m_state; 41 | }; 42 | 43 | template 44 | inline SWIGHash::SWIGHash(Digest digest) { 45 | HashFunctionT::init(digest, m_state); 46 | } 47 | 48 | 49 | 50 | template 51 | inline typename SWIGHash::State& 52 | SWIGHash::getState() 53 | { 54 | return m_state; 55 | } 56 | 57 | 58 | 59 | template 60 | inline void SWIGHash::update(unsigned int data) { 61 | HashFunctionT::update(m_state, data); 62 | } 63 | 64 | 65 | 66 | template 67 | inline typename SWIGHash::Digest 68 | SWIGHash::digest() 69 | { 70 | return HashFunctionT::digest(m_state); 71 | } 72 | -------------------------------------------------------------------------------- /include/util/hashes/SalsaHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "salsa20.h" 8 | #include 9 | #include "UnlimitedHash.h" 10 | 11 | class SalsaHash { 12 | public: 13 | // The hash's output 14 | typedef SalsaDigest Digest; 15 | 16 | // The internal state of the hash 17 | typedef SalsaState State; 18 | 19 | static void init(Digest digest, State& state); 20 | 21 | static void update(State& state, unsigned int data); 22 | 23 | static Digest digest(const State& state); 24 | }; 25 | 26 | /** 27 | * \ingroup hashes 28 | * \brief Produces symbols from the digest of a SalsaHash 29 | */ 30 | class SalsaSymbolFunction{ 31 | public: 32 | typedef SalsaHash Hash; 33 | static const unsigned int NUM_SYMBOLS_PER_STATE = 32; 34 | 35 | static void getSymbols(const Hash::State& state, 36 | uint16_t* symbols); 37 | }; 38 | 39 | typedef UnlimitedHash SalsaUnlimitedHash; 40 | -------------------------------------------------------------------------------- /include/util/hashes/SingleSymbolFunction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | /** 11 | * \ingroup hashes 12 | * \brief Extracts a single symbol from the underlying hash digest 13 | */ 14 | template 15 | class SingleSymbolFunction{ 16 | public: 17 | typedef HashFunctionT Hash; 18 | static const unsigned int NUM_SYMBOLS_PER_STATE = 1; 19 | 20 | static void getSymbols(const typename Hash::State& state, 21 | uint16_t* symbols); 22 | }; 23 | 24 | 25 | template 26 | inline void SingleSymbolFunction::getSymbols( 27 | const typename Hash::State & state, 28 | uint16_t* symbols) 29 | { 30 | *symbols = state & 0xFFFF; 31 | } 32 | -------------------------------------------------------------------------------- /include/util/hashes/ecrypt-machine.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-machine.h */ 2 | 3 | /* 4 | * This file is included by 'ecrypt-portable.h'. It allows to override 5 | * the default macros for specific platforms. Please carefully check 6 | * the machine code generated by your compiler (with optimisations 7 | * turned on) before deciding to edit this file. 8 | */ 9 | 10 | /* ------------------------------------------------------------------------- */ 11 | 12 | #if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) 13 | 14 | #define ECRYPT_MACHINE_ROT 15 | 16 | #if (defined(WIN32) && defined(_MSC_VER)) 17 | 18 | #undef ROTL32 19 | #undef ROTR32 20 | #undef ROTL64 21 | #undef ROTR64 22 | 23 | #include 24 | 25 | #define ROTL32(v, n) _lrotl(v, n) 26 | #define ROTR32(v, n) _lrotr(v, n) 27 | #define ROTL64(v, n) _rotl64(v, n) 28 | #define ROTR64(v, n) _rotr64(v, n) 29 | 30 | #endif 31 | 32 | #endif 33 | 34 | /* ------------------------------------------------------------------------- */ 35 | 36 | #if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) 37 | 38 | #define ECRYPT_MACHINE_SWAP 39 | 40 | /* 41 | * If you want to overwrite the default swap macros, put it here. And so on. 42 | */ 43 | 44 | #endif 45 | 46 | /* ------------------------------------------------------------------------- */ 47 | -------------------------------------------------------------------------------- /include/util/hashes/salsa20.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include "ecrypt-portable.h" 8 | 9 | typedef unsigned int SalsaState[16]; 10 | typedef unsigned long long SalsaDigest; 11 | 12 | 13 | void salsaInit(const SalsaDigest digest, SalsaState& state); 14 | 15 | void salsaUpdate(SalsaState& state, u32 data); 16 | 17 | SalsaDigest salsaDigest(const SalsaState& state); 18 | 19 | int salsaGetSymbol(const SalsaState& hashState, 20 | unsigned int symbolSizeBits, 21 | unsigned int pointIndex); 22 | -------------------------------------------------------------------------------- /include/util/inference/bp/BPMessage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * \ingroup bp 9 | * \brief A belief propagation message 10 | */ 11 | struct BPMessage { 12 | public: 13 | unsigned int from; 14 | float value; 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /include/util/inference/bp/BipartiteBP.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "BipartiteGraph.h" 13 | #include "NodeUpdater.h" 14 | 15 | /** 16 | * \ingroup bp 17 | * \brief Belief propagation implementation on Bipartite Graphs 18 | */ 19 | class BipartiteBP 20 | { 21 | public: 22 | // Type for quantized LLR 23 | typedef int32_t QLLR; 24 | 25 | /** 26 | * C'tor, bipartite belief propagation 27 | * 28 | * @param graph: the graph data structure on which to perform belief 29 | * propagation 30 | * @param variableNodeUpdater: an instance that updates variable nodes 31 | * @param checkNodeUpdater: the implementation used to update check nodes 32 | */ 33 | BipartiteBP( 34 | BipartiteGraph& graph, 35 | VariableNodeUpdater& variableNodeUpdater, 36 | NodeUpdater& checkNodeUpdater); 37 | 38 | /** 39 | * @return the Log Likelihood Ratios of variable nodes 40 | **/ 41 | void get_soft_values(std::vector& llrs); 42 | 43 | /** 44 | * Performs a round of belief propagation 45 | **/ 46 | void advance(uint32_t numIterations = 1); 47 | 48 | private: 49 | // Graph with edges that transmit floats 50 | BipartiteGraph& m_graph; 51 | 52 | // An updater for variable nodes 53 | VariableNodeUpdater& m_variableNodeUpdater; 54 | 55 | // An updater for check nodes 56 | NodeUpdater& m_checkNodeUpdater; 57 | }; 58 | -------------------------------------------------------------------------------- /include/util/inference/bp/LinearVariableNodeUpdater.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "NodeUpdater.h" 10 | #include "MultiVector.h" 11 | #include "BipartiteBP.h" 12 | 13 | /** 14 | * \ingroup bp 15 | * \brief Sends outgoing messages from variable nodes given incoming messages, for linear codes 16 | */ 17 | class LinearVariableNodeUpdater : public VariableNodeUpdater { 18 | public: 19 | /** 20 | * C'tor 21 | * There is neutral prior on all variable nodes 22 | */ 23 | LinearVariableNodeUpdater(uint32_t numVariables); 24 | 25 | /** 26 | * C'tor 27 | * @param priorLLRs: the prior log likelihood ratio of variable being 0 over 28 | * it being 1 29 | */ 30 | LinearVariableNodeUpdater(const std::vector& priorLLRs); 31 | 32 | /** 33 | * Given incoming messages, updates outgoing messages 34 | */ 35 | virtual void update(MultiVector& messages); 36 | 37 | /** 38 | * Computes the log likelihood ratio of each variable node to be 0 over 1 39 | */ 40 | virtual void estimate(MultiVector& messages, 41 | std::vector& llrs); 42 | 43 | private: 44 | // The prior QLLR of each variable node 45 | std::vector m_priorQLLR; 46 | 47 | // IT++ calculator used to calculate the messages 48 | itpp::LLR_calc_unit m_llrCalc; 49 | }; 50 | -------------------------------------------------------------------------------- /include/util/inference/bp/NodeUpdater.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include "MultiVector.h" 9 | 10 | /** 11 | * \ingroup bp 12 | * \brief Interface for classes that send out messages given incoming messages 13 | * 14 | * The node updater receives messages in a MultiVector, and replies in that 15 | * same MultiVector. Each virtual vector represents messages incoming to a 16 | * node, and each element in that vector is an edge incident to that node. 17 | */ 18 | template 19 | class NodeUpdater { 20 | public: 21 | /** 22 | * Virtual d'tor 23 | */ 24 | virtual ~NodeUpdater() {}; 25 | 26 | /** 27 | * Given incoming messages, updates outgoing messages in place. 28 | */ 29 | virtual void update(MultiVector& messages) = 0; 30 | }; 31 | 32 | 33 | /** 34 | * Variable node updater 35 | * In addition to deriving outgoing messages from incoming messages, the 36 | * variable node updater also estimates the log likelihood ratio for each 37 | * variable. 38 | */ 39 | template 40 | class VariableNodeUpdater : public NodeUpdater { 41 | public: 42 | /** 43 | * Computes the log likelihood ratio of each variable node to be 0 over 1 44 | */ 45 | virtual void estimate(MultiVector& messages, 46 | std::vector& llrs) = 0; 47 | }; 48 | -------------------------------------------------------------------------------- /lablog/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | lablog 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.python.pydev.pythonNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /lablog/.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | python 6 | python 2.7 7 | 8 | /lablog/src 9 | /lablog/test 10 | 11 | 12 | -------------------------------------------------------------------------------- /lablog/Makefile.am: -------------------------------------------------------------------------------- 1 | # lablog Makefile.am 2 | 3 | pkgpython_PYTHON = \ 4 | python/__init__.py \ 5 | python/SqliteExperimentRepository.py \ 6 | python/ExperimentRepository.py \ 7 | python/Results.py \ 8 | python/Distribute.py 9 | -------------------------------------------------------------------------------- /lablog/configure.ac: -------------------------------------------------------------------------------- 1 | # lablog configure.ac 2 | 3 | # Initialize 4 | AC_INIT([lablog], [1.0], [yonch@yonch.com]) 5 | 6 | # Require a minimum version of autoconf 7 | AC_PREREQ([2.68]) 8 | 9 | # Sanity check 10 | AC_CONFIG_SRCDIR([python/__init__.py]) 11 | 12 | # Initialize Automake 13 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 14 | 15 | # Get Python paths and targets 16 | AM_PATH_PYTHON 17 | 18 | # Files to be generated 19 | AC_CONFIG_FILES([Makefile]) 20 | 21 | # Do output 22 | AC_OUTPUT 23 | -------------------------------------------------------------------------------- /lablog/python/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 10, 2011 3 | 4 | @author: yonch 5 | ''' 6 | 7 | from ExperimentRepository import * 8 | from SqliteExperimentRepository import * 9 | from Distribute import * 10 | from Results import Results 11 | -------------------------------------------------------------------------------- /lablog/test/DistributeTests.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 11, 2011 3 | 4 | @author: yonch 5 | ''' 6 | import unittest 7 | from Distribute import * 8 | import random 9 | 10 | class Test(unittest.TestCase): 11 | 12 | def test_001_should_observe_min(self): 13 | for numTasks in xrange(10,100): 14 | for lst in distribute([(1,numTasks)], 7, 10): 15 | self.assertTrue(sum(x[1] for x in lst) >= 10) 16 | 17 | def test_002_under_minimum_should_work(self): 18 | for numIDs in xrange(1,30): 19 | pending = [(i,1) for i in xrange(numIDs)] 20 | distributed = list(distribute(pending, 10, 29)) 21 | self.assertEqual(len(distributed), 1) 22 | self.assertEquals(set(pending), 23 | set(distributed[0])) 24 | 25 | def test_003_should_preserve_counts(self): 26 | pending = {} 27 | for i in xrange(50): 28 | pending[i] = random.randint(0,200) 29 | resPending = {} 30 | for lst in distribute(pending.items(), 13, 53): 31 | for id,num in lst: 32 | resPending.setdefault(id,0) 33 | resPending[id] += num 34 | 35 | self.assertEqual(pending, resPending) 36 | 37 | def test_004_should_distribute_to_num_processors(self): 38 | pending = {} 39 | for i in xrange(50): 40 | pending[i] = random.randint(0,200) 41 | 42 | self.assertEquals(13, len(list(distribute(pending.items(), 13, 53)))) 43 | 44 | if __name__ == "__main__": 45 | #import sys;sys.argv = ['', 'Test.test_001_should_observe_min'] 46 | unittest.main() -------------------------------------------------------------------------------- /python/codes/__init__.py: -------------------------------------------------------------------------------- 1 | # dummy __init__.py for doxygen 2 | -------------------------------------------------------------------------------- /python/codes/spinal/__init__.py: -------------------------------------------------------------------------------- 1 | # dummy __init__.py for doxygen 2 | -------------------------------------------------------------------------------- /python/codes/spinal/reference/Hash.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | ## 5 | # \ingroup spinal_reference 6 | # \brief Hashes together two integers, s and m. 7 | def hash_func(s, m): 8 | ''' 9 | Hashes together two integers, s and m. 10 | @return a 32-bit integer, result of the hash. 11 | ''' 12 | from Lookup3Hash import lookup3Init, lookup3Update, lookup3Digest 13 | 14 | # initialize with s 15 | hash_state = lookup3Init(s) 16 | 17 | # add m into hashed state 18 | lookup3Update(hash_state, m) 19 | 20 | # digest the hash and return the output value 21 | return lookup3Digest(hash_state) -------------------------------------------------------------------------------- /python/codes/spinal/reference/Lookup3Hash.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import numpy 4 | 5 | ## 6 | # \ingroup spinal_reference 7 | # \brief Initializes lookup3 state 8 | def lookup3Init(val): 9 | return numpy.array([0xdeadbeef + val] * 3, dtype=numpy.uint32); 10 | 11 | 12 | ## 13 | # \ingroup spinal_reference 14 | # \brief Updates lookup3 state 15 | def lookup3Update(state, data): 16 | def rot(x,k): 17 | return (((x) << (k)) | ((x) >> (32-(k)))) 18 | state[1] += data 19 | state[2] ^= state[1]; state[2] -= rot(state[1],14); \ 20 | state[0] ^= state[2]; state[0] -= rot(state[2],11); \ 21 | state[1] ^= state[0]; state[1] -= rot(state[0],25); \ 22 | state[2] ^= state[1]; state[2] -= rot(state[1],16); \ 23 | state[0] ^= state[2]; state[0] -= rot(state[2],4); \ 24 | state[1] ^= state[0]; state[1] -= rot(state[0],14); \ 25 | state[2] ^= state[1]; state[2] -= rot(state[1],24); \ 26 | 27 | ## 28 | # \ingroup spinal_reference 29 | # \brief Returns digest from lookup3 state 30 | def lookup3Digest(state): 31 | return state[2]; 32 | -------------------------------------------------------------------------------- /python/codes/spinal/reference/__init__.py: -------------------------------------------------------------------------------- 1 | from SymbolMapper import SymbolMapper 2 | from Encoder import Encoder 3 | from Decoder import Decoder 4 | from SalsaHash import salsaHash, unlimitedHash 5 | from Lookup3Hash import * 6 | -------------------------------------------------------------------------------- /python/protocols/MultipleTryProtocol.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | import numpy 5 | 6 | ## 7 | # \ingroup protocols 8 | # \brief Attempts to decode at a set of times that is given beforehand 9 | class MultipleTryProtocol(object): 10 | ''' 11 | A protocol that attempts to decode at a set of times that is given 12 | beforehand 13 | ''' 14 | 15 | def __init__(self, numPackets, numSymbolsList): 16 | ''' 17 | Constructor 18 | @param numPackets: the number of packets the protocol handles in 19 | parallel 20 | @param numSymbolsList: a list with the sequence of numSymbols where 21 | decoding attempts should be performed 22 | ''' 23 | 24 | self.packetIndex = numpy.zeros([numPackets], dtype=numpy.uint32) 25 | self.numSymbolsList = numSymbolsList + [0] 26 | 27 | def numSymbolsNextDecode(self, packetInd): 28 | # get num symbols 29 | res = self.numSymbolsList[self.packetIndex[packetInd]] 30 | 31 | # update next index to be returned 32 | self.packetIndex[packetInd] += 1 33 | 34 | return res 35 | 36 | def setResult(self, packetInd, numSymbols, isFinished): 37 | # if isFinished == True, set packet to terminate. 38 | if isFinished: 39 | self.packetIndex[packetInd] = len(self.numSymbolsList) - 1 40 | 41 | def resetPacket(self, packetInd): 42 | 43 | self.packetIndex[packetInd] = 0 44 | -------------------------------------------------------------------------------- /python/protocols/__init__.py: -------------------------------------------------------------------------------- 1 | # This will import the SWIG bindings created and installed by the bindings directory, to create 2 | # a seamless protocols package integrating C++ and python code 3 | from protocols import * 4 | 5 | from MultipleTryProtocol import MultipleTryProtocol 6 | -------------------------------------------------------------------------------- /python/simulator/__init__.py: -------------------------------------------------------------------------------- 1 | import factories 2 | from Simulator import Simulator -------------------------------------------------------------------------------- /python/simulator/default_configuration.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | from factories import * 5 | 6 | ## 7 | # \ingroup simulator 8 | # \brief Gets a list of factories to query for components 9 | def get_factory_list(): 10 | """ 11 | Returns all the factories that the simulator will be using. 12 | """ 13 | return [ChannelFactory(), DemapFactory(), DetectorFactory(), MapFactory(), 14 | PacketGenFactory(), ProtocolFactory(), StatisticsFactory(), 15 | codes.FadingStriderFactory(), codes.LdpcFactory(), codes.LTFactory(), 16 | codes.MultiplexedFactory(), codes.NullFactory(), codes.RaptorFactory(), 17 | codes.SpinalFactory(), codes.StriderFactory(), codes.TurboFactory()] 18 | -------------------------------------------------------------------------------- /python/simulator/factories/DemapFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | import wireless 5 | 6 | ## 7 | # \ingroup factories 8 | # \brief Demappers factory 9 | class DemapFactory(object): 10 | def make_demapper(self, mapSpec, demapSpec): 11 | if demapSpec['type'] == 'null': 12 | return None, None 13 | elif demapSpec['type'] == 'ml-gray': 14 | mapper = wireless.mappers.GrayMapper(mapSpec['bitsPerSymbol'], 15 | mapSpec['precisionBits']) 16 | 17 | # SNR_dB = demapSpec['SNR_dB'] 18 | # SNR_ratio = math.pow(10.0, SNR_dB/10.0) 19 | # noiseAveragePower = mapper.getAveragePower() / SNR_ratio 20 | # stddev = math.sqrt(noiseAveragePower) 21 | 22 | return (wireless.demappers.GrayDemapper(mapper, 23 | mapSpec['bitsPerSymbol']), 24 | wireless.vectorf) 25 | elif demapSpec['type'] == 'BSC': 26 | return (wireless.demappers.BscDemapper(demapSpec['flipProb']), 27 | wireless.vectorf) 28 | elif demapSpec['type'] == 'QAM': 29 | if mapSpec['type'] != 'QAM': 30 | raise RuntimeError,'Only QAM mapper is supported with QAM demapper at this time' 31 | if not demapSpec.has_key('useApprox'): 32 | demapSpec['useApprox'] = False 33 | itppDemapper = wireless.itpp.QAM(2 ** mapSpec['bitsPerSymbol']) 34 | return (wireless.demappers.ItppComplexDemapper(itppDemapper, mapSpec['bitsPerSymbol'], demapSpec['useApprox']), 35 | wireless.vector_llr) 36 | else: 37 | return None 38 | -------------------------------------------------------------------------------- /python/simulator/factories/DetectorFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | import wireless 5 | 6 | ## 7 | # \ingroup factories 8 | # \brief Detectors factory 9 | class DetectorFactory(object): 10 | def make_detector(self, detectorSpec, codeSpec, packetLength, avgPower): 11 | if detectorSpec['type'] == 'oracle': 12 | return wireless.DefaultOracleDetector(1) 13 | elif detectorSpec['type'] == 'chi2': 14 | if codeSpec['type'] != 'spinal': 15 | raise RuntimeError, "chi2 detection only supported for spinal codes" 16 | 17 | from Chi2Detector import Chi2Detector 18 | from common import spinalGetSpineLength 19 | from common import spinalGetPuncturing 20 | 21 | spineLength = spinalGetSpineLength(codeSpec, packetLength) 22 | puncturing = spinalGetPuncturing(codeSpec, spineLength) 23 | 24 | return Chi2Detector( 25 | 1, 26 | detectorSpec['detectionError'], 27 | spineLength, 28 | packetLength, 29 | puncturing, 30 | avgPower) 31 | elif detectorSpec['type'] == 'crc16': 32 | return wireless.DefaultCrcDetector(1) 33 | else: 34 | return None 35 | -------------------------------------------------------------------------------- /python/simulator/factories/PacketGenFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | import wireless 5 | 6 | ## 7 | # \ingroup factories 8 | # \brief Packet generator factory 9 | class PacketGenFactory(object): 10 | def make_packet_generator(self, spec): 11 | if spec['type'] == 'random': 12 | return wireless.PacketGenerator(spec['length']) 13 | elif spec['type'] == 'crc16': 14 | return wireless.CrcPacketGenerator(spec['length']) 15 | else: 16 | return None 17 | -------------------------------------------------------------------------------- /python/simulator/factories/ProtocolFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | import wireless 5 | 6 | from wireless.protocols import OneTryProtocol 7 | from wireless.protocols import MultipleTryProtocol 8 | from wireless.protocols import RateApproxProtocol 9 | 10 | ## 11 | # \ingroup factories 12 | # \brief Link-layer protocol factory 13 | class ProtocolFactory(object): 14 | def make_protocol(self, protoSpec, codeSpec, packetLength): 15 | if protoSpec['type'] == 'one-try': 16 | return OneTryProtocol(1, 17 | protoSpec['numSymbols']) 18 | elif protoSpec['type'] == 'rate-approx': 19 | minSymbols = protoSpec.get('minSymbols',1) 20 | return RateApproxProtocol(1, 21 | protoSpec['maxSymbols'], 22 | protoSpec['delta'], 23 | minSymbols) 24 | elif protoSpec['type'] == 'multiple-try': 25 | return MultipleTryProtocol(1, 26 | protoSpec['numSymbolsList']) 27 | else: 28 | return None 29 | -------------------------------------------------------------------------------- /python/simulator/factories/StatisticsFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | 4 | from wireless.statistics import ErrorRateStatistics, ErrorLocationStatistics, FirstErrorStatistics 5 | 6 | ## 7 | # \ingroup factories 8 | # \brief Statistics factory 9 | class StatisticsFactory(object): 10 | def make_statistics(self, spec): 11 | if spec['type'] == 'errors': 12 | return ErrorRateStatistics(1) 13 | elif spec['type'] == 'bit-statistics': 14 | return ErrorLocationStatistics(1) 15 | elif spec['type'] == 'first-error': 16 | return FirstErrorStatistics(1) 17 | else: 18 | return None 19 | -------------------------------------------------------------------------------- /python/simulator/factories/__init__.py: -------------------------------------------------------------------------------- 1 | import codes 2 | 3 | from ChannelFactory import ChannelFactory 4 | from DemapFactory import DemapFactory 5 | from DetectorFactory import DetectorFactory 6 | from MapFactory import MapFactory 7 | from PacketGenFactory import PacketGenFactory 8 | from ProtocolFactory import ProtocolFactory 9 | from StatisticsFactory import StatisticsFactory 10 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/FadingStriderFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Factory to strider decoders over a fading channel 8 | class FadingStriderFactory(object): 9 | @staticmethod 10 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 11 | if decodeSpec['type'] != 'strider-fading': 12 | return None 13 | 14 | if channelSpec['type'] != 'coherence-fading_c': 15 | raise RuntimeError, "Strider fading channel currently only supports fading over complex numbers" 16 | return wireless.codes.strider.StriderFactory.createFadingDecoder(1530) 17 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/LTFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief LT encoders/decoders factory 8 | class LTFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'LT': 12 | return None 13 | 14 | neighborGen = wireless.codes.fountain.LTParityNeighborGenerator(packetLength, 0xdeadbeef) 15 | symbolFunc = wireless.util.hashes.BitwiseXorSymbolFunction() 16 | encoder = wireless.codes.fountain.LTEncoder(packetLength, neighborGen, symbolFunc) 17 | return encoder, wireless.vectorus 18 | 19 | @staticmethod 20 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 21 | if decodeSpec['type'] != 'LT': 22 | return None 23 | 24 | decoder = wireless.codes.fountain.LTDecoder(packetLength, 25 | 2 * packetLength, 26 | decodeSpec['numIter']) 27 | return decoder 28 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/LdpcFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief LDPC factory 8 | class LdpcFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'ldpc': 12 | return None 13 | 14 | if codeSpec['n'] != 648: 15 | raise RuntimeError, "packet size currently unsupported" 16 | rateNumerator, rateDenominator = codeSpec['rate'] 17 | code = wireless.codes.ldpc.getWifiLDPC648(rateNumerator, rateDenominator) 18 | 19 | encoder = wireless.codes.ldpc.MatrixLDPCEncoder( 20 | code, 21 | codeSpec['bitsPerSymbol']) 22 | return encoder, wireless.vectorus 23 | 24 | @staticmethod 25 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 26 | if decodeSpec['type'] != 'ldpc-float-bp': 27 | return None 28 | 29 | if codeSpec['n'] != 648: 30 | raise RuntimeError, "packet size currently unsupported" 31 | rateNumerator, rateDenominator = codeSpec['rate'] 32 | code = wireless.codes.ldpc.getWifiLDPC648(rateNumerator, rateDenominator) 33 | 34 | return wireless.codes.ldpc.MatrixLDPCDecoder(code, decodeSpec['numIter']) 35 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/MultiplexedFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Encoder instances that produce symbols from multiple encoders 8 | class MultiplexedFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'multiplexed': 12 | return None 13 | 14 | numEncoders = codeSpec['numEncoders'] 15 | subPacketLength = packetLength / numEncoders 16 | encoders = [EncoderFactory._make(codeSpec['spec'], subPacketLength)[0] for i in xrange(numEncoders)] 17 | encodersVec = wireless.codes.vector_encoder() 18 | for e in encoders: 19 | encodersVec.push_back(e) 20 | lengthsVec = wireless.vectorui([subPacketLength] * numEncoders) 21 | 22 | encoder = wireless.codes.EncoderMultiplexer(encodersVec, lengthsVec) 23 | return encoder, wireless.vectorus 24 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/NullFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Null encoder/decoder factories 8 | class NullFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'null': 12 | return None 13 | 14 | return wireless.codes.null.NullEncoder(packetLength), wireless.vectorus 15 | 16 | @staticmethod 17 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 18 | if codeSpec['type'] != 'null': 19 | return None 20 | 21 | return wireless.codes.null.NullDecoder(packetLength) 22 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/RaptorFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Raptor encoders and decoders 8 | class RaptorFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'raptor': 12 | return None 13 | 14 | if packetLength in [9500, 1024, 2048, 3072, 4096, 256]: 15 | import os.path 16 | dirname = wireless.util.config.get_data_dir() 17 | filename = os.path.join(dirname, 'ldpc', 'LDPC_%d.it' % packetLength) 18 | encoder = wireless.codes.fountain.RaptorEncoder(filename) 19 | return encoder, wireless.vectorus 20 | else: 21 | raise RuntimeError, "Unsupported packet size %d" % packetLength 22 | 23 | @staticmethod 24 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 25 | if codeSpec['type'] != 'raptor': 26 | return None 27 | 28 | if packetLength in [9500, 1024, 2048, 3072, 4096, 256]: 29 | import os.path 30 | dirname = wireless.util.config.get_data_dir() 31 | filename = os.path.join(dirname, 'ldpc', 'LDPC_%d.it' % packetLength) 32 | decoder = wireless.codes.fountain.RaptorDecoder(filename, 33 | decodeSpec['numIter']) 34 | return decoder 35 | else: 36 | raise RuntimeError, "Unsupported packet size %d" % packetLength 37 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/StriderFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Strider encoders and decoders 8 | class StriderFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'strider': 12 | return None 13 | 14 | if codeSpec.has_key('fragmentLength'): 15 | encoder = wireless.codes.strider.StriderFactory.createEncoder(codeSpec['fragmentLength']) 16 | else: 17 | encoder = wireless.codes.strider.StriderFactory.createEncoder(1530) 18 | return encoder, wireless.vector_csymbol 19 | 20 | @staticmethod 21 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 22 | if decodeSpec['type'] != 'strider': 23 | return None 24 | 25 | if codeSpec.has_key('fragmentLength'): 26 | return wireless.codes.strider.StriderFactory.createDecoder(codeSpec['fragmentLength']) 27 | else: 28 | return wireless.codes.strider.StriderFactory.createDecoder(1530) 29 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/TurboFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012 Jonathan Perry 2 | # This code is released under the MIT license (see LICENSE file). 3 | import wireless 4 | 5 | ## 6 | # \ingroup factories 7 | # \brief Turbo codes encoders and decoders 8 | class TurboFactory(object): 9 | @staticmethod 10 | def make_encoder(codeSpec, packetLength): 11 | if codeSpec['type'] != 'turbo': 12 | return None 13 | 14 | encoder = wireless.codes.turbo.TurboEncoder(packetLength) 15 | return encoder, wireless.vectorus 16 | 17 | @staticmethod 18 | def make_decoder(codeSpec, packetLength, decodeSpec, mapSpec, channelSpec): 19 | if codeSpec['type'] != 'turbo': 20 | return None 21 | 22 | if decodeSpec['type'] != 'regular': 23 | raise RuntimeError, 'Unknown decoder type, only regular decoder is known' 24 | 25 | decoder = wireless.codes.turbo.TurboDecoder(packetLength) 26 | 27 | return decoder 28 | -------------------------------------------------------------------------------- /python/simulator/factories/codes/__init__.py: -------------------------------------------------------------------------------- 1 | from FadingStriderFactory import FadingStriderFactory 2 | from LdpcFactory import LdpcFactory 3 | from LTFactory import LTFactory 4 | from MultiplexedFactory import MultiplexedFactory 5 | from NullFactory import NullFactory 6 | from RaptorFactory import RaptorFactory 7 | from SpinalFactory import SpinalFactory 8 | from StriderFactory import StriderFactory 9 | from TurboFactory import TurboFactory 10 | -------------------------------------------------------------------------------- /python/statistics/__init__.py: -------------------------------------------------------------------------------- 1 | from ErrorRateStatistics import ErrorRateStatistics 2 | from ErrorLocationStatistics import ErrorLocationStatistics 3 | from FirstErrorStatistics import FirstErrorStatistics 4 | -------------------------------------------------------------------------------- /python/util/serialization/__init__.py: -------------------------------------------------------------------------------- 1 | import results_pb2 2 | -------------------------------------------------------------------------------- /src/CrcPacketGenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "CrcPacketGenerator.h" 6 | 7 | #include 8 | 9 | #include "util/MTRand.h" 10 | #include "util/Utils.h" 11 | 12 | using namespace std; 13 | 14 | CrcPacketGenerator::CrcPacketGenerator(unsigned int packetLengthBits) 15 | : m_packetLengthBits(packetLengthBits), 16 | m_random(0u) 17 | { 18 | if(packetLengthBits < 40) { 19 | throw(std::runtime_error("Packet length should be no less than 40")); 20 | } 21 | } 22 | 23 | void CrcPacketGenerator::seed(unsigned int* const seed, int seedSize) { 24 | m_random.seed(seed, seedSize); 25 | } 26 | 27 | string CrcPacketGenerator::get() { 28 | // initialize packet of size k to 0 29 | string packet((m_packetLengthBits + 7) / 8, 0); 30 | 31 | unsigned int numFullBytes = m_packetLengthBits / 8; 32 | // fill the packet with random bytes, except the CRC bits 33 | for (unsigned int i = 2; i < numFullBytes; i++) { 34 | packet[i] = m_random.randInt() & 0xFF; 35 | } 36 | 37 | if(m_packetLengthBits % 8 != 0) { 38 | // generate a last byte that does not have all bits 39 | packet[packet.size()-1] = m_random.randInt() & ((1 << (m_packetLengthBits % 8)) - 1); 40 | } 41 | 42 | *(uint16_t*)packet.data() = 43 | Utils::getArrCRC16((const uint8_t*)packet.data() + 2, packet.size() - 2); 44 | 45 | return packet; 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/PacketGenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "PacketGenerator.h" 6 | 7 | #include 8 | 9 | #include "util/MTRand.h" 10 | 11 | using namespace std; 12 | 13 | PacketGenerator::PacketGenerator(unsigned int packetLengthBits) 14 | : m_packetLengthBits(packetLengthBits), 15 | m_random(0u) 16 | {} 17 | 18 | void PacketGenerator::seed(unsigned int* const seed, int seedSize) { 19 | m_random.seed(seed, seedSize); 20 | } 21 | 22 | string PacketGenerator::get() { 23 | // initialize packet of size k to 0 24 | string packet((m_packetLengthBits + 7) / 8, 0); 25 | 26 | unsigned int numFullBytes = m_packetLengthBits / 8; 27 | // fill the packet with random bytes 28 | for (unsigned int i = 0; i < numFullBytes; i++) { 29 | packet[i] = m_random.randInt() & 0xFF; 30 | } 31 | 32 | if(m_packetLengthBits % 8 != 0) { 33 | // generate a last byte that does not have all bits 34 | packet[packet.size()-1] = m_random.randInt() & ((1 << (m_packetLengthBits % 8)) - 1); 35 | } 36 | 37 | return packet; 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/channels/BscChannel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "channels/BscChannel.h" 6 | 7 | BscChannel::BscChannel(float p) 8 | : m_p(p) 9 | {} 10 | 11 | void BscChannel::seed(unsigned int *const seed, int seedSize) { 12 | m_random.seed(seed, seedSize); 13 | } 14 | 15 | void BscChannel::process(const std::vector& inSymbols, 16 | std::vector& outSymbols) 17 | { 18 | // flip bits with probability p 19 | unsigned int symbolsSize = inSymbols.size(); 20 | outSymbols.clear(); 21 | outSymbols.resize(symbolsSize); 22 | for (unsigned int i = 0; i < symbolsSize; i++) { 23 | if(m_random.rand() < m_p) { 24 | outSymbols[i] = inSymbols[i] ^ 0x1; 25 | } else { 26 | outSymbols[i] = inSymbols[i]; 27 | } 28 | } 29 | } 30 | 31 | unsigned int BscChannel::forecast(unsigned int numOutputs) 32 | { 33 | return numOutputs; 34 | } 35 | -------------------------------------------------------------------------------- /src/channels/CoherenceCoeffGenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "channels/CoherenceCoeffGenerator.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | CoherenceCoeffGenerator::CoherenceCoeffGenerator(uint32_t coherenceInterval) 12 | : m_coherenceInterval(coherenceInterval), 13 | m_sqrt2inv(1.0 / sqrt(2.0)), 14 | m_random(0u), 15 | m_remaining(0) 16 | {} 17 | 18 | void CoherenceCoeffGenerator::seed(uint32_t *const seed, int seedSize) 19 | { 20 | m_random.seed(seed, seedSize); 21 | randomizeCoefficient(); 22 | m_remaining = m_random.randInt(m_coherenceInterval - 1) + 1; 23 | } 24 | 25 | FadingMagnitude CoherenceCoeffGenerator::next() 26 | { 27 | if(m_remaining == 0) { 28 | m_remaining = m_coherenceInterval; 29 | randomizeCoefficient(); 30 | } 31 | m_remaining--; 32 | 33 | return m_fadingCoeff; 34 | } 35 | 36 | void CoherenceCoeffGenerator::randomizeCoefficient() 37 | { 38 | FadingMagnitude a = m_random.randNorm(0.0, m_sqrt2inv); 39 | FadingMagnitude b = m_random.randNorm(0.0, m_sqrt2inv); 40 | 41 | m_fadingCoeff = sqrtf(a*a + b*b); 42 | } 43 | -------------------------------------------------------------------------------- /src/codes/InterleavedEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/InterleavedEncoder.h" 6 | 7 | #include 8 | #include 9 | 10 | InterleavedEncoder::InterleavedEncoder( IEncoderPtr & encoder, 11 | const std::vector& interleaveSequence) 12 | : m_encoder(encoder), 13 | m_interleavingSequence(interleaveSequence), 14 | m_maxIndex(*(std::max_element(interleaveSequence.begin(), 15 | interleaveSequence.end()))), 16 | m_next(0) 17 | { 18 | m_encoded.reserve(m_maxIndex + 1); 19 | } 20 | 21 | void InterleavedEncoder::setPacket(const std::string & packet) { 22 | // Add packet to encoder 23 | m_encoder->setPacket(packet); 24 | 25 | // encode enough symbols for the interleaving sequence 26 | m_encoder->encode(m_maxIndex + 1, m_encoded); 27 | 28 | // reset the output to start at the beginning of interleave sequence 29 | m_next = 0; 30 | } 31 | 32 | void InterleavedEncoder::encode(unsigned int numSymbols, 33 | std::vector & outSymbols) 34 | { 35 | // Sanity check, make sure the request doesn't ask for more symbols than 36 | // interleaving sequence has 37 | if(m_next + numSymbols > m_interleavingSequence.size()) { 38 | throw(std::runtime_error("Requested more symbols than interleaver can handle")); 39 | } 40 | 41 | outSymbols.clear(); 42 | outSymbols.resize(numSymbols); 43 | 44 | for(unsigned int i = 0; i < numSymbols; i++) { 45 | outSymbols[i] = m_encoded[m_interleavingSequence[m_next++]]; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/codes/MultiToSingleStreamEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/MultiToSingleStreamEncoder.h" 6 | 7 | #include 8 | #include 9 | 10 | MultiToSingleStreamEncoder::MultiToSingleStreamEncoder( IMultiStreamEncoder::Ptr & encoder, 11 | IPuncturingSchedulePtr & puncturing) 12 | : m_encoder(encoder), 13 | m_puncturing(puncturing) 14 | {} 15 | 16 | void MultiToSingleStreamEncoder::setPacket(const std::string & packet) 17 | { 18 | m_encoder->setPacket(packet); 19 | m_puncturing->reset(); 20 | } 21 | 22 | void MultiToSingleStreamEncoder::encode(unsigned int numSymbols, 23 | std::vector & outSymbols) 24 | { 25 | // Get which spine values need to be computed 26 | m_puncturing->batchNext(numSymbols, m_streamIndicesWorkArr); 27 | 28 | // Encode all requested spine values 29 | m_encoder->encode(m_streamIndicesWorkArr, outSymbols); 30 | } 31 | -------------------------------------------------------------------------------- /src/codes/RandomPermutationGenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/RandomPermutationGenerator.h" 6 | #include // memcpy 7 | 8 | RandomPermutationGenerator::RandomPermutationGenerator( 9 | unsigned int groupSize, 10 | unsigned int *const seed) 11 | : m_rand(seed, SEED_SIZE_UINTS), 12 | m_groupSize(groupSize), 13 | m_numRemaining(groupSize), 14 | m_arr(new unsigned int[groupSize]) 15 | { 16 | for(unsigned int i = 0; i < groupSize; i++) { 17 | m_arr[i] = i; 18 | } 19 | } 20 | 21 | RandomPermutationGenerator::RandomPermutationGenerator( 22 | const RandomPermutationGenerator& other) 23 | : m_rand(other.m_rand), 24 | m_groupSize(other.m_groupSize), 25 | m_numRemaining(other.m_numRemaining), 26 | m_arr(new unsigned int[m_groupSize]) 27 | { 28 | memcpy(m_arr, other.m_arr, m_groupSize * sizeof(unsigned int)); 29 | } 30 | 31 | 32 | RandomPermutationGenerator::~RandomPermutationGenerator() { 33 | delete[] m_arr; 34 | } 35 | 36 | void RandomPermutationGenerator::reset(unsigned int *const seed) { 37 | m_rand.seed(seed, SEED_SIZE_UINTS); 38 | for(unsigned int i = 0; i < m_groupSize; i++) { 39 | m_arr[i] = i; 40 | } 41 | m_numRemaining = m_groupSize; 42 | } 43 | 44 | unsigned int RandomPermutationGenerator::next() { 45 | if(m_numRemaining == 1) { 46 | m_numRemaining = m_groupSize; 47 | return m_arr[0]; 48 | } else { 49 | m_numRemaining--; 50 | unsigned int swapDest = m_rand.randInt(m_numRemaining); 51 | unsigned int tmp = m_arr[swapDest]; 52 | m_arr[swapDest] = m_arr[m_numRemaining]; 53 | m_arr[m_numRemaining] = tmp; 54 | 55 | return tmp; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/codes/fountain/RaptorDecoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/fountain/RaptorDecoder.h" 6 | 7 | #include "util/ItppUtils.h" 8 | 9 | RaptorDecoder::RaptorDecoder(const std::string & ldpcFilename, 10 | uint32_t numLtIterations) 11 | : m_G(), 12 | m_ldpc(ldpcFilename, &m_G), 13 | m_lt(m_ldpc.get_nvar(), 14 | 8 * m_ldpc.get_nvar(), 15 | numLtIterations), 16 | m_llrs(m_ldpc.get_nvar(), 0), 17 | m_itppLlrs(m_ldpc.get_nvar()), 18 | m_decodedBits(m_ldpc.get_ninfo()) 19 | {} 20 | 21 | void RaptorDecoder::reset() 22 | { 23 | m_lt.reset(); 24 | } 25 | 26 | void RaptorDecoder::add(const std::vector & llrs) 27 | { 28 | m_lt.add(llrs); 29 | } 30 | 31 | DecodeResult RaptorDecoder::decode() 32 | { 33 | // Perform decode of LT code 34 | m_lt.softDecode(m_llrs); 35 | 36 | // Copy result into the itpp LLR vec 37 | for(uint32_t i = 0; i < m_llrs.size(); i++) { 38 | m_itppLlrs[i] = m_llrs[i]; 39 | } 40 | 41 | // Perform LDPC decode 42 | m_ldpc.decode(m_itppLlrs, m_decodedBits); 43 | 44 | DecodeResult res; 45 | ItppUtils::vectorToString(m_decodedBits, res.packet); 46 | 47 | return res; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/codes/fountain/RaptorEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/fountain/RaptorEncoder.h" 6 | #include "util/ItppUtils.h" 7 | 8 | RaptorEncoder::RaptorEncoder(const std::string & ldpcFilename) 9 | : m_G(), 10 | m_ldpc(ldpcFilename, &m_G), 11 | m_lt(m_ldpc.get_nvar(), 12 | getNeighborGenerator(m_ldpc.get_nvar()), 13 | getSymbolFunction()), 14 | m_packetBits(m_ldpc.get_ninfo()), 15 | m_encodedBits(m_ldpc.get_nvar()), 16 | m_encodedVec(m_ldpc.get_nvar(), 0) 17 | {} 18 | 19 | void RaptorEncoder::setPacket(const std::string & packet) 20 | { 21 | // Convert the packet into bvec 22 | ItppUtils::stringToVector(packet, m_packetBits); 23 | 24 | // LDPC encode the packet 25 | m_ldpc.encode(m_packetBits, m_encodedBits); 26 | 27 | // Convert the encoded bvec into a string 28 | std::string ldpcCodeword; 29 | ItppUtils::vectorToString(m_encodedBits, ldpcCodeword); 30 | 31 | // Set the ldpc codeword to the LT code 32 | m_lt.setPacket(ldpcCodeword); 33 | } 34 | 35 | void RaptorEncoder::encode(unsigned int numSymbols, std::vector & outSymbols) 36 | { 37 | m_lt.encode(numSymbols, outSymbols); 38 | } 39 | 40 | BitwiseXorSymbolFunction RaptorEncoder::getSymbolFunction() 41 | { 42 | return BitwiseXorSymbolFunction(); 43 | } 44 | 45 | LTParityNeighborGenerator RaptorEncoder::getNeighborGenerator(uint32_t codewordSize) 46 | { 47 | return LTParityNeighborGenerator(codewordSize, 0xdeadbeef); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/codes/ldpc/MatrixLDPCCode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/ldpc/MatrixLDPCCode.h" 6 | #include 7 | 8 | MatrixLDPCCode::MatrixLDPCCode( unsigned int _n, 9 | unsigned int _Z, 10 | unsigned int _rateNumerator, 11 | unsigned int _rateDenominator, 12 | const unsigned int *rowPtrs, 13 | unsigned int numValues, 14 | const unsigned char *vals, 15 | const unsigned int *cols) 16 | : n(_n), 17 | Z(_Z), 18 | rateNumerator(_rateNumerator), 19 | rateDenominator(_rateDenominator), 20 | matrix(n * (rateDenominator - rateNumerator) / (rateDenominator * Z), 21 | rowPtrs, 22 | numValues, 23 | vals, 24 | cols) 25 | { 26 | // sanity checks 27 | if(n % Z != 0) { 28 | throw(std::runtime_error("n should be a multiple of Z")); 29 | } 30 | if((n * rateNumerator) % (rateDenominator * Z) != 0) { 31 | throw(std::runtime_error("there should be a whole number of submatrices" 32 | " for message part and for parity part.")); 33 | } 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/codes/null/NullDecoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/null/NullDecoder.h" 6 | #include 7 | #include "util/Utils.h" 8 | 9 | NullDecoder::NullDecoder(uint32_t packetLength) 10 | : m_packetLength(packetLength) 11 | { 12 | m_packetVector.reserve(packetLength); 13 | } 14 | 15 | void NullDecoder::reset() { 16 | m_packetVector.clear(); 17 | } 18 | 19 | void NullDecoder::add(const std::vector & llrs) { 20 | if (llrs.size() + m_packetVector.size() > m_packetLength) { 21 | throw std::runtime_error("Tried to add more LLR values than packet length"); 22 | } 23 | 24 | for(uint32_t i = 0; i < llrs.size(); i++) { 25 | m_packetVector.push_back(llrs[i] < 0); 26 | } 27 | } 28 | 29 | DecodeResult NullDecoder::decode() { 30 | if(m_packetVector.size() != m_packetLength) { 31 | throw std::runtime_error("Not enough symbols to decode"); 32 | } 33 | 34 | DecodeResult res; 35 | Utils::vectorToString(m_packetVector, res.packet); 36 | return res; 37 | } 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/codes/null/NullEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/null/NullEncoder.h" 6 | #include "util/Utils.h" 7 | 8 | NullEncoder::NullEncoder(uint32_t packetLength) 9 | : m_packetLength(packetLength), 10 | m_numRemaining(0) 11 | { 12 | m_packetVector.reserve(packetLength); 13 | } 14 | 15 | void NullEncoder::setPacket(const std::string & packet) 16 | { 17 | // make sure packet is of the right size 18 | if (packet.size() != (m_packetLength + 7) / 8) { 19 | throw std::runtime_error("Packet size doesn't match this encoder"); 20 | } 21 | 22 | // Convert the packet into a bit vector 23 | Utils::stringToVector(packet, m_packetVector); 24 | m_numRemaining = m_packetLength; 25 | } 26 | 27 | void NullEncoder::encode(unsigned int numSymbols, std::vector & outSymbols) 28 | { 29 | if (numSymbols > m_numRemaining) { 30 | throw std::runtime_error("Requested more symbols than are available"); 31 | } 32 | 33 | outSymbols.clear(); 34 | outSymbols.reserve(numSymbols); 35 | for(uint32_t i = m_packetLength - m_numRemaining; outSymbols.size() < numSymbols; i++) { 36 | outSymbols.push_back(uint16_t(m_packetVector[i]) & 0x1); 37 | } 38 | } 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/codes/puncturing/RepeatingPuncturingSchedule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/puncturing/RepeatingPuncturingSchedule.h" 6 | 7 | #include 8 | 9 | RepeatingPuncturingSchedule::RepeatingPuncturingSchedule( 10 | IPuncturingSchedulePtr & innerSchedule, 11 | unsigned int numRepetitions) 12 | : m_innerSchedule(innerSchedule), 13 | m_numRepetitions(numRepetitions), 14 | m_remainingRepetitions(0), 15 | m_tempCache() 16 | {} 17 | 18 | void RepeatingPuncturingSchedule::reset() { 19 | m_innerSchedule->reset(); 20 | m_remainingRepetitions = 0; 21 | } 22 | 23 | void RepeatingPuncturingSchedule::batchNext( 24 | unsigned int numSymbols, 25 | std::vector & streamIndices) 26 | { 27 | streamIndices.clear(); 28 | streamIndices.resize(numSymbols); 29 | 30 | // the location into streamIndices next symbol is written to 31 | unsigned int nextLocation = 0; 32 | 33 | // First, use the cached index 34 | while((nextLocation < numSymbols) && (m_remainingRepetitions > 0)) { 35 | streamIndices[nextLocation++] = m_cachedIndex; 36 | m_remainingRepetitions--; 37 | } 38 | 39 | // Get more indices from inner schedule 40 | unsigned int numInner = ((numSymbols - nextLocation) + m_numRepetitions - 1) / m_numRepetitions; 41 | m_innerSchedule->batchNext(numInner, m_tempCache); 42 | 43 | // Put all indices except the last one 44 | for(int i = 0; i < ((int)numInner) - 1; i++) { 45 | for(unsigned int j = 0; j < m_numRepetitions; j++) { 46 | streamIndices[nextLocation++] = m_tempCache[i]; 47 | } 48 | } 49 | 50 | // Put the last index 51 | m_cachedIndex = m_tempCache[numInner - 1]; 52 | m_remainingRepetitions = m_numRepetitions; 53 | while(nextLocation < numSymbols) { 54 | streamIndices[nextLocation++] = m_cachedIndex; 55 | m_remainingRepetitions--; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/codes/puncturing/RoundRobinPuncturingSchedule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/puncturing/RoundRobinPuncturingSchedule.h" 6 | 7 | RoundRobinPuncturingSchedule::RoundRobinPuncturingSchedule( 8 | uint32_t numStreams) 9 | : m_numStreams(numStreams), 10 | m_nextStream(0) 11 | {} 12 | 13 | void RoundRobinPuncturingSchedule::reset() { 14 | m_nextStream = 0; 15 | } 16 | 17 | void RoundRobinPuncturingSchedule::batchNext( 18 | unsigned int numSymbols, 19 | std::vector& streamIndices) { 20 | streamIndices.clear(); 21 | streamIndices.reserve(numSymbols); 22 | for(uint32_t i = 0; i < numSymbols; i++) { 23 | // Add next stream to list 24 | streamIndices.push_back(m_nextStream); 25 | 26 | // Advance the next stream, wrap around. 27 | m_nextStream++; 28 | if(m_nextStream == m_numStreams) { 29 | m_nextStream = 0; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/codes/puncturing/StaticPuncturingSchedule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/puncturing/StaticPuncturingSchedule.h" 6 | 7 | #include 8 | 9 | StaticPuncturingSchedule::StaticPuncturingSchedule() 10 | : m_nextIndex(0) 11 | {} 12 | 13 | void StaticPuncturingSchedule::reset() { 14 | m_nextIndex = 0; 15 | } 16 | 17 | void StaticPuncturingSchedule::batchNext( 18 | unsigned int numSymbols, 19 | std::vector & streamIndices) 20 | { 21 | // Clear before resize, so if reallocation is needed, copies are avoided 22 | streamIndices.clear(); 23 | streamIndices.resize(numSymbols); 24 | 25 | for(unsigned int i = 0; i < numSymbols; i++) { 26 | streamIndices[i] = next(); 27 | } 28 | } 29 | 30 | uint16_t StaticPuncturingSchedule::next() { 31 | if(m_nextIndex >= m_schedule.size()) { 32 | throw(std::runtime_error("Exceeded schedule size.")); 33 | } 34 | 35 | return m_schedule[m_nextIndex++]; 36 | } 37 | 38 | void StaticPuncturingSchedule::set(const std::vector & schedule) { 39 | m_schedule = schedule; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/codes/spinal/SpinalBranchEvaluator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/spinal/SpinalBranchEvaluator.h" 6 | 7 | #include 8 | #include "util/Utils.h" 9 | 10 | // DISTANCE FUNCTIONS 11 | 12 | uint64_t IntegerEuclidianDistance::dist(Symbol x, Symbol y) 13 | { 14 | int64_t delta = ((int64_t)(x) - (int64_t)(y)); 15 | return delta * delta; 16 | } 17 | 18 | uint32_t HammingDistance::dist(Symbol x, Symbol y) 19 | { 20 | return Utils::popcount_2(x ^ y); 21 | } 22 | 23 | double FadingEuclidianDistance::dist(FadingSymbol x, 24 | FadingSymbol y) 25 | { 26 | SoftSymbol delta = (x.symbol - y.symbol); 27 | return double(delta * delta); 28 | } 29 | 30 | double SoftEuclidianDistance::dist(SoftSymbol x, SoftSymbol y) 31 | { 32 | SoftSymbol delta = x - y; 33 | return double(delta * delta); 34 | } 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/codes/spinal/StubHashDecoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/spinal/StubHashDecoder.h" 6 | 7 | StubHashDecoder::StubHashDecoder(unsigned int numSymbolsPerPass) 8 | : m_numSymbolsPerPass(numSymbolsPerPass) 9 | {} 10 | 11 | DecodeResult StubHashDecoder::decode( 12 | unsigned int numPasses, const Symbol *symbols, int symbolsSize) 13 | { 14 | lastCallNumPasses = numPasses; 15 | 16 | lastCallSymbols.clear(); 17 | lastCallSymbols.reserve(symbolsSize); 18 | for (int i = 0; i < symbolsSize; i++) { 19 | lastCallSymbols.push_back(symbols[i]); 20 | } 21 | 22 | return DecodeResult(); 23 | } 24 | 25 | 26 | unsigned int StubHashDecoder::numSymbolsPerPass() { 27 | return m_numSymbolsPerPass; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/codes/strider/LayerSuperposition.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/strider/LayerSuperposition.h" 6 | 7 | #include 8 | #include 9 | 10 | using namespace boost::numeric::ublas; 11 | 12 | LayerSuperposition::LayerSuperposition(unsigned int layerLength, 13 | std::complex* matrixG, 14 | int rowsG, 15 | int colsG) 16 | : m_G(rowsG, colsG), 17 | m_layerSymbols(colsG, layerLength), 18 | m_nextSymbol(0), 19 | m_currentPass(0) 20 | { 21 | for(int row = 0; row < rowsG; row++) { 22 | for(int col = 0; col < colsG; col++) { 23 | m_G(row, col) = *(matrixG++); 24 | } 25 | } 26 | } 27 | 28 | void LayerSuperposition::setLayer( 29 | unsigned int layerInd, 30 | const std::vector & layer) 31 | { 32 | assert(layerInd < m_layerSymbols.size1()); 33 | assert(layer.size() == m_layerSymbols.size2()); 34 | 35 | for(unsigned int i = 0; i < m_layerSymbols.size2(); i++) { 36 | m_layerSymbols(layerInd,i) = layer[i]; 37 | } 38 | } 39 | 40 | void LayerSuperposition::reset() { 41 | m_nextSymbol = 0; 42 | m_currentPass = 0; 43 | } 44 | 45 | ComplexSymbol LayerSuperposition::next() { 46 | ComplexSymbol res = inner_prod(row(m_G, m_currentPass), 47 | column(m_layerSymbols, m_nextSymbol)); 48 | 49 | m_nextSymbol++; 50 | if(m_nextSymbol == m_layerSymbols.size2()) { 51 | m_nextSymbol = 0; 52 | m_currentPass++; 53 | } 54 | 55 | return res; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/codes/turbo/TurboDecoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "codes/turbo/TurboDecoder.h" 6 | #include "codes/turbo/TurboCodec.h" 7 | #include 8 | #include 9 | 10 | TurboDecoder::TurboDecoder(uint32_t messageLength) 11 | : m_next(0) 12 | { 13 | itpp::ivec interleaveSequence; 14 | TurboCodec::getInterleaver(messageLength, interleaveSequence); 15 | m_codec.set_parameters("013 015 017", // gen1 16 | "013 015 017", // gen2 17 | 4, // constraint length 18 | interleaveSequence); 19 | 20 | m_codec.set_metric("TABLE"); 21 | 22 | m_llr.set_size(m_codec.get_Ncoded(), false); 23 | } 24 | 25 | void TurboDecoder::reset() { 26 | m_llr.zeros(); 27 | m_next = 0; 28 | } 29 | 30 | void TurboDecoder::add(const std::vector & symbols) { 31 | for(unsigned int i = 0; i < symbols.size(); i++) { 32 | assert(m_next < m_llr.size()); 33 | addLLR(m_next++, symbols[i]); 34 | } 35 | } 36 | 37 | void TurboDecoder::addLLR(unsigned int location, float llr) { 38 | assert(isfinite(llr)); 39 | m_llr[location] += llr; 40 | } 41 | 42 | DecodeResult TurboDecoder::decode() { 43 | itpp::bvec decoded; 44 | 45 | m_codec.decode(m_llr, decoded); 46 | 47 | DecodeResult res; 48 | int numBytes = ((int)decoded.size() + 7) / 8; 49 | res.packet.resize(numBytes); 50 | 51 | // all but last byte 52 | int dec_i = 0; 53 | for(int i = 0; i < numBytes - 1; i++) { 54 | unsigned char ch = 0; 55 | for (int b = 0; b < 8; b++) { 56 | ch |= ( ((unsigned char)decoded[dec_i++].value()) << b); 57 | } 58 | res.packet[i] = ch; 59 | } 60 | 61 | unsigned char ch = 0; 62 | for(int b = 0; (b < 8) && (dec_i < decoded.size()); b++) { 63 | ch |= ( ((unsigned char)decoded[dec_i++].value()) << b); 64 | } 65 | res.packet[numBytes - 1] = ch; 66 | 67 | return res; 68 | } 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/demappers/BscDemapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "demappers/BscDemapper.h" 6 | 7 | #include 8 | #include 9 | 10 | BscDemapper::BscDemapper(float flipProb) 11 | { 12 | m_llr[1] = (logf(flipProb) - logf(1-flipProb)); 13 | m_llr[0] = -m_llr[1]; 14 | } 15 | 16 | 17 | 18 | void BscDemapper::process(const std::vector& symbols, 19 | N0_t n0, 20 | std::vector& llrs) 21 | { 22 | unsigned int symbolsSize = symbols.size(); 23 | llrs.clear(); 24 | llrs.resize(symbolsSize); 25 | for(unsigned int i = 0; i < symbolsSize; i++) { 26 | llrs[i] = m_llr[symbols[i] & 0x1]; 27 | } 28 | } 29 | 30 | unsigned int BscDemapper::forecast(unsigned int numOutputs) 31 | { 32 | return numOutputs; 33 | } 34 | -------------------------------------------------------------------------------- /src/demappers/NullDemapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "demappers/NullDemapper.h" 6 | 7 | 8 | void NullDemapper::process(const std::vector& inSymbols, 9 | std::vector& outSymbols) 10 | { 11 | outSymbols = inSymbols; 12 | } 13 | 14 | Symbol NullDemapper::map(Symbol sym) { 15 | return sym; 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/mappers/ComplexLinearMapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/ComplexLinearMapper.h" 6 | 7 | #include 8 | 9 | ComplexLinearMapper::ComplexLinearMapper(unsigned int numBitsPerDim) 10 | : m_numBitsPerDim(numBitsPerDim), 11 | m_symbolMask(((1 << m_numBitsPerDim)-1)) 12 | { 13 | if (m_numBitsPerDim > 8) { 14 | throw(std::runtime_error("Number of bits per dimension to large, max 8")); 15 | } 16 | } 17 | 18 | void ComplexLinearMapper::process(const std::vector& inSymbols, 19 | std::vector& outSymbols) 20 | { 21 | unsigned int numSymbols = inSymbols.size(); 22 | outSymbols.clear(); 23 | outSymbols.resize(numSymbols); 24 | for(unsigned int i = 0; i < numSymbols; i++) { 25 | outSymbols[i] = map(inSymbols[i]); 26 | } 27 | } 28 | 29 | ComplexSymbol ComplexLinearMapper::map(uint16_t sym) 30 | { 31 | return ComplexSymbol((sym >> 0 ) & m_symbolMask, 32 | (sym >> m_numBitsPerDim) & m_symbolMask); 33 | } 34 | 35 | float ComplexLinearMapper::getAveragePower() { 36 | // N = number of constellation points in single dimension 37 | unsigned int N = (1 << m_numBitsPerDim); 38 | 39 | // signal power is the second moment of uniform discrete distribution 40 | // around its mean (see http://mathworld.wolfram.com/DiscreteUniformDistribution.html) 41 | float oneDimSignalPower = ((float)(N - 1)) * ((float)(N + 1)) / 12.0; 42 | 43 | return (2.0 * oneDimSignalPower); 44 | } 45 | 46 | unsigned int ComplexLinearMapper::forecast(unsigned int numOutputs) 47 | { 48 | return numOutputs; 49 | } 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/mappers/GrayMapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/GrayMapper.h" 6 | 7 | #include 8 | 9 | 10 | GrayMapper::GrayMapper(unsigned int symbolSizeBits, 11 | unsigned int precisionBits) 12 | : m_symbolSizeBits(symbolSizeBits), 13 | m_precisionBits(precisionBits), 14 | m_leftShiftSize(precisionBits - symbolSizeBits), 15 | m_mask((1 << symbolSizeBits) - 1) 16 | { 17 | if(m_symbolSizeBits > m_precisionBits) { 18 | throw(std::runtime_error("Precision insufficient for non-lossy mapping")); 19 | } 20 | } 21 | 22 | 23 | void GrayMapper::process(const std::vector& inSymbols, 24 | std::vector& outSymbols) 25 | { 26 | unsigned int numSymbols = inSymbols.size(); 27 | outSymbols.clear(); 28 | outSymbols.resize(numSymbols); 29 | for(unsigned int i = 0; i < numSymbols; i++) { 30 | outSymbols[i] = map(inSymbols[i]); 31 | } 32 | } 33 | 34 | 35 | float GrayMapper::getAveragePower() { 36 | // N = number of constellation points 37 | unsigned int N = (1 << m_symbolSizeBits); 38 | 39 | // encoder power is the second moment of uniform discrete distribution 40 | // around its mean (see http://mathworld.wolfram.com/DiscreteUniformDistribution.html) 41 | float encoderPowerWithoutAddedPrecision = ((float)(N - 1)) * ((float)(N + 1)) / 12.0; 42 | 43 | // need to add precision. Since the average is over the signal squared, 44 | // we need to add square the precision 45 | unsigned long long precisionFactor = ((unsigned long long)1 << (2 * m_leftShiftSize)); 46 | float encoderPower = encoderPowerWithoutAddedPrecision * precisionFactor; 47 | 48 | return encoderPower; 49 | } 50 | 51 | unsigned int GrayMapper::forecast(unsigned int numOutputs) 52 | { 53 | return numOutputs; 54 | } 55 | -------------------------------------------------------------------------------- /src/mappers/QPSKMapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/QPSKMapper.h" 6 | 7 | #include 8 | 9 | void QPSKMapper::process( const std::vector & inSymbols, 10 | std::vector & outSymbols) 11 | { 12 | // Convert inputs into a bvec 13 | itpp::bvec bits(inSymbols.size()); 14 | for(unsigned int i = 0; i < inSymbols.size(); i++) { 15 | bits[i] = ((inSymbols[i] & 0x1) != 0); 16 | } 17 | 18 | // Modulate using ITPP 19 | itpp::cvec modulated = m_qpsk.modulate_bits(bits); 20 | 21 | // Fill into the output 22 | outSymbols.clear(); 23 | outSymbols.resize(modulated.size()); 24 | for(int i = 0; i < modulated.size(); i++) { 25 | outSymbols[i] = modulated[i]; 26 | } 27 | } 28 | 29 | float QPSKMapper::getAveragePower() { 30 | return 1.0f; 31 | } 32 | 33 | unsigned int QPSKMapper::forecast(unsigned int numOutputs) { 34 | return (numOutputs * 2); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/mappers/QamMapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/QamMapper.h" 6 | 7 | #include 8 | #include 9 | 10 | QamMapper::QamMapper(uint32_t k) 11 | : m_k(k), 12 | m_qam(1 << m_k) 13 | {} 14 | 15 | void QamMapper::process( const std::vector & inSymbols, 16 | std::vector & outSymbols) 17 | { 18 | if (inSymbols.size() % m_k != 0) { 19 | throw(std::runtime_error("number of input bits must be a multiple of k to modulate in QAM-2^k")); 20 | } 21 | 22 | // Convert inputs into a bvec 23 | itpp::bvec bits(inSymbols.size()); 24 | for(unsigned int i = 0; i < inSymbols.size(); i++) { 25 | bits[i] = ((inSymbols[i] & 0x1) != 0); 26 | } 27 | 28 | // Modulate using ITPP 29 | itpp::cvec modulated = m_qam.modulate_bits(bits); 30 | 31 | // Fill into the output 32 | outSymbols.clear(); 33 | outSymbols.resize(modulated.size()); 34 | for(int i = 0; i < modulated.size(); i++) { 35 | outSymbols[i] = modulated[i]; 36 | } 37 | } 38 | 39 | float QamMapper::getAveragePower() { 40 | return 1.0f; 41 | } 42 | 43 | 44 | unsigned int QamMapper::forecast(unsigned int numOutputs) { 45 | return (numOutputs * m_k); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/mappers/SoftMapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/SoftMapper.h" 6 | 7 | #include 8 | 9 | 10 | SoftMapper::SoftMapper(unsigned int symbolSizeBits) 11 | : m_symbolSizeBits(symbolSizeBits), 12 | m_symbolMask(((1 << m_symbolSizeBits)-1)) 13 | { 14 | if (symbolSizeBits > 16) { 15 | throw(std::runtime_error("Symbol size to big, max 16")); 16 | } 17 | } 18 | 19 | 20 | void SoftMapper::process(const std::vector& inSymbols, 21 | std::vector& outSymbols) 22 | { 23 | unsigned int numSymbols = inSymbols.size(); 24 | outSymbols.resize(numSymbols); 25 | for(unsigned int i = 0; i < numSymbols; i++) { 26 | outSymbols[i] = map(inSymbols[i]); 27 | } 28 | } 29 | 30 | SoftSymbol SoftMapper::map(uint16_t sym) { 31 | return SoftSymbol(sym & m_symbolMask); 32 | } 33 | 34 | float SoftMapper::getAveragePower() { 35 | // N = number of constellation points 36 | unsigned int N = (1 << m_symbolSizeBits); 37 | 38 | // encoder power is the second moment of uniform discrete distribution 39 | // around its mean (see http://mathworld.wolfram.com/DiscreteUniformDistribution.html) 40 | float encoderPowerWithoutAddedPrecision = ((float)(N - 1)) * ((float)(N + 1)) / 12.0; 41 | 42 | return encoderPowerWithoutAddedPrecision; 43 | } 44 | 45 | unsigned int SoftMapper::forecast(unsigned int numOutputs) 46 | { 47 | return numOutputs; 48 | } 49 | -------------------------------------------------------------------------------- /src/mappers/TruncatedNormalDistribution.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "mappers/TruncatedNormalDistribution.h" 6 | 7 | #include 8 | #include "mappers/NormalDistribution.h" 9 | 10 | TruncatedNormalDistribution::TruncatedNormalDistribution(double a, double b) 11 | : m_a(a), 12 | m_b(b), 13 | m_cdfOfA(NormalDistribution::cdf(a)), 14 | m_weightGivenAB(NormalDistribution::cdf(b) - m_cdfOfA) 15 | {} 16 | 17 | 18 | 19 | double TruncatedNormalDistribution::ppf(double p) { 20 | return NormalDistribution::ppf(m_cdfOfA + (m_weightGivenAB * p)); 21 | } 22 | 23 | 24 | 25 | double TruncatedNormalDistribution::variance() { 26 | // Formula at http://en.wikipedia.org/wiki/Truncated_normal_distribution 27 | double secondTerm = 28 | ( (m_a * NormalDistribution::pdf(m_a)) 29 | - (m_b * NormalDistribution::pdf(m_b))) / m_weightGivenAB; 30 | double thirdTermBeforeSqrt = 31 | ( NormalDistribution::pdf(m_a) 32 | - NormalDistribution::pdf(m_b)) / m_weightGivenAB; 33 | 34 | return ( 1 35 | + secondTerm 36 | - sqrt(thirdTermBeforeSqrt)); 37 | } 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/protocols/OneTryProtocol.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "protocols/OneTryProtocol.h" 6 | 7 | #include 8 | 9 | OneTryProtocol::OneTryProtocol( unsigned int numPackets, 10 | unsigned int numSymbols) 11 | : m_numSymbols(numSymbols), 12 | m_nextDecode(numPackets, numSymbols) 13 | { 14 | if (numSymbols < 1) { 15 | throw std::runtime_error("this protocol requires at least 1 symbol"); 16 | } 17 | } 18 | 19 | unsigned int OneTryProtocol::numSymbolsNextDecode(unsigned int packetInd) { 20 | return m_nextDecode[packetInd]; 21 | } 22 | 23 | void OneTryProtocol::setResult( unsigned int packetInd, 24 | unsigned int numSymbols, 25 | bool isFinished) 26 | { 27 | if(numSymbols != m_nextDecode[packetInd]) { 28 | throw (std::runtime_error("unexpected result from packet")); 29 | } 30 | 31 | // After one try, we're done 32 | m_nextDecode[packetInd] = 0; 33 | } 34 | 35 | void OneTryProtocol::resetPacket(unsigned int packetInd) { 36 | m_nextDecode[packetInd] = m_numSymbols; 37 | } 38 | -------------------------------------------------------------------------------- /src/protocols/RateApproxProtocol.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "protocols/RateApproxProtocol.h" 6 | 7 | #include 8 | #include 9 | 10 | RateApproxProtocol::RateApproxProtocol( 11 | unsigned int numPackets, 12 | unsigned int maxSymbols, 13 | float delta, 14 | uint32_t minSymbols) 15 | : m_maxSymbols(maxSymbols), 16 | m_oneOverDelta(1.0 / delta), 17 | m_minSymbols(minSymbols), 18 | m_nextNumSymbols(numPackets, minSymbols) 19 | {} 20 | 21 | unsigned int RateApproxProtocol::numSymbolsNextDecode(unsigned int packetInd) 22 | { 23 | return m_nextNumSymbols[packetInd]; 24 | } 25 | 26 | void RateApproxProtocol::setResult( 27 | unsigned int packetInd, 28 | unsigned int numSymbols, 29 | bool isFinished) 30 | { 31 | if(numSymbols < m_nextNumSymbols[packetInd]) { 32 | throw(std::runtime_error("Last run used last symbols than instructed!")); 33 | } 34 | 35 | if(isFinished || (numSymbols >= m_maxSymbols)) { 36 | m_nextNumSymbols[packetInd] = 0; 37 | } else { 38 | // Otherwise, find the next number of symbols 39 | numSymbols = std::max((numSymbols + 1), 40 | (unsigned int)(numSymbols * m_oneOverDelta)); 41 | numSymbols = std::min(m_maxSymbols, numSymbols); 42 | m_nextNumSymbols[packetInd] = numSymbols; 43 | } 44 | } 45 | 46 | void RateApproxProtocol::resetPacket(unsigned int packetInd) 47 | { 48 | m_nextNumSymbols[packetInd] = m_minSymbols; 49 | } 50 | -------------------------------------------------------------------------------- /src/util/BitStatCounter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "util/BitStatCounter.h" 6 | 7 | BitStatCounter::BitStatCounter(uint32_t num_bits) 8 | : m_num_bits(num_bits), 9 | m_stats(num_bits, 0) 10 | {} 11 | 12 | void BitStatCounter::process(const std::string& s) { 13 | for(uint32_t i = 0; i < m_num_bits; i++) { 14 | m_stats[i] += (uint8_t(s[i/8]) >> (i % 8)) & 0x1; 15 | } 16 | } 17 | 18 | uint32_t BitStatCounter::query(uint32_t bit_index) { 19 | return m_stats[bit_index]; 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/util/BlockStatCounter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "util/BlockStatCounter.h" 6 | 7 | #include 8 | #include "util/Utils.h" 9 | 10 | BlockStatCounter::BlockStatCounter(uint32_t num_bits, uint32_t k) 11 | : m_num_bits(num_bits), 12 | m_k(k), 13 | m_num_blocks(num_bits / m_k), 14 | m_stats(m_num_blocks, 0) 15 | { 16 | if((m_num_bits % m_k) != 0) { 17 | throw std::runtime_error("String length must be divisible by block length"); 18 | } 19 | 20 | if(m_k > 32) { 21 | throw std::runtime_error("Currently only <= 32 bit blocks are supported."); 22 | } 23 | } 24 | 25 | void BlockStatCounter::process(const std::string& s) { 26 | // Divide the string bits into blocks of k bits 27 | Utils::blockify(s, m_num_bits, m_k, m_tmp_blocks); 28 | 29 | for(uint32_t i = 0; i < m_num_blocks; i++) { 30 | if(m_tmp_blocks[i] != 0) { 31 | m_stats[i]++; 32 | } 33 | } 34 | } 35 | 36 | uint32_t BlockStatCounter::query(uint32_t block_index) { 37 | return m_stats[block_index]; 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/util/ItppUtils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "util/ItppUtils.h" 6 | 7 | #include 8 | 9 | void ItppUtils::stringToVector(const std::string & src, itpp::bvec & dst) 10 | { 11 | uint32_t dstSizeBits = dst.size(); 12 | uint32_t dstSizeBytes = (dstSizeBits + 7) / 8; 13 | 14 | // Check input size 15 | if(src.size() != dstSizeBytes) { 16 | throw(std::runtime_error("String size incompatible with destination's size")); 17 | } 18 | 19 | // convert the string to a bvec 20 | int bitInd = 0; 21 | // All but the last byte 22 | for(unsigned int i = 0; i + 1 < dstSizeBytes; i++) { 23 | unsigned char byte = static_cast(src[i]); 24 | for(int b = 0; b < 8; b++) { 25 | dst[bitInd++] = (byte >> b) & 0x1; 26 | } 27 | } 28 | // Last byte 29 | unsigned char byte = static_cast(src[dstSizeBytes - 1]); 30 | for(int b = 0; (b < 8) && (bitInd < dst.size()); b++) { 31 | dst[bitInd++] = (byte >> b) & 0x1; 32 | } 33 | } 34 | 35 | void ItppUtils::vectorToString(const itpp::bvec & src, std::string & dst) 36 | { 37 | uint32_t srcSizeBits = src.size(); 38 | uint32_t srcSizeBytes = (srcSizeBits + 7) / 8; 39 | 40 | // Resize string to the appropriate size 41 | dst.resize(srcSizeBytes); 42 | 43 | // Put the bits into the string 44 | uint32_t bitInd = 0; 45 | // All but the last byte 46 | for(unsigned int i = 0; i + 1 < srcSizeBytes; i++) { 47 | uint8_t byte = 0; 48 | for(int b = 0; b < 8; b++) { 49 | byte |= (uint8_t(bool(src[bitInd++])) & 0x1) << b; 50 | } 51 | dst[i] = byte; 52 | } 53 | // Last byte 54 | uint8_t byte = 0; 55 | for(int b = 0; (b < 8) && (bitInd < srcSizeBits); b++) { 56 | byte |= (uint8_t(bool(src[bitInd++])) & 0x1) << b; 57 | } 58 | dst[srcSizeBytes - 1] = byte; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/util/hashes/BitwiseXor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "BitwiseXor.h" 6 | 7 | void BitwiseXor::init(Digest digest, State & state) { 8 | state = digest; 9 | } 10 | 11 | void BitwiseXor::update(State & state, unsigned int data) { 12 | state ^= data; 13 | } 14 | 15 | BitwiseXor::Digest BitwiseXor::digest(const State & state) { 16 | return state; 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/util/hashes/Lookup3Hash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "Lookup3Hash.h" 6 | 7 | #include 8 | 9 | /************************** 10 | * Lookup3Hash 11 | **************************/ 12 | 13 | void Lookup3Hash::init(Digest digest, State& state) { 14 | state[0] = state[1] = state[2] = 0xdeadbeef + digest; 15 | } 16 | 17 | #define rot(x,k) (((x) << (k)) | ((x) >> (32-(k)))) 18 | 19 | 20 | void Lookup3Hash::update(State& state, unsigned int data) { 21 | state[1] += data; 22 | state[2] ^= state[1]; state[2] -= rot(state[1],14); \ 23 | state[0] ^= state[2]; state[0] -= rot(state[2],11); \ 24 | state[1] ^= state[0]; state[1] -= rot(state[0],25); \ 25 | state[2] ^= state[1]; state[2] -= rot(state[1],16); \ 26 | state[0] ^= state[2]; state[0] -= rot(state[2],4); \ 27 | state[1] ^= state[0]; state[1] -= rot(state[0],14); \ 28 | state[2] ^= state[1]; state[2] -= rot(state[1],24); \ 29 | } 30 | 31 | Lookup3Hash::Digest Lookup3Hash::digest(const State& state) { 32 | return state[2]; 33 | } 34 | 35 | uint64_t Lookup3Hash::digest_extended(const State& state) { 36 | return state[2] | (uint64_t(state[1]) << 32); 37 | } 38 | 39 | 40 | /************************** 41 | * Lookup3SymbolFunction 42 | **************************/ 43 | 44 | 45 | void Lookup3SymbolFunction::getSymbols(const Hash::State & state, 46 | uint16_t* symbols) 47 | { 48 | symbols[0] = state[2] & 0xffff; 49 | symbols[1] = state[2] >> 16; 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/util/hashes/OneAtATimeHash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "OneAtATimeHash.h" 6 | 7 | #include 8 | 9 | /************************** 10 | * OneAtATimeHash 11 | **************************/ 12 | 13 | void OneAtATimeHash::init(Digest digest, State& state) { 14 | state = 3321836253 ^ digest; 15 | } 16 | 17 | #define rot(x,k) (((x) << (k)) | ((x) >> (32-(k)))) 18 | 19 | 20 | void OneAtATimeHash::update(State& state, unsigned int data) { 21 | for(unsigned int i = 0; i < 4; ++i) { 22 | state += data; 23 | state += (state << 10); 24 | state ^= (state >> 6); 25 | data >>= 8; 26 | } 27 | 28 | state += (state << 3); 29 | state ^= (state >> 11); 30 | state += (state << 15); 31 | } 32 | 33 | OneAtATimeHash::Digest OneAtATimeHash::digest(const State& state) { 34 | return state; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/util/hashes/SalsaHash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "SalsaHash.h" 6 | #include "salsa20.h" 7 | 8 | /************************** 9 | * SalsaHash 10 | **************************/ 11 | 12 | void SalsaHash::init(Digest digest, State& state) { 13 | salsaInit(digest, state); 14 | } 15 | 16 | void SalsaHash::update(State& state, u32 data) { 17 | salsaUpdate(state, data); 18 | } 19 | 20 | SalsaHash::Digest SalsaHash::digest(const State& state) { 21 | return salsaDigest(state); 22 | } 23 | 24 | 25 | /************************** 26 | * SalsaSymbolFunction 27 | **************************/ 28 | void SalsaSymbolFunction::getSymbols( 29 | const Hash::State & state, 30 | uint16_t *symbols) 31 | { 32 | for(unsigned int i = 0; i < 16; i++) { 33 | symbols[(2 * i) + 0] = (state[15 - i] >> 16) & 0xFFFF; 34 | symbols[(2 * i) + 1] = (state[15 - i] >> 0) & 0xFFFF; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/util/inference/bp/BipartiteBP.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jonathan Perry 3 | * This code is released under the MIT license (see LICENSE file). 4 | */ 5 | #include "util/inference/bp/BipartiteBP.h" 6 | 7 | #include "util/inference/bp/MultiVector.h" 8 | 9 | BipartiteBP::BipartiteBP(BipartiteGraph& graph, 10 | VariableNodeUpdater& variableNodeUpdater, 11 | NodeUpdater& checkNodeUpdater) 12 | : m_graph(graph), 13 | m_variableNodeUpdater(variableNodeUpdater), 14 | m_checkNodeUpdater(checkNodeUpdater) 15 | { 16 | MultiVector& left(m_graph.left()); 17 | for(uint32_t i = 0; i < left.total_num_elements(); i++) { 18 | left[i] = 0; 19 | } 20 | } 21 | 22 | void BipartiteBP::get_soft_values(std::vector & llrs) 23 | { 24 | m_variableNodeUpdater.estimate(m_graph.left(), llrs); 25 | } 26 | 27 | void BipartiteBP::advance(uint32_t numIterations) 28 | { 29 | for (uint32_t i = 0; i < numIterations; i++) { 30 | // advance variable nodes 31 | m_variableNodeUpdater.update(m_graph.left()); 32 | 33 | // transmit messages to right 34 | m_graph.leftToRight(); 35 | 36 | // advance check nodes 37 | m_checkNodeUpdater.update(m_graph.right()); 38 | 39 | // transmit messages to left 40 | m_graph.rightToLeft(); 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /test/codes/InterleavedEncoderTests.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | import math 4 | import numpy 5 | import random 6 | 7 | import wireless as rf 8 | import wireless.codes.ldpc as ldpc 9 | 10 | class InterleavedEncoderTests(unittest.TestCase): 11 | 12 | def test_001_interleaving_works(self): 13 | NUM_TESTED_SYMBOLS = 2000 14 | 15 | # randomize message 16 | msg = numpy.random.bytes(40) + chr(numpy.random.randint(0,1<<4)) 17 | # randomize interleaving seqeuence 18 | interleaving = [random.randrange(648) for i in xrange(NUM_TESTED_SYMBOLS)] + [647] 19 | 20 | # Encode the message using a reference encoder 21 | refEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1,2), 1) 22 | refSeq = rf.vectorus() 23 | refEnc.setPacket(msg) 24 | refEnc.encode(648, refSeq) 25 | 26 | # Encode the message using an InterleavedEncoder 27 | innerEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1,2), 1) 28 | interleavingVec = rf.vectorus(interleaving) 29 | enc = rf.codes.InterleavedEncoder(innerEnc, interleavingVec) 30 | enc.setPacket(msg) 31 | out = [] 32 | tmpOut = rf.vectorus() 33 | numRemaining = NUM_TESTED_SYMBOLS 34 | while(numRemaining > 0): 35 | print "remaining", numRemaining 36 | numNew = random.randrange(1, min(10, numRemaining)+1) 37 | enc.encode(numNew, tmpOut) 38 | out.extend(list(tmpOut)) 39 | numRemaining -= numNew 40 | 41 | # compare actual sequence to anticipated sequence 42 | for i in xrange(NUM_TESTED_SYMBOLS): 43 | self.assertEqual(out[i], refSeq[interleaving[i]], 44 | "output sequence doesn't match computed output at index %d" % i) 45 | 46 | if __name__ == "__main__": 47 | unittest.main() 48 | -------------------------------------------------------------------------------- /test/codes/ldpc/WordWidthTransformerTests.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Mar 17, 2011 3 | 4 | @author: yonch 5 | ''' 6 | import unittest 7 | import codeBench 8 | import numpy 9 | import random 10 | import math 11 | 12 | 13 | class WordWidthTransformerTests(unittest.TestCase): 14 | def test_001_nonimportant_bits_do_not_influence(self): 15 | src = (numpy.random.randint(0, high=1024, size=30).astype(numpy.int32) << 1) 16 | 17 | dst = numpy.ones([15], dtype = numpy.int32) * 0xFFFF 18 | 19 | codeBench.transformSymbols(src, dst, 1, 2) 20 | 21 | self.assertTrue((dst == 0).all()) 22 | 23 | def test_002_random_test_correctness(self): 24 | for srcNumBits in [1,2,7,8,31]: 25 | for dstNumBits in [1,2,7,8,31]: 26 | src = numpy.random.randint(0, 27 | high=((1<> (i % srcNumBits)) & 0x1, 37 | (dst[i / dstNumBits] >> (i % dstNumBits)) & 0x1) 38 | 39 | 40 | if __name__ == "__main__": 41 | #import sys;sys.argv = ['', 'Test.testEncoder'] 42 | unittest.main() -------------------------------------------------------------------------------- /test/codes/strider/LayerSuperpositionTests.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | import math 4 | import numpy 5 | 6 | import wireless as rf 7 | 8 | 9 | class LayerSuperpositionTests(unittest.TestCase): 10 | def test_001_layering_works(self): 11 | for batchSize in [1,2,3,7]: 12 | for numPasses in [1,2,3,7]: 13 | for passLength in [1,2,3,7,11]: 14 | G = numpy.zeros([numPasses, batchSize], dtype = numpy.complex64) 15 | G += numpy.random.random((numPasses, batchSize)) + 1j*numpy.random.random((numPasses, batchSize)) 16 | layers = numpy.random.random((batchSize, passLength)) + 1j*numpy.random.random((batchSize, passLength)) 17 | 18 | enc = rf.codes.strider.LayerSuperposition(passLength, G) 19 | for i in xrange(batchSize): 20 | enc.setLayer(i, rf.general.vector_csymbol(list(layers[i,:]))) 21 | 22 | expectedResult = list((numpy.matrix(G) * numpy.matrix(layers)).flat) 23 | 24 | gotResult = [enc.next() for i in xrange(passLength * numPasses)] 25 | 26 | self.assertEqual(len(expectedResult), len(gotResult)) 27 | for i in xrange(len(expectedResult)): 28 | self.assertAlmostEqual(expectedResult[i], gotResult[i], 5) 29 | 30 | if __name__ == "__main__": 31 | unittest.main() -------------------------------------------------------------------------------- /test/codes/strider/strider-message.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/strider/strider-message.dat -------------------------------------------------------------------------------- /test/codes/strider/strider_packets_doubles_imag.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/strider/strider_packets_doubles_imag.dat -------------------------------------------------------------------------------- /test/codes/strider/strider_packets_doubles_real.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/strider/strider_packets_doubles_real.dat -------------------------------------------------------------------------------- /test/codes/strider/turbo-interleaved-1530.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/strider/turbo-interleaved-1530.dat -------------------------------------------------------------------------------- /test/codes/strider/turbo-message-1530.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/strider/turbo-message-1530.dat -------------------------------------------------------------------------------- /test/codes/turbo/test-codeword-1530.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/turbo/test-codeword-1530.dat -------------------------------------------------------------------------------- /test/codes/turbo/test-message-1530.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonch/wireless/5e5a081fcf3cd49d901f25db6c4c1fabbfc921d5/test/codes/turbo/test-message-1530.dat -------------------------------------------------------------------------------- /test/demappers/BitwiseDemapperTests.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Mar 17, 2011 3 | 4 | @author: yonch 5 | ''' 6 | import unittest 7 | import codeBench 8 | import numpy 9 | import random 10 | import math 11 | 12 | 13 | class BitwiseDemapperTests(unittest.TestCase): 14 | def test_001_Gray_demapper(self): 15 | SNR = 3 16 | mapper = codeBench.GrayMapper(3, 6) 17 | sigma = math.sqrt(mapper.getAveragePower() / SNR) 18 | demapper = codeBench.GrayDemapper(mapper, 19 | 3, 20 | sigma) 21 | 22 | for x in xrange(-64, 128): 23 | for bit in xrange(3): 24 | probs = numpy.zeros([2], dtype=numpy.float32) 25 | for y in xrange(8): 26 | delta = 1.0*x - mapper.map(y) 27 | p = math.exp(-1.0 * delta*delta / (2*sigma*sigma)) 28 | if (y & (1 << bit)): 29 | probs[1] += p 30 | else: 31 | probs[0] += p 32 | expectedResult = numpy.log(probs[1] / probs[0]) 33 | 34 | gotResult = demapper.demap(x,bit) 35 | if expectedResult > 70: 36 | self.assertTrue(gotResult > 60) 37 | elif expectedResult < -70: 38 | if not gotResult < -60: 39 | pass 40 | self.assertTrue(gotResult < -60) 41 | else: 42 | self.assertAlmostEquals(expectedResult, gotResult, places=5) 43 | 44 | 45 | if __name__ == "__main__": 46 | #import sys;sys.argv = ['', 'Test.testEncoder'] 47 | unittest.main() -------------------------------------------------------------------------------- /util/GenerateCrcCode.py: -------------------------------------------------------------------------------- 1 | # Based on examples.py from the crcmod package 2 | #----------------------------------------------------------------------------- 3 | # Demonstrate the use of the code generator 4 | from crcmod import Crc 5 | 6 | g8 = 0x185 7 | g16 = 0x11021 8 | g24 = 0x15D6DCB 9 | g32 = 0x104C11DB7 10 | 11 | def polyFromBits(bits): 12 | p = 0 13 | for n in bits: 14 | p = p | (1 << n) 15 | return p 16 | 17 | # The following is from Standard ECMA-182 "Data Interchange on 12,7 mm 48-Track 18 | # Magnetic Tape Cartridges -DLT1 Format-", December 1992. 19 | 20 | g64 = polyFromBits([64, 62, 57, 55, 54, 53, 52, 47, 46, 45, 40, 39, 38, 37, 21 | 35, 33, 32, 31, 29, 27, 24, 23, 22, 21, 19, 17, 13, 12, 10, 9, 7, 22 | 4, 1, 0]) 23 | 24 | print('Generating crc.c') 25 | out = open('crc.c', 'w') 26 | out.write('''// Define the required data types 27 | typedef unsigned char UINT8; 28 | typedef unsigned short UINT16; 29 | typedef unsigned int UINT32; 30 | typedef unsigned long long UINT64; 31 | ''') 32 | #Crc(g8, rev=False).generateCode('crc8',out) 33 | #Crc(g8, rev=True).generateCode('crc8r',out) 34 | #Crc(g16, rev=False).generateCode('crc16',out) 35 | Crc(g16, rev=True).generateCode('crc16r',out) 36 | #Crc(g24, rev=False).generateCode('crc24',out) 37 | #Crc(g24, rev=True).generateCode('crc24r',out) 38 | #Crc(g32, rev=False).generateCode('crc32',out) 39 | Crc(g32, rev=True).generateCode('crc32r',out) 40 | #Crc(g64, rev=False).generateCode('crc64',out) 41 | #Crc(g64, rev=True).generateCode('crc64r',out) 42 | 43 | # Check out the XOR-out feature. 44 | #Crc(g16, initCrc=0, rev=True, xorOut=~0).generateCode('crc16x',out) 45 | #Crc(g24, initCrc=0, rev=True, xorOut=~0).generateCode('crc24x',out) 46 | #Crc(g32, initCrc=0, rev=True, xorOut=~0).generateCode('crc32x',out) 47 | #Crc(g64, initCrc=0, rev=True, xorOut=~0).generateCode('crc64x',out) 48 | 49 | out.close() 50 | print('Done') 51 | -------------------------------------------------------------------------------- /util/GenerateRaptorLDPC.py: -------------------------------------------------------------------------------- 1 | 2 | from scipy.stats import binom 3 | import itpp 4 | 5 | def generateRaptorLDPC(numInfoBits, rate, outFilename): 6 | """ 7 | Generates a left 4-degree regular, random right degree LDPC code with 8 | 'numInfoBits' information bits. 9 | 10 | @param numInfoBits: the number of message bits the LDPC code will handle 11 | @param rate: the rate of the LDPC code 12 | @param outFilename: filename where the bits will be written 13 | """ 14 | 15 | leftDegree = 4 16 | 17 | numVariables = int(numInfoBits / rate) 18 | print "numVariables:", numVariables 19 | 20 | dist = binom(numInfoBits, 1.0 * leftDegree / (numVariables - numInfoBits)) 21 | maxRightDegree = int(dist.isf(1e-8)) 22 | itRight = itpp.vec(maxRightDegree) 23 | for i in xrange(maxRightDegree): 24 | itRight[i] = dist.pmf(i+1) 25 | itRight[maxRightDegree-1] = itRight[maxRightDegree-1] + 1e-8 26 | 27 | itLeft = itpp.vec(leftDegree) 28 | for i in xrange(leftDegree-1): 29 | itLeft[i] = 0 30 | itLeft[leftDegree - 1] = 1.0 31 | print itLeft 32 | 33 | H = itpp.LDPC_Parity_Irregular() 34 | H.generate(numVariables, itLeft, itRight, "rand", itpp.ivec("150 8")) 35 | H.display_stats() 36 | print "got code with ", (H.get_nvar() - H.get_ncheck()), " nodes" 37 | 38 | 39 | G = itpp.LDPC_Generator_Systematic(H); 40 | C = itpp.LDPC_Code(H, G) 41 | C.save_code(outFilename); 42 | 43 | #generateRaptorLDPC(9500 + 30, 0.9525, 'LDPC_9500.it') 44 | #generateRaptorLDPC(256 + 0, 0.95, 'LDPC_256.it') 45 | generateRaptorLDPC(256 + 0, 0.95, 'LDPC_256.it') --------------------------------------------------------------------------------