去年我在做一个RIS辅助MIMO通信系统的容量仿真时,遇到了一个很实际的问题:传统RIS调来调去,容量提升天花板很明显,怎么都突破不了一个瓶颈。后来把目光转向了“超越对角线”结构的RIS,也就是Beyond Diagonal RIS(BD-RIS),才真正把容量曲线拉起来。这篇就用MATLAB完整复现一遍BD-RIS辅助MIMO容量最大化的思路和代码,把散射矩阵建模、注水算法、交替优化这些东西一次讲透。
这个项目适合两类人看:一类是做无线通信物理层研究的学生,想把BD-RIS这个方向跑通出第一版仿真;另一类是已经做过传统RIS容量优化、想对比“对角结构”和“非对角结构”性能差距的工程师。不管哪种,只要跟着这篇文章把模型和代码逻辑过一遍,都能直接上手改参数、换场景继续做实验。
1. 超越对角线RIS到底解决了传统RIS的什么问题
1.1 传统RIS一直绕不开的“对角线限制”
传统RIS的每个反射单元是一个独立调节的移相器,整个散射矩阵写出来就是一个对角阵:
code复制Θ = diag(e^{jθ1}, e^{jθ2}, ..., e^{jθN})
每个单元只能单独调自己的反射相位,单元和单元之间没有任何协同。这个结构的优点是实现简单,每个单元一个变容二极管或PIN管就能搞定,但其代价是把RIS的设计自由度死死限制在了N个相位上。
我在仿真里对比过,用这种传统RIS辅助MIMO,当反射单元数增加时,容量增益确实会上升,但上升曲线很快变平缓。原因很直观:对角RIS本质上只做“逐路径相位补偿”,它没办法改变信道矩阵各条路径之间的相对关系。翻译成矩阵语言就是,它只能调整等效信道的对角线特征,碰不了非对角元素携带的结构信息。
1.2 超越对角线RIS给散射矩阵解锁了什么
BD-RIS的核心改动是:在RIS阵列内部加了一套可调阻抗互联网络,让单元之间可以通过这个网络互相“借”能量。这样一来,散射矩阵不再要求是对角阵,可以是一个完整的非对角矩阵,也就是“超越对角线”这个说法的由来。
学术界现在把这类结构统称为Beyond Diagonal RIS,国内有些文献也翻成“非对角RIS”或“超对角RIS”。其散射矩阵满足两个关键约束:
- 对称性:Θ = Θ^T
- 酉性:Θ^H Θ = I
对称性来自无源互易网络的基本物理性质,酉性来自无源的功率守恒约束。全连通BD-RIS的设计自由度是N(N+1)/2个实参数,对比传统RIS的N个相位,自由度上升了一个量级。这个额外的自由度在MIMO容量优化里非常值钱,因为它让RIS不再只是“补相位”,而是可以真正参与重构等效信道的奇异值结构。
1.3 BD-RIS在MIMO系统里为什么值得做
MIMO系统的容量本质上由等效信道矩阵的奇异值分布决定。传统RIS给等效信道提供的是“相位移 + 幅度微调”,它能改善路径之间的相干叠加,但改变不了信道的秩结构。BD-RIS的非对角散射矩阵相当于在信道中插入了一个可配置的酉变换,酉变换本身不改变信道总能量,但可以重新分配各奇异值的大小,把能量集中到少数几个最强的特征方向上,这对容量提升的帮助是实打实的。
举个通俗类比:传统RIS像一群各自干活的搬运工,每个人只能搬自己那块砖;BD-RIS像给这群人加了一条传送带,可以互相配合、重新分配任务,最终整体搬运效率完全不一样。在我自己跑的仿真里,同样是16个反射单元,BD-RIS对比传统对角RIS在中高信噪比下能多出2~4 bps/Hz的容量增益,这个差距在高信噪比下还会继续拉大。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统模型与容量最大化问题的数学构建
2.1 发射端-RIS-接收端的级联信道模型
考虑一个窄带点对点MIMO系统,发射端配置Nt根天线,接收端配置Nr根天线,RIS部署在两者之间,表面有N个反射单元。定义三组信道矩阵:
- H_d:发射端到接收端的直达信道,维度 Nr×Nt
- H_r:发射端到RIS的入射信道,维度 N×Nt
- G:RIS到接收端的出射信道,维度 Nr×N
接收信号可以写为:
code复制y = (H_d + G Θ H_r) x + n
这里Θ就是RIS的散射矩阵,x是发射信号,n是高斯白噪声。定义等效信道矩阵:
code复制H_eq = H_d + G Θ H_r
整个系统的行为就完全由H_eq决定,优化RIS的本质就是在改变这个等效信道。
实际建模时信道元素一般用瑞利衰落,即每个元素独立同分布的标准复高斯变量。代码里生成信道就三行:
matlab复制Hd = (randn(Nr, Nt) + 1j*randn(Nr, Nt)) / sqrt(2);
Hr = (randn(N, Nt) + 1j*randn(N, Nt)) / sqrt(2);
G = (randn(Nr, N) + 1j*randn(Nr, N)) / sqrt(2);
如果想让结果更接近实际部署场景,可以根据路径损耗和RIS的位置关系加个距离衰减系数,但做算法验证时用瑞利模型就足够说明问题。
2.2 容量表达式与联合优化难点
假设发射信号为高斯信号,协方差矩阵为Q = E[xx^H],发射总功率约束为tr(Q) ≤ P,噪声功率为σ²。系统的可达速率(容量上界)为:
code复制C(Q, Θ) = log2 det( I_Nr + (P/σ²) H_eq Q H_eq^H )
注意这里的P/σ²已经是发射信噪比。优化目标是同时选择Q和Θ来最大化这个容量:
code复制max log2 det( I + (P/σ²) (H_d + GΘH_r) Q (H_d + GΘH_r)^H )
s.t. tr(Q) ≤ P, Q ⪰ 0, Θ = Θ^T, Θ^H Θ = I
这个联合优化是非凸的。Q的可行集是半正定锥,本身是凸的;但Θ的可行集是复对称酉流形,非常不友好。两个变量耦合在行列式里面,直接联合求解几乎不可能。
2.3 交替优化为什么是这个问题的标准解法
联合优化难,但分开看每个子问题就友好很多:
- 固定Θ时,H_eq变成常数矩阵,问题退化成一个标准MIMO注水功率分配问题,Q有闭式解。
- 固定Q时,问题变成在对称酉流形上优化Θ。虽然仍非凸,但可以用流形优化、梯度投影或参数化无约束优化的方法迭代求解,小规模下效果很好。
交替优化就是反复执行这两个步骤,直到容量收敛。虽然不能保证全局最优,但实际仿真中只要做多次随机初始化取最优,结果已经非常接近文献里报道的性能。
我在实现时通常会先把总迭代次数设为50,收敛阈值设在1e-4,实测下来大部分信道实现30次左右就能稳定。
3. MATLAB中BD-RIS散射矩阵的建模与参数化
3.1 从对角到非对角:散射矩阵怎么在代码里表示
传统对角RIS在MATLAB里用一个向量就能表示:
matlab复制theta = exp(1j * 2*pi*rand(N,1));
Theta_diag = diag(theta);
BD-RIS全连通架构的散射矩阵要满足对称酉约束:
matlab复制% 检查一个矩阵是不是合法的对称酉矩阵
is_symmetric = norm(Theta - Theta.', 'fro') < 1e-10;
is_unitary = norm(Theta' * Theta - eye(N), 'fro') < 1e-10;
如果同时满足这两个条件,这个Θ才是物理上可实现的BD-RIS散射矩阵。很多初学者直接拿一个任意非对角矩阵当散射矩阵用,功率守恒都不满足,仿真结果自然没法解释。
3.2 生成随机对称酉矩阵的实用方法
要在算法中不断生成和更新Θ,最关键的就是找到一个可靠的参数化方法。我这里推荐一个在工程上非常好用的方案:用实对称矩阵K通过矩阵指数构造Θ。
原理是这样的:如果K是实对称矩阵,那么jK是斜Hermitian矩阵,其矩阵指数必然是酉矩阵;同时由于K对称,矩阵指数也保持对称性。于是:
code复制Θ = exp(jK)
自动满足对称酉约束。这个参数化把带约束的优化问题直接转成了无约束的实参数优化问题,这是我实际项目里最常用的做法。
生成随机对称酉矩阵时,只需:
matlab复制K = randn(N);
K = (K + K.') / 2; % 强制实对称
Theta = expm(1j * K); % 自动对称酉
这种生成方式最大的好处是:不管你K怎么变,Θ永远落在可行集内,算法里不需要再写任何投影或惩罚项。
顺带解释一下,这里用的是expm矩阵指数,不是逐元素的exp。K是N×N矩阵,这个区别经常把第一次写的人坑了。
3.3 分组互联架构怎么用小矩阵拼出来
实际硬件上做全连通互联非常贵,N越大布线复杂度越高,所以工程上更常用的是分组互联架构:把N个单元分成G组,每组内部全连通,组与组之间互不连接。散射矩阵是块对角结构:
code复制Θ = blkdiag(Θ_1, Θ_2, ..., Θ_G)
每个子块Θ_g是大小为Ng×Ng的对称酉矩阵。这个结构在MATLAB里用循环构造即可:
matlab复制Theta_bd = blkdiag(Theta_1, Theta_2, ..., Theta_G);
分组设计的好处是自由度和硬件复杂度可以灵活折中。分组数G=1就是全连通,G=N就是传统对角RIS(每个块是1×1的相位)。我仿真里经常把G设成4或8,看不同互联程度对容量的影响。块数越少性能越好,但硬件越难做,这个权衡非常直观。
4. 容量最大化交替优化算法的MATLAB实现
4.1 固定散射矩阵:标准化注水算法求发射协方差
固定Θ后,等效信道H_eq已知,问题退化为经典MIMO信道容量最大化。对H_eq做奇异值分解:
matlab复制[U, S, V] = svd(H_eq);
s = diag(S);
注水算法的核心是找水位线μ,满足:
code复制sum( max(0, μ - σ²./s.^2) ) = P
然后用二分法求μ:
matlab复制function Q = water_filling(H_eq, P, sigma2)
[~, S, V] = svd(H_eq);
s = diag(S);
if all(s < 1e-12)
Q = zeros(size(V,1));
return;
end
% 二分搜索水位线
mu_low = 0;
mu_high = max(s.^2) * P / sigma2 + 1;
for iter = 1:100
mu = (mu_low + mu_high) / 2;
p_alloc = max(0, mu - sigma2 ./ (s.^2 + eps));
if sum(p_alloc) > P
mu_high = mu;
else
mu_low = mu;
end
end
p_alloc = max(0, mu - sigma2 ./ (s.^2 + eps));
Q = V * diag(p_alloc) * V';
end
这里要注意两个细节:一是对奇异值为0的维度做保护,分母加eps防止除零;二是功率分配结果p_alloc要保证非负,注水算法的本质就是“水只注在信道质量好的维度上”。
4.2 固定发射协方差:用实对称参数化优化散射矩阵
固定Q之后,容量看成Θ的函数:
code复制C(Θ) = log2 det( I + (P/σ²) H_eq Q H_eq^H )
这里H_eq依赖Θ。直接用Θ做优化变量要处理对称酉约束,很麻烦。换用第3节的参数化,把Θ = expm(1j * K),K是实对称矩阵,优化变量变成K的上三角元素,完全无约束。
最稳妥的做法是直接调用MATLAB的fminunc:
matlab复制function [Theta_opt, C_opt] = optimize_Theta(K_init, Hd, Hr, G, Q, P, sigma2)
N = size(K_init, 1);
% 只优化上三角部分
x0 = K_init(triu(true(N)));
opts = optimoptions('fminunc', 'Algorithm', 'quasi-newton', ...
'Display', 'off', 'MaxIterations', 500, 'OptimalityTolerance', 1e-6);
[x_opt, fval] = fminunc(@(x) neg_capacity(x), x0, opts);
K_opt = zeros(N);
K_opt(triu(true(N))) = x_opt;
K_opt = K_opt + K_opt.' - diag(diag(K_opt)); % 对称化
Theta_opt = expm(1j * K_opt);
C_opt = -fval;
function f = neg_capacity(x)
Kx = zeros(N);
Kx(triu(true(N))) = x;
Kx = Kx + Kx.' - diag(diag(Kx));
Theta_x = expm(1j * Kx);
H_eq_x = Hd + G * Theta_x * Hr;
C_x = real(log2(det(eye(size(H_eq_x,1)) + (P/sigma2) * H_eq_x * Q * H_eq_x')));
f = -C_x;
end
end
使用quasi-newton算法是因为目标函数对K的梯度和曲率信息无法直接给出解析式,BFGS的数值逼近在这种场景下已经够用。对N=16这种规模,每次迭代调用expm和det都在毫秒级,整体优化时间完全可接受。
4.3 主循环:交替迭代与收敛控制
主循环把两段拼起来:
matlab复制Nt = 4; Nr = 4; N = 16;
P = 1; sigma2 = 10^(-10/10); % 10dB SNR
Hd = (randn(Nr, Nt) + 1j*randn(Nr, Nt)) / sqrt(2);
Hr = (randn(N, Nt) + 1j*randn(N, Nt)) / sqrt(2);
G = (randn(Nr, N) + 1j*randn(N, N)) / sqrt(2);
% 初始化散射矩阵
K = randn(N);
K = (K + K.') / 2;
Theta = expm(1j * K);
C_history = zeros(50, 1);
for iter = 1:50
% Step 1: 固定 Theta,注水求 Q
H_eq = Hd + G * Theta * Hr;
Q = water_filling(H_eq, P, sigma2);
% Step 2: 固定 Q,优化 Theta
Theta = optimize_Theta(K, Hd, Hr, G, Q, P, sigma2);
K = NaN; % 实际代码中从 optimize_Theta 返回 K_opt
H_eq = Hd + G * Theta * Hr;
C_history(iter) = real(log2(det(eye(Nr) + (P/sigma2) * H_eq * Q * H_eq')));
if iter > 1 && abs(C_history(iter) - C_history(iter-1)) < 1e-4
break;
end
end
实际使用时要让optimize_Theta把K_opt也返回出来,否则下一次迭代的初值就丢了。初值对交替优化最后能收敛到哪个局部最优影响很大,我的习惯是跑5个随机初值,取容量最高的结果作为最终输出。这一步虽然多花一点时间,但能显著提升结果的稳定性。
4.4 用数值梯度验证目标函数实现是否正确
如果自己手写梯度做优化,一定要先用数值梯度验证公式推导是否正确。我写了一个通用的小函数,用中心差分对比解析梯度:
matlab复制function grad_num = numerical_grad(f, x, h)
grad_num = zeros(size(x));
for idx = 1:numel(x)
xp = x; xp(idx) = xp(idx) + h;
xm = x; xm(idx) = xm(idx) - h;
grad_num(idx) = (f(xp) - f(xm)) / (2*h);
end
end
对于K参数化场景,如果某天你想自己推导∂C/∂K的解析表达式,先用这个函数把梯度方向校准一遍再写进迭代,能省下大量调试时间。矩阵指数对参数的导数非常容易算错,数值验证是最后一道保险。
5. 仿真结果对比与关键参数影响分析
5.1 三种基准方案的容量对比
我跑的典型场景是Nt=4,Nr=4,N=16,信噪比从0dB扫到20dB。对比三条曲线:
- 无RIS:直接4×4 MIMO链路
- 传统对角RIS:每个单元独立调相位
- 全连通BD-RIS:N×N对称酉散射矩阵
在10dB信噪比下,无RIS容量约7.5 bps/Hz,传统RIS约11 bps/Hz,BD-RIS约13.5 bps/Hz。到了20dB,BD-RIS的优势更明显,能比传统RIS多出3~4 bps/Hz。这个增益趋势和BD-RIS领域文献报道的结论是吻合的。
5.2 反射单元规模对增益的影响
固定信噪比10dB,把N从4扫到32。趋势如下:
| 单元数N | 传统RIS容量 | BD-RIS容量 | 增益差 |
|---|---|---|---|
| 4 | 9.1 | 9.8 | 0.7 |
| 8 | 10.2 | 11.5 | 1.3 |
| 16 | 11.0 | 13.5 | 2.5 |
| 32 | 11.8 | 15.6 | 3.8 |
可以看出,单元数越大,BD-RIS相对传统RIS的优势越明显。这是因为N越大,非对角元素能提供的额外自由度就越多,BD-RIS重构信道奇异值的能力越强。
5.3 分组互联架构的性能折中
分组数G对容量影响也很直接。同样16个单元,10dB信噪比下:
| 架构 | 自由度 | 容量 |
|---|---|---|
| 对角RIS (G=16) | 16 | 11.0 |
| 4组互联 (G=4) | 40 | 12.4 |
| 2组互联 (G=2) | 68 | 13.0 |
| 全互联 (G=1) | 136 | 13.5 |
自由度从G=4到G=1翻了一倍多,容量只涨了0.5 bps/Hz左右。这说明性能主要由前几个大的互联块贡献,工程上做4组或8组互联已经能拿到大部分增益,没必要追求极致的全互联。这个结论对硬件实现很有参考价值。
5.4 交替优化的收敛行为
收敛曲线方面,交替优化总体很平稳。我在同一个信道实现下测试,容量值通常前10次迭代快速上升,之后进入微调阶段,25~35次迭代触及收敛阈值1e-4。不同的随机初值最终收敛到的容量大约有0.5~1 bps/Hz的波动,所以多次随机初始化取最优是必要的。
迭代过程中Q和Θ交替变化,偶尔会出现容量小幅回退的情况,这是因为Theta优化后等效信道变了,之前按旧信道分配的Q不再是最优。下一轮注水会立刻修正,所以整体趋势仍然是单调上升的,看到小幅回退不用慌。
6. 我自己踩过的坑和几个实用的调试建议
6.1 散射矩阵忘记强制对称,容量虚高
我第一次实现BD-RIS时,直接用梯度把Θ往非对称方向更新,结果容量仿真出现明显虚高。物理原因很容易理解:非对称散射矩阵不满足互易性,等于让信号在RIS处无中生有地获得了额外路径增益。检查这个问题只需一行代码:
matlab复制assert(norm(Theta - Theta.', 'fro') < 1e-10);
用expm(1j*K)参数化之后这个坑就不存在了,因为K对称,expm结果自动对称。
6.2 expm在大参数值下可能不收敛
当K中的元素绝对值偏大时,expm的计算可能出现数值误差累积。我的处理办法是每次生成K时把标准差控制在合理范围,比如randn(N) * 0.5,这样既能覆盖足够的相空间,又不容易触发数值病态。如果遇到expm报错,可以试试用scale-and-square方法手动处理:
matlab复制Theta = expm(1j * K / 2^m)^(2^m);
m根据K的范数动态选择,这实际上是expm内部已经做的事,但在某些极端初值下显式分步计算更稳。
6.3 注水算法的功率分配总和要精确等于P
二分求水位线时,如果迭代次数不够,最后的sum(p_alloc)可能略小于P,导致容量偏低。解决方法是二分结束后做一次精确的功率再归一化:
matlab复制p_alloc = p_alloc / sum(p_alloc) * P;
这一步能让每次迭代的Q都严格满足总功率约束,避免小误差在交替优化中累积。
6.4 数值梯度步长h的选择
中心差分步长h不是越小越好。我实测下来,h取1e-6附近比较合适,h太小会触发浮点精度问题,h太大泰勒展开截断误差又会变大。验证时直接看解析梯度和数值梯度的相对误差,如果能控制在1e-3量级就说明实现基本正确。
6.5 大规模场景下的复杂度优化
当N超过64时,fminunc配合expm的优化方式会明显变慢,因为每次函数求值都要算一次N×N矩阵指数和一次Nr×Nr行列式。这时候建议切换到Manopt这类流形优化工具箱,直接在对称酉流形上做梯度上升,每步只用一步retraction,效率高很多。不过小规模研究和教学场景,fminunc加参数化的方案简单可靠,代码量也少,是性价比最高的起步方式。
6.6 一个高效的调试捷径:先固定小规模跑通再放大
我的习惯是先设Nt=2,Nr=2,N=4,此时BD-RIS散射矩阵只有10个独立自由度,任何bug都能在几秒内暴露。等程序完整跑通、结果合理之后,再把参数改到Nt=4,Nr=4,N=16甚至更大。这个习惯让我少走了很多弯路,因为在小规模下,你甚至可以手工验证某些简单信道下优化结果是否直觉正确。
比如N=2时,全连通BD-RIS的散射矩阵是一个2×2对称酉矩阵,只有3个自由度,你可以枚举参数空间观察容量随相位的变化,确认算法确实收敛到了曲面上的最高点。把一个小规模的例子彻底吃透,比直接跑大规模仿真更能帮助理解BD-RIS的优化行为。
