实在是受不了MATLAB改函数了
试图找到如何修改代码,诶嘿,失败了,那我就自己写一下吧
randint函数
%% P pre-MMSE
clear all;clc
% 参数设置
N_frame = 100; %帧数
N_packet = 1000; % 分组数
b = 2; % 每符号比特数
M = 2 ^ b; % 调制阶数
mod_obj = modem.qammod('M',M,'SymbolOrder','Gray','InputType','bit');
demod_obj = modem.qamdemod(mod_obj);
Nt = 4;
Nr = 4;
sq2 = sqrt(2);
N_pbits = N_frame * Nt * b;
N_tbits = N_pbits * N_packet;
fprintf('=======================================\n');
fprintf('Pre-MMSE transmission');
fprintf('\n %d x %d MIMO \n %d QAM',Nt , Nr , M);
fprintf('\n Simulation bits: %d',N_tbits);
fprintf('=======================================\n');
SNRdBs = [0:2:20];
for i_SNR = 1 : length(SNRdBs)
SNRdB = SNRdBs(i_SNR);
noise_var = Nt * 0.5 * 10^(-SNRdB / 10);
sigma = sqrt(noise_var);
rand('seed',1);
randn('seed',1);
N_ebits = 0;
%%%%%%%%%%发射机%%%%%%%%%%%
for i_packet = 1 : N_packet
msg_bit = randint(N_pbits , 1); % 比特生成
symbol = modulate(mod_obj,M); % QAM调制
Scale = modnorm(symbol , 'avpow' , 1); % 归一化
Symbol_nomalized = reshape(Scale * symbol, Nt, N_frame); % 重构数组
……
……
end
end
……
……
这是书《MIMO-OFDM无线通信技术及MATLAB实现》P336页MMSE预均衡的代码的一部分,我的MATLAB版本是2023,理所当然的,randint函数和modem.qammod,modem.qamdemod都运行不了,需要修改
那么首先了解一下randint函数
f = randint(n,m);
这个函数表示产生一个元素为0或者1的n*m的随机矩阵
f = randint(n,m,[a,b])
这个函数表示产生一个元素在区间[a,b]之间的n*m的随机矩阵
在新版本中的MATLAB中,函数randint显示已经被删除了,需要修改成randi,但是并不能直接将函数修改成randi就可以了,这两者并不等价,在MATLAB中,randi函数式用于生成随机整数的,以第一个randint函数为例,如果将函数f = randint(n,m)直接修改成f = randi(n,m),那么此时f就不再是一个元素为0或者1的n*m的随机矩阵,而会变成一个m*m的矩阵,矩阵中的元素为[1,n] 的均匀离散分布得到的伪随机整数。从下图中可以发现,如果直接把代码中的randint函数改成randi函数,那么只会得到一个伪随机的整数,而不会得到我们想要的矩阵
经过研究,我发现可以利用round函数配合rand函数使用
如果将randint函数直接修改成rand函数,虽然可以得到我们想要的N_pbits*1矩阵,但是矩阵中的元素是0到1之间均匀分布的随机数,并不能得到我们想要的非0即1的元素。
不过搭配上round函数就可以很好的弥补这一点。round函数式一个四舍五入的函数,round(X)可以将X的每个元素四舍五入至最近的整数,由于rand输出的数在0到1之间,因此round四舍五入之后的结果只可能是0和1,这就很好地达到了我们想要的结果。
modem.qammod函数
randint函数的修改实际上还是蛮简单的,我记得其他地方也有讲解,比较麻烦的是QAM调制解调的函数,不过我还是改出来了
我们先看一下modem.qammod函数和qammod函数之间的相似性,首先,二者都需要有M这个元素,M表示调制阶数,指定为2的正整数幂,指定的是信号中的点数星座,SymbolOrder表示符号顺序,Gray表示使用格雷编码排序,InputType表示输入类型,bit表示指定输入信号必须包含二进制。
上述信息是非常重要的,这关乎着在修改函数之后代码是否能运行。
在老版MATLAB中,modem.qammod函数通常是配合着modulate使用的,modulate表示着通信仿真的调制,但是新版的就不再需要了,我修改好可以运行的代码如下所示
% Y = Q^THPx + N Q是接收预编码,H是信道,P是发送预编码
%% P pre-MMSE
clear all;clc
% 参数设置
N_frame = 100; %帧数
N_packet = 1000; % 分组数
b = 2; % 每符号比特数
M = 2 ^ b; % 调制阶数
Nt = 4;
Nr = 4;
sq2 = sqrt(2);
N_pbits = N_frame * Nt * b;
N_tbits = N_pbits * N_packet;
fprintf('=======================================\n');
fprintf('Pre-MMSE transmission');
fprintf('\n %d x %d MIMO \n %d QAM',Nt , Nr , M);
fprintf('\n Simulation bits: %d',N_tbits);
fprintf('=======================================\n');
SNRdBs = [0:2:20];
for i_SNR = 1 : length(SNRdBs)
SNRdB = SNRdBs(i_SNR);
noise_var = Nt * 0.5 * 10^(-SNRdB / 10);
sigma = sqrt(noise_var);
rand('seed',1);
randn('seed',1);
N_ebits = 0;
%%%%%%%%%%发射机%%%%%%%%%%%
for i_packet = 1 : N_packet
msg_bit = round(rand(N_pbits , 1)); % 比特生成
symbol = qammod(msg_bit , M , 'gray' , 'InputType' , 'bit'); % QAM调制
Scale = modnorm(symbol , 'avpow' , 1); % 归一化
Symbol_nomalized = reshape(Scale * symbol, Nt, N_frame); % 重构数组
……
……
end
end
……
……
首先是删除源代码中已经被删除用不了的两个函数,其次是将通信仿真调制函数直接修改成qammod函数,后面的调制格式一定要跟,就上面一段函数来说,如果缺少了bit这一限制条件,那么下面的reshape函数就会报错,因为symbol输出的时候就不是用二进制调制出来的400*1的矩阵,而是800*1的矩阵。