4发4收MIMO预编码:ZF与MMSE原理及MATLAB仿真对比
2026/9/12 16:26:41 网站建设 项目流程

简介:面向4发4收MIMO系统的ZF和MMSE预编码算法Matlab实现,主要解决多天线场景下干扰抑制与预编码矩阵设计问题,适合通信工程专业学生、课程设计者以及预编码技术入门研发人员。4发4收配置在系统复杂度与传输性能之间取得平衡,该仿真可为进一步理解大规模MIMO预编码奠定基础。压缩包内共4个文件,包含2个Matlab源码脚本、1篇MIMO信道预编码技术研究PDF和1份算法辅学文档,整体大小约2.94MB;代码经校正测试可百分百运行,且主算法与测试脚本分离,便于定位与调试。目前已有2349人学习浏览。读者可获得完整的ZF/MMSE预编码仿真框架,通过调整信噪比等参数直观对比两种预编码方案的误码率性能;PDF覆盖信道预编码原理与分类,docx提供Prim算法等扩展笔记,既能支撑理论理解,也可直接复用代码开展性能验证或毕业设计仿真实验。资源体量小巧、核心集中,无论用于课程实验还是工程预研,都能快速上手并顺利复现结果。

1. 4发4收MIMO下预编码,为什么先拿ZF和MMSE开刀

做MIMO系统仿真的人,第一次接触预编码大多是从ZF和MMSE这两个名字开始的。4发4收天线配置是单用户MIMO里最经典的对称拓扑,信道矩阵是4×4方阵,求逆、奇异值分解、功率归一化这些操作在MATLAB里都有一行命令能直接落地的形态,特别适合把预编码的算法逻辑和仿真链路剥离开来看。很多人一上手就去看MU-MIMO的块对角化、SLNR、脏纸编码,结果被用户间干扰和功率分配的细节淹没,反而连「预编码矩阵到底在乘什么位置、为什么要做归一化」都没真正建立起来。

ZF和MMSE代表了线性预编码的两条路线:一条是彻底消除干扰但放大噪声,另一条是在干扰和噪声之间做折中。4发4收场景下信道矩阵可逆,ZF的逆矩阵存在且数值稳定,MMSE的正则项也容易调到合理范围,两者的对比效应在误码率曲线上非常直观。这篇文章就把4发4收的ZF/MMSE预编码从原理、MATLAB实现到仿真验证完整走一遍,给出可以直接跑的源码结构、参数设法和坑点,让你在换到更大规模天线或MU-MIMO之前先把这个基础模型彻底吃透。新手能跟着把链路搭起来,老手也能在归一化方式和数值稳定性上看到一些容易忽略的细节。

2. ZF和MMSE预编码的数学基础与4发4收信道模型

2.1 系统模型:从发射符号到接收信号的矩阵表示

4发4收MIMO系统里,发射端有4根天线,接收端有4根天线。设发射符号向量为 s(4×1),预编码矩阵为 W(4×4),接收端测量到的信号向量为 y(4×1),信道矩阵为 H(4×4),那么接收信号可以写为:

y = H * W * s + n

其中 n 是4×1的加性高斯白噪声向量,每个元素独立同分布,服从均值为0、方差为σ²的正态分布。预编码的作用是让 H*W 在某种准则下逼近一个对角矩阵,这样接收端每个天线接收到的就主要是对应发射符号,而非多个符号的叠加。

在接收端,可以做一个简单的检测:对 y 左乘接收矩阵 G,得到对发射符号的估计 ŝ = G * y。但如果预编码做得好,G 往往可以取单位矩阵,或者只是每个符号的功率归一化因子。这也是预编码相对接收端均衡的一个关键区别:处理放到了发射端,接收端的复杂度被压低。

为方便后续推导,通常会假设信道是平坦衰落的,即在一个符号周期内信道不变。4发4收的 H 矩阵每个元素是复高斯随机变量,实部虚部独立同分布。仿真里每次信道实现都要重新随机生成 H,这就引出蒙特卡洛仿真的基本框架:跑很多次信道和噪声实现,统计误码率。

2.2 ZF预编码:伪逆与完全干扰消除

2.2.1 数学推导:为什么是伪逆而不是普通逆

ZF预编码的核心目标是让 H*W 等于单位矩阵(或单位矩阵的标量倍),这样接收端不需要任何额外处理就能直接解出符号。即需要满足:

H * W = I

因此 W = H⁻¹。在4发4收方阵信道下,H⁻¹存在,直接用MATLAB的 inv(H) 或 H^(-1) 就能求。但实际工程中几乎不用 inv,原因是两个方面:一是数值稳定性,inv 在矩阵接近奇异时误差很大;二是通用性,当发射天线数和接收天线数不等、H不是方阵时,inv 根本没有定义。

标准做法是取 H 的伪逆(Moore-Penrose伪逆)。因为此时 H 是方阵且满秩,伪逆退化为普通逆,但伪逆的求解过程(基于奇异值分解)数值上更稳定。公式为:

W_zf = H^H * (H * H^H)^(-1)

其中 H^H 是 H 的共轭转置。这个形式即使在发射天线数大于接收天线数时也能用,所以作为通用写法保留。在MATLAB里可以直接用 pinv(H),也可以按公式写 H'/(H*H')。

2.2.2 ZF的致命缺点:噪声放大

把 W_zf 代入接收信号公式,得到 y = H * H⁻¹ * s + n = s + n。看起来噪声项没有变化,但别忘了 W_zf 本身含有 H 的逆。如果 H 的某些奇异值很小,H⁻¹ 的对应奇异值就很大,预编码矩阵 W 的范数就会很大。发射端有功率约束时,必须对 W 做归一化,比如每列归一化或整体功率缩放,这个过程会把大范数的 W 缩放回去,等效于放大了噪声。

打个比方,H 的条件数越大,ZF预编码后的有效噪声约大。条件数是最大奇异值和最小奇异值的比值,在4发4收情況下,随机信道矩阵的条件数通常在2到20之间波动,遇到深衰落时可能更大,误码率平台就会出现。这也是ZF在低信噪比下明显不如MMSE的根本原因。

2.3 MMSE预编码:在干扰消除与噪声抑制之间取折中

2.3.1 带正则项的伪逆

MMSE的思想是允许 H*W 不等于单位矩阵,而是等于一个尽量接近单位矩阵的结果,同时把预编码矩阵的发射功率纳入优化目标。最常用的线性MMSE预编码形式是:

W_mmse = H^H * (H * H^H + α * I)^(-1)

其中 α 是正则化系数,最常见取 α = 1/SNR = N0 / P,N0是噪声功率谱密度,P是发射功率。这个形式在信道矩阵接近奇异时,αI 保证了 HH^H + αI 始终可逆,数值稳定性远好于纯ZF。从本质上看,MMSE预编码是在「让 HW 接近单位矩阵」和「让 W 的范数不要太大」两个目标之间做权衡,这个权衡通过 α 来控制。

2.3.2 正则项在不同SNR区间的行为

把 α 看成一个随SNR变化的参数,就能看出MMSE和ZF的联系。当SNR很高时,α = 1/SNR趋向于0,MMSE预编码退化为ZF预编码,此时干扰消除的需求压倒噪声抑制;当SNR很低时,α 很大,MMSE预编码趋向于 H^H/α,等效于匹配滤波预编码,以最大化接收信号强度为主,哪怕有少量干扰残留也可以接受。这个渐变关系在仿真曲线上体现为:高信噪比下MMSE和ZF重合,低信噪比下MMSE明显更好。

2.3.3 在4发4收场景下的实际效果

4发4收的4×4信道矩阵在随机生成时,求逆后的范数放大效应已经不可忽视。按经验,SNR在0到10 dB区间内,ZF的误码率可能比MMSE差一个数量级;超过20 dB后两者逐渐接近。原因很简单:α在低信噪比下扮演了阻尼角色,抑制了H⁻¹中小奇异值带来的放大效应。

3. MATLAB源码实现:从信道生成到核心函数

3.1 仿真主循环与系统参数配置

先看一个最简可跑的4发4收ZF/MMSE预编码仿真脚本。这段代码没有用通信工具箱的复杂对象,只用纯矩阵运算,方便看清每一步在做什么,也方便移植到别的版本。

%% 参数配置 clear; clc; Nt = 4; % 发射天线数 Nr = 4; % 接收天线数 M = 4; % QPSK调制阶数,每个符号2比特 numBits = 100000; % 每次SNR点发送的总比特数 numSymbols = numBits / log2(M); % 符号数 SNR_dB = 0:2:24; % 信噪比范围,单位dB % 预编码方式选择:'ZF' 或 'MMSE' mode = 'MMSE'; ber = zeros(size(SNR_dB)); % 误码率存储 % QPSK调制映射表:格雷编码,保证相邻符号只有1比特不同 symbolMap = [ 1+1i, -1+1i, -1-1i, 1-1i ] / sqrt(2); for idx = 1:length(SNR_dB) bitErrors = 0; totalBits = 0; for symIdx = 1:numSymbols / 4 % 每次处理4个符号,对应4根天线同时发射 % 随机生成4x1的发射比特向量(每符号2比特) bits = randi([0 1], Nt, log2(M)); % 比特映射为QPSK符号 symIdxVec = bi2de(bits, 'left-msb') + 1; s = symbolMap(symIdxVec).'; % 生成4x4复高斯信道矩阵 H = (randn(Nr, Nt) + 1i * randn(Nr, Nt)) / sqrt(2); % 噪声功率计算 noiseVar = 1 / (10^(SNR_dB(idx)/10)); % 根据模式计算预编码矩阵 if strcmpi(mode, 'ZF') W = H' / (H * H'); % ZF伪逆 else alpha = noiseVar; % 正则项 = 1/SNR W = H' / (H * H' + alpha * eye(Nt)); end % 功率归一化:保证预编码后平均发射功率为1 W = W / sqrt(trace(W * W') / Nt); % 发射信号 x = W * s; % 接收信号:加性高斯白噪声 n = sqrt(noiseVar/2) * (randn(Nr, 1) + 1i * randn(Nr, 1)); y = H * x + n; % 线性接收:直接对y做等增益合并,因为预编码已等效出信道 sHat = y; % 期望 H*W ≈ I,因此 y ≈ s + n % 符号判决 sHat = sign(real(sHat)) / sqrt(2) + 1i * sign(imag(sHat)) / sqrt(2); % 解码判决后的符号为比特 rxBits = zeros(Nt, log2(M)); for k = 1:Nt % QPSK四个星座点映射回比特 [~, idxMin] = min(abs(sHat(k) - symbolMap)); rxBits(k, :) = de2bi(idxMin - 1, log2(M), 'left-msb'); end % 统计误比特 bitErrors = bitErrors + sum(sum(bits ~= rxBits)); totalBits = totalBits + Nt * log2(M); end ber(idx) = bitErrors / totalBits; end % 绘图 figure; semilogy(SNR_dB, ber, 'bo-', 'LineWidth', 1.5); grid on; xlabel('SNR (dB)'); ylabel('BER'); title('4x4 MIMO ZF/MMSE Precoding BER');

这段代码的核心逻辑是每轮循环里发射4个QPSK符号(4根天线各一个),通过预编码矩阵变换后经过信道。接收端只做符号判决,不做均衡,因为预编码的设计目标就是让等效信道 H*W 接近单位矩阵。

需要注意功率归一化那行:W = W / sqrt(trace(W * W') / Nt);。trace(W * W') 是所有发射天线总功率,除以Nt得到平均每天线功率,开根号后作为归一化因子。如果不做这步,预编码矩阵的范数会直接影响实际SNR,不同信噪比下的对比就失去意义。

3.2 函数化封装:把ZF和MMSE提取为可复用函数

上面脚本把整个链路挤在一个循环里,对教学友好,对做对比实验不方便。建议把预编码计算封装成独立函数,后续换信道模型、换调制方式、换成MU-MIMO都能复用。

function W = zf_precoder(H) % ZF预编码矩阵计算 % 输入:H - Nr x Nt 信道矩阵 % 输出:W - Nt x Nr 预编码矩阵 W = H' / (H * H'); end function W = mmse_precoder(H, noiseVar) % MMSE预编码矩阵计算 % 输入:H - Nr x Nt 信道矩阵 % noiseVar - 噪声方差 % 输出:W - Nt x Nr 预编码矩阵 Nt = size(H, 2); W = H' / (H * H' + noiseVar * eye(Nt)); end function W = powerNormalize(W) % 功率归一化,保证每根发射天线平均功率为1 Nt = size(W, 1); W = W / sqrt(trace(W * W') / Nt); end

把预编码矩阵的生成和归一化解耦,主循环里只需要两行调用。注意MMSE函数里的 noiseVar 参数,在主脚本里怎么传是关键:

% 线性接收:对 y 左乘接收矩阵,得到符号估计 if strcmpi(mode, 'ZF') sHat = W' * y; % 由于 H*W ≈ I,这里 W' 相当于 W^H,实际是匹配滤波接收 else sHat = W' * y; end

这段本质上是把发射端的预编码矩阵共轭转置后当作接收滤波,虽然没有用到MMSE检测器的最优接收矩阵形式,但在预编码场景下已经足够。原因是预编码后的等效信道已经是近似单位阵,接收端用简单的匹配滤波不会带来明显性能损失,换来的是实现复杂度大幅降低。

另一点容易忽略的是噪声方差的单位。如果信号功率归一化为1,那么噪声方差就是 1/SNR(线性域)。如果发射信号星座点功率不是1,比如用QPSK但星座幅度是1而不是1/sqrt(2),噪声方差就要按实际信号功率折算,否则MMSE的正则项大小就错位了。

3.3 用矩阵运算替代循环的向量化实现

对小规模蒙特卡洛仿真,循环完全够用。但当 numSymbols 上到百万量级、SNR点增加到20个以上时,MATLAB的for循环会成为瓶颈。4发4收场景适合做一个中等程度的向量化,即一次处理多个信道实现。

% 向量化批量处理版本:每次生成 batchSize 个信道实现 batchSize = 1000; H_batch = (randn(Nr, Nt, batchSize) + 1i*randn(Nr, Nt, batchSize)) / sqrt(2); % 对每个信道计算ZF预编码,批量伪逆可用 pagemldivide(R2022a+) % 或者用循环 + 预分配,避免动态数组增长 W_batch = zeros(Nt, Nr, batchSize); for k = 1:batchSize W_batch(:,:,k) = H_batch(:,:,k)' / (H_batch(:,:,k) * H_batch(:,:,k)'); end

MATLAB从R2022a开始支持pagemldividepagectranspose等分页矩阵运算,可以直接批量求伪逆,但兼容性不如for循环。实际项目里我倾向于保持for循环但把内层符号生成改成矩阵批量生成,平衡可读性和速度。

3.4 核心参数对BER的影响

参数典型值对性能的影响调整建议
发射天线数Nt4决定空间复用增益,Nt越大频谱效率越高,但ZF求逆条件数风险上升固定为4,若要扩展优先观察条件数分布
接收天线数Nr4方阵时伪逆稳定,Nr>Nt时有分集增益对比1发4收与4发4收的BER差异
正则项alphanoiseVar太小则退化为ZF,噪声放大明显;太大则残留干扰固定为1/SNR后,再试0.5/SNR和2/SNR对比
调制阶数QPSK高阶调制对残留干扰更敏感,MMSE优势更明显换16QAM后观察误码平台
归一化方式总功率归一化影响发射功率定义,对比每天线归一化和最大特征值归一化用trace归一化做标准,另列两种对比

MMSE的alpha并不是越大越好。当alpha设置过大,H*W偏离单位矩阵较多,残留干扰成为主矛盾。仿真时可以在固定SNR=10dB条件下扫描alpha,取BER最低点,你会发现最优值通常在0.5/SNR到2/SNR之间,偏离这个区间性能快速恶化。

4. 仿真实验设计:MIMO信道容量与BER对比

4.1 信道容量随SNR的变化曲线怎么画

预编码的一个直接收益可以在信道容量上体现。对4发4收MIMO,遍历容量公式为:

C = log2(det(I + (P/Nt) * H * H^H))

其中 P 是发射总功率,Nt是发射天线数。注意 H 需要按归一化信道来计算,即信道系数的平均增益为1。

% 信道容量仿真 SNR_dB = 0:2:30; SNR_linear = 10.^(SNR_dB/10); Nt = 4; Nr = 4; numChannel = 5000; capacity_sum = zeros(size(SNR_dB)); for snrIdx = 1:length(SNR_dB) capTmp = zeros(numChannel, 1); for chIdx = 1:numChannel H = (randn(Nr, Nt) + 1i*randn(Nr, Nt)) / sqrt(2); % 发射总功率等分为Nt份 capTmp(chIdx) = log2(det(eye(Nr) + (SNR_linear(snrIdx)/Nt) * (H * H'))); end capacity_sum(snrIdx) = mean(capTmp); % 遍历容量均值 end figure; plot(SNR_dB, capacity_sum, 'r-', 'LineWidth', 1.5); grid on; xlabel('SNR (dB)'); ylabel('Ergodic Capacity (bits/s/Hz)'); title('4x4 MIMO Ergodic Capacity');

容量曲线的意义在于:它给出了预编码方案性能的理论上界。ZF/MMSE预编码的速率如果超过这个容量,仿真数据一定有问题;如果远低于容量,说明还有优化空间。这个交叉验证思维在调试仿真链时很有用。

注意容量公式里 SNR_linear/Nt 的写法。如果发射总功率固定为1,每根天线分到的功率是1/Nt,因此每个数据流实际SNR是 SNR_linear/Nt。把这个细节写错,容量结果会系统性偏高。

4.2 不同SNR下ZF与MMSE的误码率差异

在3.1节的代码基础上跑一次,把 mode 分别改为 'ZF' 和 'MMSE',保存BER结果后叠加在同一条曲线上:

% 主脚本中改成两个模式循环 modes = {'ZF', 'MMSE'}; berResults = zeros(2, length(SNR_dB)); colors = {'b-o', 'r-s'}; for mIdx = 1:2 mode = modes{mIdx}; % ... 内部仿真循环同上 ... berResults(mIdx, :) = ber; end figure; for mIdx = 1:2 semilogy(SNR_dB, berResults(mIdx, :), colors{mIdx}, 'LineWidth', 1.5); hold on; end grid on; legend('ZF', 'MMSE'); xlabel('SNR (dB)'); ylabel('BER'); title('ZF vs MMSE Precoding in 4x4 MIMO');

典型结果是:0到12 dB区间MMSE比ZF有明显优势,比如SNR=8dB时ZF的BER约在1e-2量级,MMSE可能在1e-3以下,差距接近一个数量级。随着SNR升高到20dB以上,两条曲线开始缠绕,因为alpha趋近于0,MMSE的解趋近于ZF。如果看到MMSE在高SNR时反而比ZF差,通常说明数值精度有问题,或者数据点太少导致统计波动。

4.3 蒙特卡洛仿真样本数怎么定才可信

误码率仿真的误差来自有限的信道和噪声实现。如果统计到100个错误比特时,相对标准偏差约为10%,要做到BER在1e-4处可信,至少需要1e6个符号。实际操作建议分两个阶段:

第一轮用少量符号(比如每SNR点1e4比特)快速判断曲线趋势和大致性能位置;第二轮在BER接近1e-3到1e-4区间的SNR点加跑,每点至少累计100个错误比特再停。MATLAB里可以用while循环控制,错误数不够就继续发:

targetErrors = 100; errorCount = 0; totalBits = 0; while errorCount < targetErrors && totalBits < 1e7 % 发送一批符号,统计errorCount和totalBits end

样本量过少最典型的表现是BER曲线在低误码率区间剧烈抖动,甚至出现 SNR升高但BER反而升高的假象。看到这种结果先别怀疑算法,先查样本数。此外信道在4发4收场景下每次重新生成,本身就带来方差,同样的SNR点重复跑两次BER结果可能差一倍以上,增加样本数或者把随机种子固定(rng(42))都可以减少这种困扰。

4.4 换成16QAM后,MMSE的优势窗口有变化

把调制阶数从QPSK换成16QAM后,星座点间的欧氏距离变小,相同SNR下误码率整体上移。此时MMSE的优势会变得更明显,原因是16QAM对噪声更敏感,ZZ的噪声放大效应在低SNR区域带来的惩罚被调制阶数放大。仿真时要注意两点:一是发射符号的功率归一化要和QPSK保持一致,二是判决函数要改成16QAM的最小距离判决,用qammodqamdemod会比手写星座映射更稳。

% 16QAM调制和解调 s = qammod(bits, 16, 'InputType', 'bit', 'UnitAveragePower', true); % 接收端 rxBits = qamdemod(y / (sqrt(mean(abs(y(:)).^2))), 16, 'OutputType', 'bit', 'UnitAveragePower', true);

这个切换能顺便验证预编码矩阵的归一化是否做对了:如果发射端的归一化把平均功率压到1,接收端就无需再做功率估计;否则接收端必须已知预编码增益才能正确判决,否则星座点整体偏移导致大面积错误。

5. 预编码矩阵的归一化陷阱与数值稳定性校验

5.1 三种归一化方式到底该选哪个

预编码矩阵算出来之后,直接乘到发射信号上会让平均发射功率偏离预设值。常见的归一化有三种:每根天线分别归一化、总功率归一化、按最大特征值归一化。

% 方式1:每根天线单独归一化(每列功率为1) W_colNorm = W ./ sqrt(sum(abs(W).^2, 1)); % 方式2:总功率归一化(所有天线总功率为Nt,平均每根为1) W_totalNorm = W / sqrt(trace(W * W') / Nt); % 方式3:按预编码矩阵的最大奇异值归一化 W_svNorm = W / max(svd(W));

三种方式的差别在于:每根天线归一化能确保发射端每个射频链路不超功率,适合有功率放大器饱和约束的真实系统,但会破坏预编码矩阵各列之间的相对幅度关系;总功率归一化保持了列间相对关系,但可能存在某一根天线瞬时功率过高;按最大奇异值归一化是最保守的,全系统功率利用率最低。在4发4收仿真里,建议默认用总功率归一化,因为仿真不关心射频链路饱和,只关心整体SNR关系。真实系统里再切到每天线归一化。

选择时还要留意接收端的自动增益控制假设。如果采用总功率归一化,接收端看到信号的平均功率相对稳定,配合固定的判决阈值就能工作。如果采用每列归一化,不同天线对应符号的信噪比不再一致,判决时需要按各列增益做补偿,复杂度上了一个台阶。

5.2 条件数恶化时,ZF误码率的异常平台

4发4收信道在强相关场景下(比如天线间距小或视距分量强),H的条件数可能超过100甚至几百。此时ZF的预编码矩阵中某些元素会异常大,归一化之后相当于其他天线被压低,有效分集度下降,BER曲线出现明显平台——增加SNR也不往下走。

排查方法:在仿真循环里加一行收集条件数分布,画出条件数的累积分布函数。

condNumber = zeros(numChannel, 1); for k = 1:numChannel Hk = H_batch(:,:,k); condNumber(k) = cond(Hk); end figure; histogram(condNumber, 50); xlabel('Condition Number'); ylabel('Count'); title('4x4 Channel Condition Number Distribution');

如果条件数超过100的样本比例超过5%,ZF性能会自动恶化到不可用,这是信道本身的问题而非算法实现的bug。此时要么改用MMSE(正则项天然压低条件数影响),要么对信道做去相关处理,比如在发射端加预编码前先做一次奇异值分解的功率分配。

5.3 数值稳定性检查:用恢复误差代替眼图观察

很多人在仿真里画出星座图来看预编码效果,这在低阶调制下可行,但恢复误差这个标量指标更适合量化对比。定义恢复误差为:

errorMetric = mean(abs(H * W - eye(Nr)).^2, 'all');

当errorMetric接近0,说明等效信道越接近单位阵,ZF效果越好。MMSE的errorMetric不会到0,因为它的目标不是严格单位阵。但MMSE对应的接收端误差更小——直接把接收信号sHat和原始s比较:

% 接收信号的信噪比指标 signalPower = mean(abs(s).^2); noisePlusInterf = mean(abs(sHat - s).^2); SINR_est = signalPower / noisePlusInterf;

这个SINR估计值和理论上 (SNR_dB + 预编码增益) 的关系可以互相校验。如果实测SINR比理论值低3dB以上,优先检查归一化那步有没有写错。

小技巧:在仿真的中间SNR点(比如10dB)把sHat的散点图叠加在理论星座点上,如果散点云呈圆形扩散,说明噪声主导;如果呈拉长形,说明有残余干扰。这个判断比单看BER值更快定位问题所在。

5.4 把仿真代码写成param结构体的可复用版本

最后一个实用技巧:把参数集中到一个结构体里,仿真函数只接受param入口参数。这样切换天线数、调制方式、SNR范围不需要改函数体,也为后面做多组对比实验打下结构基础。

param.Nt = 4; param.Nr = 4; param.modOrder = 4; % QPSK param.modType = 'qpsk'; param.numBits = 1e5; param.SNRdB = 0:2:24; param.mode = 'MMSE'; param.randomSeed = 42; rng(param.randomSeed); [ber, sinrEst] = runPrecodingSim(param);

runPrecodingSim内部用一个switch param.mode选择预编码函数。以后加一个THP预编码、加一个正则化ZF(alpha取非最优值),全部在param和函数内部扩展,不碰主脚本。到这一步,这套4发4收的ZF/MMSE预编码代码才能算是真正「可复用」,而不是只跑通一次的玩具脚本。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询