可重构智能表面辅助多用户MIMO:无源波束成形与交替优化仿真解析

发布时间:2026/10/12 16:35:19
可重构智能表面辅助多用户MIMO:无源波束成形与交替优化仿真解析
简介可重构智能表面RIS辅助多用户MIMO系统的无源波束成形与信息传输设计Matlab实现包面向通信工程、电子信息及数学等专业学生适用于课程设计、期末大作业或毕业设计。资源包共29个文件包含23个.m主程序与仿真函数、2个.asv自动备份、1个.mat数据文件、1个Readme说明及License等压缩包仅47KB轻量且便于部署。已有50人学习浏览。代码采用参数化编程并附详细注释支持Matlab2014a/2019b/2024b多版本运行内置可直接运行的案例数据便于调整参数以复现无源波束成形、信道估计如SBL-GAMP、EM算法及CVX优化等关键流程。通过动态调节RIS反射单元相位与幅度在无需增加发射功率的前提下提升信号覆盖与传输可靠性对研究智能超表面辅助通信、多用户MIMO资源分配具有直接参考价值。1. 可重构智能表面辅助多用户MIMO这个仿真包到底在算哪一步拿到“可重构智能表面辅助多用户MIMO系统的无源波束成形和信息传输设计.zip”这类仿真包很多人第一反应是解压后找入口文件却面对一堆脚本不知道先打开哪个。先给结论这类代码解决的是一个典型下行链路联合设计问题——基站用有源预编码同时服务K个单天线用户部署在环境中的可重构智能表面RIS靠M个无源反射单元调整相位把原本被遮挡、被散射的反射链路变成可控信号路径。你要做的核心计算只有一件事怎么联合调节基站侧的有源波束成形矩阵和RIS侧的无源相移向量让系统总频谱效率最大。对刚入门的研究生这是进入RIS-MIMO的第一道完整阶梯对做算法验证的工程师这是理解信道建模、交替优化和功率分配相互耦合的最小可运行框架。下面按一条可复现的路线展开从信道模型一路走到避坑。2. 系统模型与信道建模直连与级联信道的数值先把对2.1 系统构成与仿真参数一张表说清楚先验假设RIS辅助多用户MIMO的模型自由度很多参数设不对后面全是白算。我的习惯是先把坐标和距离写死基站坐标为原点RIS放在基站和用户簇之间偏一侧的位置用户在RIS近场区域内随机撒点。参数常用值说明基站天线数 N4~8N 越大有源波束成形的空间自由度越高用户数 K2~4K 超过 N 后用户间干扰会急剧上升RIS 单元数 M16~128M 决定无源波束成形的阵列增益上限载频 fc2.4 GHz / 3.5 GHz决定波长进而决定路径损耗参考值BS-RIS 距离 d_BR50 m反射链路的主路径RIS-用户距离 d_RU5~10 mRIS 離用户越近反射链路越强BS-用户距离 d_BU70~90 m直连链路通常比反射链路长路径损耗指数2~3.5反射链路按两段独立计算噪声功率-100 dBm带宽 10 MHz 下的典型热噪声底路径损耗用参考距离 1 m 的自由空间模型乘上距离的负指数次方即 β (λ / 4πd₀)² · (d/d₀)^(-α)其中 d₀ 取 1 m。这是 RIS 仿真里最容易被低估的细节反射链路要分段算BS-RIS 算一次RIS-用户再算一次两部分乘起来才是级联链路的增益。有人图省事把 d_BR 和 d_RU 直接相加再用一个路径损耗算结果是小规模下数值完全失真。2.2 信道生成代码瑞利衰落之外还要留好莱斯因子接口下面这段 MATLAB 代码对应最常用的平坦瑞利衰落模型同时在注释里留了加入莱斯因子和阵列导向矢量的位置。% 系统参数 N 8; % 基站天线数 K 4; % 用户数 M 64; % RIS 反射单元数 fc 2.4e9; % 载频 lambda 3e8 / fc; % 波长 P 10^(30/10); % 基站总发射功率 30 dBm转线性值 sigma2 10^(-100/10); % 噪声功率 -100 dBm转线性值 % 距离与路径损耗参考距离 1m d_BR 50; d_RU 5; d_BU 80; beta_BR (lambda / (4*pi*d_BR))^2; beta_RU (lambda / (4*pi*d_RU))^2; beta_BU (lambda / (4*pi*d_BU))^2; % BS-RIS 信道 GM×N 复高斯按路径损耗缩放 G sqrt(beta_BR) * (randn(M,N) 1j*randn(M,N)) / sqrt(2); % RIS-用户 信道 HrK×M Hr sqrt(beta_RU) * (randn(K,M) 1j*randn(K,M)) / sqrt(2); % BS-用户 直连信道 HdK×N Hd sqrt(beta_BU) * (randn(K,N) 1j*randn(K,N)) / sqrt(2); % 如需加入莱斯 K 因子视线分量用阵列导向矢量叠加 % a_steer exp(1j*2*pi*(0:N-1)*sin(phi)/lambda*dx); % G sqrt(beta_BR)*( sqrt(Kfac/(Kfac1))*a_steer*a_steer. % sqrt(1/(Kfac1))*scatter_component );代码逻辑说明这里的信道维度一定要盯死——G 是 M×N代表从基站每个天线到 RIS 每个单元之间的复增益Hr 是 K×M是 RIS 每个单元到每个用户的链路Hd 是 K×N是基站到用户的直连。最后统一除以 sqrt(2) 是为了让复高斯变量的实部和虚部各占一半功率保证 E[|h|²]1这样路径损耗系数就能独立反映距离衰减。参数说明d_RU 取 5 m 意味着 RIS 紧贴用户簇这是 RIS 仿真里的典型假设——无源波束成形性能对 d_RU 极其敏感如果用户离 RIS 超过 20 m反射链路的贡献会肉眼可见地缩小。如果你发现仿真里 RIS 完全没带来增益第一件事就查这三个 β 的数量级是不是合理。2.3 等效信道与接收 SINR把相移矩阵从信道中间抽出来多用户系统的每个用户 k 的等效信道是直连加反射两条路径叠加h_k^H h_d,k^H h_r,k^H · Φ · G其中 Φ diag(θ) 是 RIS 的相移对角矩阵θ ∈ ℂ^M 且每个元素模长为 1G 是 BS-RIS 信道h_r,k 是 RIS 到用户 k 的信道。发送信号 x W sW 是 N×K 的预编码矩阵s 是 K×1 的数据符号。用户 k 接收y_k h_k^H w_k s_k Σ_{j≠k} h_k^H w_j s_j n_k对应的 SINR 表达式就是后面所有目标函数的地基SINR_k |h_k^H w_k|² / (Σ_{j≠k} |h_k^H w_j|² σ²)仿真里最容易翻车的点藏在这个表达式的转置里h_r,k^H Φ G w_k 要展开成 θ^T·diag(h_r,k^H)·G·w_k 的形式才能把相移向量从级联信道里抽出来独立优化。注意这里是 θ 的转置而不是共轭转置因为 h_r,k^H 本身已经带共轭和 Φ diag(θ) 相乘后θ 以非共轭形式出现。这一小步的转置习惯决定了后面目标函数梯度的方向错了只会让迭代越跑越偏。3. 交替优化主循环把预编码和相移拆成两个可解的子问题3.1 联合设计的困难与交替优化的基本框架直接把 W 和 θ 放进一个目标函数里求联合最优是非凸的没有闭合解。工程上最常用的做法是交替优化固定 θ 求 W再固定 W 求 θ两个子问题交替迭代直到总速率不再上升。这个框架本身不是新东西但它在 RIS 场景下有一个特别的优势两个子问题各自有成熟工具RIS 单元数从 16 到 128 都只需要复用同一套主循环。% 交替优化主循环 theta exp(1j*2*pi*rand(M,1)); % 随机相移初始化 max_iter 30; R_hist zeros(max_iter,1); for iter 1:max_iter % 步骤1固定 theta计算等效信道并更新预编码 H_eff Hd Hr * (diag(theta) * G); W update_precoder(H_eff, P, sigma2, K, N); % 步骤2固定 W求解无源波束成形 theta [A, b] build_theta_problem(Hd, Hr, G, W, K, M); theta solve_theta_problem(theta, A, b, sigma2, K, M); % 记录本轮总速率 R_hist(iter) compute_sum_rate(Hd, Hr, G, theta, W, sigma2, K); end代码逻辑说明H_eff 的构建顺序不能改——diag(theta)*G 是先把 RIS 相移作用在 BS-RIS 信道上再乘以 Hr 得到反射链路对每个用户的贡献最后和 Hd 相加。update_precoder 和 solve_theta_problem 是两个独立函数下面分别展开。参数说明max_iter 取 30 是因为交替优化前几步收益最大后面往往进入平台期。初始化用随机单位模向量比全 1 向量更稳因为全 1 相移在信道强相关时容易把系统锁在对称的次优点上。3.2 有源预编码子问题从 ZF 到正则化 RZF固定 θ 之后H_eff 变成已知的 K×N 等效信道矩阵问题退化为传统多用户 MIMO 预编码。零迫零ZF在 NK 时可用但病态信道下会放大噪声所以仿真里我更常用正则化 ZFRZF也叫 MMSE 预编码。function W update_precoder(H_eff, P, sigma2, K, N) % 正则化系数低SNR时取大高SNR时趋近于零 alpha K * sigma2 / P; % RZF 预编码器H * (H H alpha I)^{-1} W H_eff / (H_eff * H_eff alpha * eye(K)); % 功率归一化让 W 的总功率等于 P W W * sqrt(P / trace(W * W)); end代码逻辑说明H_eff 是 K×NH_eff 是 N×K中间括号里的矩阵是 K×K求逆是每次子问题的最大计算开销。alpha 的取值直接对应信噪比噪声大、功率小时正则化项让预编码偏向抑制噪声而非完全迫零P 远大于 σ² 时 alpha 退化为 0RZF 自动变成 ZF。功率归一化是这步最容易漏的地方——如果不做 trace 归一化下一轮无源波束成形的梯度幅度会被 W 的模长带偏导致相移迭代不稳定。参数说明alpha K·σ²/P 是经验且常用的一种设置严格推导来自最小化均方误差的线性接收机。若你仿真的信噪比范围很大可以让 alpha 变成可调参数而不是固定计算观察它对高信噪比用户的影响。3.3 把无源相移从目标函数里抽出来预计算 A 和 b固定 W 之后每个用户 k 的期望信号和干扰都可以写成关于 θ 的线性函数嵌套二次形式。关键在于预先算好两组系数a_kj diag(Hr(k,:)) · G · w_j 维度 M×1 b_kj Hd(k,:) · w_j 标量那么用户 k 收到来自数据流 j 的有效系数就是 θ^T a_kj b_kj。function [A, b] build_theta_problem(Hd, Hr, G, W, K, M) A zeros(M, K, K); % A(:,k,j)用户k的数据流j对应的相移线性系数 b zeros(K, K); % b(k,j)直连部分的常数项 for k 1:K for j 1:K A(:,k,j) diag(Hr(k,:)) * G * W(:,j); b(k,j) Hd(k,:) * W(:,j); end end end代码逻辑说明diag(Hr(k,:)) 把 1×M 向量变成 M×M 对角矩阵再乘 G 和 w_j得到 M×1 向量。这一步在数学上等价于把 h_k^H w_j 展开其中 θ 作为线性因子出现。预先算好 A 和 b 的作用是让后续目标函数计算从每次重复做矩阵乘法变成直接查数组几十个用户时看不出差别但蒙特卡洛循环几千次后差别很明显。参数说明A 的三维数组结构容易记混。我的习惯是第 1 维永远是 RIS 单元下标第 2 维是用户编号第 3 维是数据流编号。A(:,k,j) 代表“用户 k 收到的来自数据流 j 的反射路径系数”写注释比记脑内索引可靠得多。3.4 无源子问题求解极简黎曼梯度投影法有了 A 和 b用户 k 的 SINR 写成SINR_k |θ^T a_kk b_kk|² / (Σ_{j≠k} |θ^T a_kj b_kj|² σ²)目标函数是 Sum log₂(1SINR_k)。对 θ 求梯度时要用复 Wirtinger 导数对 θ 的共轭方向求偏导。下面是解析梯度实现完全没有工具箱依赖。function g obj_grad_theta(theta, A, b, sigma2, K, M) g zeros(M,1); for k 1:K f_kk theta. * A(:,k,k) b(k,k); % 期望信号复数幅度 interf sigma2; for j 1:K if j ~ k interf interf abs(theta. * A(:,k,j) b(k,j))^2; end end % 对 score log2(1 |f|^2/interf) 求梯度 % 分子部分梯度a_kk * conj(f_kk) / (interf |f_kk|^2) % 分母部分梯度- sum_j a_kj * conj(f_kj) / interf num_grad A(:,k,k) * conj(f_kk) / (interf abs(f_kk)^2); den_grad zeros(M,1); for j 1:K if j ~ K f_kj theta. * A(:,k,j) b(k,j); den_grad den_grad A(:,k,j) * conj(f_kj); end end g g (num_grad - den_grad / interf) / log(2); end end梯度算出来后在单位圆流形上做投影上升先投影到切空间再沿切方向走一步最后归一化回到单位圆。function theta solve_theta_problem(theta, A, b, sigma2, K, M) mu 0.1; % 初始步长小步慢走更稳 for it 1:200 g obj_grad_theta(theta, A, b, sigma2, K, M); % 投影到切空间去掉径向分量 g_tan g - real(conj(theta) .* g) .* theta; theta_new theta mu * g_tan; % 归一化回单位圆 theta_new theta_new ./ abs(theta_new); if norm(theta_new - theta) 1e-5 theta theta_new; break; end theta theta_new; end end代码逻辑说明obj_grad_theta 里的梯度公式不用背理解它的结构即可——分子的梯度想把信号放大分母的梯度想压低干扰两者方向相反最后的梯度是叠加结果。/ log(2) 来自对 log₂ 求导。外部循环的步长 mu 取 0.1 是为了避免目标函数在非凸地形上震荡如果目标函数一直不涨把 mu 减半再跑。参数说明200 次迭代是上限实际在 20~50 次内基本收敛。收敛判据用的是 θ 自身的欧式距离变化而非目标函数变化因为目标函数在平坦区域可能变化很小但 θ 还没找到真正的最优点。3.5 更高级的路线与选型SDR、流形工具箱、闭式解梯度投影法够用但不是唯一选择。SDR半定松弛是经典路线把 |θ^T a b|² 展开成关于 V θθ^H 的线性函数松弛掉秩一约束后用 CVX 求解最后用高斯随机化恢复。它的优点是全局性比梯度法好缺点是 M 超过 64 时 V 是 64×64 的半定矩阵内点法跑一轮就要分钟级蒙特卡洛循环里基本不现实。Manopt 工具箱的 complexcirclefactory 是更专业的流形优化实现带 Armijo 线搜和共轭梯度收敛速度比手写梯度快也省去手推勒让德变换。路线适合规模工具箱依赖精度每次迭代开销闭式相移对齐单用户或强干扰近似无中极低黎曼梯度投影M ≤ 512无高低SDR 随机化M ≤ 64CVX极高高Manopt 流形M ≤ 2048Manopt极高中闭式解只在单用户时严格成立用户 k 的数据流系数确定后θ_m 的最优相位让反射项与直连项同相叠加即 θ_m exp(j(angle(b_kk) - angle(a_kk(m))))。多用户场景没有这种简单形式但可以用这个闭式值作为交替优化的初始化比随机初始化更靠近好解的区域。4. 信息传输设计不只调波束还要分配功率和选择用户4.1 功率分配等功率是基线注水不是银弹预编码矩阵 W 的列范数本质上就是各用户的发射功率。上面的 RZF 代码做了整体功率归一化但没分配——每个用户的功率是均等的。等功率是几乎所有论文的基线因为公平性最好且实现零成本。注水功率分配在理论上能提升和速率但多用户场景没有闭合解需要迭代注水每次按当前有效信道的奇异值重新分配功率更新预编码后再算一次循环十几轮。你的仿真包里可能已经有功率分配模块但我的建议是先跑通等功率确认交替优化的趋势正确再考虑迭代注水——否则功率分配和相移更新耦合在一起出问题很难定位。% 等功率分配给每个用户的数据流分到相同的功率 P_stream P / K; % 将 RZF 的各列做列归一化再乘上每流功率 for k 1:K W(:,k) W(:,k) / norm(W(:,k)) * sqrt(P_stream); end % 检查总功率trace(W*W) 应等于 P代码逻辑说明这里用了列归一化而不是整体 trace 归一化。区别在于整体归一化只保证总功率正确但不保证每列功率一致列归一化则把每个用户的发射功率锁在 P/K。在 RIS-MIMO 场景里用户信道差异很大列归一化能让弱用户不至于被强用户抢走全部功率仿真结果更稳定。参数说明如果你切换到迭代注水需要每一步都重新计算 H_eff 的特征结构注意注水目标是等效信道而非物理信道。这个细节常被忽略导致注水效果反而不如等功率。4.2 用户调度RIS 增益对用户相关性极其敏感信息传输设计里的第二件事是选谁在这个时隙被服务。K4 固定激活是最简单的做法但在用户全部随机撒点、有些用户离得很近的情况下两个强相关用户的信道向量几乎平行无源波束成形难以同时满足两边的相位对齐。这会直接拉低和速率。常见做法是贪心调度从候选用户里逐个挑每次都选让当前系统总速率增量最大的那个。% 贪心用户调度伪代码候选用户集 C目标服务用户集 S S []; remaining 1:K; while length(S) K_active best_user 0; best_R -inf; for k remaining S_try [S, k]; R_try evaluate_sum_rate(S_try, theta, W, Hd, Hr, G); if R_try best_R best_R R_try; best_user k; end end S [S, best_user]; remaining(remaining best_user) []; end代码逻辑说明evaluate_sum_rate 要重新计算选出用户集合对应的等效信道子矩阵和预编码不能直接复用上一轮的全用户矩阵。贪心调度的复杂度是 K² 量级K 在 4 到 10 之间完全可接受。仿真里如果你希望看到 RIS 的增益更明显可以让 d_RU 最小的用户优先入选——离 RIS 近的用户反射链路强调度它更能体现无源波束成形的价值。参数说明K_active 常用 2 或 3。K_active 越少无源波束成形的自由度越充裕总速率通常单调下降但公平性上升这个折衷建议在你的仿真报告里单独画一条曲线。4.3 速率与能量效率瞬时、遍历和 EE 的口径别搞混信息传输设计的最终输出通常是一组速率曲线。这里最容易犯的错是把一次信道实现下的瞬时速度直接画成折线图却没说明这是哪一次随实现。规范做法是先做蒙特卡洛平均——每次信道生成后运行交替优化和功率分配记录该次总速率循环 1000 到 5000 次后取平均值。能量效率EE是另一套口径EE R_total / (P M·P_RIS P_circuit)P_RIS 是每个 RIS 单元的相移功耗典型取 5 mW 量级P_circuit 是基站电路功耗约 10 W。% 蒙特卡洛平均遍历速率 num_mc 2000; R_sum 0; for mc 1:num_mc % 在这里生成信道 G, Hr, Hd运行交替优化和功率分配 % R compute_sum_rate(...) R_sum R_sum R; end R_avg R_sum / num_mc;代码逻辑说明你的仿真包里如果对每个信噪比点都跑完整蒙特卡洛耗时主要由 SDR 或高精度流形优化决定。一个实用优化是对小规模做精确计算对大规模只用梯度投影法——论文里如果同时报两条曲线一定要在注释里标明各自用了什么求解器否则别人复现时对不上数。参数说明蒙特卡洛循环的随机种子要每隔 200 次重设一次防止长循环里的随机数状态漂移导致前后段不可比。很多复现踩坑最后都查到这一条。5. RIS仿真的常见问题排查五个必查细节5.1 现象交替优化的总速率不升反降原因无源相移更新后的 theta 没有做单位模归一化或者预编码 W 在迭代中被整体 trace 归一化和列归一化重复施加导致功率逐轮漂移。另一个常见原因是梯度投影里的切空间投影符号写反。解决在每次迭代末尾加一行断言代码检查 abs(theta) 是否全等于 1以及 trace(W*W) 是否等于 P。两者都通过但速率还在掉就得检查目标函数实现是否一致——用同一个函数去计算 R_hist 和用于梯度的值别搞成两套口径。5.2 现象SDR 的结果反而比随机相移还差原因SDR 松弛后得到的 V 是满秩矩阵高斯随机化只采样十几次远不足以逼近被丢弃的秩一最优解尤其是 M 较大时随机化的效果完全取决于采样次数。解决把高斯随机化次数提高到 200 次以上每次采样后归一化到单位模并重算目标函数保留最高的那个。还有一个前置检查看 V 的特征值分布如果最大特征值与次大特征值之比小于 10说明松弛解本身离秩一很远这类信道下 SDR 天然不占优。5.3 现象加上 RIS 之后系统速率没有明显提升原因反射链路的路径损耗乘积远大于直连链路。例如 d_BR100 m、d_RU50 m 时β_BR·β_RU 的数量级比 β_BU 小很多RIS 再怎么调相位也只是杯水车薪。这是仿真里最常见的“没有效果”假象。解决检查三个 β 的相对大小。RIS 辅助系统的关键几何条件是 d_BR·d_RU 要明显小于 d_BU·d_ref 的等效关系。把 d_RU 从 50 m 改成 10 m曲线立刻不一样。仿真报告里必须写明几何参数否则你得到的结论对硬件实验毫无参考价值。5.4 现象梯度投影法在某一轮迭代后卡住速率长期不变原因步长 mu 太大越过最优点后在鞍点附近震荡或步长太小200 次迭代走不到盆地底部。非凸目标函数对步长极其敏感这是典型的玄学调参区。解决改用回溯线搜索——每轮从 mu0.5 开始如果目标函数没上升就减半直到上升为止。另外换多个随机初值跑取最优。如果换了初值曲线差异很大说明目标函数地形很碎这时可以考虑加大 RIS 单元数的散射随机性让信道更“丰富”一点。5.5 现象蒙特卡洛跑完结果和论文对不上原因信道生成里的随机数种子顺序不对。很多人习惯在循环内动态生成信道导致不同信噪比点的信道不是同一组实现平均结果天然不可比。解决把信道生成移到蒙特卡洛循环外层事先存好所有信道实现内层循环只读取和使用。这样跑信噪比扫描时每个信噪比点的信道集合完全一致曲线平滑度也更好。这个坑是我复现别人论文时最深的血泪经验——对不上的原因七成在随机种子管理。6. 验证方法与进阶方向先跑通单用户曲线再谈扩展收到这个仿真包第一件事不是直接跑 K4 的多用户结果而是先缩到单用户做一次穷举校验。取 M4、N4、K1把每个 RIS 单元的相位限定在 QPSK 集合 {±1, ±j}穷举 4⁴256 种相移组合遍历后找出最大速率的那个 θ。然后把你的交替优化代码跑同一个信道实例如果交替优化的结果差出穷举值几个百分点以上说明代码里有 bug修好再继续。第二个验证点是闭式解对比单用户情形下用 θ_m exp(j(angle(b_kk) - angle(a_kk(m)))) 得到的闭式相移应该和交替优化结果非常接近。两者差异可以评估梯度投影法离最优解有多远也是一个有用的 debug 信号。第三个必做验证是随机相移基线。把 theta 初始化为随机单位模向量并固定不迭代测一条速率曲线作为下界。任何迭代算法如果跑不出比这更高的速率直接说明求解器实现有问题。进阶方向上这个仿真包可以往三个方向扩展宽带 OFDM 子载波下的无源波束成形每个子载波的相移都要协调非理想 CSI 下的鲁棒设计用信道估计误差的统计量来约束最小 SINR双 RIS 协作两个反射面之间还会形成第二条级联路径。每个方向都是把这里的交替优化框架改一步子问题求解器。我做这类仿真初期最常犯的错就是 H_eff 和转置符号搞混后来养成用 M4 穷举校验的习惯所有时间成本都花得值。希望帮到你。本文还有配套的精品资源点击获取