准备知识
ldpc码属于(n,k)线性分组码,n表示编码后的码长,k表示信息位长度,m=n-k表示校验位长度。802.11ac协议下的qc-ldpc码具有3种码长、4种码率共12种不同的选择,它们之间的对应关系如下表所示:
码长 | 码率 | 信息位 | 校验位 |
---|---|---|---|
648 | 1/2 | 324 | 324 |
648 | 2/3 | 432 | 216 |
648 | 3/4 | 486 | 162 |
648 | 5/6 | 540 | 108 |
1296 | 1/2 | 648 | 648 |
1296 | 2/3 | 846 | 432 |
1296 | 3/4 | 972 | 324 |
1296 | 5/6 | 1080 | 216 |
1944 | 1/2 | 972 | 972 |
1944 | 2/3 | 1296 | 648 |
1944 | 3/4 | 1458 | 486 |
1944 | 5/6 | 1620 | 324 |
该协议下的校验矩阵H按照不同的码长具有不同的提升因子Z和基矩阵Hb大小,对应关系如下表所示:
码长 | 码率 | Z | Hb | H |
---|---|---|---|---|
648 | 1/2 | 27 | 12*24 | 324*648 |
648 | 2/3 | 27 | 8*24 | 216*648 |
648 | 3/4 | 27 | 6*24 | 162*648 |
648 | 5/6 | 27 | 4*24 | 108*648 |
1296 | 1/2 | 54 | 12*24 | 648*1296 |
1296 | 2/3 | 54 | 8*24 | 432*1296 |
1296 | 3/4 | 54 | 6*24 | 324*1296 |
1296 | 5/6 | 54 | 4*24 | 216*1296 |
1944 | 1/2 | 81 | 12*24 | 972*1944 |
1944 | 2/3 | 81 | 8*24 | 648*1944 |
1944 | 3/4 | 81 | 6*24 | 486*1944 |
1944 | 5/6 | 81 | 4*24 | 324*1944 |
从上表可以i看出,H的行(或列) = Hb的行(或列)*提升因子Z。
基矩阵Hb中的每个元素代表一个Z x Z大小的方阵,0值表示该方阵中所有元素为0,非0值表示单位阵I需要循环右移的次数,即该方阵是由单位I循环右移多少次才得到。
编码器
ldpc的编码算法目前尝试过以下几种,分别是传统算法、Efficient算法。
第一种:传统算法
该算法主要有两种方式,一种是通过校验矩阵
H
\bm{H}
H,一种是通过生成矩阵
G
\bm{G}
G。由于生成矩阵
G
\bm{G}
G和校验矩阵
H
\bm{H}
H之间存在正交性,所以可以通过高斯消元法进行求解。步骤如下:
首先将给定的校验矩阵
H
\bm{H}
H通过高斯消元转化成以下形式:
H
=
[
I
r
×
r
∣
P
k
×
r
T
]
(1-1)
H = [I_{r \times r} | P_{k \times r}^T] \tag{1-1}
H=[Ir×r∣Pk×rT](1-1)
则对应的生成矩阵
G
\bm{G}
G为:
G
=
[
P
k
×
r
∣
I
k
×
k
]
(
r
=
n
−
k
)
(1-2)
G=[P_{k \times r} | I_{k \times k](r = n-k) }\tag{1-2}
G=[Pk×r∣Ik×k](r=n−k)(1-2)
两者的关系如下:
H
×
G
T
=
0
或
G
×
H
T
=
0
(1-3)
H \times G^T = 0 或 G \times H^T = 0 \tag{1-3}
H×GT=0或G×HT=0(1-3)
对于一个长为k的信息序列
m
\bm{m}
m,它与生成矩阵相乘可以得到长度为n的码字
c
\bm{c}
c,公式如下:
c
=
m
×
G
(1-4)
c = m \times G \tag{1-4}
c=m×G(1-4)
由(1-3)、(1-4)可得编码后的码字满足下式:
c
×
H
T
=
m
×
G
×
H
T
=
0
(1-5)
c\times H^T = m\times G \times H^T = 0 \tag{1-5}
c×HT=m×G×HT=0(1-5)
即每个码字和
H
\bm{H}
H矩阵的每行正交。
高斯消元实现
经过ldpc编码后的码字矢量
c
\bm{c}
c,满足
H
c
T
=
0
\bm{Hc^T = 0}
HcT=0,所以可由校验矩阵得到编码后的码字,将给定的校验矩阵通过高斯消元变换成下图所示的下三角阵结构。
将
H
′
\bm{H'}
H′分成两部分
[
H
1
′
∣
H
2
′
]
\bm{[H'_1 | H'_2]}
[H1′∣H2′],其中
H
1
′
\bm{H'_1}
H1′为
r
×
(
n
−
r
)
r\times (n-r)
r×(n−r)矩阵,
H
2
′
\bm{H'_2}
H2′为
r
×
r
r\times r
r×r的下三角矩阵,码字
c
c
c也分为两部分
[
s
∣
p
]
\bm{[s | p]}
[s∣p],
s
\bm{s}
s表示发送端产生的信源矢量,
p
\bm{p}
p表示信源矢量对应的校验比特矢量,由校验式
H
c
T
=
0
\bm{Hc^T = 0}
HcT=0得:
[
H
1
′
∣
H
2
′
]
[
s
T
p
T
]
=
0
(1-6)
[H'_1 | H'_2][\begin {matrix} s^T\\ p^T \end {matrix}] = 0 \tag{1-6}
[H1′∣H2′][sTpT]=0(1-6)
则有:
H
1
′
s
T
+
H
2
′
p
T
=
0
(1-7)
H'_1s^T+H'_2p^T = 0 \tag{1-7}
H1′sT+H2′pT=0(1-7)
故而可知:
p
T
=
−
(
H
2
′
)
−
1
H
1
′
s
T
(1-8)
p^T = -(H'_2)^{-1}H'_1s^T \tag{1-8}
pT=−(H2′)−1H1′sT(1-8)
对于二元域GF(2)而言,"
−
H
\bm{-H}
−H"就等于
H
\bm{H}
H自身。
改进一:
相比上面的设计,下面这种个人理解更注重
H
c
T
=
0
Hc^T = 0
HcT=0这个整体(即
∑
j
=
1
n
H
i
,
j
∗
c
j
T
=
0
\sum_{j=1}^{n}H_{i,j}*c_j^T = 0
∑j=1nHi,j∗cjT=0,
H
H
H矩阵的每行元素与码字
c
c
c的乘积结果之和进行模2运算都为0)。
主要有两步骤,首先直接将要传输的
(
n
−
r
)
(n-r)
(n−r)位信息比特直接赋给
s
\bm{s}
s,
其次利用后向递推公式计算第
i
i
i个校验比特(
i
=
1
,
2
,
.
.
.
r
i=1,2,...r
i=1,2,...r)
p
i
=
∑
j
=
1
n
−
r
H
i
,
j
s
j
+
∑
j
=
1
i
−
1
H
i
,
j
+
n
−
r
p
j
p_i = \sum_{j=1}^{n-r}H_{i,j}s_j+\sum_{j=1}^{i-1}H_{i,j+n-r} p_j
pi=j=1∑n−rHi,jsj+j=1∑i−1Hi,j+n−rpj
如果暂时不理解上述公式,请看完第二种方法的改进二,相信可以理解上述公式,两者实现思路个人理解在大方向上是一致的,具体原文请看参考文献[3]:
第二种:Efficient算法
将校验矩阵
H
\bm{H}
H分解成具有下图所示的近似下三角阵结构。
其中横轴表示行数,纵轴表示列数,如A矩阵为M-g行,N-M列;B矩阵为M-g行,g列;T为下三角矩阵,且对角线上元素全为‘0’。经过变换后
H
\bm{H}
H矩阵可以大大降低编码复杂度,设
H
′
\bm{H'}
H′为变化后的
H
\bm{H}
H表达式,则有:
H
′
=
[
A
B
T
C
D
E
]
(1-9)
{H' = [\begin {matrix} A&B&T \\ C&D&E \end {matrix}]} \tag{1-9}
H′=[ACBDTE](1-9)
假设发送端产生的信源矢量为
s
\bm{s}
s,长度为m,该信源矢量
s
\bm{s}
s被编码成对应的码字
c
\bm{c}
c,且
c
=
[
s
,
p
1
,
p
2
]
\bm{c = [s,p_1,p_2]}
c=[s,p1,p2],其中
p
1
\bm{p_1}
p1、
p
2
\bm{p_2}
p2为校验矢量,
p
1
\bm{p_1}
p1长度为g,
p
1
\bm{p_1}
p1长度为M-g。对
H
′
\bm{H'}
H′左乘矩阵
[
I
0
−
E
T
−
1
I
]
[\begin {matrix} I&0 \\ -ET^{-1}&I \end {matrix}]
[I−ET−10I]有:
[
I
0
−
E
T
−
1
I
]
H
=
[
A
B
T
−
E
T
−
1
A
+
C
−
E
T
−
1
B
+
D
0
]
(1-10)
[\begin {matrix} I&0 \\ -ET^{-1}&I \end {matrix}] H = [\begin {matrix} A&B&T \\ -ET^{-1}A+C&-ET^{-1}B+D&0 \end {matrix}] \tag{1-10}
[I−ET−10I]H=[A−ET−1A+CB−ET−1B+DT0](1-10)
利用校验矩阵和码字
c
H
T
=
0
\bm{cH^T = 0}
cHT=0和码字表达式
c
=
[
s
,
p
1
,
p
2
]
\bm{c = [s,p_1,p_2]}
c=[s,p1,p2]可得:
A
s
T
+
B
p
1
T
+
T
p
2
T
=
0
(1-11)
As^T+Bp_1^T+Tp_2^T = 0 \tag{1-11}
AsT+Bp1T+Tp2T=0(1-11)
(
−
E
T
−
1
A
+
C
)
s
T
+
(
−
E
T
−
1
B
+
D
)
p
1
T
=
0
(1-12)
(-ET^{-1}A+C)s^T+(-ET^{-1}B+D)p_1^T= 0 \tag{1-12}
(−ET−1A+C)sT+(−ET−1B+D)p1T=0(1-12)
令
α
=
−
E
T
−
1
B
+
D
\alpha = -ET^{-1}B+D
α=−ET−1B+D,并设
α
\alpha
α为可逆矩阵,则有:
p
1
T
=
−
α
−
1
(
−
E
T
−
1
A
+
C
)
s
T
(1-13)
p_1^T = -\alpha^{-1}(-ET^{-1}A+C)s^T \tag{1-13}
p1T=−α−1(−ET−1A+C)sT(1-13)
p
2
T
=
−
T
−
1
(
A
s
T
+
B
p
1
T
)
(1-14)
p_2^T = -T^{-1}(As^T+Bp_1^T) \tag{1-14}
p2T=−T−1(AsT+Bp1T)(1-14)
改进一:直接用下面的结论
由于802.11ac协议的qc-ldpc码,其所有的校验矩阵通过RU算法计算出来的
α
−
1
\alpha^{-1}
α−1都是一个特殊矩阵
−
I
\bm{-I}
−I,为一个单位阵的逆元,对于二元域GF(2)而言就是单位阵本身。所以上式可以简化为:
p
1
T
=
(
−
E
T
−
1
A
+
C
)
s
T
(1-15)
p_1^T =(-ET^{-1}A+C)s^T \tag{1-15}
p1T=(−ET−1A+C)sT(1-15)
p
2
T
=
−
T
−
1
(
A
s
T
+
B
p
1
T
)
(1-16)
p_2^T = -T^{-1}(As^T+Bp_1^T) \tag{1-16}
p2T=−T−1(AsT+Bp1T)(1-16)
改进二:利用准循环特性
给定校验矩阵
H
\bm{H}
H之后,将它划分为
H
I
\bm{H_I}
HI与
H
P
\bm{H_P}
HP,子矩阵
H
I
\bm{H_I}
HI与编码后码字的信息位对应,子矩阵
H
P
\bm{H_P}
HP与编码后码字的校验位对应,并且具有下图所示的结构特征:
H
P
\bm{H_P}
HP的阶数为
M
z
×
M
z
{M_z\times M_z}
Mz×Mz,
P
i
{P^i}
Pi为 Z 阶的排列阵,通过对单位阵的每行进行i位的循环右
移得到,并且
P
i
=
P
i
y
=
P
i
M
z
−
1
{P^i = P^{iy} = P^{i_{M_z}-1}}
Pi=Piy=PiMz−1。子矩阵
H
I
\bm{H_I}
HI的结构如下所示:
矩阵
H
I
{H_I}
HI的维数为
M
z
×
K
z
{M_z\times K_z}
Mz×Kz,
K
z
=
N
z
−
M
z
{K_z = N_z-M_z}
Kz=Nz−Mz,其中
P
i
,
j
{P_{i,j}}
Pi,j为Z阶的单位矩阵经过循环移位后得到的循环阵。
假设发送端产生的信源矢量为
s
\bm{s}
s,编码后的码字矢量为
c
\bm{c}
c,
c
=
[
s
,
p
1
,
p
2
]
\bm{c = [s,p_1,p_2]}
c=[s,p1,p2],且
p
1
=
[
p
0
]
\bm{p_1 = [p_0]}
p1=[p0],
s
=
[
s
0
,
s
1
,
.
.
.
,
s
N
z
−
M
z
−
1
]
\bm{s = [s0,s1,...,s_{{N_z}-{M_z}-1}]}
s=[s0,s1,...,sNz−Mz−1],
s
i
、
p
i
\bm{s_i、p_i}
si、pi均为
1
×
Z
{1\times Z}
1×Z阶的向量,则有:
H
I
s
+
H
p
1
p
1
+
H
p
2
p
2
=
0
(1-17)
{H_Is+H_{p_1}p_1+H_{p_2}p_2} = 0 \tag{1-17}
HIs+Hp1p1+Hp2p2=0(1-17)
将矩阵
H
I
、
H
p
1
、
H
p
2
\bm{H_I、H_{p_1}、H_{p_2}}
HI、Hp1、Hp2带入上式,并将结果按行展开得到方程组如下:
对上述方程组进行
模二加
\color{red}模二加
模二加,有:
∑
j
=
0
M
z
−
1
∑
i
=
0
K
z
−
1
P
j
,
i
s
i
+
P
i
y
p
0
=
0
(1-18)
\sum_{j=0}^{M_z-1}\sum_{i=0}^{K_z-1}P_{j,i}s_i + P^{i_y}p_0 = 0 \tag{1-18}
j=0∑Mz−1i=0∑Kz−1Pj,isi+Piyp0=0(1-18)
所以有:
P
i
y
p
0
=
∑
j
=
0
M
z
−
1
∑
i
=
0
K
z
−
1
P
j
,
i
s
i
(1-19)
P^{i_y}p_0 = \sum_{j=0}^{M_z-1}\sum_{i=0}^{K_z-1}P_{j,i}s_i \tag{1-19}
Piyp0=j=0∑Mz−1i=0∑Kz−1Pj,isi(1-19)
查看该协议的基矩阵可知,
P
i
y
{P^{i_y}}
Piy是一个单位矩阵(即循环移位值为0),而单位阵乘以任何矩阵等于该矩阵本身,所以有
p
0
=
P
i
y
p
0
{p_0=P^{i_y}p_0}
p0=Piyp0。将得出的校验位
p
0
{p_0}
p0带入上图方程式中的第一个方程,可以求得校验位
p
1
{p_1}
p1,用相似的方式,带入剩下的方程可以逐次求出剩余的所有校验位,最终得到编码后的码字
c
=
[
s
,
p
1
,
p
2
]
\bm{c = [s,p_1,p_2]}
c=[s,p1,p2]。
代码实现:
(自己写的一般,具体实现上面公式都有,百度一下matlab里面的公式用法,应该不难,就不献丑了。这边给一份matlab自带的该协议编码函数实现)
%% ldpc rate
function P = ldpc_rate(Z,R)
% matrix prototype for codeword block length n = 1296 bits, subblock size is Z = 54 bits
P_54_12 = [
40 -1 -1 -1 22 -1 49 23 43 -1 -1 -1 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
50 1 -1 -1 48 35 -1 -1 13 -1 30 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1
39 50 -1 -1 4 -1 2 -1 -1 -1 -1 49 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1
33 -1 -1 38 37 -1 -1 4 1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1
45 -1 -1 -1 0 22 -1 -1 20 42 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1
51 -1 -1 48 35 -1 -1 -1 44 -1 18 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1
47 11 -1 -1 -1 17 -1 -1 51 -1 -1 -1 0 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1
5 -1 25 -1 6 -1 45 -1 13 40 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1
33 -1 -1 34 24 -1 -1 -1 23 -1 -1 46 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1
1 -1 27 -1 1 -1 -1 -1 38 -1 44 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1
-1 18 -1 -1 23 -1 -1 8 0 35 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0
49 -1 17 -1 30 -1 -1 -1 34 -1 -1 19 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
];
P_54_23 = [
39 31 22 43 -1 40 4 -1 11 -1 -1 50 -1 -1 -1 6 1 0 -1 -1 -1 -1 -1 -1
25 52 41 2 6 -1 14 -1 34 -1 -1 -1 24 -1 37 -1 -1 0 0 -1 -1 -1 -1 -1
43 31 29 0 21 -1 28 -1 -1 2 -1 -1 7 -1 17 -1 -1 -1 0 0 -1 -1 -1 -1
20 33 48 -1 4 13 -1 26 -1 -1 22 -1 -1 46 42 -1 -1 -1 -1 0 0 -1 -1 -1
45 7 18 51 12 25 -1 -1 -1 50 -1 -1 5 -1 -1 -1 0 -1 -1 -1 0 0 -1 -1
35 40 32 16 5 -1 -1 18 -1 -1 43 51 -1 35 -1 -1 -1 -1 -1 -1 -1 0 0 -1
9 24 13 22 28 -1 -1 37 -1 -1 25 -1 -1 52 -1 13 -1 -1 -1 -1 -1 -1 0 0
32 22 4 21 16 -1 -1 -1 27 28 -1 38 -1 -1 -1 8 1 -1 -1 -1 -1 -1 -1 0
];
P_54_34 = [
39 40 51 41 3 29 8 36 -1 14 -1 6 -1 33 -1 11 -1 4 1 0 -1 -1 -1 -1
48 21 47 9 48 35 51 -1 38 -1 28 -1 34 -1 50 -1 50 -1 -1 0 0 -1 -1 -1
30 39 28 42 50 39 5 17 -1 6 -1 18 -1 20 -1 15 -1 40 -1 -1 0 0 -1 -1
29 0 1 43 36 30 47 -1 49 -1 47 -1 3 -1 35 -1 34 -1 0 -1 -1 0 0 -1
1 32 11 23 10 44 12 7 -1 48 -1 4 -1 9 -1 17 -1 16 -1 -1 -1 -1 0 0
13 7 15 47 23 16 47 -1 43 -1 29 -1 52 -1 2 -1 53 -1 1 -1 -1 -1 -1 0
];
P_54_56 = [
48 29 37 52 2 16 6 14 53 31 34 5 18 42 53 31 45 -1 46 52 1 0 -1 -1
17 4 30 7 43 11 24 6 14 21 6 39 17 40 47 7 15 41 19 -1 -1 0 0 -1
7 2 51 31 46 23 16 11 53 40 10 7 46 53 33 35 -1 25 35 38 0 -1 0 0
19 48 41 1 10 7 36 47 5 29 52 52 31 10 26 6 3 2 -1 51 1 -1 -1 0
];
% matrix prototype for codeword block length n = 648 bits, subblock size is Z = 27 bits
P_27_12 = [
0 -1 -1 -1 0 0 -1 -1 0 -1 -1 0 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
22 0 -1 -1 17 -1 0 0 12 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1
6 -1 0 -1 10 -1 -1 -1 24 -1 0 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1
2 -1 -1 0 20 -1 -1 -1 25 0 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1
23 -1 -1 -1 3 -1 -1 -1 0 -1 9 11 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1
24 -1 23 1 17 -1 3 -1 10 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1
25 -1 -1 -1 8 -1 -1 -1 7 18 -1 -1 0 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1
13 24 -1 -1 0 -1 8 -1 6 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1
7 20 -1 16 22 10 -1 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1
11 -1 -1 -1 19 -1 -1 -1 13 -1 3 17 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1
25 -1 8 -1 23 18 -1 14 9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0
3 -1 -1 -1 16 -1 -1 2 25 5 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
];
P_27_23 = [
25 26 14 -1 20 -1 2 -1 4 -1 -1 8 -1 16 -1 18 1 0 -1 -1 -1 -1 -1 -1
10 9 15 11 -1 0 -1 1 -1 -1 18 -1 8 -1 10 -1 -1 0 0 -1 -1 -1 -1 -1
16 2 20 26 21 -1 6 -1 1 26 -1 7 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1
10 13 5 0 -1 3 -1 7 -1 -1 26 -1 -1 13 -1 16 -1 -1 -1 0 0 -1 -1 -1
23 14 24 -1 12 -1 19 -1 17 -1 -1 -1 20 -1 21 -1 0 -1 -1 -1 0 0 -1 -1
6 22 9 20 -1 25 -1 17 -1 8 -1 14 -1 18 -1 -1 -1 -1 -1 -1 -1 0 0 -1
14 23 21 11 20 -1 24 -1 18 -1 19 -1 -1 -1 -1 22 -1 -1 -1 -1 -1 -1 0 0
17 11 11 20 -1 21 -1 26 -1 3 -1 -1 18 -1 26 -1 1 -1 -1 -1 -1 -1 -1 0
];
P_27_34 = [
16 17 22 24 9 3 14 -1 4 2 7 -1 26 -1 2 -1 21 -1 1 0 -1 -1 -1 -1
25 12 12 3 3 26 6 21 -1 15 22 -1 15 -1 4 -1 -1 16 -1 0 0 -1 -1 -1
25 18 26 16 22 23 9 -1 0 -1 4 -1 4 -1 8 23 11 -1 -1 -1 0 0 -1 -1
9 7 0 1 17 -1 -1 7 3 -1 3 23 -1 16 -1 -1 21 -1 0 -1 -1 0 0 -1
24 5 26 7 1 -1 -1 15 24 15 -1 8 -1 13 -1 13 -1 11 -1 -1 -1 -1 0 0
2 2 19 14 24 1 15 19 -1 21 -1 2 -1 24 -1 3 -1 2 1 -1 -1 -1 -1 0
];
P_27_56 = [
17 13 8 21 9 3 18 12 10 0 4 15 19 2 5 10 26 19 13 13 1 0 -1 -1
3 12 11 14 11 25 5 18 0 9 2 26 26 10 24 7 14 20 4 2 -1 0 0 -1
22 16 4 3 10 21 12 5 21 14 19 5 -1 8 5 18 11 5 5 15 0 -1 0 0
7 7 14 14 4 16 16 24 24 10 1 7 15 6 10 26 8 18 21 14 1 -1 -1 0
];
% matrix prototype for codeword block length n = 1944 bits, subblock size is Z = 81 bits
P_81_12 = [
57 -1 -1 -1 50 -1 11 -1 50 -1 79 -1 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
3 -1 28 -1 0 -1 -1 -1 55 7 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1
30 -1 -1 -1 24 37 -1 -1 56 14 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1
62 53 -1 -1 53 -1 -1 3 35 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1 -1
40 -1 -1 20 66 -1 -1 22 28 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1 -1
0 -1 -1 -1 8 -1 42 -1 50 -1 -1 8 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1
69 79 79 -1 -1 -1 56 -1 52 -1 -1 -1 0 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1
65 -1 -1 -1 38 57 -1 -1 72 -1 27 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1
64 -1 -1 -1 14 52 -1 -1 30 -1 -1 32 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 -1
-1 45 -1 70 0 -1 -1 -1 77 9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1
2 56 -1 57 35 -1 -1 -1 -1 -1 12 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0
24 -1 61 -1 60 -1 -1 27 51 -1 -1 16 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
];
P_81_23 = [
61 75 4 63 56 -1 -1 -1 -1 -1 -1 8 -1 2 17 25 1 0 -1 -1 -1 -1 -1 -1
56 74 77 20 -1 -1 -1 64 24 4 67 -1 7 -1 -1 -1 -1 0 0 -1 -1 -1 -1 -1
28 21 68 10 7 14 65 -1 -1 -1 23 -1 -1 -1 75 -1 -1 -1 0 0 -1 -1 -1 -1
48 38 43 78 76 -1 -1 -1 -1 5 36 -1 15 72 -1 -1 -1 -1 -1 0 0 -1 -1 -1
40 2 53 25 -1 52 62 -1 20 -1 -1 44 -1 -1 -1 -1 0 -1 -1 -1 0 0 -1 -1
69 23 64 10 22 -1 21 -1 -1 -1 -1 -1 68 23 29 -1 -1 -1 -1 -1 -1 0 0 -1
12 0 68 20 55 61 -1 40 -1 -1 -1 52 -1 -1 -1 44 -1 -1 -1 -1 -1 -1 0 0
58 8 34 64 78 -1 -1 11 78 24 -1 -1 -1 -1 -1 28 1 -1 -1 -1 -1 -1 -1 0
];
P_81_34 = [
48 29 28 39 9 61 -1 -1 -1 63 45 80 -1 -1 -1 37 32 22 1 0 -1 -1 -1 -1
4 49 42 48 11 30 -1 -1 -1 49 17 41 37 15 -1 54 -1 -1 -1 0 0 -1 -1 -1
35 76 78 51 37 35 21 -1 17 64 -1 -1 -1 59 7 -1 -1 32 -1 -1 0 0 -1 -1
9 65 44 9 54 56 73 34 42 -1 -1 -1 35 -1 -1 -1 46 39 0 -1 -1 0 0 -1
3 62 7 80 68 26 -1 80 55 -1 36 -1 26 -1 9 -1 72 -1 -1 -1 -1 -1 0 0
26 75 33 21 69 59 3 38 -1 -1 -1 35 -1 62 36 26 -1 -1 1 -1 -1 -1 -1 0
];
P_81_56 = [
13 48 80 66 4 74 7 30 76 52 37 60 -1 49 73 31 74 73 23 -1 1 0 -1 -1
69 63 74 56 64 77 57 65 6 16 51 -1 64 -1 68 9 48 62 54 27 -1 0 0 -1
51 15 0 80 24 25 42 54 44 71 71 9 67 35 -1 58 -1 29 -1 53 0 -1 0 0
16 29 36 41 44 56 59 37 50 24 -1 65 4 65 52 -1 4 -1 73 52 1 -1 -1 0
];
P = zeros(12,24);
if Z == 54
switch R
case 1/2
P = P_54_12;
case 2/3
P = P_54_23;
case 3/4
P = P_54_34;
case 5/6
P = P_54_56;
end
elseif Z == 27
switch R
case 1/2
P = P_27_12;
case 2/3
P = P_27_23;
case 3/4
P = P_27_34;
case 5/6
P = P_27_56;
end
elseif Z == 81
switch R
case 1/2
P = P_81_12;
case 2/3
P = P_81_23;
case 3/4
P = P_81_34;
case 5/6
P = P_81_56;
end
else
P = zeros(12,24);
end
end
clear; clc; close all;
Z = 27;
R = 1/2;
P = ldpc_rate(Z,R);
pcmatrix = ldpcQuasiCyclicMatrix(Z,P);
cfgLDPCEnc = ldpcEncoderConfig(pcmatrix);
infoBits = randi([0 1], cfgLDPCEnc.NumInformationBits, 1);
encode1 = ldpcEncode(infoBits, cfgLDPCEnc);
mathworks官网链接:MathWorks,解决matlab中使用help帮助文档时反应缓慢问题。
参考文献:
- 刘睿. 802.11ac系统中的LDPC编译码研究与实现[D]. 重庆:重庆邮电大学,2012. DOI:10.7666/d.Y2399046.
- 李锐. WIFI系统中QC-LDPC编码算法研究与FPGA实现[D]. 四川:电子科技大学,2014. DOI:10.7666/d.D497762.
- T. J. Richardson and R. L. Urbanke, “Efficient encoding of low-density parity-check codes,” in IEEE Transactions on Information Theory, vol. 47, no. 2, pp. 638-656, Feb 2001, doi: 10.1109/18.910579.
译码器
ldpc的译码算法主要分成硬判决译码和软判决译码两类,硬判决算法BF(bit-fipping algorithm)实现是将输入译码器的数据进行硬判决,将得到的“0”、“1”序列带入所有的校验方程进行验证,找出使校验方程不成立数目最多的变量节点,将其对应的比特翻转。重复上述操作,直到最后所有校验方程得到满足,译出正确结果。虽然BF算法实现简单,但是性能一般,现在一般常用软判决译码算法BP(belief-propagation algorithm),似乎这个算法有时又叫和积译码算法(sum-product algorithm),有点迷。
软判决就必须说下tanner图了,对于迭代过程的展示形象且生动!
先来个链接:- KSY至上主义者.LDPC译码原理(公式推导)及其matlab代码实现(超详细)
我觉得博主写的挺好的,不过好像收费了
敲重点: \color{red}敲重点: 敲重点: 如果觉得译码看公式不好理解,有大佬已经做好动画版本了,点击这个链接即可:- Quasi-cyclic LDPC decoder
2023-8-30,暂时阶段总结下!有空再写