第【48期】-- 通信问题的cvx教程之基础篇【一】-- MU-MIMO下行功率分配问题

1、最近有大量小伙伴在问关于通信领域里面CVX的代码编写问题,因此计划新开系列文章,讲解无线通信优化问题中关于MATLAB CVX工具的使用。

2、计划前期先写经典的简单通信问题的CVX求解以打实基础,后期再针对目前热门的通信方向,如RIS,NOMA,UAV,ISAC等方向的复杂非凸问题的近似迭代后的CVX求解。

3、本文为第一期,讲解MU-MIMO系统简单的功率分配问题的CVX代码,感兴趣的朋友后续可以点个关注后续追更。

文章目录

    • [1 引言:为什么需要凸优化工具箱(CVX)?](#1 引言:为什么需要凸优化工具箱(CVX)?)
    • [2 系统建模与问题表述](#2 系统建模与问题表述)
      • [2.1 系统建模](#2.1 系统建模)
      • [2.2 优化问题](#2.2 优化问题)
      • [2.3 非凸转凸](#2.3 非凸转凸)
    • [3 CVX代码分析](#3 CVX代码分析)
      • [3.1 CVX基础语法](#3.1 CVX基础语法)
      • [3.2 CVX关键规则](#3.2 CVX关键规则)
      • [3.3 第2.3小节的凸问题CVX求解](#3.3 第2.3小节的凸问题CVX求解)
    • [4 总结](#4 总结)

1 引言:为什么需要凸优化工具箱(CVX)?

  • 在无线通信系统设计中,我们经常遇到资源分配、波束成形、功率控制等核心问题。这些问题通常可以建模为带有约束的优化问题,而其中的许多都可以转化为凸优化问题(如线性规划、二次规划、二阶锥规划等)。

  • CVX 是一个专为凸优化设计的建模系统,它允许我们用接近数学公式的自然语法描述优化问题,并自动调用底层求解器(如 SeDuMi、SDPT3、MOSEK)进行求解。对于通信领域的研究生和工程师,CVX 是快速验证算法性能的首选工具。

  • 本文将通过一个具体的多用户多输入多输出(MU‑MIMO)下行链路功率最小化例子,教学 CVX 的基本用法。从问题建模开始,一步步编写、调试并解读代码,最终绘制出结果曲线。

2 系统建模与问题表述

2.1 系统建模

2.2 优化问题

2.3 非凸转凸

两边同时开平方,得到:

因此得到标准的二阶锥约束(左侧是 2-范数,右侧是仿射函数)

再通过引入辅助变量tao,则等价凸问题形式为:

3 CVX代码分析

3.1 CVX基础语法

本小节讲解CVX语法基础,会的可以直接跳到3.3节。

CVX核心用法是构建一个"规范",通过几个关键部分来定义优化问题。

  • 框架:cvx_begin + 声明变量 + 目标 + 约束 + cvx_end
命令 作用
cvx_begin / cvx_end 必须成对出现,包裹所有优化代码
quiet 不显示求解过程信息,优化速度(加在 cvx_begin 后面)
sdp 启用半正定规划模式(处理矩阵半正定约束时使用)
  • 变量:用 variable 声明,用法如下表
代码 含义
variable x 声明实数标量
variable x(n) 声明 n 维实数向量
variable X(m, n) 声明 m×n 实数矩阵
variable x(n) complex 声明 n 维复数向量
variable X(m, n) complex 声明 m×n 复数矩阵
variable x(n) nonnegative 声明非负向量(x ≥ 0)
variable X(n, n) symmetric 声明实对称矩阵
variable X(n, n) hermitian 声明复 Hermitian 矩阵(即 X = X^H)
variable X(n, n) semidefinite 声明半正定矩阵(X ⪰ 0)
  • 核心约束规则:整体约束必需为凸约束

3.2 CVX关键规则

CVX 不是任何数学表达式都能接受的。它要求整个问题必须是凸的。

规则1:目标函数必须符合凸性

  • minimize 后面的表达式必须是凸函数(如 norm、sum、quad_form)

  • maximize 后面的表达式必须是凹函数(如 log、geo_mean)

规则2:约束的左右结构有限制

boyd的凸优化里面关于上镜图和下镜图有讲原因,感兴趣可搜

约束类型 左侧要求 右侧要求 合法示例 非法示例
<= norm(x) <= 1 1 <= norm(x)
>= 1 >= norm(x) norm(x) >= 1
== 仿射 仿射 A * x == b norm(x) == 1

常用函数的凹凸性:

类型 常见函数 说明
仿射 +, -, *, /(常数除法), real, imag, conj, trace, diag, sum, vec, reshape 线性运算,既是凸也是凹
norm, norm(x, p), quad_form, sum_square, maxabs(实数),square, inv_pos, log_sum_exp 可用于 <= 的左侧或 minimize
log, log_det, geo_mean, sqrt, 可用于 >= 的左侧或 maximize

3.3 第2.3小节的凸问题CVX求解

先上代码:

c 复制代码
clear; clc;
K = 4;                % 用户数
M = 4;                % 基站天线数
sigma = 1;            % 噪声标准差(噪声功率 = 1)
num_realizations = 10; % 每个 gamma 值下的随机信道次数(可调,大一点更平滑)

% 定义要扫描的 gamma 范围(线性值)
gamma_vec = 0.5:0.5:4;  % 从 0.5 到 8,步长 0.5
avg_power = zeros(size(gamma_vec)); % 存储每个 gamma 对应的平均功率

fprintf('开始扫描不同 gamma 值...\n');
for g_idx = 1:length(gamma_vec)
    gamma = gamma_vec(g_idx);
    power_sum = 0;
    valid_count = 0;
    
    for z = 1:num_realizations
        H = randn(K, M); % 随机信道
        
        cvx_begin quiet
            variable tau nonnegative
            variable W(M, K) complex
            minimize(tau)
            subject to
                for i = 1:K
                    % SINR 约束(含噪声)
                    norm([H(i,:) * W, sigma]) <= sqrt(1 + 1/gamma) * real(H(i,:) * W(:,i));
                    % 强制接收信号为实数且非负
                    imag(H(i,:) * W(:,i)) == 0;
                    real(H(i,:) * W(:,i)) >= 0;
                end
                norm(vec(W)) <= sqrt(tau);
        cvx_end
        
        % 检查求解状态,只累加成功求解的结果
        if strcmp(cvx_status, 'Solved')
            power_sum = power_sum + tau;
            valid_count = valid_count + 1;
        else
            % 若不可行,忽略该次实现(或可记录失败次数)
            % fprintf('gamma = %.2f, 第 %d 次不可行\n', gamma, z);
        end
    end
    
    if valid_count > 0
        avg_power(g_idx) = power_sum / valid_count;
        fprintf('gamma = %.2f, 有效次数 = %d, 平均功率 = %.4f\n', gamma, valid_count, avg_power(g_idx));
    else
        avg_power(g_idx) = NaN; % 若全部不可行,置 NaN
        fprintf('gamma = %.2f, 无可行的信道实现!\n', gamma);
    end
end

% 绘图:gamma vs 平均最小发射功率
figure;
plot(gamma_vec, avg_power, 'b-o', 'LineWidth', 2);
xlabel('SINR 门限 \gamma (线性值)');
ylabel('平均最小发射功率 (||W||_F^2)');
title(['M=', num2str(M), ', K=', num2str(K), ', 噪声功率 \sigma^2=', num2str(sigma^2), ...
       ', 每个\gamma下随机信道次数=', num2str(num_realizations)]);
grid on;

解释如下:

  1. 这里信道,噪声并没完全按照通信的要求来,随便给了一个数值,只为体现cvx的用法;
  2. 约束和目标函数的写法和第二章的理论完全一致;
  3. 为了克服信道随机性的影响,对同一个横坐标,多次进行随机信道,取结果的平均值以克服随机性的影响。(通信论文里面常用,也叫蒙特卡洛仿真);
  4. CVX代码讲解其实蕴含在理论解释部分以及代码注释部分,这里不再赘述了。

仿真如图:模拟不同SINR要求下的最小功率的变化,SINR要求越高,系统的总发射功率就越大,且增长率也越大,符合物理意义。

4 总结

  • 写了很多年的CVX了,其实感觉不太好用,很多时候理论本身没问题,但是受限于数据的精度或者CVX要求的DCP规则,导致代码仿真出现异常,特别是涉及到迭代的的收敛性很难控制。奈何通信领域用传统凸优化主流还是得用matlab的CVX工具,所以没办法得学。
  • 最近发现了一个叫AMPL的编程,也能够用来求解凸优化问题,我用了一段时间,感觉比CVX好用点,感兴趣也可留言后续会写学习笔记出来。
  • 通信优化问题路漫漫其修远兮~