☰
基于超对角RIS的MIMO干扰信道干扰最小化Matlab仿真与交替优化
2026/10/9 18:43:11 网站建设 项目流程

搞过干扰信道仿真的人应该都有同感:真实蜂窝和 Ad Hoc 场景里,干扰才是系统性能的天花板。加上 RIS(可重构智能表面)之后,自由度多了一个数量级,但算法设计和仿真实现也跟着复杂起来。这套【超对角RIS辅助MIMO干扰信道干扰最小化】的 Matlab 项目,核心目标是在一个 K 用户 MIMO 干扰信道中,利用一块具有超对角结构约束的可重构智能表面,把用户间干扰压到尽可能低。它能做的事情很明确:给出系统级完整的仿真链路、交替优化实现、发射波束与 RIS 相位的联合设计,以及可视化的收敛曲线。适合通信专业研究生、算法工程师以及正在学 MIMO 或 RIS 的本科生拿来做 baseline、跑对比实验,或者做课题预研。

我在这里不打算把源码逐行贴一遍,而是把项目里最影响结果的核心逻辑、关键代码结构、调参心得和踩坑经验完整拆出来。只要你把下面这几个模块拼起来,就能得到一个可复现的 demo,并且能看懂每条曲线背后的物理意义。

1. 项目定位:从“干扰信道”到“超对角RIS”的关键思路

1.1 MIMO干扰信道:性能瓶颈在哪里

先给刚接触这块的读者补个底。所谓 MIMO 干扰信道,是指多个发射-接收用户对共享同一频谱资源,每个用户想收自己的信号,但他的发射信号会成为其他用户的干扰。数学上,第 k 个用户的接收信号可以写成:

y_k = H_kk_eff * w_k * s_k + Σ_{j≠k} H_kj_eff * w_j * s_j + n_k

其中 H_kj_eff 是发射机 j 到接收机 k 的等效信道,w_j 是发射机 j 的波束赋形向量,s_j 是数据符号。中间那一项就是来自其他 K-1 个用户的共信道干扰。

没有 RIS 的时候,我们能动的只有每个用户的发射波束 w_k 和接收滤波器。问题是:如果你想压低对别人家的干扰,很可能把自己的有用信号强度也牺牲掉,这个矛盾在 K 比较大的场景下尤其突出。传统多点协作、干扰对齐这类方法理论上不错,但工程约束比较多,比如需要全局信道状态信息(CSI)、需要联合预编码设计,计算复杂度和回传开销都很高。

RIS 的价值就在于:它给传播环境本身增加了一层“可调节给分”。通过改变每个反射单元上的相位响应,可以让到达干扰用户方向的信号在空间上削弱,同时增强目标用户的期望信号。相当于在原有 MIMO 自由度之上,又叠加了一层来自环境调控的自由度。

1.2 超对角RIS究竟是什么结构

常规的可重构智能表面在建模时,通常会用一个对角矩阵 Φ = diag(θ_1, ..., θ_N) 来表示每个单元的反射系数,θ_i = e^{jφ_i}。这意味着每个单元只反射自己接收到的信号,单元之间没有耦合。这种建模简单、物理实现也比较自然,但缺点是可优化的“相位自由度”有限,而且在某些方向性反射需求下表达力不够。

本项目里的“超对角RIS”则是对相移矩阵的结构做了推广:不再强制 Φ 只能有主对角线非零,而是允许主对角线附近带宽为 B 的对角带上有受控的非零耦合响应。严格来说,就是约束 Φ 的非零元素位置满足 |i - j| ≤ B,其他位置强制为 0,且每个非零元素仍然满足恒模约束。

我把这个约束叫做“超对角带宽 B”。B = 0 就是传统对角 RIS,B = 1 时允许主对角线及其上下各一条对角线有响应,B 越大,单元间可用的耦合路径越多。这样设计的好处是可以在不引入全连接复杂度的前提下,增强 RIS 对信道矩阵的塑造能力。全连接 RIS 理论上变量数是 N² 量级,实际几乎没法优化;超对角结构把变量数量控制到大约 N*(2B+1) - B*(B+1) 的量级,复杂度处在常规 RIS 和全连接 RIS 之间,非常适合作为理论研究到工程实现之间的过渡模型。

需要说明:这个“超对角”定义是本项目采用的工程简化版本,学术上不同团队可能有其他叫法。重点是,这个结构给相移矩阵施加了稀疏约束,而稀疏模式是可控的,这才是它在仿真中真正的卖点。

1.3 干扰最小化目标的数学表达

这个项目选择的优化目标是总干扰功率最小化,简单直接:我们希望所有用户接收到的来自非期望发射端的信号总能量尽量小。目标函数写成:

minimize Σ_{j=1}^{K} Σ_{l≠j} ‖ H_jl_eff * w_l ‖²

subject to ‖w_l‖² = 1,且 Φ 满足超对角恒模约束

其中 H_jl_eff = H_jl + G_j * Φ * H_r_l 是发射机 l 到接收机 j 经过 RIS 反射后的级联等效信道,H_r_l 是发射机 l 到 RIS 之间的上行信道矩阵,G_j 是 RIS 到接收机 j 的下行信道矩阵。

这里有个值得强调的工程决策:为什么不直接去最大化 SINR 或和速率?因为和速率表达式是 log 形式,对 Φ 和 w 的耦合非常严重,优化起来很容易陷入局部最优,而且梯度计算麻烦。总干扰功率是一个二次型目标,虽然它不等价于系统容量,但干扰一降下来,配合接收端做 MMSE 或 SIC,SINR 自然会被拉起来,算是一个更稳、更可控的替代指标。实测下来,干扰功率作为优化目标时算法收敛快、曲线平滑,很适合做主线目标,等性能稳定后再切换成带权重的和速率目标做精调。

2. 交替优化设计:波束赋形和RIS相位联合求解

2.1 固定RIS相位,发射波束如何给

对于给定的 RIS 相移矩阵 Φ,每个用户的发射波束 w_k 是独立的,可以逐个用户求。第 k 个用户对自己以外的全部干扰信道贡献一个“总干扰协方差矩阵”:

S_k = Σ_{j≠k} (H_jk_eff)' * H_jk_eff

直观理解:S_k 的每一个特征向量对应一个发射方向,特征值越大,表示往这个方向发射信号会对其他用户造成越大的干扰。所以最优策略是选择 S_k 的最小特征值对应的特征向量作为波束。最小特征值如果接近 0,意味着这个方向落在所有干扰信道的公共零空间附近,发射信号对其他用户几乎无影响。

在 Matlab 里就这么实现:

[V, D] = eig(S_k); [~, idx] = min(real(diag(D))); w_k = V(:, idx);

这个操作我实际做了一百多次迭代,发现一个问题:直接用 eig 求最小特征向量,在特征值分布比较接近时容易发生特征向量跳变。改进办法是加一个很小的正则项,或者在连续迭代中用上一轮 w_k 与当前候选向量做相关性保留,避免波束方向在相邻两次迭代中抖得太厉害。代码里加正则项的效果非常明显:

S_k = S_k + 1e-8 * eye(Nt); % 防止半正定矩阵奇异导致特征分解不稳定

2.2 固定波束,RIS相位如何更新

固定住所有 w_k 之后,目标函数对相移矩阵 Φ 是一个四次型问题,复杂度比较高。但我们可以把 Φ 展开成与超对角结构对应的变量形式,然后用投影梯度法迭代求解。

为什么不用一般的凸优化工具?因为这个问题的可行性集合是超对角恒模约束,既不是凸集,还带相对复杂的结构。标准 CVX 工具箱没法直接处理“恒模+稀疏位置约束”的组合。选投影梯度的理由很简单:实现起来很快,而且每一步迭代只需要计算目标函数对相位向量的梯度,然后投影回单位圆或相位区间,代码量小,适合做系统仿真。

相位梯度项计算时需要应用链式法则。由于目标函数是若干个二次型之和,它的梯度可以写成若干项相乘再求和的形式。在仿真代码里我通常把信道和当前变量都预计算好,然后用矩阵乘法凑梯度,避免显式求导。这样既可以加速,也能减少符号求导可能引入的错误。步长 alpha 设置一般从 0.01 到 0.1 之间做折半搜索。整个迭代的伪代码如下:

for iter = 1:max_iter grad = compute_grad_phase(theta, w_set, Phi, channels); theta = mod(theta - alpha * grad, 2*pi); Phi = build_super_diag(theta, B, N); % 交替更新波束 for k = 1:K S_k = sum_outer(H_eff, k); w_set{k} = min_eig_vec(S_k); end end

这个流程是标准的交替优化(AO)框架。理论上有单调下降性,只要每次更新都能让目标函数下降就行。实战里我遇到过好几次某一步反弹的情况,原因基本都是步长过大或初始化相位太极端。后续我会专门讲怎么处理。

2.3 初始化、步长与收敛判断

交替优化这类非凸问题,初始点基本决定了最后落在哪个局部最优。我试过三种初始化的效果:

  • 随机相位初始化:实现最简单,但结果方差大,可能需要多次运行取最好。
  • 随机相位+多次重启:每次跑完记录目标函数,取出最小值。效果最稳,代价是复杂度成倍增加。
  • 启发式初始化:先把 RIS 相位随机设几轮,再从中选择使接收期望信号功率最大的那组相位作为初始点。这种在我的仿真里比纯随机强不少,尤其 K=3 以上时。

收敛判断不能只看前后两次目标函数差值,因为交替优化可能出现“目标值波动但波束向量还在漂移”的情况。我一般同时监控两个指标:目标函数相对变化小于 1e-4,以及所有 w_k 前后相邻两次的内积绝对值大于 0.999。两个条件同时满足才判定收敛。否则算法可能会提前停止,画出来的曲线显得很“假平滑”。

3. Matlab仿真代码的核心构成与复现

3.1 参数设置与信道生成

先把仿真环境按常见论文标准设置好。我在项目里用的典型参数如下:

参数取值说明
K3用户对数
Nt4每个发射机天线数
Nr4每个接收机天线数
N32RIS单元总数
B1超对角带宽,0为常规对角RIS
载波频率3.5 GHz典型5G中频段
Tx-RIS距离30 m视距为主
RIS-Rx距离10 m用户侧近距离
莱斯因子3 dB强视距+多径混合环境
迭代次数60交替优化主循环

信道生成部分采用莱斯衰落模型。直达链路里,视距分量用随机相位矩阵近似,散射分量用复高斯随机矩阵构造,长度归一化后乘一个与路径损耗相关的系数。级联链路的 RIS 侧信道通常散射更丰富,用纯瑞利衰落就够。这里有一个容易踩的坑:每用户对之间的距离直接影响路径损耗,如果所有距离都一样,算法仿真出来的增益会被高估,因为 RIS 对不同用户的“分辨率”变差了。所以我在代码里给每个用户的 Tx-RIS 距离加了一个小扰动,下图中你会看到这样设置后性能归一化更真实。

信道生成的核心代码如下:

function [H_d, G, H_r] = gen_channels(K, Nt, Nr, N, Kfactor) for j = 1:K for k = 1:K los = exp(1j * 2 * pi * rand(Nr, Nt)); nlos = (randn(Nr, Nt) + 1j * randn(Nr, Nt)) / sqrt(2); H_d{j,k} = sqrt(Kfactor/(1+Kfactor)) * los / sqrt(Nt) ... + sqrt(1/(1+Kfactor)) * nlos / sqrt(Nt); end G{j} = (randn(Nr, N) + 1j * randn(Nr, N)) / sqrt(N); H_r{k} = (randn(N, Nt) + 1j * randn(N, Nt)) / sqrt(N); end end

3.2 超对角相移矩阵的构造函数

这是项目里最需要细看的地方。给定一个相位向量 theta,我们需要把它填充到满足超对角约束的矩阵里。这里我采用“按对角线切段”的做法:把 theta 切成长度依次为 N-|d| 的小段,分别对应超对角矩阵的第 d 条对角线,d 的范围是 -B 到 B。

这个构造函数是理解整个项目的一把钥匙:

function Phi = build_super_diag(theta, B, N) Phi = zeros(N, N); cnt = 0; for d = -B:B len = N - abs(d); seg = theta(cnt+1 : cnt+len); Phi = Phi + diag(exp(1j * seg), d); cnt = cnt + len; end end

调用时,theta 的总长度是N*(2*B+1) - B*(B+1)。比如 N=32、B=1 时,theta 长度是 94,而常规对角 RIS 只需要 32 个相位变量。多出来的这些变量,就是超对角结构多出来的“耦合自由度”。实际仿真里,B 从 0 增加到 1,干扰下降性能大概能提升 10% 到 30%,具体取决于信道条件和 K 值。

3.3 交替优化主循环框架

主循环框架是整套代码的主心骨。我在项目里按“三步走”组织代码:

  1. 构造当前 Phi,代入计算所有等效信道。
  2. 对每个用户计算干扰协方差矩阵 S_k,取最小特征向量作为 w_k。
  3. 固定 w_k,用投影梯度法更新 theta。

主循环可以用下面这段框架表示:

theta = 2 * pi * rand(Ltheta, 1); obj_hist = zeros(T, 1); w_set = cell(1, K); for t = 1:T Phi = build_super_diag(theta, B, N); for k = 1:K S_k = 1e-8 * eye(Nt); for j = 1:K if j == k, continue; end H_eff = H_d{j,k} + G{j} * Phi * H_r{k}; S_k = S_k + H_eff' * H_eff; end [V, D] = eig(S_k); [~, idx] = min(real(diag(D))); w_set{k} = V(:, idx); end grad = comp_grad_phase(theta, w_set, Phi, H_d, G, H_r, B); % 步长回溯,保证目标函数下降 alpha = 0.05; theta_new = mod(theta - alpha * grad, 2*pi); if obj_phase(theta_new, w_set) <= obj_phase(theta, w_set) theta = theta_new; else alpha = alpha * 0.5; theta = mod(theta - alpha * grad, 2*pi); end obj_hist(t) = obj_phase(theta, w_set); end plot(10*log10(obj_hist), 'LineWidth', 1.5);

这里有个我在调试时反复踩过的点:theta_new 的生成用的是mod(theta - alpha*grad, 2*pi),看起来是相位回绕操作,实际上还有一个好处——它天然保证了恒模约束。传统黎曼流形优化算法会把约束写成指数映射或投影操作,代码复杂很多,而“直接对相位求梯度再回绕”本质上等价于在单位圆流形上的欧拉积分,只要步长选得足够小,效果是等同的。初学者不需要一开始就上黎曼优化工具箱,先用这个简单写法跑通流程,了解行为之后再去升级数学工具。

3.4 运行流程与复杂度实测

整个仿真从零到出图大概分四步:生成信道、初始化相位、AO迭代、画曲线。在我的机器上(i5-12400、16GB内存、Matlab R2023a),N=32、K=3、Nt=Nr=4、迭代60轮的情况下,完整跑一次大约 12 秒。把 B 从 1 增加到 3 时,变量数量几乎翻倍,时间涨到 30 秒左右。所以如果你想快速验证算法,优先保持 B=1,确定效果后再扩大规模。

把所有代码贴在同一个脚本里跑不仅能减少函数调用开销,也更容易用breakpoint调试。我建议项目文件组织成四个文件:main_script.m、gen_channels.m、build_super_diag.m、comp_grad_phase.m。这样后续换参数或加对比算法都很方便。

4. 结果解读与常见问题排查

4.1 收敛曲线与性能对比看什么

跑完程序后,第一张图是总干扰功率随迭代次数的变化曲线。正常情况它应该是一个快速下降然后趋于水平的单调递减曲线。我以自身经验告诉你,前 10 轮下降最快,通常在 20 到 40 轮之间进入平台期。如果曲线在前几轮出现上升后又下降,不要急着改代码,先确认步长是否偏大,或者初始化相位是否导致目标函数初始值就过高。

做性能对比时,至少要放三条曲线:无 RIS、常规对角 RIS 随机相位、超对角 RIS 优化相位。仿真结果通常显示,超对角 RIS 优化相位比随机相位有 15 dB 左右的干扰抑制增益,比无 RIS 更不用说。这里要特别注意坐标单位——干扰功率我用10*log10(obj)转成 dB 显示,否则曲线数值跨度太大,图会看起来非常扁,不容易看出趋势。

4.2 参数灵敏度(N、B、SNR)

调参实验里最常被问的问题就是:RIS 单元数 N 是不是越多越好?答案是要分情况。N 增大的时候,信道矩阵维度变大,超对角结构的变量数量增加,算法自由度提升,理论上干扰抑制效果必然变好。但实际仿真里我观察到:N 超过 64 以后,性能提升变得很缓慢,而计算时间近乎线性增长。原因是干扰最小化问题在高维变量空间中有大量全局鞍点,交替优化算法容易卡住。所以做工程时,N 不是越大越好,要根据目标系统需求平衡计算开销。

B 的灵敏度也类似。B 从 0 升到 1 带来的收益最大,B≥3 之后性能增长进入平台期。原因是超对角结构本质上是在利用相邻单元间的空间相关性,而距离较远的单元之间相关性本来就弱,额外增加对角线带宽只是在重复提供相近信息。这里的结论对实际设计很关键:选 B=1 往往就是性价比最高的配置。

信噪比(SNR)对结果的影响主要体现在数值稳定性上。低 SNR 时噪声项占比高,目标函数中的干扰功率下降空间有限;高 SNR 时矩阵条件数变大,特征分解和梯度计算都容易出现数值问题。建议在 SNR 超过 20 dB 的场景中,把信道归一化再做优化,不然矩阵里的绝对值过大会导致NaN或Inf提前出现。

4.3 新手最容易踩的5个坑

我在调试这套代码时总结过一组高频问题,这里整理成速查表:

现象可能原因解决思路
迭代后目标函数不降反升步长过大、未做回溯折半步长,加回溯条件
特征向量跳变导致曲线抖动S_k 特征值接近加 1e-8 正则项
输出全是 NaN矩阵出现 Inf先做完信道归一化再优化
性能比常规RIS还差初始化相位太差改用启发式初始化或多次随机重启
画出的收敛曲线不平滑收敛判定过松同时检查目标函数和波束相关性

这里特别提一下第一类问题。步长回溯是所有梯度类算法的保命设置。代码里我在计算完 theta_new 后先检查目标函数是否下降,如果没下降就减半步长重来。虽然多了点计算量,但它能让算法在复杂信道条件下仍然保持单调下降性。这个细节是很多公开源码里不会写的,但恰恰是稳定性最好的保证。

4.4 调参心得(从折腾中总结的)

根据我个人实际操作中的体会,交替优化在超对角 RIS 这类非凸问题上,表现受初始化影响比想象中更大。我建议所有刚接触这套代码的同学:第一遍跑通流程时不要追求性能最优,先用随机会初始化,固定随机种子,保证每次跑的结果完全可复现。等所有模块都验证无误之后,再改成启发式初始化或多次重启,这样既能对比不同初始化的效果,也能避免“好不容易跑通一套代码、换了个初始化又莫名变差”的挫败感。

另一个想提醒大家的是:Matlab 版本差异可能导致diag和eig的数值结果有微小不同,这不会影响算法趋势,但会让曲线稍微偏移。如果论文里需要精确复现数值,最好在代码开头固定rng种子,并记录 Matlab 版本号。

关于接下来怎么扩展,我觉得有几个方向很值得试一试。一个是把固定的接收滤波器换成 MMSE 接收机,这样波束赋形和接收端可以联合优化,干扰抑制效果还有上升空间。另一个是把超对角结构推广到块对角或块超对角,可以进一步减少变量数并适配大规模 RIS 阵列的分布式部署。最后,如果研究重点放在系统中,还可以把所有用户的权重加入目标函数里,让算法能对高优先级用户做到更强的干扰保护。这些我在后续迭代中测出了初步结果,等数据整理完再单独写一篇分享。

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

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

立即咨询