资讯详情

资讯详情

毫米波大规模MIMO混合波束成形仿真:最小相差算法与Matlab实现

如果你做过毫米波大规模MIMO的链路级仿真一定对“混合波束成形”四个字又爱又恨。爱的是它能让频谱效率逼近全数字方案恨的是模拟域的恒模约束——移相器只能改变相位不能改变幅度——让预编码设计从单纯的线性代数问题变成了带约束的优化问题。我最近整理了一套多用户毫米波大规模MIMO系统混合波束成形Matlab仿真核心思路是“最小相差”让混合预编码矩阵与理想全数字预编码矩阵之间的距离最小化。整套代码跑通之后频谱效率和误差收敛曲线都能稳定复现这篇就把背后的原理、交替迭代实现、Matlab代码结构以及几个容易翻车的细节一次聊透。1. 为什么非要用混合波束成形成本、功耗与恒模约束1.1 全数字架构在毫米波频段的尴尬大规模MIMO的理论基础很漂亮天线数量翻倍阵列增益和空间自由度跟着涨频谱效率能线性提升。但落到毫米波频段问题就来了——波长只有毫米级天线间距小塞几十上百根天线不难难的是每一根天线后面都得跟着一条完整的射频链路包含DAC、混频器、功放、滤波器。这套全数字架构在30GHz以上频段的功耗和成本放到工程项目里根本压不住。我最早仿真的版本就是全数字预编码把所有天线都接在独立射频链上配置128根天线、8个用户基站侧射频链也设成128条。跑出来的性能曲线确实漂亮但功耗表和硬件成本表一摆出来谁都知道这不现实。所以业界才退一步用少量射频链支撑大量天线射频链数量降到8甚至4其余天线通过移相器网络连接这就是混合波束成形的出发点。1.2 混合架构的基本分工混合架构里模拟域和数字域的分工很明确。数字预编码器在基带处理负责调整每个数据流在射频链之间的幅度和相位主要用来消除多用户之间的干扰模拟预编码器由一组移相器组成只改变相位不改变幅度每条射频链通过移相器网络连到所有天线上负责把波束指向目标用户的方向。这种分工直接带出一个约束模拟预编码矩阵FRF的每个元素幅度必须是1也就是恒模约束。恒模约束看着简单实际上把设计问题变得很棘手。直接用SVD分解取前几个奇异向量得到的结果大概率不满足恒模条件硬把幅度归一化掉又会损失性能。所以混合预编码从来不是单纯求一个最优解而是在一系列工程约束下找到尽量逼近理想解的办法。这套代码里所有迭代操作本质上都在跟这个约束较劲。1.3 “最小相差”到底在说什么这套代码标题里提到的“最小相差”我第一次看到时也琢磨了一下后来把它明确实现成一种优化准则设计混合预编码矩阵FRF和FBB让两者的乘积尽可能接近某个理想预编码矩阵Fopt。用数学语言写就是|| Fopt - FRF·FBB ||_F² → min约束是FRF每个元素都落在恒模集合里。Fopt一般取全数字无约束方案下的最优解比如对等效信道做奇异值分解后取对应主奇异值的右奇异向量方向。这个准则的物理含义很直观既然全数字方案性能最好但硬件做不到那就退一步让硬件能做到的混合方案与理想方案之间的“差距”最小。这个差距在信号空间里体现为波束方向的偏差和功率分配的偏差所以叫最小相差本质上是最小误差逼近。这种思路的好处是不再需要针对每个信道做复杂闭式推导只要反复用交替最小化逼近Fopt就能拿到一组性能良好的FRF和FBB。后面要做的所有事情都围绕这个目标函数展开。2. 系统模型与信道生成先把仿真地基打牢2.1 基站、用户与射频链参数我这次搭建的系统配置如下基站侧用均匀线阵天线数Nt128射频链数量NRF8同时服务K4个单天线用户每个用户配一根接收天线。数据流数NsK4也就是说每个用户分配一路独立数据流。射频链数量满足工程常见条件NRF≥Ns这里8条射频链留出了一定冗余。载频取28GHz系统带宽20MHz。为了先把核心算法跑通我用了窄带信道建模不做OFDM子载波扩展。这种单载波假设在毫米波场景里偏理想但作为算法验证完全够用很多论文的第一步也是这么做的。参数层面有几个点需要提前说清楚第一移相器精度会影响模拟预编码的码本设计源码里默认用均匀量化移相器位数取4比特也就是每个移相器有16个可选相位第二信噪比范围取-10dB到20dB每隔2dB采一个点多用户场景下这个范围能看到从噪声主导到干扰主导的完整变化。2.2 毫米波信道的稀疏多径模型毫米波信道和传统低频信道最大的区别是稀疏性。28GHz频段有效散射体数量少信道能量集中在少数几条路径上。我这里用的是常用的S-V集群信道模型每个用户包含Ncl4个散射簇每个簇Nray8条射线总共L32条路径。每条路径都有自己的离开角和到达角由于基站侧是均匀线阵只需要考虑离开角一个维度的正弦值。信道矩阵的生成逻辑是每个用户对应的信道行向量等于所有路径增益乘以阵列响应向量的加权和。阵列响应向量对第l条路径离开角θ_l可以写成a(θ_l) [1, e^{j·2π·d·sin(θ_l)/λ}, ..., e^{j·2π·(Nt-1)·d·sin(θ_l)/λ}]^T其中d是天线间距取半波长λ是载波波长。角度在[-60°, 60°]内服从拉普拉斯分布路径增益服从复高斯分布簇间功率按指数衰减。这套模型跑出来的信道矩阵通常只有少数几个较大的奇异值低秩特性非常明显恰好是混合波束成形能发挥优势的场景。2.3 优化目标在程序里的落地“最小相差”准则落到程序里就是写一个目标函数然后交替优化FRF和FBB。具体实现时第一步先计算全数字基准Fopt。这里Fopt的选择有讲究如果直接对信道矩阵H做SVD取V的前Ns列得到的是无约束下最大化频谱效率的方向但这样得到的Fopt会包含许多幅度很小的分量混合方案很难逼近。我沿用了文献里的常规做法对信道矩阵H做SVD取前Ns个右奇异向量作为Fopt。然后交替执行两步固定FRF时更新FBB固定FBB时更新FRF。每一步都让差值范数单调不增迭代十来次就能收敛到稳定值。3. 交替最小化模拟域和数字域轮流修正3.1 固定数字域模拟预编码怎么求模拟预编码矩阵FRF的每个元素必须满足恒模条件这是整个设计里最硬的一条约束。固定FBB之后问题变成一个带恒模约束的最小二乘问题。最简单的解法是相位提取直接取Fopt的相位作为FRF的相位幅度强制归一化。这个方法复杂度低但坏处是在多用户场景下会残余比较明显的用户间干扰。我实际测试下来直接相位提取在4用户、SNR大于5dB时频谱效率比理想全数字方案低2~3dB不算差但还有提升空间。于是我在代码里多走了一步先做相位提取再用码本搜索把所有候选移相器组合过一遍选出差值范数最小的一组。码本大小取决于移相器位数4比特就是16个候选相位128×8的FRF矩阵如果做全局搜索复杂度会爆炸所以实际的搜索方法是逐列替换每次固定其他列对当前列的每个候选相位计算目标函数选最小的更新进去扫完所有列算一轮迭代几轮。这个方法在工程上叫坐标下降法相当于把全局搜索拆成多次局部搜索每次只动一列复杂度从指数级降到线性级性能损失很小。我试过把候选相位从16提高到64频谱效率只提升了不到0.3dB算法运行时间却翻了4倍性价比很低所以4比特足够。3.2 固定模拟域数字预编码怎么求FRF定下来之后FBB的问题就友好很多了。此时等效信道是Heq H·FRF维度是K×NRF而FBB是NRF×Ns。如果目标是追着Fopt跑直接用最小二乘解FBB (FRF^H·H^H·H·FRF)^(-1)·FRF^H·H^H·Fopt这个解能最小化||Fopt - FRF·FBB||_F²但它是普通最小二乘没有考虑用户间干扰的结构。我在多用户场景里更倾向于加一步线性迫零把等效信道Heq直接求伪逆再把结果映射到Fopt对应的行空间上这样既保证混合预编码尽量接近Fopt又能把多用户干扰压到很低。需要注意FBB解出来之后要配合模拟预编码做功率规范化。发送端总功率固定我习惯让||FRF·FBB||_F²等于Ns。这个规范化看起来简单但放的位置不对所有性能曲线都会整体偏移后面专门讲这个坑。3.3 迭代流程与收敛判据整个交替最小化循环结构很清晰初始化FRF为单位恒模矩阵FBB先给一个合法解循环里先更新FRF再更新FBB计算当前差值范数error如果error相对上一次的变化小于阈值或者迭代次数到达上限就跳出。我在代码里设阈值1e-4上限15次实测8到12次就能收敛。有一点值得提醒交替最小化只能保证迭代过程中目标函数单调下降不能保证全局最优。好消息是毫米波信道低秩初始点选得不算离谱的情况下最终结果和全数字方案的差距基本能维持在1dB以内。如果你想要更稳妥可以把初始化重复几次取差值范数最小的一次作为最终结果。我测试下来重复3次初始化能再榨出0.2dB左右的性能。4. Matlab代码结构与关键实现4.1 文件划分与主脚本流程这套仿真我把代码拆成几个模块避免一个上千行的脚本让人看晕。首先是参数配置文件集中设置天线数、射频链数、用户数、信噪比范围和移相器位数然后是信道生成函数输入用户数量和路径参数输出信道矩阵H和阵列响应再是核心预编码函数输入H、FRF初值、Fopt和迭代参数输出优化后的FRF和FBB最后是主脚本负责循环不同SNR做蒙特卡洛仿真收集频谱效率和误差范数并输出对比图。主脚本的流程骨架如下% 主仿真脚本骨架 clear; clc; config loadConfig(); % 加载参数 rng(2025); snr_list -10:2:20; se_hybrid zeros(size(snr_list)); error_norm zeros(size(snr_list)); for s 1:length(snr_list) for monte 1:config.numMonte H generateChannel(config); Fopt computeFopt(H, config); [FRF, FBB, err] hybridBeamforming(H, Fopt, config); se computeSpectralEfficiency(H, FRF, FBB, config, snr_list(s)); se_hybrid(s) se_hybrid(s) se; error_norm(s) error_norm(s) err; end se_hybrid(s) se_hybrid(s) / config.numMonte; end蒙特卡洛次数我取100次。这个次数在算法验证阶段够用曲线已经比较平滑再多跑收益有限。4.2 信道生成与阵列响应信道生成函数的实现要点是把S-V模型的累加过程写清楚。每个用户的行向量等于所有路径增益与阵列响应向量相乘后求和。路径增益里包含路径损耗和衰落幅度服从瑞利分布相位均匀分布。离开角在簇中心角度附近服从拉普拉斯分布簇中心角度服从均匀分布。这里最容易出bug的是角度和阵列响应对不上。我用的是正弦域均匀线阵表达式里只出现sin(θ_l)如果直接拿角度算相位记得统一用sin形式否则旁瓣方向会算错。另一个容易忽略的是天线间距d与波长λ的比值取半波长时相位增量为π·sin(θ_l)代码里写清楚就不会乱。4.3 核心预编码函数混合预编码函数是整个仿真的核心。我用坐标下降法替代直接相位提取同时保留了一个开关参数允许对比两种做法的效果。核心代码逻辑如下function [FRF, FBB, error_seq] hybridBeamforming(H, Fopt, config) Nt config.Nt; NRF config.NRF; FRF exp(1j * 2 * pi * rand(Nt, NRF)); FRF FRF ./ abs(FRF); % 恒模初始化 FBB zeros(NRF, size(Fopt, 2)); for iter 1:config.maxIter % 坐标下降更新FRF for col 1:NRF for phase 1:config.codebookSize cand FRF; cand(:, col) codebook(:, phase); err(phase) norm(Fopt - cand * FBB, fro); end [~, best] min(err); FRF(:, col) codebook(:, best); end % 更新FBB最小二乘加规范化 FBB (FRF * FRF) \ (FRF * Fopt); FBB FBB * sqrt(Ns) / norm(FRF * FBB, fro); error_seq(iter) norm(Fopt - FRF * FBB, fro); if iter 1 abs(error_seq(iter-1) - error_seq(iter)) 1e-4 break; end end end这里FBB规范化用的系数要根据发射功率基准来定这一点下面详细说。4.4 对比基线与绘图有对照才有说服力。我在仿真里同时算了三个基线全数字无约束预编码作为性能上限纯模拟波束成形不经过数字域直接把波束对准最强路径方向以及随机相位初始化的混合方案用来体现交替优化的增益。绘图时把频谱效率随SNR的变化画成一张图三条线分别是全数字、混合、纯模拟。另外画一张误差范数随迭代次数下降的曲线直观展示交替最小化每一步的收敛情况。这两张图足以支撑一篇仿真类项目的主要结论。5. 复现这套代码时最容易踩的四个坑5.1 发送功率规范化位置不对性能整体漂移我最早一版代码里数字预编码的规范化写错了把||FRF·FBB||_F²直接缩放成Ns结果低SNR段没什么感觉到高SNR段频谱效率曲线明显低于正常值看起来就像混合波束成形比纯模拟还差。查了半天发现是功率基准搞混了。规范化要看你想约束的是总发射功率还是每流功率。如果总发射功率等于Ns那就让||FRF·FBB||_F² Ns如果想约束每根天线的平均功率一致得除以Nt再开方。我最终统一用总发射功率约束FBB乘以sqrt(Ns)/norm(FRF·FBB, fro)。这个细节通常不写在文档里但它直接决定所有曲线能否对上。5.2 移相器码本分辨率和角度量化码本分辨率直接决定模拟预编码的逼近能力。4比特只有16个相位我一开始也怀疑不够专门测试过8比特结果性能提升微乎其微但计算量翻了4倍。原因在于毫米波信道的低秩性主路径就那么几条角度域稍微偏一点数字域的线性调整也能补回来。真正需要注意的是码本覆盖范围。如果覆盖范围写成[-90°, 90°]但系统设定用户在[-60°, 60°]码本里一半候选角度是空闲的反过来如果用户角度超出覆盖范围高频段频谱效率会明显下降。我建议码本范围跟系统角度范围保持一致不要图省事直接用全角度。5.3 多用户流数与射频链的约束关系射频链数量NRF决定数字域最多能支撑几路数据流。我第一次扩展多用户时直接设K8用户、每用户1流NRF也设成8一路跑通后发现迭代误差范数死活降不下去。后来意识到问题在于模拟域只有8条射频链但每列FRF要同时服务8个用户自由度被严重透支必须把NRF增加到至少K2才有余量做干扰抑制。实际工程里NRF一般取2K到4K既要满足流数需求又要留出空间给迫零矩阵做干扰消除。如果要压缩射频链数量就得在用户调度上做文章不能指望算法自己变魔术。5.4 交替最小化不收敛的排查思路如果误差范数曲线出现反复震荡或者收敛到明显高于正常水平的值我的排查顺序是先看FRF初值是不是恒模再看候选码本里是否有无效相位然后检查FBB更新时伪逆是否稳定。这三个环节里最容易出问题的是伪逆当NRF和流数相等时FRF*FRF可能接近奇异数值溢出会让FBB突然变大把误差范数顶上去。解决方法有两个一个是用pinv代替inv求伪逆另一个是在FBB更新后做一步规范化再进下一轮坐标下降。我实测用pinv之后迭代曲线稳定了很多再也没有出现误差范数突然反弹的情况。6. 结果怎么看频谱效率曲线、收敛曲线与扩展方向6.1 频谱效率曲线的解读当SNR从-10dB升到20dB混合波束成形的频谱效率曲线稳步上升在低SNR段几乎贴着全数字方案走高SNR段由于多用户干扰和量化误差逐渐拉开约1dB差距。纯模拟方案在SNR超过0dB后增速放缓说明它只靠方向增益无法消除用户间干扰高频段被干扰拖住是必然的。实际复现中如果你看到混合方案在低SNR和高SNR都低于纯模拟不用怀疑算法方向大概率是数字预编码或功率规范化写错了。正确实现下混合方案应当在全SNR范围内都明显优于纯模拟。6.2 迭代收敛曲线误差范数随迭代次数的曲线通常在前3到5次迭代快速下降之后趋于平缓。我设置的阈值1e-4在大部分信道实现下不到10次收敛。偶尔在信道相关性较强的场景会多跑几轮但不会超过15次的设置上限。这个收敛行为还有一个实用价值如果想降低实时处理时延可以把迭代次数设成5性能损失通常不超过0.5dB计算量减少一半。工程上这个权衡很常用。6.3 代码还能怎么扩展这套代码基础版本跑通后下一步有几个很自然的扩展方向。第一把窄带信道换成多径OFDM每个子载波分别做数字预编码模拟部分整段频带共享这会带来新的复杂度但更接近真实系统。第二加入信道估计环节用导频和最小二乘估计出瞬时信道替代理想的信道已知假设。第三把发射端单边波束成形扩展到收发端联合设计也就是收发两端都采用混合架构此时需要同时对发射端FRF和接收端WRF做交替优化。我目前已经做了OFDM扩展的第一版数字预编码按子载波分别计算模拟预编码用所有子载波的平均信道来设计效果比我预期好后面有机会单独写一篇分享。整套源码跑通之后我最大的感受是混合波束成形的核心难点不在算法推导而在恒模约束和功率规范化的实现细节上。坐标下降和最小二乘交替迭代的原理十分钟就能讲完但真正让仿真曲线对得上理论预期靠的是把每一个矩阵维度、每一个规范化因子都抠清楚。如果你复现时发现曲线对不上建议从第5章的四个坑开始排查尤其注意规范化那一步。代码里还剩几个参数可以调包括移相器位数、迭代次数和初始化次数调参的过程往往比跑通本身更有收获。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →