ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

可重构智能表面辅助多用户MIMO:无源波束成形与信道估计实战解析

可重构智能表面辅助多用户MIMO:无源波束成形与信道估计实战解析

简介:面向计算机、电子信息工程与数学专业大学生的MATLAB项目资源,聚焦可重构智能表面(RIS)辅助多用户MIMO系统中的无源波束成形与信息传输设计。采用参数化编程,注释详尽、参数可灵活修改,且附带可直接运行的案例数据,适用于课程设计、期末大作业或毕业设计。资源压缩包共29个文件,以23个.m源代码文件为核心,涵盖信道生成、信号估计、CVX优化等算法模块,另含.asv备份、说明文档(txt/md)、许可证及.mat数据文件,压缩包整体仅47KB,轻量但完整。目前已有50人学习,代码中模块划分清晰,从MIMO_algorithm、MIMO_EM到SBL_GAMP等脚本均配有注释,便于理解与二次开发。通过该设计可系统掌握RIS辅助MIMO系统的建模、无源波束成形优化及信息传输流程,为后续研究或工程实践提供可直接套用的基础代码。

1. 可重构智能表面辅助多用户MIMO系统:为什么无源反射单元能改写信道容量

在一个可重构智能表面辅助多用户MIMO系统里,最反直觉的结果之一,是那些没有射频链、不发射任何功率的无源反射单元,能让整个系统的和速率翻倍。RIS 做的不是放大信号,而是把传播环境本身变成可编程参数:通过调整大量反射单元的相位,让直射、散射和反射路径在用户天线处对齐,等效地把信道矩阵重新画了一遍。无源波束成形和信息传输设计,正是这背后的核心问题——只改相位,不增功率,同时理顺有用信号和多用户干扰。理解它的关键不在于背等效信道公式,而在于看懂一个 matlab 工程里从信道生成、稀疏估计、星座映射到 CVX 优化的数据流。下面从模型机制开始拆。

2. 无源波束成形的物理机制:恒模约束如何把信道变成可编程参数

2.1 多用户 MIMO 的信道困境与 RIS 的切入点

传统多用户 MIMO 下行链路中,基站侧可以设计预编码矩阵去适配信道,但信道本身是环境给的。楼宇反射、车辆移动、用户位置变化,都会改变基站到每个用户之间的传播矩阵。当两个用户的信道方向过于接近时,信道的列相关性变高,预编码能压制的干扰空间就变窄。换句话说,传统 MIMO 能做的只有“适配信道”,不能“修改信道”。

RIS 的思路是直接往传播环境里插入一层可控的反射面。每个反射单元通过改变变容二极管的偏置电压,能调整自身对入射信号的反射相位,理想情况下还可以微调反射幅度。数学上,这一层反射面对信道的作用等价于乘一个对角矩阵:

一个典型 RIS 反射系数矩阵可以写成

Θ = diag(β_1·e^{jθ_1}, β_2·e^{jθ_2}, ..., β_N·e^{jθ_N})

其中 β_n 是第 n 个单元的幅度响应,θ_n 是相移。无源单元没有放大能力,理想无损条件下 β_n ≈ 1,所以每个反射单元的设计自由度只剩下 θ_n,并且受制于恒模约束 |θ_n| = 1。实际硬件里 θ_n 往往只能取 1-bit、2-bit 或 3-bit 的离散值,这为后面的优化问题埋下了非凸的根。

把信道写完整,基站到第 k 个用户的等效信道由两部分组成:基站到用户的直射信道 h_d,k,以及基站→RIS→用户这条级联反射信道。RIS 对信号的调制可以用一个对角矩阵 Θ 描述,于是第 k 个用户看到的总信道为

h_eq,k^H = h_d,k^H + h_r,k^H · Θ · G

其中 G 是基站到 RIS 的 M×N 信道矩阵,h_r,k 是 RIS 到第 k 个用户的 N×1 信道向量,h_d,k 是基站到第 k 个用户的 M×1 直射信道向量。关键点在于:G 和 h_r,k 本来是随机且不可控的,但 Θ 的 N 个对角元素是我们可以设计的。也就是说,RIS 用 N 个相移自由度,把一部分随机信道重写成了可编程信道。

对比一下传统 MIMO 和 RIS 辅助 MIMO 的调节对象,会更清楚:

调节对象传统 MIMORIS 辅助 MIMO
基站侧预编码矩阵 W预编码矩阵 W(可联合设计)
用户侧接收合并向量接收合并向量(可联合设计)
传播环境不可控通过 Θ 改变反射路径
是否消耗发射功率是RIS 不消耗发射功率

这个差异是理解 RIS 价值的核心:传统 MIMO 的所有自由度都集中在收发两端,而 RIS 把自由度物理地铺到了信道中间。无源波束成形的“无源”二字,指的就是它只调相位、不放大信号,用近乎零的硬件功耗去换取空间自由度。

2.2 无源波束成形的目标:信号增强和干扰抑制怎么同时满足

有了等效信道模型,第 k 个用户的接收信号可以写成

y_k = h_eq,k^H · w_k · s_k + Σ_{j≠k} h_eq,k^H · w_j · s_j + n_k

第一项是期望信号,第二项是来自其他用户的干扰,n_k 是高斯噪声。RIS 相移对期望信号的影响很直观:如果反射路径与直射路径在用户天线处相位对齐,两个分量的幅度相加,信号功率增强;如果反相,则信号被削弱。所以“无源波束成形能增强信号强度”的本质,是相干叠加。

但多用户场景比单用户复杂得多。同一个 Θ 同时出现在所有用户的信号和干扰项里,调整某一个 θ_n,会让用户 k 的期望信号变强的同时,也可能让用户 j 的干扰路径变强。这意味着一味增强反射信号是不够的,还需要让反射路径与直射干扰分量反相相消。信号增强和干扰抑制两个目标经常互相拉扯,因为该用户之间的关系在 RIS 相移空间里是全局耦合的。

正式的无源波束成形和信息传输设计问题,通常写成加权和速率最大化或发射功率最小化形式。如果取前者,优化变量是基站预编码矩阵 W 和 RIS 相移向量 θ,目标是

max Σ_k w_k · log2(1 + SINR_k) s.t. ||W||_F² ≤ P, |θ_n| = 1

这里 SINR_k 是第 k 个用户的信干噪比,分母包含所有其他用户经过 RIS 反射后的干扰功率。问题的难点很明显:SINR 本身是分式,恒模约束又是非凸的,W 和 θ 还在同一个 SINR 表达式里相乘。这是一个典型的非凸联合优化问题,不可能一步得到全局最优解。

这也是为什么源码里的方法几乎都是交替优化:固定 RIS 相移,用 CVX 优化基站预编码;固定预编码,再更新 RIS 相移。两件事拆开之后,每一步都有成熟工具可用,但合在一起时需要反复迭代。工程里的 CVX_Optimal_Simplify.m 和 CVX_Optimal_SAA.m 就是对应这两个阶段的实现变体。把目标函数从“最大化和速率”换成“在给定 SINR 门槛下最小化发射功率”,RIS 的价值更容易看到:同样的覆盖率和 SINR 门槛,有 RIS 时需要的基站发射功率更小,这正好对应摘要里“不增加发射端功率前提下,显著改善信号覆盖和传输质量”的说法。

理解了物理机制,下一步就是看这套 matlab 工程到底怎么把信道估计和波束优化接起来的。

3. 从 matlab 源码看求解链路:SBL-GAMP-EM 估计与 CVX 波束优化

3.1 信道估计:SBL、GAMP、EM 在源码里怎么分工

RIS 没有射频链,基站和用户都无法直接拿回 RIS 各单元上的信道信息。想要设计 Θ,就得先把级联信道估计出来。常见的工程做法是让 RIS 在 T 个导频时隙内切换不同的相移模式,每次切一套 Θ_t,用户端就观测到一个不同的等效信道。把 T 次观测堆叠起来,问题变成从线性观测中恢复一条高维级联信道向量。

这条级联信道在很多场景下具有稀疏性:信号在角度域、距离域或者波束域里只占据少量基向量。稀疏贝叶斯学习(SBL)天然适合这种问题:它为每个待估计元素设置一个参数化先验,然后用贝叶斯公式迭代更新后验。但直接做 SBL 需要反复求逆一个高维矩阵,当 RIS 单元数 N 到 256、512 时,复杂度几乎是灾难。GAMP(广义近似消息传递)就是来解决这个问题的,它把矩阵求逆换成两个矩阵乘法和逐元素标量函数,复杂度大幅下降。

源码文件里的 AwgnEstimIn.m、CAwgnEstimIn.m、CAwgnEstimOut.m,就是 GAMP 中“标量估计通道”的实现,CA 前缀表示复值 AWGN 通道。GAMP 迭代时,观测节点向变量节点传递外信息 r 和外方差 p,变量节点用这些输入计算后验均值和后验方差。下面按该工程常见的命名风格,还原一个复 AWGN 估计通道的职责:

% GAMP 中复AWGN输入估计通道的示意实现 % rhat: 来自观测节点消息的外均值(复向量) % rvar: 与外均值对应的外方差 % v0 : 稀疏先验先验方差,由EM更新 function [xhat_next, xvar_next] = CAwgnEstimIn(rhat, rvar) % 在标准AWGN先验 p(x) ~ CN(0, v0) 下, % 后验均值是维纳滤波形式:按信噪比加权混合先验和外信息 gain = rvar ./ (rvar + v0); xhat_next = gain .* rhat; xvar_next = gain .* rvar; end

GAMP 迭代时,外信息 rhat 的精度会逐渐提高,估计出来的 xhat 越来越接近真实级联信道。这个函数的机制看着简单,但它把原来需要操作整个 Gram 矩阵的贝叶斯更新,拆成了对每个元素独立计算,计算量从 O(N³) 量级降到每次迭代两个矩阵乘法的量级。前提是观测矩阵在列归一化后近似满足右酉性质,这也是导频设计不能乱来的原因。

SBL 和 GAMP 之间还缺一个关键环节:超参数谁来调。级联信道的稀疏程度由先验方差控制,噪声方差也需要知道。源码里的 MIMO_EM.m、MIMO_EMX.m、MIMO_EMS.m 就是这层角色。EM 在每一步交替执行:E 步用当前超参数跑一次 GAMP,得到后验均值和后验方差;M 步用这些后验矩更新噪声方差和稀疏先验方差。这样就不用手动去调正则系数。

源码里同时提供三个 EM 版本,我一般会这么理解其中的差别:SBL_GAMP_S.m 和 SBL_GAMP_X.m 是两个方向的稀疏估计,一个倾向于估计与导频符号相关的通道,另一个针对发送数据矩阵;MIMO_EMX.m 把发送数据矩阵 X 当作未知量一起加入 EM 循环,MIMO_EMS.m 则把导频符号序列 S 也纳入估计。不同文件名对应的其实是同一套 SBL/GAMP 框架在不同变量组合下的实例。对使用者来说,先用哪个版本取决于你手里是“导频已知”还是“导频也需要和数据一起做盲估计”。

3.2 波束成形:CVX_Optimal_Simplify 与 CVX_Optimal_SAA 在交替优化里的角色

信道估计完成之后,无源波束成形设计才有了可靠的输入。由于 2.2 里已经说明联合优化非凸,工程实现的标准套路是交替优化。下面这段代码展示了一个典型的主循环骨架,与文件清单里的 CVX_Optimal_Simplify.m、CVX_Optimal_SAA.m 是对应的:

% 交替优化主循环:AO, Alternating Optimization % W: 基站预编码矩阵, theta: RIS相移向量 for iter = 1:max_iter % 第一步:固定theta,用CVX求解当前RIS等效信道下的预编码W H_eff = H_d + H_r * diag(theta) * G; W = cvx_optimal_simplify(H_eff, Pmax, gamma); % 第二步:固定W,更新RIS相移 % 恒模约束不直接进CVX时,一般先投影到单位圆再量化 theta = update_ris_phase(H_d, H_r, G, W); % 记录当前和速率,用于判断是否收敛 rate(iter) = compute_sum_rate(H_eff, W, sigma2); end

CVX_Optimal_Simplify.m 通常对应理想信道状态信息下的简化求解:把 RIS 相位当成给定常数,用 CVX 解一个带 SINR 约束或功率约束的预编码问题。这个版本快,适合快速验证理论界,但它的结果建立在“信道估计完全准确”这个不太现实的假设上。

CVX_Optimal_SAA.m 中的 SAA 是样本平均近似(Sample Average Approximation),一般用在信道统计信息不确定的场景。做法是生成 L 组信道样本,把平均后的 SINR 或中断概率作为目标,让 CVX 求解一个更稳健的预编码。计算量随 L 线性增长,所以工程里通常先用小样本数调通,再加大样本数验证稳定性。

如果只有一个固定相位约束,恒模约束往往不直接交给 CVX。常见的处理思路是先把单位模约束松弛成 |θ_n| ≤ 1,求解后再投影到单位圆,或者用半定松弛得到连续相位,最后量化到硬件支持的离散相位。这一步处理得好不好,直接影响后面星座映射的实际误码率。

整个 main.m 的数据流可以这样理解:Generate_H.m 生成信道矩阵,Constell_Modulate.m 把比特流映射成 QAM/PSK 符号,经过 RIS 辅助信道后由 SBL/GAMP/EM 模块估计等效信道,再交给 CVX 模块做波束优化,最终把可复现的数值结果写进 MIMO_result.txt。Constell_Mapping.m 负责在接收端把估计符号映射回软比特,为 EM 迭代提供符号先验。这套链路里,信道估计和波束成形共享同一个 H_eff,任何一边更新后另一边没有同步,结果就会差出好几个 dB,这是下一章要展开的实战问题。

4. 避坑:RIS 仿真工程从 matlab2014a 跑到 2024b 的五个翻车现场

4.1 环境与工具箱:CVX 版本、asv 文件和历史数据

现象 1:在 matlab2014a 里直接运行 main.m,第一行就报错 “Undefined function or variable 'cvx_begin'”。

原因:CVX 并不是 matlab 自带的功能包,需要单独下载安装并执行 cvx_setup。工程里所有 CVX_Optimal_* 和 CVX_Text.m 都依赖它,省略安装步骤时 matlab 根本不知道 cvx_begin 是什么。

解决:先安装与当前 matlab 版本兼容的 CVX 版本,运行 cvx_setup 完成路径配置。如果不想引入 CVX,可以先把 CVX_Optimal_Simplify.m 替换成注水功率分配的闭式解,跑通其余链路后再加回 CVX 做对照。这样能区分“环境问题”和“算法问题”。

现象 2:打开工程目录时发现 MIMO_algorithm.m 和 MIMO_algorithm.asv 同时存在,改了半天代码没反应。

原因:.asv 是 matlab 编辑器自动保存的备份文件,不是正式源码。文件列表里同时出现同名 .m 和 .asv,说明项目在编辑过程中自动保存过旧版本。双击 .asv 打开的是历史快照,直接运行当然不是最新逻辑。

解决:所有修改都针对 .m 文件,运行也用 .m。可以在 matlab 编辑器设置里关闭自动备份,或者定期清理目录里的 .asv。血泪经验是:只看同名 .asv 容易让人误以为代码被改坏了,其实只是版本搞混。

现象 3:加载 matlab.mat 后,工作区里的变量名和 main.m 期望的变量名对不上,运行到中间报 “Unrecognized field name”。

原因:matlab.mat 是某一次仿真结束后的工作区快照,里面的变量名和结构体字段取决于被保存的那一刻。工程代码经过参数化修改后,字段名可能已经变化,旧快照不再兼容。

解决:始终从 main.m 重新生成所有变量,不要把 matlab.mat 当作输入。如果只是想复现论文里的某一张图,先用 whos 检查 matlab.mat 里到底有哪些变量,再决定是否值得手动映射到当前代码。依赖历史快照是这条路线上最隐蔽的坑。

4.2 算法数值:GAMP 不收敛、SAA 内存爆炸和随机数种子

现象 4:SBL_GAMP_S.m 迭代之后,估计出来的级联信道全变成零,信号彻底消失。

原因:稀疏先验的方差 γ 初始化得太小,GAMP 把真实信号误判成噪声,后验均值被压到零。另一个常见诱因是导频时隙数 T 太少,观测矩阵的相干性过高,导致消息传递无法区分真实分量和伪影。

解决:先用 Generate_H.m 随机生成一次信道,观察信道向量功率的量级,然后把 γ 初始化到与该功率同一个数量级。热启动也很有用:先跑一次最小二乘估计,把结果作为 GAMP 的初始均值,而不是从零开始。这个坑往往不是算法本身的问题,而是尺度不对。

现象 5:CVX_Optimal_SAA.m 跑一次要十几分钟,中间提示内存不足。

原因:SAA 用 L 组信道样本近似期望,每组样本都会引入一套 SINR 约束,CVX 内部的内点法会同时处理所有约束,变量规模随 L 线性增长。L 设到一千以上时,普通配置的机器很容易爆内存。

解决:先用 L=50 调通代码流程,确认结果合理后再升到 300~500。若还是内存不足,检查约束里有没有重复项,或者先用 CVX_Text.m 验证当前参数组合是否可行,不要一上来就跑完整蒙特卡洛。

现象 6:固定参数跑两次,MIMO_result.txt 里的和速率忽高忽低,差距达到 2~3 dB。

原因:Generate_H.m 生成信道时使用了随机种子,每次运行的信道实现都不一样,而外层平均的次数又不够多,性能估计的方差自然大。这类现象看着像玄学,其实是蒙特卡洛次数不足。

解决:在 main.m 开头固定 rng 种子,例如 rng(2024),先用同一批信道做算法对比;等所有模块都对齐后,再放开种子做多组实验并平均。做课程设计或毕业设计时,这个习惯能省下大量怀疑人生的时间。

5. 设计取舍:EM/SBL/GAMP 三层嵌套与验证方法

5.1 为什么是 EM+SBL+GAMP,而不是直接调一个通用优化器

如果只用标准 SBL,每次迭代都要计算后验协方差矩阵,复杂度是 O(N³),N=512 时几乎不可接受。GAMP 的优势在于把高维矩阵求逆换成矩阵乘法和逐元素标量函数,使单次迭代复杂度降到 O(N²) 甚至更低。代价是它对观测矩阵的列归一化性质很敏感,导频设计稍差就可能不收敛,这也是上一章避坑 4 的根因。EM 放在最外层,负责自动更新噪声方差和稀疏先验方差,否则 SBL 的正则系数只能靠手调,那就真的成了玄学。

三层嵌套的本质是用模型结构换计算复杂度。如果 RIS 单元数小于 32,纯 SBL 反而更稳、精度更高;单元数到上百之后,GAMP 的优势才真正体现出来。这套 matlab 工程同时提供 SBL_GAMP_S.m、SBL_GAMP_X.m 和多种 EM 变体,正是为了让使用者在不同规模下选择合适版本。我一般会这么理解:这不是代码冗余,而是把学术论文里的备选方案完整保留下来。

5.2 用 MIMO_result.txt 验证算法有没有跑偏

拿到一份新的 RIS 仿真工程,我建议先别改任何参数,而是完成三个检验:

测试项固定条件改变条件期望结果
无源波束成形验证K=2, SNR=10 dBN 从 16 调到 64和速率上升,且增益递减
信道估计验证N=32, K=2导频时隙数 T 增加估计 NMSE 下降
干扰受限验证N=64, SNR=10 dBK 从 2 调到 4总分和速率增速放缓

第一项若增益不变,说明 RIS 相位没有被优化到有效方向上;第二项若 NMSE 不降,检查导频矩阵设计和 GAMP 参数;第三项若和速率反而下降,说明用户间干扰占主导,需要检查 SINR 约束是否真的被满足。MIMO_result.txt 里每一个字段的变化趋势都比绝对值更有参考意义。

从那以后,我每拿到一个 RIS 仿真工程,都强制自己先跑一遍 main.m,再看结果文件里的数值随 N、K、SNR 的变化是否符合物理论断,最后才会动 SBL_GAMP 里的超参数。这套流程帮我避开了很多“看着收敛、实际跑偏”的尴尬。希望帮到你。

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进