文章目录
前言
本博客介绍了LDPC码的基本原理,其中包括校验矩阵的构造、Tanner 图和编译码的基础知识。
1. 简介
低密度奇偶校验码 (Low-density parity-check, LDPC) 是一类线性分组码,Gallager在 1962 年里首次提出 LDPC 码,但当时没有受到重视。30 多年后,Mackay在 1999 年重新发现 LDPC 的高性能特性,并推广应用。如今,LDPC 码广泛应用于通信领域,例如 5G、WIFI、WIMAX 和 DVB-S2 等领域。
2. 校验矩阵和生成矩阵
当我们在传递信息时,接收端如何判断接收到的信息是正确的呢?首先想到,在有用信息之后增加一些额外的信息,这些额外信息和有用信息存在某种约束。这样在接收端就可以用这种约束关系来验证接收信息正确与否。
最简单的一种方式是单奇偶校验码 (single parity check code, SPC),即额外增加一位奇偶校验码。例如有一个7位的信源即
s
=
1010011
{\bf{s}}{\rm{ = 1010 011}}
s=1010011,奇偶校验码增加到第8位。当
s
{\bf{s}}
s中有偶数个1时,第8位奇偶校验码置为”0”,否则置为”1”。此例最终的码字为
s
′
=
10100110
{\bf{s'}}{\rm{ = 1010 0110}}
s′=10100110.
对于7位源码和1位奇偶校验码,我们定义码字具有如下的形式:
s
=
[
s
1
,
s
2
,
s
3
,
s
4
,
s
5
,
s
6
,
s
7
,
s
8
]
(1)
{\bf{s}} = \left[ {{s_1},{s_2},{s_3},{s_4},{s_5},{s_6},{s_7},{s_8}} \right]\tag{1}
s=[s1,s2,s3,s4,s5,s6,s7,s8](1)式中
s
i
{s_i}
si为”0”或”1”,并且码字满足如下约束:
s
1
⊕
s
2
⊕
s
3
⊕
s
4
⊕
s
5
⊕
s
6
⊕
s
7
⊕
s
8
=
0
{s_1} \oplus {s_2} \oplus {s_3} \oplus {s_4} \oplus {s_5} \oplus {s_6} \oplus {s_7} \oplus {s_8} = 0
s1⊕s2⊕s3⊕s4⊕s5⊕s6⊕s7⊕s8=0
上式为奇偶校验方程,式中
⊕
\oplus
⊕表示模-2相加。
当信源码字由于信道干扰造成了一个比特的翻转,这种情况可以通过上述单奇偶校验码检测出来。但是无法给出哪一位错误,或对于更多比特的翻转,无法给出正确的译码结果。因此检测更多比特错误需要增加编码的冗余度,即需要设计更加复杂的奇偶校验码。
考虑如下6bit的码字:
s
=
[
s
1
,
s
2
,
s
3
,
s
4
,
s
5
,
s
6
]
{\bf{s}} = \left[ {{s_1},{s_2},{s_3},{s_4},{s_5},{s_6}} \right]
s=[s1,s2,s3,s4,s5,s6]满足三个奇偶校验方程:
s
1
⊕
s
2
⊕
s
4
=
0
s
2
⊕
s
3
⊕
s
5
=
0
s
1
⊕
s
2
⊕
s
3
⊕
s
6
=
0
(2)
\begin{array}{l} {s_1} \oplus {s_2} \oplus {s_4} = 0\\ {s_2} \oplus {s_3} \oplus {s_5} = 0\\ {s_1} \oplus {s_2} \oplus {s_3} \oplus {s_6} = 0 \end{array}\tag{2}
s1⊕s2⊕s4=0s2⊕s3⊕s5=0s1⊕s2⊕s3⊕s6=0(2)上述码字的奇偶校验方程可以写成矩阵形式:
[
1
1
0
1
0
0
0
1
1
0
1
0
1
1
1
0
0
1
]
⋅
⏟
H
[
s
1
s
2
s
3
s
4
s
5
s
6
]
=
[
0
0
0
]
(3)
\underbrace{\left[ \begin{matrix} 1 & 1 & 0 & 1 & 0 & 0 \\ 0 & 1 & 1 & 0 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 & 1 \\ \end{matrix} \right] \cdot}_{\mathbf{H}}\left[ \begin{matrix} {{s}_{1}} \\ {{s}_{2}} \\ {{s}_{3}} \\ {{s}_{4}} \\ {{s}_{5}} \\ {{s}_{6}} \\ \end{matrix} \right]=\left[ \begin{matrix} 0 \\ 0 \\ 0 \\ \end{matrix} \right]\tag{3}
H
101111011100010001
⋅
s1s2s3s4s5s6
=
000
(3)式中矩阵
H
\mathbf{H}
H是奇偶校验矩阵。矩阵
H
\mathbf{H}
H的每一行与一个奇偶校验方程相关,每一列与码字中的一个比特关联。因此,对于一个具有
m
m
m个奇偶校验方程约束并且码字长度为
n
n
n位的奇偶校验矩阵可用一个
m
×
n
m\times n
m×n维的矩阵表示。经过信道接收到带噪声和干扰的比特流
y
=
[
y
1
,
y
2
,
y
3
,
y
4
,
y
5
,
y
6
]
\mathbf{y}=\left[ {{y}_{1}},{{y}_{2}},{{y}_{3}},{{y}_{4}},{{y}_{5}},{{y}_{6}} \right]
y=[y1,y2,y3,y4,y5,y6],如果满足以下方程(4),则认为该比特流通过校验,是有效的码字。
H
y
T
=
0
(4)
\mathbf{H}{{y}^{T}}=\mathbf{0}\tag{4}
HyT=0(4)以上是关于校验矩阵的定义。对于生成矩阵,首先将奇偶校验方程(2)重写为如下:
s
4
=
s
1
⊕
s
2
s
5
=
s
2
⊕
s
3
s
6
=
s
1
⊕
s
2
⊕
s
3
(5)
\begin{array}{l} {s_4} = {s_1} \oplus {s_2}\\ {s_5} = {s_2} \oplus {s_3}\\ {s_6} = {s_1} \oplus {s_2} \oplus {s_3} \end{array}\tag{5}
s4=s1⊕s2s5=s2⊕s3s6=s1⊕s2⊕s3(5)上式方程可以理解为码字
s
{\bf{s}}
s包含了三个信息比特
s
1
,
s
2
,
s
3
{s_1},{s_2},{s_3}
s1,s2,s3,同时包含了三个校验比特
s
4
,
s
5
,
s
6
{s_4},{s_5},{s_6}
s4,s5,s6。同样,(5)式的约束可以写为矩阵形式:
[
s
1
,
s
2
,
s
3
,
s
4
,
s
5
,
s
6
]
=
[
s
1
,
s
2
,
s
3
]
⋅
[
1
0
0
1
0
1
0
1
0
1
1
1
0
0
1
0
1
1
]
⏟
G
(6)
\left[ {{s}_{1}},{{s}_{2}},{{s}_{3}},{{s}_{4}},{{s}_{5}},{{s}_{6}} \right]=\left[ {{s}_{1}},{{s}_{2}},{{s}_{3}} \right]\cdot\underbrace{\left[ \begin{matrix} 1 & 0 & 0 & 1 & 0 & 1 \\ 0 & 1 & 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 0 & 1 & 1 \\ \end{matrix} \right]}_{\mathbf{G}}\tag{6}
[s1,s2,s3,s4,s5,s6]=[s1,s2,s3]⋅G
100010001110011111
(6)式中矩阵
G
\mathbf{G}
G称为码字的生成矩阵。信息比特通常用
u
=
[
u
1
,
u
2
,
⋯
,
u
k
]
\mathbf{u}=\left[ {{u}_{1}},{{u}_{2}},\cdots ,{{u}_{k}} \right]
u=[u1,u2,⋯,uk]表示,因此编码后的码字可用生成矩阵表示:
s
=
u
G
(7)
{\bf{s = uG}}\tag{7}
s=uG(7)生成矩阵
G
{\bf{G}}
G是
k
×
n
k \times n
k×n的二进制矩阵,
k
/
n
k/n
k/n称为编码的码率。从上面的描述可以看出,生成矩阵可以由校验矩阵获得,且满足:
H
s
T
=
H
G
T
u
T
=
0
⇒
H
G
T
=
0
(8)
\begin{array}{c} {\bf{H}}{{\bf{s}}^T}{\bf{ = H}}{{\bf{G}}^T}{{\bf{u}}^T}{\bf{ = 0}}\\ \Rightarrow {\bf{H}}{{\bf{G}}^T}{\bf{ = 0}} \end{array}\tag{8}
HsT=HGTuT=0⇒HGT=0(8)生成矩阵
G
\mathbf{G}
G的任意行向量属于校验矩阵的零空间(Null Space)。校验矩阵
H
{\bf{H}}
H一旦确认,信息比特的编码就可以确定。
注:上述运算均在GF(2)域。
————————————————————————————————————————————
对于校验矩阵
H
{\bf{H}}
H还有一个额外的约束,即:
n
−
k
=
r
a
n
k
(
H
)
(9)
n - k = {\rm{rank}}\left( {\bf{H}} \right)\tag{9}
n−k=rank(H)(9)式中,
r
a
n
k
(
H
)
{\rm{rank}}\left( {\bf{H}} \right)
rank(H)表示矩阵
H
{\bf{H}}
H的秩。(这里需要注意,
m
m
m有可能大于
n
−
k
n - k
n−k,但
H
{\bf{H}}
H中有些行之间是线性相关的)
查阅了很多资料,大部分都没有解释。这里根据自己的理解简单解释一下。
由矩阵方程
A
n
×
n
⋅
x
n
×
1
=
0
{{\bf{A}}_{{\rm{n}} \times {\rm{n}}}}\cdot{{\bf{x}}_{{\rm{n}} \times {\rm{1}}}}{\bf{ = 0}}
An×n⋅xn×1=0 可知,当
A
{\bf{A}}
A满秩时方程没有非零解,每当
A
{\bf{A}}
A的秩减1,则释放一个自由度给
x
{\bf{x}}
x。同理
s
{\bf{s}}
s中的信源比特为
k
k
k位,也就是说
H
s
T
=
0
{\bf{H}}{{\bf{s}}^T}{\bf{ = 0}}
HsT=0这个线性方程组要有
k
k
k个自由度 (因为信源比特是不确定的),那么
r
a
n
k
(
H
)
{\rm{rank}}\left( {\bf{H}} \right)
rank(H)等于
n
−
k
n - k
n−k,这样才能保证对于任意的信源比特
H
s
T
=
0
{\bf{H}}{{\bf{s}}^T}{\bf{ = 0}}
HsT=0都有非零解。
————————————————————————————————————————————
3. LDPC码的表达形式
3.1 矩阵形式
如上所述,校验矩阵一旦确认,编码也就定下了。因此校验矩阵
H
{\bf{H}}
H可以完全表示LDPC码。以下面式 (10) 的LDPC校验矩阵为例:
H
=
[
0
1
0
1
1
0
0
1
1
1
1
0
0
1
0
0
0
0
1
0
0
1
1
1
1
0
0
1
1
0
1
0
]
(10)
\mathbf{H}=\left[ \begin{matrix} 0 & 1 & 0 & 1 & 1 & 0 & 0 & 1 \\ 1 & 1 & 1 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 1 & 1 & 1 \\ 1 & 0 & 0 & 1 & 1 & 0 & 1 & 0 \\ \end{matrix} \right]\tag{10}
H=
01011100011010011001011000111010
(10)该矩阵定义了
m
=
4
m=4
m=4 个奇偶校验方程和码字长度为
n
=
8
n=8
n=8 位的LDPC编码。在校验矩阵
H
\mathbf{H}
H中定义两个参数:
w
r
{{w}_{r}}
wr为每行中”1”的个数,
w
c
{{w}_{c}}
wc为每列中”1”的个数。如果
w
c
≪
n
{{w}_{c}}\ll n
wc≪n且
w
r
≪
m
{{w}_{r}}\ll m
wr≪m则称
H
\mathbf{H}
H是“低密度”的,这也是低密度奇偶校验编码名字的由来。
3.2 Tanner 图形式
Tanner对LDPC码引入了一个有效的“图”表达形式,称作为Tanner 图。Tanner 图不仅能够完整表达LDPC码,而且Tanner 图能够有效解释译码原理。
Tanner 图是一种二分图,它由两类节点组成:变量节点(variable nodes, v-nodes)和校验节点(check nodes, c-nodes)。变量节点对应码字中的每个比特位,而校验节点对应奇偶校验校验方程。两类节点通过边 (edges) 连接,图中的边表示码字中的比特位参与了哪个校验方程。
式(10)所示的校验矩阵可以用图(1)所示的Tanner 图表示。图中包含了
m
m
m 个(奇偶校验比特位数)校验节点和
n
n
n 个 (码字长度) 变量节点。如果校验矩阵
H
{\bf{H}}
H中
h
i
j
=
1
{h_{ij}} = 1
hij=1,则校验节点
c
i
{c_i}
ci与变量节点
v
j
{v_j}
vj通过边连接。
3.3 规则/不规则LDPC码
如果校验矩阵 H {\bf{H}} H中每一列的 w c {w_c} wc是个常数且每一行的 w r {w_r} wr也是个常数,那么则称这样的LDPC码是规则的。式(10)给出的校验矩阵 H {\bf{H}} H是规则的: w c = 2 , w r = 4 {w_c} = 2,{w_r} = 4 wc=2,wr=4。从Tanner 图中也可以看出,连接每个校验节点的边数都相同且连接每个变量节点的边数也都相同。其他情况下则称为不规则LDPC码。
3.4 LDPC码的构造
如上所述,LDPC码完全可以用校验矩阵 H {\bf{H}} H来表示,所以LDPC码的构造也就是如何构造校验矩阵 H {\bf{H}} H以尽量逼近香农极限。正常来说,校验矩阵应该根据不同信源比特来构造,但企图对每个不同信源比特构造校验矩阵 H {\bf{H}} H是不现实的!所以,一般是根据不同信道和码率等条件提前构造好校验矩阵 H {\bf{H}} H,对于不同的信源比特均采样同样的 H {\bf{H}} H。Gallager自己提出了一种构造方式,后来MacKay提出了一种半随机的稀疏校验矩阵。有兴趣的可参考相关资料[1],这里不详细介绍LDPC码的构造。
4. 编码 Encoding
如前所述,生成矩阵
G
{\bf{G}}
G的任意行向量都属于校验矩阵
H
{\bf{H}}
H的零空间(Null Space)。一旦构造完成
H
{\bf{H}}
H之后,就可以获取生成矩阵。
可以先通过高斯-约当消元法将校验矩阵
H
{\bf{H}}
H转换成如下形式:
H
=
[
A
(
n
−
k
)
×
k
,
I
n
−
k
]
(11)
{\bf{H}} = \left[ {{{\bf{A}}_{\left( {n - k} \right) \times k}},{{\bf{I}}_{n - k}}} \right]\tag{11}
H=[A(n−k)×k,In−k](11)那么生成矩阵为:
G
=
[
I
k
,
A
T
]
(12)
{\bf{G}} = \left[ {{{\bf{I}}_{k}},{{\bf{A}}^T}} \right]\tag{12}
G=[Ik,AT](12)进而通过式(12)的矩阵相乘操作就可以完成LDPC编码。具体操作过程可以参考这篇LDPC码:编码举例。
虽然校验矩阵
H
{\bf{H}}
H是稀疏的,但是生成矩阵
G
{\bf{G}}
G往往不是,所以通过这种方式的编码复杂度为
O
(
n
2
)
O\left( {{{\rm{n}}^2}} \right)
O(n2)。这样的复杂度太高了,具体实现时其实是通过稀疏校验矩阵直接生成的编码码字,复杂度可以降低到
O
(
n
)
O\left( {\rm{n}} \right)
O(n),博客低复杂度LDPC编码算法详细讨论了基于稀疏校验矩阵的低复杂度编码方法。
5. 译码 Decoding
LDPC的译码算法可以统称为一类“信息传递”算法,因为在译码中总是通过Tanner图的边在变量节点和校验节点之间传递“信息”。每个节点都是相互独立的,只有与之连接的边和该节点有信息传递。根据节点间信息类型传递的不同,译码算法有硬判算法和软判算法,常见的有:比特翻转译码算法(硬)、信任传播译码算法(软)、和积译码算法(软)。
为了简要说明译码原理,这里仅介绍二进制对称信道BSC最简单的硬判算法,其他算法后续博客讨论。
硬判算法
这里还是以式(10)的校验矩阵为例,考虑编码后待发送的码字为
s
=
[
1
,
0
,
0
,
1
,
0
,
1
,
0
,
1
]
{\bf{s}} = \left[ {1,0,0,1,0,1,0,1} \right]
s=[1,0,0,1,0,1,0,1],假设经过信道后只有
s
1
{s_1}
s1发生了错误,从”0”变成了”1”,即接收到的码字变成了
y
=
[
1
,
1
,
0
,
1
,
0
,
1
,
0
,
1
]
{\bf{y}} = \left[ {1,1,0,1,0,1,0,1} \right]
y=[1,1,0,1,0,1,0,1]。
算法步骤可以概括为如下:
第一步:所有的变量节点
v
i
{v_i}
vi给与之相连的校验节点
c
j
{c_j}
cj传递一个“信息”,这个“信息”是变量节点认为自己正确的比特信息 (“0”或”1”)。在算法开始之初,变量节点
v
i
{v_i}
vi只有接收信号所对应的比特位
y
i
{y_i}
yi。例如,变量节点
v
0
{v_0}
v0给校验节点
c
1
{c_1}
c1和
c
3
{c_3}
c3发送”1”,变量节点
v
1
{v_1}
v1给校验节点
c
0
{c_0}
c0和
c
1
{c_1}
c1发送
y
1
{y_1}
y1即”1”,以此类推。
第二步:每一个校验节点 c j {c_j} cj计算一个响应信息,并发送给与之相连的变量节点。此响应信息是校验节点 c j {c_j} cj认为变量节点 v i {v_i} vi正确的比特信息 (“0”或”1”),计算时假设与 c j {c_j} cj相连的除了 i i i之外的变量节点全部都是正确的,然后通过该校验节点对应的奇偶校验方程得出的变量节点 v i {v_i} vi的比特信息。这里,每个校验节点 c j {c_j} cj连接了4个变量节点,所以校验节点利用接收到的三个变量节点的信息,然后通过计算该节点对应的奇偶校验方程获得第四个变量节点的比特信息。表1给出了前两步的大致过程。
校验节点 | 接收/发送 |
---|---|
c 0 {c_0} c0 | 接收:
c
1
→
1,
c
3
→
1
,
c
4
→
0
,
c
7
→
1
{c_1} \to 1{\rm{,}}{c_3} \to 1,{c_4} \to 0,{c_7} \to 1
c1→1,c3→1,c4→0,c7→1 发送: 0 → c 1 , 0 → c 3 , 1 → c 4 , 0 → c 7 0 \to {c_1}{\rm{,0}} \to {c_3},1 \to {c_4},0 \to {c_7} 0→c1,0→c3,1→c4,0→c7 |
c 1 {c_1} c1 | 接收:
c
0
→
1,
c
1
→
1
,
c
2
→
0
,
c
5
→
1
{c_0} \to 1{\rm{,}}{c_1} \to 1,{c_2} \to 0,{c_5} \to 1
c0→1,c1→1,c2→0,c5→1 发送: 0 → c 0 , 0 → c 1 , 1 → c 2 , 0 → c 5 0 \to {c_0}{\rm{,0}} \to {c_1},1 \to {c_2},0 \to {c_5} 0→c0,0→c1,1→c2,0→c5 |
c 2 {c_2} c2 | 接收:
c
2
→
0,
c
5
→
1
,
c
6
→
0
,
c
7
→
1
{c_2} \to 0{\rm{,}}{c_5} \to 1,{c_6} \to 0,{c_7} \to 1
c2→0,c5→1,c6→0,c7→1 发送: 0 → c 2 , 1 → c 5 , 0 → c 6 , 1 → c 7 0 \to {c_2}{\rm{,1}} \to {c_5},0 \to {c_6},1 \to {c_7} 0→c2,1→c5,0→c6,1→c7 |
c 3 {c_3} c3 | 接收:
c
0
→
1,
c
3
→
1
,
c
4
→
0
,
c
6
→
0
{c_0} \to 1{\rm{,}}{c_3} \to 1,{c_4} \to 0,{c_6} \to 0
c0→1,c3→1,c4→0,c6→0 发送: 1 → c 0 , 1 → c 3 , 0 → c 4 , 0 → c 6 1 \to {c_0}{\rm{,1}} \to {c_3},0 \to {c_4},0 \to {c_6} 1→c0,1→c3,0→c4,0→c6 |
第三步:变量节点接收来自校验节点的响应信息,然后变量节点会根据接收信号比特和校验节点反馈的附加响应信息综合判决当前节点的比特信息。最简单的方法是投票,统计”0”和”1”的票数,票多胜出。这里,每个变量节点有三个信息来判定当前的比特位,分别是接收信号和两个校验节点的响应信息。表2给出了这一步的过程。
第四步:判断校验矩阵方程是否都满足,如果满足或者达到设定迭代次数,则结束并反馈解码成功;否则返回第二步。
变量节点 | 接收信号 y i y_i yi | 校验节点响应信息 | 判决 |
---|---|---|---|
v 0 {v_0} v0 | 1 | c 1 → 0 , c 3 → 1 {c_1} \to 0, {c_3} \to 1 c1→0,c3→1 | 1 |
v 1 {v_1} v1 | 1 | c 0 → 0 , c 1 → 0 {c_0} \to 0,{c_1} \to 0 c0→0,c1→0 | 0 |
v 2 {v_2} v2 | 0 | c 1 → 1 , c 2 → 0 {c_1} \to 1,{c_2} \to 0 c1→1,c2→0 | 0 |
v 3 {v_3} v3 | 1 | c 0 → 0 , c 3 → 1 {c_0} \to 0,{c_3} \to 1 c0→0,c3→1 | 1 |
v 4 {v_4} v4 | 0 | c 0 → 1 , c 3 → 0 {c_0} \to 1,{c_3} \to 0 c0→1,c3→0 | 0 |
v 5 {v_5} v5 | 1 | c 1 → 0 , c 2 → 1 {c_1} \to 0,{c_2} \to 1 c1→0,c2→1 | 1 |
v 6 {v_6} v6 | 0 | c 2 → 0 , c 3 → 0 {c_2} \to 0,{c_3} \to 0 c2→0,c3→0 | 0 |
v 7 {v_7} v7 | 1 | c 1 → 1 , c 2 → 1 {c_1} \to 1,{c_2} \to 1 c1→1,c2→1 | 1 |
在此例中,第一次循环之后校验矩阵方程成立,那么迭代算法就结束了。成功译码。
总结
以上介绍的就是LDPC码最基础的内容,文中有三个方面没有展开介绍,分别是校验矩阵的构造、基于校验矩阵稀疏性的编码算法、软判译码的算法介绍,但是不影响对LDPC码原理和编、译码过程的理解。后续将进一步扩充,感兴趣的可以关注一下。
本文作者: 渺小的颗星
本文链接: https://blog.csdn.net/weixin_40319158/article/details/148202866?spm=1001.2014.3001.5501
版权声明: 转载请注明出处!
参考:
【1】D. J. C. MacKay, “Good error-correcting codes based on very sparse matrices,” IEEE Trans. Inform. Theory, vol. 45, no. 2, pp. 399–431, March 1999
【2】LDPC码:编码举例
【3】低复杂度LDPC编码算法