喷泉码的原理详解以及实现

      喷泉码是一类基于图的线性纠删码,在广播方式的通信系统中,发送端对原始信息进行编码,得到源源不断的编码信息并且发送,只要接收端能正确接收到足够的编码信息就可以译出原始数据信源,反馈重传的差错摔制方式相比,其更为有效,尤其适用于深空通信环境。 LT码是一种典型的喷泉码,本文将介绍LT码的编译码过程及思路推导,具体的代码我写了3份,一份是c++的,将LT码的整体功能封装为了一个类,如果要使用只需注册一个发送回调函数即可使用,另一份是纯c语言编写的,这一份c语言的提供了LT码的各种编译码功能函数,还有一份是matlab的,方便理解数学推导过程,我的代码放在GitHub上,网址为:https://github.com/zk3326312/LT_code/。如果你使用觉得还可以请为我点一颗星。下面我将开始介绍喷泉码的设计思路以及编译码过程。

      喷泉码的设计需要主要考虑2方面的问题:①译码开销尽量小,使其趋近于0;②编译码复杂度尽量低:理想情况下,希望做到每个编码分组需要的运算量是一个与K无关的常量,获得K个原始数据分组的成功译需要的运算量是K的线性函数。,下面就介绍一下LT码的编译码过程。

1. LT码的编码算法

      LT码作为第一种实用的喷泉码,其编码过程较为简单,下面就某一编码包的产生过程介绍如下:

①   由已定的度分布ρ(d);

②   随机选取一个度值d;

③   将这d 个不同的数据包求异或和,生成该编码包。

具体过程如下图所示

喷泉码的原理详解以及实现

      不断重复上面的步骤,就可以得到无限多个编码分组。在这些步骤中一些细节需要注意:LT 码编码之前要先确定度分布函数,度值的确定由度分布函数来计算。不同的度分布,k的概率值是不同的,但度分布概率函数只是确定了取度值为d的概率是多少,而并不能确定这d个原始编码分组是哪些,所以对于这d个原始编码分组的选择来说是任意的,本文对这d个原始编码分组的选择采用均匀分布来进行选取,即从区间[1,k]中按均匀分布随机生成d个整数。区间[1,k]中所有整数被选取的概率是相等的。把这d个整数进行异或,就得到了一个编码分组。

      译码算法本文就只介绍GE(高斯消元法),BP算法其实就是GE方法的简单版,GE是每接收到数据包就对生成矩阵进行恢复,而 BP算法仅在接收到度数为1的消息包时才进行译码。BP算法的好处是算法复杂度较低(GE算法每次收到数据包就进行恢复,会对接受方的译码性能有要求),坏处就是当度数为1的包丢失时无法译码,造成接收方等待时间过长,误码率高等情况,下面就来介绍LT码的译码算法。

2.LT码的译码算法

      编码器在编码后会给每一个生成的数据包伴随一个生成向量,比如:我的原始编码分组有10个,我生成的消息包度数为3,由原始编码分组的第1个,第3个,第5个得到,那么我的伴随向量就为[1 0 1 0 1 0 0 0 0 0]';通过编码,我将源源不断的获得消息包和伴随向量,接收方将收到的消息包和伴随向量组合起来就是收到的消息矩阵和伴随矩阵,伴随矩阵进行高斯消元,同时对消息矩阵做同样的行列变换,当伴随矩阵的秩等同于其行数时,那么,消息矩阵就可以成功恢复了。示例如下:

      喷泉码的原理详解以及实现

      伴随矩阵经过高斯消元后,秩为8,说明还未成功恢复出来,但其对角元的第一行至第四行均为1,说明其第1到第4个数据包均已得到成功恢复,再继续接收数据包,等其对角元均为1后(等同于秩为10),则说明原始数据的10个编码分组均已得到成功恢复。

      说的这么复杂,总结一下,译码过程就是编码过程的逆,编码过程就是先生成一个度分布,然后每次要生成数据包时,去度分布里随机抽取一个,得到度数d,然后去编码分组里抽d个出来做异或,同时将做异或的数据包通过一个向量来记录,发送时将向量和消息一同发出,接收呢就是把消息包收到后再通过异或运算将其对应的伴随向量消除的只剩一个1就行啦。

      LT码的编译码算法我觉得其实不是难点,难点在于度分布函数的设计,如果我们需要传输l个比特,那么我们可以将其分为m个输入分组,每个输入分组中包含n个比特,其中l=m×n。我们根据喷泉码的原理将这m个输入分组进行编码,编码之后生成p个输出分组,我们可以将每个分组看作一个符号,输入分组就是输入符号,输出分组就是输出符号。良好的度分布函数的作用就是保证编码的时候,这m个分组均有机会参与到混合过程来,这样才能保证译码的时候不会因为有一个数据包没有参与到编码或者发送时丢包,迟迟无法译码的问题,如何设计度分布函数呢?先思考一个问题,假设独立地把n个球扔到k个筐中,当n和k很大时,求每个筐中至少有一个球的概率。这个问题就可以看作是一个度分布,每一次投球的过程中,只有一个筐可以接到这个球,而每个筐接到这个球的概率是相等的,都是1/k,所以这种度分布可以看作是均匀分布。我们把每个球看作一个编码符号,它就表示所有的编码符号的度数都是1,而成功译码的前提就是每个筐中都有球。

      在k 保持不变且n≥k 时,n 越大,每个筐中至少有一个球的概率越大,而经过概率论的知识可以求得,在k不变时,若要使每个筐中都有球的概率是1 -p,则需要球的数量为:

          n =k ln(k /p )(这里是约等于)

      而将n 个球独立地扔到k 个筐中,空筐数量的期望也可求得是k*e^(-n/k)。可见我们如果要保证每个容器中都有球,就必须要扔很多的球,让期望尽可能是一个很小的数值x ,而这时就需要n > k ln(k /p )。