libwireless 源码解析

来源:互联网 发布:福州淘宝代运营 编辑:程序博客网 时间:2024/05/29 02:29

libwireless 源码的解析,扩展 和 使用

注:工程主体部分采用了抽象工厂模式,我们按照工程目录的结构,自顶向下地分析代码

源码可以在 Jonathan Perry 的 github 上面下载:https://github.com/yonch/wireless

代码在Ubuntu14.04版本上面的安装步骤可参考:http://blog.csdn.net/baobao3456810/article/details/50955788


1 python

说明:顶层 python 代码

1.1 python/codes

说明:只有 python 版本的 Spinal Codes ,C++版本的 Spinal Codes 以工厂的形式呈现

1.2 python/protocols

说明:protocol 共包括,
1 Spinal Codes 的 protocol(C++)
2 One Try protocol(C++)
3 Multiple Try protocol(Python)
4 Rate Approximate protocol(C++)

文件包含:
protocols/MultipleTryProtocol.pypython/simulator/factories/ProtocolFactory.py的第三种

1.3 python/simulator

说明:抽象工厂,根据给定的参数构造具体工厂,各个具体工厂根据参数生产具体产品

文件包含:
simulator/factories 给出了一些具体的工厂,包括:

  • Channel_Factory
  • Demap_Factory
  • Detector_Factory
  • Map_Factory
  • PacketGen_Factory
  • Protocol_Factory:除了 Spinal Codes 外所使用的 protocol
  • Statistics_Factory:调用 python/statistics 中的内容
  • Codes_Factory: 包含几种信道编码的具体工厂,下面详细展开

simulator/factories/codes/*.py 给出了几种信道编码的具体工厂,包括:

  • Fading_Strider_Factory
  • LDPC_Factory
  • LT_Factory
  • Multiplexed_Factory
  • Null_Factory
  • Raptor_Factory
  • Spinal_Factory

    • public:
      • make_encoder:最终返回 MultiToSingleStreamEncoder 构造的编码器,以及符号数组类型,如 wireless.vectorus=vector< unsigned short>=16-bit
      • make_decoder
      • make_protocol
    • private:

      围绕着include/codes/spinal/CodeFactory.h 的编译码的实现,其中的三个模块是相互递进的关系。
      CodeFactory 为Spinal编译码的主工厂,返回一种具体的哈希函数编码方案,包括:salsa,lookup3,oneAtATime。
      IEncoderFactory Spinal 信道选择工厂,返回针对特定信道下的编码方案,包括:linear,soft,gaussian,bitwise,coherence。
      ISearchFactory Spinal 译码算法选择工厂,在楼上的基础上选择一种译码方案,包括:beamDecoder,lookaheadBeamDecoder,并返回译码器和信道符号类型。

      • _make_unpunctured_encoder:选择一种哈希编码方案,使用CodeFactory.encoder()方法构造编码器。
      • _make_unpunctured_decoder:选择一种信道模式,以及译码算法(regular,lookahead,parallel)
      • _get_punctured_decoder_type:返回与信道对应打孔后的符号类型,使用了MultiToSingleStreamDecoder类,符号的表示不清楚可以参考bindings/codes/codes.i 的类型的重命名(即python与C++版本的对应关系)
      • _get_num_blocks:=n/k
      • _get_puncturing:选择一种打孔机制(8-way-v2,static),以及是否要重复打孔(encoderToSymbolRate)
  • Strider_Factory
  • Turbo_Factory

simulator/default_configuration.py 返回一个列表,为仿真组建提供了可以访问的工厂,参考 simulator/factories/ 中实现的工厂。
simulator/FactoryCollection.py 工厂类,使仿真组建可以聚合多个具体工厂,也就是生产工厂的工厂

  • self._factories:字典,Key=’make_pre_packet_manipulator’, ‘make_packet_generator’, ‘make_encoder’, ‘make_mapper’, ‘make_channel’, ‘make_demapper’, ‘make_decoder’, ‘make_detector’, make_protocol’, ‘make_statistics’,Value=[defaulte_configuration中工厂类中所有名为 Key 值的工厂方法]
  • self._cache:字典,Key同上,Value为一个元组(工厂方法的参数,工厂方法返回的值“产品”)
  • add_factory(self, factory):输入 factory 为 defaulte_configuration 的 get_factory_list() 方法返回的各种工厂之一(如 ChannelFactory),功能是为 _factories 添加 Value
  • make(self, func_name, *args):需要注意的是,工厂方法接收到“不认识”的参数时,会返回None,遍历_factories[某工厂方法名],即同名的所有方法,当参数不满足时返回None,也就是说只要传给工厂方法的参数满足某个工厂方法的输入要求,就会返回该工厂的“产品”

simulator/SanityTest.py 包含了多个测试程序,配合 simulator/Simlator.py 使用,包括:

  • Spinal Codes:

    • run_Test:random packet,spinal,linear map,AWGN,no demap,regular beamSearch decode,oracle detect,sequential protocol,errors statistics
    • run_ParallelK_Test:parallel k beamSearch decode,其他同“1”
    • run_Coherence_FadingTest:soft map,coherence-fading channel,其他同“1”
    • run_Rate_Approx_ProtocolTest:rate-approx protocol,其他同“1”
    • run_Gaussian_Test:trunc-norm-v2 map,其他同“1”
    • run_Lookahead_Test:lookahead decode,其他同“1”
    • run_Crc_Test:crc16 packet,crc16 detector,其他同“1”
    • run_First_Error_Statistics_Test:first-error,其他同“1”
  • LDPC:

    • run_LDPC_Test:random packet,ldpc,gray map,AWGN,ml-gray demap,ldpc-float-bp decode,oracle detector,one-try protocol,errors statistics
    • run_Itpp_Qam_LDPC_Test:QAM map,AWGN_c(),QAM demap,其他同“2”
    • run_Bsc_LDPC_Test:linear map,BSC,BSC demap,其他同“2”
  • Turbo:

    • run_Itpp_Qam_Turbo_Test:random packet,Turbo,AWGN_c,QAM map,regular demap,oracle detector,one-try protocol,errors statistics
  • LT codes

    • run_LT_Test:random packet,LT codes,QAM map,AWGN_c,LT decode,oracle detector,rate-approx protocol,errors statistics
  • Raptor codes

    • run_Raptor_Test:raptor codes,raptor decode,其他同“3”
  • Strider codes

    • run_Strider_Test:strider codes,null map,null demap,strider decode,multiple-try protocol,其他同“3”
    • run_Short_Strider_Test:与上面长度不同
    • run_Strider_Transparent_Fading_Test:transparent-coherence_c channel,其他同上strider
    • run_Strider_Fading_Test:coherence-fading_c channel,strider-fading decode,其他同上
  • Null 无编码

    • run_Null_Decoder_Test:random packet,null code,AWGN_c,QAM map,null decode,oracle detector,one-try protocol,errors statistics

simulator/Simulator.py 具体类,实现了一个完整的数据包的发送过程,适用于所有的编码方案,包括:

  • getComponents (experiment): 由 exper_spec 给出的参数方案 make 组件(由工厂生产产品)
  • seed (seed): 为用到 random 的组件的提供“种子”
  • runPacket (): 针对单个数据包 模拟传输机制,当统计结果中 isFinish==True 或者 nextNumChannelSymbols == 0 时,停止对当前数据包的发送,转向下一个数据包。
  • runExperiment(experiment, initialSeed, numPackets): 运行实验的过程

1.4 python/statistics

说明:给出收集统计信息的方式,Jonathan实现了三种方式,这里给出的是python实现,被 StatisticsFactory() 工厂类调用
三种统计方式的区别还有待于研究

文件包含:
statistics/ErrorLocationStatistics.py :对应 StatisticsFactory 中的 bit-statistics 模式。Collected statistics on location of errors

  • ErrorLocationStatisticsResult:(被下者调用的):记录单条信息的错误模式(error pattern)
  • ErrorLocationStatistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数

statistics/ErrorRateStatistics.py :对应 StatisticsFactory 中的 error 模式。Collected statistics on number of errors

  • Error_Rate_Statistics_Result(被下者调用的):针对某一个 packet,将译码后的 packet 与发送的 packet 做比较,统计当前 packet 的译码正确率
  • Error_Rate_Statistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数

statistics/FirstErrorStatistics.py:对应 StatisticsFactory 中的 first-error 模式。 Collected statistics on bit-index of first bit error ,包括以下几类:

  • First_Error_Statistics_Result(被下者调用的):记录单条信息的错误模式(error pattern)
  • First_Error_Statistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数

1.5 python/util

说明:Google Protocol Buffer,

util/serialization/results.proto 不太明确,只知道被ErrorRateStatistics.py 调用


2 bindings

说明:python API from C++,在阅读或修改 binding 代码时最好对应着 ./include 中的内容
补充:在 SWIG 中,不是所有头文件以及辅助文件中被包含的模块都要封装到 binding codes 中,所以在 SWIG 中使用 %include 来导入模块,且 %include 的内容在预编译时只编译一次,同时把不需要预编译的模块放入 %{ ... %} 中。
注意:该工程中多处定义了各种不同功能的智能指针,这些将留在指针的定义中详细介绍,SWIG 使用只能指针的方法是 %shared_ptr(T) ;另外,binding 中的所有注释有 numpy 的地方请见 Numpy.i SWIG 文档

2.1 bindings/codes

说明:顾名思义,该模块实现了几种仿真需要的信道编码的 Python 接口

codes/spinal

  • codes/spinal/spinal.i :实现了 include/codes/spinal 中的模块的接口

codes/codes_workaround.i :辅助下面的 codes.i
codes/codes.i 封装几乎所有跟差错控制编码有关的智能指针,并包含 include/codes 中所有跟代码有关的功能模块,如 编码指针/解码指针/打孔/码流控制 等

codes/fountain.i 封装了 LT 码 和 Raptor 码 相关的模块和智能指针,对应 include/codes/fountain

codes/ldpc.i 封装了LDPC模块,对应 include/codes/ldpc
codes/null.i 对应 include/codes/null ,无编码
codes/strider.i 封装了 strider 模块,对应 include/codes/strider
codes/turbo.i 封装了 turbo 模块,对应 include/codes/turbo

2.2 bindings/itpp

说明:虽然 IT++ 中实现了大部分通信仿真所需要的功能,但该工程中并没有使用 IT++ 中的规则,而只是使用了 IT++ 中个别的模块,详细请见下文

包括:

  • base_sparse.i
  • base_vec.i
  • ldpc.i
  • llr.i
  • modulator.i

2.3 bindings/util

说明:对应实现了include/util/ 中的部分模块的接口

包括:(基本与 include 目录下的模块对应,详细功能去 include 中查找)

  • config.i
  • hashes.i
  • inference.i

2.4 bindings/*.i

bindings/numpy.i :binding 的节头注意中有表述

bindings/common.i 包括 Exception handling,numpy,Smart pointers,SWIG 对 exception 和 Smart pointers 有相应的扩展,故这里可以直接 %include,另外若要了解 SWIG 使用 shared_ptr 的详细用法请参考 SWIG 的官方文档,简单地说就是定义一个宏变量,并包含 %include < std_shared_ptr.i>,至于 numpy.i 在前面介绍过

bindings/general.i :STL模板的实例化,以及数据类型的转换,其中所使用到的模板的定义在C++声明中,留意各个数据类型的定义即可,比较复杂,故这里一一列出,以便查找

  • Symbol = int
  • SoftSymbol = float
  • N0_t = float
  • FadingMagnitude = float
  • LLRValue = float
  • ComplexSymbol = complex
  • FadingSymbol == FadingSymbolTuple< SoftSymbol>
  • FadingComplexSymbol == FadingSymbolTuple< ComplexSymbol>
  • vectori == vector< int>
  • vectorcf == vector< std::complex< float> >
  • vectorcd == vector< std::complex< double> >
  • vectorui == vector< unsigned int>
  • vectorus == vector< unsigned short>
  • vectors == vector< short>
  • vectorul == vector< unsigned long>
  • vectorull == vector< unsigned long long>
  • vectorb == vector< bool>
  • vectorf == vector< float>
  • vectorstr == vector< string>
  • vector_fadingsymbol == vector< FadingSymbol>
  • vector_fading_csymbol == vector< FadingComplexSymbol>
  • vector_csymbol = vectorcd
  • vector_symbol = vectori
  • vector_softsymbol = vectorf
  • vector_llr = vectorf

bindings/channels.i :主要包括 下面模块(详细请见代码),比较复杂,故这里一一列出,以便查找

  • SymbolAwgnChannel == AwgnChannel< Symbol>
  • ComplexAwgnChannel == AwgnChannel< ComplexSymbol>
  • SoftAwgnChannel == AwgnChannel< SoftSymbol>
  • FadingAwgnChannel == AwgnChannel< FadingSymbol>
  • FadingComplexAwgnChannel == AwgnChannel< FadingComplexSymbol>
  • SoftCoherenceFading == CoherenceFading< SoftSymbol>
  • ComplexCoherenceFading == CoherenceFading< ComplexSymbol>
  • MimoAwgnChannel == CompositeChannel< MimoChannel ,ComplexAwgnChannel>
  • AwgnCoherenceFadingChannel == CompositeChannel< SoftCoherenceFading, FadingAwgnChannel>
  • AwgnCoherenceComplexFadingChannel == CompositeChannel< ComplexCoherenceFading, FadingComplexAwgnChannel>
  • ComplexTransparentFadingChannel == TransparentCoherenceFading< ComplexSymbol>
  • SoftTransparentFadingChannel == TransparentCoherenceFading< SoftSymbol>
  • SymbolTransparentFadingChannel == TransparentCoherenceFading< Symbol>

bindings/mappers_workaround.i:辅助下面的 mappers.i ,但据观察,下文并没有包含这个文件

bindings/mappers.i:封装了只能指针 IMapper,QPSKMapper,QamMapper,LinearMapper,并包含了 include/mappers 中的内容

bindings/demappers_workaround.i:辅助下面的 demappers.i ,但据观察,下文并没有包含这个文件

bindings/demappers.i:包含了 include/mappers 中的部分内容,封装并实例化了 IDemapper 智能指针,分别为 template_IDemapper_Symbol,template_IDemapper_ComplexSymbol,GrayDemapper,ItppComplexDemapper

bindings/misc.i

bindings/protocols.i:实现了对应 include/protocol 中的模块的接口,即 OneTryProtocol 和 RateApproxProtocol


3 include

说明:大部分功能模块的声明(.h),个别功能模块的实现(.hh)。本人C++不是很好,只能先这样理解,在这里具体的类往往声明和实现是分开的,而模板类中方法的实现是定义在模板类的声明文件中

3.1 include/channels

AwgnChannel.h:实现了 AWGN 信道的仿真,其中 N0_t 为 float 类型,名称规则要与channel.i 一致

  • AwgnChannel(N0_t n0):定义噪声的功率谱密度
  • void seed(unsigned int* const seed, int seedSize):所有的伪随机数生成器都要有种子
  • void process(const std::vector& inSymbols, std::vector& outSymbols):将噪声加到 inSymbols 上,生成 outSymbols
  • unsigned int forecast(unsigned int numOutputs):骗人的,没实现啥
  • double getStddevPerDimension():返回噪声的标准差
  • ChannelSymbol noisify(ChannelSymbol x, double stddevPerDimension):见AwgnNoiseGenerator.h
  • AwgnChannel.hhAwgnChannel.h 中方法的实现

AwgnNoiseGenerator.h:实现了将噪声加到符号上
BscChannel.h:BSC 信道的仿真,结构跟 AWGN 差不多,但实现起来要简单多了
CoherenceFading.h:瑞利衰减信道实现(接收端知道衰减系数

  • CoherenceFading.hh
  • CoherenceCoeffGenerator.h:可以根据相干时间计算衰减系数

TransparentCoherenceFading.h:瑞利衰减信道实现(接收端不知道衰减系数

  • TransparentCoherenceFading.hh

CompositeChannel.h:通过合并两个信道成为一个新的信道

  • CompositeChannel.hh

MimoChannel.h:MIMO 信道的仿真

3.2 include/codes

说明:该模块给出了编码器和译码器的实现结构,以及多种编码译码方法(这里用“方法”是为了与util中的“算法想区分”),由于该部分是本工程的主体,故这里对主要的类的组成结构也做详细介绍,虽然只是把内容从代码中摘出来,但这样看起来对功能的理解会很有帮助。特别要注意的是虚基类的使用。

注意:代码中的“I”开头的类表示接口(interface),实现上都是采用虚基类,且与 shared_ptr 指针一同使用,下文不一一雷述。而我们使用的都是“非接口”模块,所以对所有的模块都要好好的理解。

另外,值得注意的是,对 Spinal Codes 来说,打孔(puncturing)的方法可能与传统上有些差别,涉及到将一个码流(Code Stream)分解(divide)为多个子码流,故这里Jonathan(代码作者)在包含打孔的编码器和译码器的命名上采用 MultiStream××× 的形式,这里为了方便理解单独指出。

include/codes/archive

说明: 顾名思义,编码过程中的所有的内存管理。

  • CachedEncoder.h还有待于研究,继承自 IEncoder,符号输出前在 pass 中的内存管理类,以通道(passes)为单位成批地生产编码符号,代码结构如下:
    • public:
      • CachedEncoder( Encoder encoder, unsigned int numPackets, unsigned int numCachedSymbolsPerPacket):指定编码器,数据包的数量,每个 batch 中的符号数量
      • ~CachedEncoder()
      • void setPacket(unsigned int packetInd, const string& packet)
      • void removePacket(unsigned int packetInd):Removes the packet from the cache
      • bool hasPacket(unsigned int packetInd):True if packet exists, False otherwise.
      • void getSymbols( unsigned int packetInd, unsigned int firstSymbolToEmit, unsigned int lastSymbolToEmit, std::vector< Symbol>& outSymbols):从指定的 pass 中取出输出符号到 outSymbol 中
    • private:
      • CachedEncoder(const CachedEncoder&)
      • CachedEncoder& operator=(const CachedEncoder&)
      • void getAndCacheSymbolBlock(unsigned int packetInd, unsigned int blockIndex):为每个 symbol block 分配内存
      • Encoder m_encoder:指定的编码器
      • unsigned int m_numPackets:实例所提供的数据包数量
      • unsigned int m_numCachedSymbolsPerPacket:每个数据包所分配的 cache 数量
      • vector< string> m_packets:待编码的数据包,下面的成员数组中的序号应该是数据包的编号
      • vector< bool> m_hasPacket:是否指定了数据包
      • vector< int> m_cachedBlockIndex不是很明确,packet 的数量往往不是正好的,故有多少 cache 需要额外补偿呢?
  • CachedEncoder.hh:楼上的实现
  • IMultiEncoder.h:虚基类,功能更多的 IEncoder,但大部分用的都是 IEncoder,结构如下:

    • virtual ~IMultiEncoder() {}
    • virtual void setPacket(unsigned int packetInd, const std::string& packet) = 0
    • virtual void removePacket(unsigned int packetInd) = 0
    • virtual bool hasPacket(unsigned int packetInd) = 0
    • virtual void encode( unsigned int packetInd, unsigned int numSymbols, std::vector< uint16_t>& outSymbols) = 0
  • IMultiDecoder.h:结构如下:

    • virtual ~IMultiDecoder() {}
    • virtual void resetPacket(unsigned int packetInd) = 0
    • virtual void addSymbols( unsigned int packetInd, const std::vector< ChannelSymbol>& symbols) = 0
    • virtual void decode(unsigned int packetInd) = 0
    • virtual DecodeResult getDecodeResult(unsigned int packetInd) = 0
  • CachedMultiDecoder.h:继承自 IMultiDecoder ,功能不是很明确
  • CachedMultiDecoder.hh :楼上的实现
  • LinearCheckNodeUpdater.h:结合 BP 使用,参考 include/util/inference/bp/NodeUpdater.h
    • class LogPmQ
    • class LinearCheckNodeUpdater : public NodeUpdater< float>
  • LinearCheckNodeUpdater.cpp:楼上的实现

include/codes/fountain

说明:主要实现了 LT 和 Raptor 喷泉码的算法

  • LT Codes:
    • LTParityNeighborGenerator.h:生成 LT 的节点分布,并选择使用哪些 bit 进行 XOR
    • ParityEncoder.h:LT 码编码器,只是被抽象成了根据给定的节点分布的图编码
      • public:
        • ParityEncoder( unsigned int numMessageBits, const NeighborGenerator& neighborGenerator, const SymbolFunction& symbolFunction):其中 neighborGenerator 由楼上的模块产生
        • virtual ~ParityEncoder() {}
        • virtual void setPacket(const std::string& packet)
        • virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
      • private:
        • uint16_t next()
        • const unsigned int m_numMessageBits
        • NeighborGenerator m_neighborGenerator
        • SymbolFunction m_symbolFunction
        • unsigned int m_nextSymbolIndex
        • std::vector< bool> m_packetVector
        • std::vector< unsigned int> m_neighbors
    • LTDecoder.h:继承自 ILLRDecoder,LT 码的译码器,
      • public:
        • LTDecoder(uint32_t numVariables, uint32_t llrBufferSize, uint32_t numIterations)
        • virtual ~LTDecoder() {}
        • virtual void reset()
        • virtual void add(const std::vector< LLRValue>& llrs):为译码器添加似然信息,注意译码器只支持连续的似然信息
        • virtual DecodeResult decode():根据给定的接受符号解码出数据包
        • virtual void softDecode(std::vector< LLRValue>& llrs):软判决译码方法,
      • private:
        • const uint32_t m_numVariables:可变节点的数量
        • std::vector< LLRValue> m_llrs
        • LTParityNeighborGenerator m_neighborGenerator:存储度分布
  • Raptor Codes:
    • RaptorEncoder.h:外码(预编码) LDPC(取自 itpp 库),内码 LT,而 Raptor Codes 真正生成的函数位于python/simulator/factories/codes/RaptorFactory.py 中 。注意:在级联码的概念中,预编码称为外码(首先操作),与之级联的码称为内码(在预编码之后操作)
      • public:
        • RaptorEncoder(const std::string& ldpcFilename):ldpcFilename 位于 ./data/ldpc 中,为 itpp 生成的 *.it 文件,data 中的数据是如何产生的???
        • virtual void setPacket(const std::string& packet):(这个函数很讲究),其中首先将 数据包转换成 itpp::bvec 类型,然后使用 itpp::ldpc 编码,得到 ldpcCodeword,转为 string 后,在将 ldpc 的编码结果传递给 LT 码编码器
        • virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols):必须结合 setPacket 方法,因为这一步只进行 LT 编码,但 LT 的输入为 ldpc 码字
      • private:
        • static BitwiseXorSymbolFunction getSymbolFunction()
        • static LTParityNeighborGenerator getNeighborGenerator(uint32_t codewordSize)
        • itpp::LDPC_Generator_Systematic m_G
        • itpp::LDPC_Code m_ldpc
        • ParityEncoder< BitwiseXorSymbolFunction, LTParityNeighborGenerator> m_lt
        • itpp::bvec m_packetBits
        • itpp::bvec m_encodedBits
        • std::vector< uint16_t> m_encodedVec
    • RaptorDecoder.h:继承自 ILLRDecoder ,先 LT 解外码,然后用 itpp::ldpc 解内码
      • public:
        • RaptorDecoder(const std::string& ldpcFilename, uint32_t numLtIterations)
        • virtual ~RaptorDecoder() {}
        • virtual void reset()
        • virtual void add(const std::vector< LLRValue>& llrs)
        • virtual DecodeResult decode()
      • private:
        • itpp::LDPC_Generator_Systematic m_G
        • itpp::LDPC_Code m_ldpc
        • LTDecoder m_lt
        • std::vector< LLRValue> m_llrs
        • itpp::vec m_itppLlrs
        • itpp::bvec m_decodedBits

include/codes/ldpc

说明: 没有仔细看,自己实现的 LDPC 码,有一些扩展功能

include/codes/null

说明: 继承了 IEncoder,基本就是一个空壳,不对输入做任何修改

  • NullDecoder.h
  • NullEncoder.h

include/codes/puncturing

说明:实现了各种打孔机制

  • IPuncturingSchedule.h:打孔机制的接口
    • virtual ~IPuncturingSchedule() {}
    • virtual void reset() = 0
    • virtual void batchNext(unsigned int numSymbols, std::vector< uint16_t>& streamIndices) = 0:产生输出码流
  • RepeatingPuncturingSchedule.h:Splits the symbols stream to 8 sub-groups, then sends symbols from each sub-group
  • RoundRobinPuncturingSchedule.h:Gets symbols from index 0 to last index and wraps around,一种调度机制
  • StaticPuncturingSchedule.h:Punctures according to a given vector,传统的打孔
  • StridedPuncturingSchedule.h:Splits the symbols stream to 8 sub-groups, then sends symbols from each sub-group,strider 的打孔方式

include/codes/spinal (重点!故换颜色!)

说明:重点中的重点,整个工程的核心编码算法,实现部分最好也要搞明白

IMultiStreamEncoderIMultiStreamDecoder

图注:从上面两幅层次结构图可以看出 IMultiStreamEncoder 和 IMultiStreamDecoder 基本就是为 Spinal Codes 这样的编码设计的,因为两者都包含码流结构的打孔方法。

  • protocols

    说明:为 Spinal Codes 提供传输协议

    • SequentialProtocol.h:pinal protocol, transmits one pass after another,一个 pass 接一个 pass 发送
      • SequentialProtocol.hh:楼上的实现
    • StridedProtocol.h超级重要!!! Spinal Codes 的 Strided 传输协议,配合 Strided 打孔使用。 Spinal protocol, suited for StridedPuncturingSchedule (“8-way puncturing”).
      • public:
        • StridedProtocol(unsigned int numPackets,
          unsigned int spineLength,
          unsigned int maxSymbols,
          unsigned int numLastStepSymbolsPerPass,
          unsigned int numRepetitions)
        • unsigned int numSymbolsNextDecode(unsigned int packetInd)
        • void setResult(unsigned int packetInd,
          unsigned int numSymbols,
          bool isFinished):起到记录当前译码结果的作用。如果本次译码成功,则记录所发送的符号数,如果本次译码失败,则使用 maxSymbol 作为下一次译码的 推荐符号数
        • void resetPacket(unsigned int packetInd)
      • private:
        • const unsigned int m_maxSymbols:阈值,译码器用来尝试译码的最大的符号数,超过这个值就放弃译码。
        • vector< unsigned int> m_numSymbolsPerSubpass
        • vector< unsigned int> m_lastSubpassInd
        • vector< unsigned int> m_lastOutputNumSymbols:numSymbolsNextDecode的返回值。
        • vector< unsigned int> m_lastActualNumSymbols:上一次译码使用到的符号的数量。
  • IHashDecoder.h
    • struct SpinalDecodeResult : public DecodeResult:Spinal Codes 译码结果保存形式,多了一个 weight 参数
    • class IHashDecoder : public IMultiStreamDecoder< ChannelSymbol>
  • CodeFactory.h:针对 Spinal Codes 的编解码的各个工厂模块,包括:
    • class CodeFactory:编解码主工厂,选择一种编码方式(IEncoderFactory),包括:salsa/lookup3/oneAtATime
    • class IEncoderFactory:选择一种信道模式,也就是接收端接收到的信道的符号格式(ISymbolSearchFactory),包括:linear/soft/gaussian/bitwise/coherence
    • class ISearchFactory:选择一种译码时使用到的搜索方式,包括:beamDecoder/lookaheadBeamDecoder
  • FlatSymbolStorage.h:symbol 的存储,使用 Spine 值作为索引
    • FlatSymbolStorage.hh:楼上的实现
  • HashEncoder.h:Spinal Codes 的编码器,class HashEncoder : public IMultiStreamEncoder
    • public:
      • HashEncoder(unsigned int k, unsigned int spineLength):Encodes the packet “packet” into real symbols in [-1,1].
      • virtual void setPacket(const std::string& packet)
      • virtual void encode( const std::vector< uint16_t>& spineValueIndices, std::vector< uint16_t>& outSymbols)
    • private:
      • const unsigned int m_k:“K”值
      • const unsigned int m_numMessageBits:信息序列的比特数
      • const unsigned int m_spineLength:Spine 的比特长度
      • std::vector< SpineValueType> m_spine:用于存储 spine 值的数组
    • HashEncoder.hh:楼上的实现
  • SpinalBranchEvaluator.h:用于 Spinal Codes Bubble decode 译码树上的分支度量的计算,包括:
    • IntegerEuclidianDistance.dist(Symbol x, Symbol y):计算整数符号 x 和 y 的欧式距离
    • SoftEuclidianDistance.dist(SoftSymbol x, SoftSymbol y):计算符号 x 和 y 的欧式距离
    • HammingDistance.dist(Symbol x, Symbol y):计算整数符号 x 和 y 的汉明距离
    • FadingEuclidianDistance.dist(Symbol x, Symbol y):计算衰减后的软符号 x 和 y 的欧式距离
    • struct SpinalNode:存储了 Spinal Codes 译码树的节点结构
      • bool operator<(const SpinalNode& other) const
      • WeightType getWeight()
      • WeightType getLikelihood
      • WeightType likelihood
      • WeightType lastCodeStepLikelihood
      • SpineValueSeed hash
    • struct SymbolCollection:用于存储接收符号
    • class SpinalBranchEvaluator:用于估计译码树上的分支最大似然值
      • public:
        • SpinalBranchEvaluator(const ChannelTransformation& xform, uint32_t k)
        • void branch(Node& parent, unsigned int edge, BranchData& syms, Node& child)
        • void initNode(Node& node)
      • private:
        • const uint32_t m_k
        • const uint32_t m_mask:低 k 比特的 mask
        • ChannelTransformation m_xform:ChannelTransformation from bits to symbols,不明觉历
        • typename std::vector< uint16_t> m_encodedSymbols:重新编码后的符号
        • std::vector< typename ChannelTransformation::OutputType> m_candidateSymbols:序列译码的候选符号
        • std::vector< typename ChannelTransformation::OutputType> m_observedSymbols:被计算过分支度量的符号
      • 个别模板类的实现,其他的实现在 src/codes/spinal/ 中
  • HashDecoder.h:Spinal Codes 的译码
    • struct SpinalIntermediateResult:保存了译码的中间状态
    • class HashDecoder : public IHashDecoder < typename Search::Evaluator::ChannelSymbol>:真正的译码器部分
    • HashDecoder.hh:实现
  • StubHashDecoder.h:译码器的输入被保存起来,可访问,用于测试用的译码器
  • Composites.h:typedef SequentialProtocol< StridedPuncturingSchedule> StridedSequentialProtocol,没有别的内容了

include/codes/strider

说明: strider 编码的实现,没有对这个编码有详细的研究

  • LayeredDecoder.h
  • LayeredEncoder.h
  • LayerManipulator.h
  • LayerSuperposition.h StriderFactory.h
  • StriderGeneratorMatrix.h StriderInterleaver.h
  • StriderTurboCode.h

include/codes/turbo

说明: 基于 itpp 的 turbo 编码

  • TurboCodec.h:Turbo 交织器
  • TurboEncoder.h:Turbo 编码器
  • TurboDecoder.h:Turbo 译码器

注意:下面给出的编码器和译码器一部分是提供了顶层的接口,一方便用户使用,另一部分是为 Spinal Codes 提供编码和译码,继承关系如下图所示

IEcoder

codes/IEncoder.h:虚基类,编码器的接口,同 shared_ptr 一同使用,大部分的编码器都继承自 IEncoder 类,因此可以理解为编码器的框架,包括:

  • virtual ~IEncoder() {}
  • virtual void setPacket(const std::string& packet) = 0:读入将被编码的数据包
  • virtual void encode(unsigned int numSymbols, std::vector< uint16_t>& outSymbols) = 0:将第numSymbols个编码符号存入outSymbols

codes/IMultiStreamEncoder.h:提供打孔功能的编码器的接口,貌似处理 location 和 stream 能够实现打孔功能,包括:

  • virtual ~IMultiStreamEncoder() {}
  • virtual void setPacket(const std::string& packet) = 0
  • virtual void encode( const std::vector< uint16_t>& streamIndices, std::vector< uint16_t>& outSymbols) = 0

codes/EncoderMultiplexer.h:继承自 IEcoder,负责将源信息分别分给不同的编码器,并用 round-robins 方法调度不同的编码器

  • public:
    • typedef std::tr1::shared_ptr< EncoderMultiplexer> Ptr
    • EncoderMultiplexer(const std::vector< IEncoderPtr>& encoders, const std::vector< uint32_t>& messageLengthsBits)
    • virtual ~EncoderMultiplexer() {}
    • virtual void setPacket(const std::string& packet)
    • virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
  • private:
    • const std::vector< IEncoderPtr> m_encoders
    • const std::vector< uint32_t> m_messageLengthsBits
    • uint32_t m_next
    • std::vector< uint16_t> m_symbolBuffer

codes/InterleavedEncoder.h:继承自 IEcoder,首先使用指定的编码器进行编码,然后根据给定的交织序列随机打乱(shuffle)编码器的输出符号,以实现交织,实现部分位于 src/codes/InterleavedEncoder.cpp

  • public:
    • InterleavedEncoder(IEncoderPtr& encoder, const std::vector< uint16_t>& interleaveSequence)
    • virtual ~InterleavedEncoder() {}
    • virtual void setPacket(const std::string& packet)
    • virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
  • private:
    • IEncoderPtr m_encoder:给定的编码器
    • const std::vector< uint16_t> m_interleavingSequence:交织序列
    • const uint16_t m_maxIndex:交织序列中的最大的序号
    • std::vector< uint16_t> m_encoded:编码后的数据包
    • unsigned int m_next:下一个输出的符号

codes/MultiToSingleStreamEncoder.h:继承自 IEncoder,使用指定的编码器对数据包进行编码,并采用“分流法”对编好的码字打孔,产生一系列的码流的过程。其实现位于 src/codes/MultiToSingleStreamEncoder.cpp 中,代码结构如下:

  • MultiToSingleStreamEncoder(IMultiStreamEncoder::Ptr& encoder, IPuncturingSchedulePtr& puncturing):指定编码器 与 打孔机制。
  • -

IDecoder< ChannelSymbol >

ILLRDecoder

codes/DecodeResult.h:译码后结果的结构,包括:

  • std::string packet:(string)某数据包的译码结果
  • float logProbError:(float)经过译码处理后表现出来的差错概率的 log 值。

codes/IDecoder.h:虚基类,译码器接口,同 shared_ptr 一同使用,包括:

  • virtual ~IDecoder() {}
  • virtual void reset() = 0:Resets the decoder, so a different packet can be decoded
  • virtual void add(const std::vector< ChannelSymbol>& symbols, N0_t n0) = 0:假设噪声功率对不同的信息符号是相同的,为译码器添加符号
  • virtual void add(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0) = 0:假设数据包传输在衰减信道中,其中噪声功率是恒定的,但接收到的噪声功率发生了变化,同样是为译码器添加符号
  • virtual DecodeResult decode() = 0:译码函数,返回译码结果 DecodeResult

codes/ILLRDecoder.h:在译码时,基于对数似然比估计信息比特,结果与 IDecoder 很像,包括

  • virtual ~**ILLRDecoder**() {}
  • virtual void reset() = 0
  • virtual void add(const std::vector< LLRValue>& llrs) = 0:为译码器加入最大似然信息
  • virtual DecodeResult decode() = 0:译码函数

codes/IMultiStreamDecoder.h:为打孔码字(punctured codes)提供译码器的接口,包括:

  • virtual ~IMultiStreamDecoder() {}
  • virtual void reset() = 0
  • virtual void add(const std::vector< uint16_t>& streamIndices, const std::vector< ChannelSymbol>& symbols, N0_t n0) = 0:为译码器添加符号,其中 streamIndices 为当前 symbol 所属的 stream 编号
  • virtual DecodeResult decode() = 0

codes/InterleavedDecoder.h:继承自 ILLRDecoder ,解交织,再译码

  • public:
    • InterleavedDecoder(const Decoder& decoder, const std::vector< uint16_t>& interleaveSequence)
    • virtual ~InterleavedDecoder() {}
    • virtual void reset()
    • virtual void add(const std::vector< float>& symbols)
    • virtual DecodeResult decode()
  • private:
    • Decoder m_decoder
    • std::vector< uint16_t> m_interleavingSequence:有交织功能,就要有交织序列存储在译码器中
  • codes/InterleavedDecoder.hh:InterleavedDecoder 中方法的实现

codes/MultiToSingleStreamDecoder.h:继承自 IDecoder< ChannelSymbol>,通过对接收符号进行重新排序(或者称之为组合跟容易理解),以实现对打孔后的接收序列的译码

  • public:
    • typedef std::tr1::shared_ptr< MultiToSingleStreamDecoder< ChannelSymbol> > Ptr
    • MultiToSingleStreamDecoder(typename IMultiStreamDecoder< ChannelSymbol>::Ptr& decoder, IPuncturingSchedulePtr& puncturing)
    • virtual void reset()
    • virtual void add(const std::vector< ChannelSymbol>& symbols, N0_t n0)
    • virtual void add(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0)
    • virtual DecodeResult decode()
  • private:
    • typename IMultiStreamDecoder< ChannelSymbol>::Ptr m_decoder
    • IPuncturingSchedulePtr m_puncturing
    • std::vector< uint16_t> m_streamIndicesWorkArr
  • codes/MultiToSingleStreamDecoder.hh:MultiToSingleStreamDecoder 的实现

codes/RandomPermutationGenerator.h:随机排列(permutation)生成,不知作者在这里为什么用排列,而不用序列,没遇到使用这个模块的其他模块,等遇到了再好好研究这个模块的功能

codes/SymbolToLLRDecoderAdaptor.h:将指定的 demaper 和 LLRdecoder 结合起来
codes/SymbolToLLRDecoderAdaptor.hh:楼上的实现部分

3.3 include/mappers

说明: 实现了调制过程,因为在定义工厂时,调制也会有详细的使用,所以这里尽量列出代码结构。

IMapper.h:映射的接口,包括:

  • virtual ~IMapper() {}
  • virtual void process(const std::vector< uint16_t>& inSymbols, std::vector< ChannelSymbol>& outSymbols) = 0
  • virtual float getAveragePower() = 0
  • virtual unsigned int forecast(unsigned int numOutputs) = 0

ComplexLinearMapper.h:把一个整数映射到 I-Q 域上,代码结构如下:

  • public:
    • ComplexLinearMapper(unsigned int numBitsPerDim)
    • void process(const std::vector< uint16_t>& inSymbols, std::vector< ComplexSymbol>& outSymbols):Maps symbols to the complex domain. 规则是 LSB’s taken for real part, next bits for imaginary
    • ComplexSymbol map(uint16_t sym):Maps a single symbol to the complex domain
    • float getAveragePower():假设 Spinal 编码的结果是均匀分布的,求出了信号的平均功率
    • unsigned int forecast(unsigned int numOutputs):
  • private:
    • const unsigned int m_numBitsPerDim:单维度上,每个符号的比特数
    • const uint16_t m_symbolMask:取符号的 LSB 作为一个维度,如:Mask(I-Q) = 0x00FF

GaussianMapper.h:将符号映射到 truncated Gaussian 分布上,代码结构:

  • public:
    • GaussianMapper(unsigned int inputNumBits, unsigned int precisionBits, float numStandardDevs): inputNumBits 为输入数据的比特数,precisionBits 信道支持的比特数,numStandardDevs 为高斯分布的标准差
    • GaussianMapper(const GaussianMapper& other)
    • ~GaussianMapper()
    • void process(const std::vector< uint16_t>& inSymbols, std::vector< Symbol>& outSymbols):将符号线性映射成较大的精度
    • Symbol map(uint16_t sym):Maps a single symbol to the (larger) precision, linearly
    • float getAveragePower()
    • unsigned int forecast(unsigned int numOutputs)
  • private:
    • uint16_t m_highestInput:模块支持的最大的输入值
    • Symbol* m_mappingTable:[(1 << inputNumBits) - 1] 长的数组,构造位于构造函数中
    • float m_variance:输出符号的方差

NormalDistribution.h:被 TruncatedNormalDistribution.cpp 包含,帮忙实现正太分布

  • static double pdf(double u):Probability Density Function
  • static double cdf(double u):Cumulative Distribution Function
  • static double ppf(double p):Percentage Point Function

TruncatedNormalDistribution.h:被 GaussianMapper.cpp 包含,生成一个(a,b)截断区间的高斯分布

  • public:
    • TruncatedNormalDistribution(double a, double b)
    • double ppf(double p)
    • double variance()
  • private:
    • double m_a
    • double m_b
    • double m_cdfOfA:The CDF of point a on a standard normal variable

GrayMapper.h:使用 Gray code 将比特序列映射到 constellation,换汤不换药,不做详细介绍了
LinearMapper.h:Maps integers to fixed-precision symbols,个人对 precision 的理解不是很好

  • LinearMapper(unsigned int symbolSizeBits, unsigned int precisionBits):输入符号的精度,和信道要求的精度
  • 其他部分同上

QamMapper.h:使用了 IMapper,但程序中使用了 itpp::QAM,参考 binding 中的内容,此处可以作为了解
QPSKMapper.h:使用了IMapper ,但程序中使用了 itpp::QPSK,参考 binding 中的内容,此处可以作为了解
SoftMapper.h不明确,参考 simulation 中的实验再回头看看。

3.4 include/demappers

说明:需要了解一些 map 和 demap 的方法

IDemapper.h:Demapper 的接口模块,代码结构:

  • virtual ~IDemapper() {}
  • virtual void process(const std::vector< ChannelSymbol>& symbols, N0_t n0, std::vector< LLRValue>& llrs) = 0:将接受符号解调为 soft bit values,理解不是很好
  • virtual void process(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0, std::vector< LLRValue>& llrs) = 0:将接受符号解调为 soft bit values,且每个符号有不同的噪声值
  • virtual unsigned int forecast(unsigned int numOutputs) = 0

BitwiseDemapper.h:通过枚举星座图上的点,来解星座映射,找到最大似然的点解调

  • BitwiseDemapper.hh:楼上的实现函数

BscDemapper.h:比特翻转 BSC 信道解调
ItppDemapper.h:继承 IDemapper,相比之下只有参数不太一样 ,IT++ Modulator 和 IDemapper 之间的适配器

  • public:
    • ItppDemapper(ModulatorPtr& modulator, unsigned int forecastFactor, bool useApprox):
    • virtual ~ItppDemapper() {}
    • virtual void process(const std::vector< ChannelSymbol>& symbols, N0_t n0, std::vector< LLRValue>& llrs)
    • virtual void process(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0, std::vector< LLRValue>& llrs):
    • virtual unsigned int forecast(unsigned int numOutputs)
  • private:
    • ModulatorPtr m_modulator
    • const unsigned int m_forecastFactor
    • itpp::Soft_Method m_softMethod
  • ItppDemapper.hh:楼上的实现

NullDemapper.h:不调制,不解调

3.5 include/protocols

说明:给出了两种编码符号的传输方案,回头仿真时时再好好研究每个函数的功能
注意:还有第三种传输方案,位于 pythonprotocols/MultipleTryProtocol.py 中。
另外:Spinal Codes 的 protocol 定义在 Spinal Codes 本身中,当使用 Simulator 做仿真时,只要定义了 Spinal,protocol 就会使用 Spinal 中的,位于 include/codes/spinal/protocols 中

OneTryProtocol.h:一次性发送所有的编码符号

  • public:
    • OneTryProtocol(unsigned int numPackets, unsigned int numSymbols)
    • unsigned int numSymbolsNextDecode(unsigned int packetInd)
    • void setResult(unsigned int packetInd, unsigned int numSymbols, bool isFinished)
    • void resetPacket(unsigned int packetInd)
  • private:
    • unsigned int m_numSymbols
    • vector< unsigned int> m_nextDecode

RateApproxProtocol.h:自适应码率传输,怕理解不好,直接引用原文:

Attempts a sequence of rates, to find a rate up to (1+delta) factor from the minimal possible rate for the channel.
A protocol that tries rates such that the spacing between rates is at most a given constant factor ‘delta’. This means that if a system achieves a rate R, then the protocol will at the worst case try rate R * delta.

  • public:
    • RateApproxProtocol( unsigned int numPackets, unsigned int maxSymbols, float delta, uint32_t minSymbols)
    • unsigned int numSymbolsNextDecode(unsigned int packetInd)
    • void setResult(unsigned int packetInd, unsigned int numSymbols, bool isFinished)
    • void resetPacket(unsigned int packetInd)
  • private:
    • const unsigned int m_maxSymbols
    • const float m_oneOverDelta
    • const unsigned int m_minSymbols
    • std::vector< unsigned int> m_nextNumSymbols

3.6 include/util

说明很重要,给出了差错控制编码和信道的实现的基础函数,实现了工程中大部分的基础算法
Spinal Codes 说明:基于 hash 函数算法的差错控制编码,在使用是请注意区分 symbol,state,hash digest 的概念

include/util 结构图

util/hashes

说明:分为三个部分介绍,一部分是 hash 函数 的“生产”方式;另一种是,hash 函数算法的具体实现;然后是,hash 函数的 Python 接口

hash 函数的顶层模板类:

  • UnlimitedHash.h重要):较为常用的类,实现一个可以生成 16-bit 的 stream 的 hash 函数
    • UnlimitedHash.hh:IMPLEMENTATION OF UnlimitedHash.h INLINE FUNCTIONS.
    • UnlimitedHash(const Seed prevSeed, uint32_t data):初始化
    • void hash(uint32_t data):Hash the internal seed with an external 32-bit word is done with hash().
    • Seed getSeed():The internal state (the “seed”) can be retrieved using getSeed().
    • uint16_t next():The stream of 16-bit values is produced by iteratively calling nextBits().
  • SingleSymbolFunction.h:从当前的 hash digest 中取出编码符号,相当与一个小型的生产 hash 函数的工厂,可以让用户不必知道内部算法而直接使用
  • ShiftRegisterAdaptorHash.h:An adaptor class that allows updates bit-by-bit, then hashes the entire state.(没有用到,没有细看)

hash 函数的实现:

  • BitwiseXor.h :32-bit-state 的 XOR 更新操作,类声明,实现位于文件src/util/hashes/BitwiseXor.cpp
  • Lookup3Hash.h:实现了Bob Jenkin’s lookup3 算法,此处为类声明,实现位于 src/util/hash/Lookup3Hash.cpp 中,包括:
    • Lookup3Hash 类:Implementation of Bob Jenkin’s lookup3 hash function.
    • Lookup3SymbolFunction 类:Produces symbols from the digest of a Lookup3Hash,相当于Spinal Codes中提到的 RNG 的作用,即取 32-bit-state 的 16-bit 移位
  • OneAtATimeHash.h:实现了Bob Jenkin’s one-at-a-time 算法,实现部分位于 src/util/hashes/OneAtATimeHash.cpp
  • salsa20.h:Salsa20 算法中使用到的类型和函数的定义
  • SalsaHash.h:Salsa20 算法的实现类,结构基本与Lookup3Hash.h 相同
  • ecrypt-config.h:源自于 Salsa20 算法,请勿改动
  • ecrypt-machine.h:源自于 Salsa20 算法,请勿改动
  • ecrypt-portable.h:源自于 Salsa20 算法,请勿改动

hash 函数的 Python 接口:

  • SWIGHash.h:配合 bindings/util/hashes.i%pythoncode %{ %}使用,使用方法为,在 Python 环境下按如下方式,即可调用封装好的 hash 函数:
import wireless.util.hashes as hashhash_func = hash.OneAtATimeHash_init()

util/inference

说明:给出了两种译码时用到的推到方式,一种是基于置信度的 BP 法,另一种是基于状态图的搜索算法。

  • bp:LDPC 译码中使用,这里先不做介绍
    • BipartiteBP.h
    • BipartiteGraph.h
    • BPMessage.h
    • ElementHeap.h
    • LinearVariableNodeUpdater.h
    • MessagePassingDecoder.h
    • MessagePassingDecoder.hh
    • MultiStack.h
    • MultiVector.h
    • NodeUpdater.h
  • hmm:广义来说这些搜索方法是可以算作是 HMM 的,作者这样命名也不无道理

    • LookaheadBeamSearch.h:A beam search, with lookahead.
      • LookaheadAdaptor.h
      • BeamSearch.h:A generic implementation of beam search exploration.
        • Backtracker.h
        • BestK.h
        • DualPool.h
    • IPruner.h:return: true if the node might be added, false if the node has been pruned.
    • ParallelBestK.h:Collection of several BestK lists, insertions round-robin within the collection.
  • util/Utils.h :不同的 bit / string / likelihood 之间的转换,其中的类方法均为静态方法 ,以便在只定义类的情况下也能够调用类方法,而不需将其实例化

  • util/ItppUtils.h :实现 string 与 itpp bvec 之间的转换
  • util/BitStatCounter.h:统计多个字符串中“1”出现的次数
  • util/BlockStatCounter.h:统计一个长为 k 的 block 非零的次数
  • util/crc.h:实现了 crc16 和 crc32
  • util/MTRand.h:MersenneTwister 随机数生成

3.7 include/*.h

说明:定义了一些包括 代码符号定义规则,变换的级联,两种检测译码是否正确的方法(crc,oracle),包生成

代码符号定义规则:

  • include/CodeBench.h :C++ 部分的编码标准,给出了一些 typedef 和 define 等,注意如果在这里进行了修改,那么 ./binding 中的相关内容也要修改,对应的封装在 bindings/general.i 中,如需要请向前查阅

变换的级联:

  • include/ComposedTransformation.h :ComposedTransformation2 类的声明和实现,将两种变换组合为一种变换,包括 constructor,transform,forecast 方法,可以理解为变换的级联吧。
  • include/TransformationAdaptor.h:貌似没怎么用过,且文件中有详细表述,等遇到了再做研究

检测译码是否正确:

  • include/CrcDetector.h :CRC -16的检测模块的声明和实现,包括 CrcDetector() / setPacket() / isFinished() 方法,由 CrcPacketGenerator 生成的数据包的正确性。检测方法是使用接收的数据(这里一般为译码后的结果)的除了前两个字节之外的其他部分生成的CRC值和前两个字节的值想对比,若相等则 isFinished=True
  • include/OracleDetector.h:将译码后得到的 result 数据结构中的 packet 和 与之相对的发送的 packet 做对比,以判断译码是否成功,包括 OracleDetector,setPacket,isFinished 方法

数据包生成:

  • include/PacketGenerator.h:生成随机的数据包,包括PacketGenerator,seed,get 方法,实现部分在 src/PacketGenerator.cpp
  • include/CrcPacketGenerator.h:实现了使用include/util/crc.h 中的CRC-16 查表算法,生成带有CRC头(位于数据包的前两个字节)的数据包,实现部分在 src/CrcPacketGenerator.cpp中,包括 CrcPacketGenerator,seed,get,这里要注意生成的是完整的包而不是根据包生成头

4 src

说明:大部分功能模块的实现(.cpp),在 include (上一节)中顺带说明,不做单独介绍


5 .metadata

说明:不知道是什么


6 .settings

说明:eclipse的设置记录


7 autom4te.cache

说明:不知道是什么


8 build-aux

说明:存放了一些m4的辅助宏


9 data

说明:LDPC的编码结果


10 doc

说明:Doxyfile文档


11 lablog

说明


12 release

说明


13 test

说明


14 util

1 0
原创粉丝点击