信道编码:MATLAB使用卷积编译码函数

信道编码:MATLAB 使用Conv函数

1. 相关函数

在进行卷积编码的过程中,使用的函数是convenc()函数和vitdec()函数,同时需要poly2trellis()函数。

1.1 poly2trellis()函数

先看poly2trellis()函数,用来生成卷积编码所需要的网表。

trellis = poly2trellis(ConstraintLength,CodeGenerator)

这个函数相当于定义了编码器中寄存器的结构,一般来说,在查看卷积编码的相关资料中都是类似于(2,1,3)这种结构,但是这这个函数只需要两个参数:

  • ConstraintLength参数代表约束长度
  • CodeGenerator 代码生成器,指定为八进制数的KN矩阵、多项式字符向量的KN单元阵列或KN字符串阵列。CodeGenerator为编码器的K个输入比特流中的每一个指定N个输出连接。

通俗理解这两个参数的含义和作用,首先约束长度决定了再译码时候的回溯深度的大小,根据不同的编码速率有不同的关系,技术文档中对此有介绍:

计算回溯深度

根据设定的n,k,和L值来确定,如对于(2,1,3)结构类型的卷积编码器,其中rate = k/n = 1/2,对应第一种计算方式,那么回溯深度为5*(L-1),结果为10,在进行译码的时候利用这个值对齐或者截断,这个在下面使用过程中会有。

回到函数本身,如设计(2,1,7)类型的编码器,可以用:

L = 7;
trellis = poly2trellis(L,[171 133]);

其中的第二个参数是8进制数据的表现形式,对应二进制为[111_1111, 101_1011]。可以理解为进入1bit数据,输出2bit数据,所以这个是2维的,同时这个7bit每一位代表寄存器的抽头,可以根据这个画出编码器的连接形式。

有了这些概念就可以使用这个函数了。

1.2 convenc()函数

再看convenc()函数

codedout = convenc(msg,trellis)
codedout = convenc(msg,trellis,puncpat)

简单使用卷积编码就用这个第1种调用方式就可以了,其中

  • msg参数是需要编码的信息,这个需要输入0,1二进制数据。
  • trellis参数就是上面函数生成的结果,传输到这里。

在使用时,需要注意的是 msg数据的长度要是k的整数倍,同时利用上面的约束长度,计算回溯深度,利用回溯深度在信息后面添加0

1.3 vitdec()函数

最后看译码函数。

decodedout = vitdec(codedin,trellis,tbdepth,opmode,dectype)
decodedout = vitdec(codedin,trellis,tbdepth,opmode,'soft',nsdec)
decodedout = vitdec(codedin,trellis,tbdepth,opmode,dectype,puncpat)

译码函数的参数相对校多,主要是需要设置模式:

  • codedin参数是需要译码的结果,模式选择硬判决的时候必须输入是整数,模式选择软判决的时候可以输入小数。
  • trellis参数也编码函数的一致。
  • tbdepth这个参数参数就是回溯深度,前面利用约束长度计算的结果。
  • opmode 这个参数有三个不同的选项,分别为cont,termtrunc
  • dectype参数用来设置是硬解码hard还是软解码soft,硬解码输入的数据都是01,软解码可以说输入小数。

有一点需要注意的是,对于termtrunk模式,回溯深度tbdepth必须是一个正整数,并且小于或等于输入编码中的输入符号数,说白了就是在编码前的信息msg长度就得大于等于回溯深度,要不然不够译码的。

这三个参数的差别,term模式下没有延时,就是译码的第一个数据就是编码的第一个数据。trunc参数也没有延时,cont参数有延时,是回溯深度。还有差别就是连续编码的区别。

下面用程序看具体的区别。

2.使用方法

利用(2,1,7)结构的形式进行卷积编译码,如下是测试代码,首先选择conthard模式。

close all;
clear;
clc;

msg_source = [randi([0 1],1,50),zeros([1,30])];  % 一共10e4个点 
n = 2;
k = 1;
rate = k/n; % rate为 1/2
L = 7;
tblen = 5*(L-1); % 回溯深度
trellis = poly2trellis(L,[171 133]);

code_data = convenc(msg_source,trellis);

d = vitdec(code_data,trellis,tblen,'cont','hard');

figure(1);
stairs(msg_source(1:end-30),':*r');
hold on;
stairs(d(31:end),':+b');
ylim([-0.1,1.1]);
grid on;
legend('原始信息','恢复信息');

得到的实验结果为:
卷积编码前后信息对比

当译码函数在使用term模式的时候

close all;
clear;
clc;
msg_source = [randi([0 1],1,50),zeros([1,30])];  % 一共10e4个点 
% msg_source2 = [randi([0 1],1,50),zeros([1,30])];  % 一共10e4个点
n = 2;
k = 1;
rate = k/n; % rate为 1/2
L = 7;
tblen = 5*(L-1); % 回溯深度
trellis = poly2trellis(L,[171 133]);

code_data = convenc(msg_source,trellis);

d = vitdec(code_data,trellis,tblen,'term','hard');

figure(1);
stairs(msg_source(1:end),':*r');
hold on;
stairs(d(1:end),':+b');
ylim([-0.1,1.1]);
grid on;
legend('原始信息','恢复信息');

此时的到的结果为:

卷积编码前后信息对比

从上图中可以看出来,译码之后的信息直接从第一位开始,不需要利用回溯深度来截断之后对比数据,但是这种模式适用的情况是需要编码的信息后面存在足够的多的0数据才可以,当把上一段的代码中的原始数据msg_source后面的30个0,改为20个1时

msg_source = [randi([0 1],1,50),ones([1,30])];

得到的试验结果为:

卷积编码前后信息对比

可以发现虽然译码的结果可以从与原始数据从第1位对齐,但是最后的数据会出现错误。

在测试连续编码的情况:对两段信息分别编码,然后把编码后的信息拼接在一起进行解码,采用的模式为trunchard,程序代码如下:

close all;
clear;
clc;

msg_source1 = [randi([0 1],1,50)];  % 一共10e4个点 
msg_source2 = [randi([0 1],1,50),zeros([1,30])];  % 一共10e4个点 
msg_source = [msg_source1,msg_source2];
n = 2;
k = 1;
rate = k/n; % rate为 1/2
L = 7;
tblen = 5*(L-1); % 回溯深度
trellis = poly2trellis(L,[171 133]);

code_data1 = convenc(msg_source1,trellis);
code_data2 = convenc(msg_source2,trellis);

code_data = [code_data1, code_data2];

d = vitdec(code_data,trellis,tblen,'trunc','hard');

figure(1);
stairs(msg_source(1:end),':*r');
hold on;
stairs(d(1:end),':+b');
ylim([-0.1,1.1]);
grid on;
legend('原始信息','恢复信息');

得到的结果为:

连续编码再进行译码

从结果中可以看出来译码是存在错误的。

可以对上面的msg_source1进行更改,改为

msg_source1 = [randi([0 1],1,50),zeros([1,30])];

在后面添加回溯深度个0,再次运行,可以得到结果

连续编码再进行译码"

可以得到正确的结果,总结起来方便操作就是在信息的末尾添加回溯深度个0

  • 7
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
码是一种常用的信道编码技术,可以在数据传输过程中提高数据的可靠性。以下是利用Matlab实现卷信道编码的基本步骤: 1. 生成卷码的生成多项式。生成多项式是卷码的核心,它决定了编码器的结构和编码性能。可以根据需要选择不同的生成多项式。 2. 构建卷编码器。卷编码器可以使用矩阵乘法实现,也可以使用状态转移图实现。在Matlab中,可以使用comm.ConvolutionalEncoder对象实现卷编码器。 3. 对待编码数据进行编码。通过将待编码数据输入卷编码器,即可得到卷编码后的数据。 下面是一个简单的Matlab代码示例,演示如何实现卷信道编码: ```matlab % 生成卷码的生成多项式 g1 = [1 0 1]; % 第一个分量的生成多项式 g2 = [1 1 1]; % 第二个分量的生成多项式 trellis = poly2trellis(3, [2 1 3 2]); % 生成卷码的状态转移图 % 构建卷编码器 encoder = comm.ConvolutionalEncoder(trellis, [g1; g2]); % 待编码数据 data = [1 0 1 1 0 0 1 0 1 1]; % 进行编码 codedData = step(encoder, data); disp('原始数据:'); disp(data); disp('编码后的数据:'); disp(codedData); ``` 以上代码中,我们首先使用poly2trellis函数生成了一个卷码的状态转移图,然后使用comm.ConvolutionalEncoder对象构建了一个卷编码器。接着,我们生成了一个待编码的数据序列,将其输入到编码器中,即可得到编码后的数据。最后,我们输出了原始数据和编码后的数据。 需要注意的是,以上代码仅演示了如何进行卷编码,实际应用中还需要考虑信道译码、误码率等问题。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一支绝命钩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值