您的位置:首页 > 编程语言 > MATLAB

[Matlab]如何随机产生信息码元矩阵u

2013-03-13 15:45 633 查看
因为毕设仿真的需要,今天遇到了这个问题。将自己遭遇到的困难和解决的办法记录下来。

首先描述一下我需要解决的问题。

对于线性分组码,其全部码字的产生都是通过生成矩阵G矩阵得到,而c=u*G,故而如果需要产生全部的c,则需要全部的u。从初步思考来看只需将u矩阵进行穷举即可,但是对于(n,k)码中较大的k时——意味着有2^k个码字,这么做既不方便,也失去的仿真的意义。所以需要换一种思路产生u矩阵。

一开始我也没觉得这个是个问题,因为现在的计算机CPU的主频已经达到如此高的频率,仿真个这些代码应该不在话下,毕竟从算法分析上来讲只是O(n)的复杂度,但是我错误估计了形势——面对(512,256)的LDPC码的时候我瞬间明白自己摊上事儿了,摊上大事儿了——这个在我有生之年是不太可能跑出来u矩阵的,更不说和G矩阵相乘产生c码字了,当然LDPC码产生G是另一个麻烦的问题,但是这里在第一步就没办法进行了下去。因为2^256≈1.16*10^77,也就是说我的笔记本一刻不停地跑,也至少需要1.53*10^60年才能完成这个巨大的任务——那个时候或许宇宙都不存在了吧...

通过和师兄等交流后我才恍然明白这一类仿真只需要仿真一定数量点即可,并不需要全部的码字——一般选取的N=10000。于是目前面临的问题就变成了如何在2^k个码字中选取出互不重复的N个码字出来。

师兄给了一个比较简单的代码来解决这个问题:

u = (rand(1,576)>0.5)


再在外面套一层N圈的循环即可实现。

但是仔细一想,这个跟我的初衷有一定违背,毕竟这个有可能产生相同的u,因为不能保证在N次循环内产生的u矩阵不重复。为了算法的严谨和数据的准确,只能想其他的办法。

我想到的思路是:先生成0~2^k-1的十进制数,然后转为二进制数,取出每一位,再添上不足矩阵长度的零。

这里面有两个问题需要解决的是:生成不重复的十进制随机数、取出对应位并补足。后面的那个问题比较好解决,通过矩阵运算即可。稍微复杂一点儿的是前面的不重复检验。Matlab提供了randperm函数用于产生从1到n的随机排序,但是对于2^256这种巨型的数字,已经超出了randperm函数的适用范围。也就是否定了要把所有数字产生后再进行排序选取的思路,只能采用先产生随机数字然后进行是否重复的检验——由于我们需要的N是一个比较小的数字(相对于2^256这种巨型数字而言),是在计算机可以运算出结果的范围内,而且这种开销远比生成大矩阵来的少,所以算法可行。

下面直接贴代码:

while 1
u_origin=unidrnd(2^k-1,N,1);
if length(unique(u_origin))==N
break;
end
end
对于较小的k,采用randperm函数的方法亦可,甚至有可能更快,下面是极其简洁的源代码:

a = randperm(2^k-1);
b = a(1:N);


实质上,如果为了从这两者中取得最好的选择,可以将这两种方法封装成同一个函数,根据2^k的大小来选择哪一种方法生成随机数序列。

if k>=20
while 1 u_origin=unidrnd(2^k-1,N,1); if length(unique(u_origin))==N break; end end
else
temp=randperm(2^k-1);
u_origin=temp(1:N)';
end

至此,问题基本解决。但是回过头来看会觉得这个方法琐碎而且繁杂,于是回到最开始师兄给出的程序代码,其实只要用unique函数加上一个判定条件,也能实现这个功能,代码会十分简洁:

while 1
u_final=(rand(N,k)>0.5);
if length(unique(u_final,'rows'))==N
break;
end
end
经过实际测试,两种方法的速度却并不相同,在大部分情况下,第一种方法速度更快,不过从思路上讲,第二种显然更为简洁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Matlab 矩阵 算法