矩阵知识补充:
矩阵 A A ∗ AA^* AA∗(其中 A A A是一个复数矩阵, A ∗ A^* A∗是其共轭转置)的迹(即对角元素之和)具有几个重要的特性:
-
非负性:由于 A A ∗ AA^* AA∗是正定或至少是半正定的,
它的对角元素必然是实数
,它的所有特征值都是非负实数
。因为矩阵的迹等于其所有特征值的和,所以 A A ∗ AA^* AA∗的迹也是非负实数。 -
与内积的关系:在某种意义上, A A ∗ AA^* AA∗的迹可以看作是矩阵 A A A各列向量之间内积的总和。具体来说,如果将 A A A的列视为向量,则 A A ∗ AA^* AA∗的迹实际上是这些列向量各自的模长平方和,反映了 A A A在空间中扩展或压缩体积的能力。
-
度量矩阵的规模:在应用中, A A ∗ AA^* AA∗的迹常被用来衡量矩阵的总体“规模”或“能量”。例如,在信号处理领域,对于信号的自相关矩阵(通常形如 A A ∗ AA^* AA∗),其迹可以解释为信号的总功率。
-
-
-
MIMO系统信道容量表达式中的行列式(det)?
1. 从单天线到多天线的推广
在单天线(SISO)系统中,香农容量公式为:
C = log 2 ( 1 + SNR ⋅ ∣ h ∣ 2 ) C = \log_2 \left( 1 + \text{SNR} \cdot |h|^2 \right) C=log2(1+SNR⋅∣h∣2)
其中 h h h是信道增益,容量与信道的功率增益 ∣ h ∣ 2 |h|^2 ∣h∣2直接相关。
在多天线(MIMO)系统中,信道变成一个矩阵 H \mathbf{H} H,其容量不再是单一信道的相加,而是通过矩阵的奇异值(或特征值)表征多个并行的子信道。每个子信道相当于独立的传输路径,它们的容量可以叠加。
2. 为什么需要行列式(det)?
行列式的物理意义在于它量化了一个线性变换的“体积缩放因子”。在MIMO信道中, d e t ( I + S N R ∗ H H H ) det(I + SNR * H^H H) det(I+SNR∗HHH) 的作用是:
- 将所有并行子信道的贡献统一表达:矩阵 H H H \mathbf{H}^H \mathbf{H} HHH的特征值表示各个子信道的增益(平方奇异值 σ i 2 \sigma_i^2 σi2)。
- 乘积反映总容量:
行列式是矩阵特征值的乘积
,因此:
det ( I + SNR ⋅ H H H ) = ∏ i = 1 n T ( 1 + SNR ⋅ σ i 2 ) \det(\mathbf{I} + \text{SNR} \cdot \mathbf{H}^H \mathbf{H}) = \prod_{i=1}^{n_T} \left( 1 + \text{SNR} \cdot \sigma_i^2 \right) det(I+SNR⋅HHH)=i=1∏nT(1+SNR⋅σi2)
每个因子 ( 1 + SNR ⋅ σ i 2 ) (1 + \text{SNR} \cdot \sigma_i^2) (1+SNR⋅σi2)对应一个子信道的容量,总容量是它们的乘积取对数。
3. 数学推导步骤
(1)奇异值分解(SVD)
对MIMO信道矩阵进行奇异值分解:
H = U Σ V H , \mathbf{H} = \mathbf{U} \mathbf{\Sigma} \mathbf{V}^H, H=UΣVH,
其中 Σ \mathbf{\Sigma} Σ是对角矩阵,包含奇异值 σ i \sigma_i σi,代表各子信道的增益。
(2)等效标子信道模型
通过预编码和合并,MIMO信道可以解耦为多个并行子信道,每个子信道的容量为:
C i = log 2 ( 1 + SNR n T σ i 2 ) C_i = \log_2 \left( 1 + \frac{\text{SNR}}{n_T} \sigma_i^2 \right) Ci=log2(1+nTSNRσi2)
(3)总容量的合并
总容量是所有子信道容量之和:
C 总 = ∑ i = 1 n T C i = log 2 ∏ i = 1 n T ( 1 + SNR n T σ i 2 ) C_{\text{总}} = \sum_{i=1}^{n_T} C_i = \log_2 \prod_{i=1}^{n_T} \left( 1 + \frac{\text{SNR}}{n_T} \sigma_i^2 \right) C总=i=1∑nTCi=log2i=1∏nT(1+nTSNRσi2)
而特征值的乘积对应于行列式:
∏ i = 1 n T ( 1 + SNR n T λ i ) = det ( I + SNR n T H H H ) , \prod_{i=1}^{n_T} \left( 1 + \frac{\text{SNR}}{n_T} \lambda_i \right) = \det\left( \mathbf{I} + \frac{\text{SNR}}{n_T} \mathbf{H}^H \mathbf{H} \right), i=1∏nT(1+nTSNRλi)=det(I+nTSNRHHH),
因此总容量可简洁地表示为:
C OL = log 2 det ( I + SNR n T H H H ) . C_{\text{OL}} = \log_2 \det\left( \mathbf{I} + \frac{\text{SNR}}{n_T} \mathbf{H}^H \mathbf{H} \right). COL=log2det(I+nTSNRHHH).
4. 物理意义
- 并行传输:MIMO系统通过空间维度创建多个独立的子信道,行列式 det \det det的作用是统计这些子信道的总容量。
- 对数的性质: log ( det ( ⋅ ) ) \log(\det(\cdot)) log(det(⋅))本质上是 ∑ log ( ⋅ ) \sum \log(\cdot) ∑log(⋅),这继承了香农公式中对数叠加的思想。
- 均匀功率分配:开环条件下功率均分到所有天线上,因此每个子信道的功率为 SNR n T \frac{\text{SNR}}{n_T} nTSNR。
5. 对比闭环容量
在闭环容量(如注水算法)中,功率不再均匀分配。优化后的容量表达式为:
C CL = ∑ i = 1 r log 2 ( 1 + p i σ i 2 n T ) , C_{\text{CL}} = \sum_{i=1}^{r} \log_2 \left( 1 + p_i \frac{\sigma_i^2}{n_T} \right), CCL=i=1∑rlog2(1+pinTσi2),
其中 p i p_i pi是注水算法优化的功率分配值。此时 det \det det不再直接出现,而是显式地写出每个子信道的影响。
闭环容量公式中没有使用 det \det det的原因是:功率分配改变了每个子信道的增益权重,无法直接用统一的行列式表达式覆盖动态调整的功率¹。但若将功率分配矩阵显式写出,仍然可以通过行列式表达:
C CL = log 2 det ( I + 1 n T Γ Σ 2 ) , C_{\text{CL}} = \log_2 \det\left( \mathbf{I} + \frac{1}{n_T} \mathbf{\Gamma} \mathbf{\Sigma}^2 \right), CCL=log2det(I+nT1ΓΣ2),
其中 Γ = diag ( p 1 , p 2 , … , p n T ) \mathbf{\Gamma} = \text{diag}(p_1, p_2, \dots, p_{n_T}) Γ=diag(p1,p2,…,pnT)。
总结
- 行列式的作用:在开环容量中,行列式 det \det det是将多个独立子信道的容量合并成一个紧凑表达式的数学工具,体现了多天线系统的空间复用本质。
- 对比单天线系统:在单天线系统中,总容量直接相加;在多天线系统中,行列式自然地将独立子信道的乘积转换为对数和(通过 log ∏ = ∑ log \log \prod = \sum \log log∏=∑log)。
通过这个视角可以看出,行列式的出现是信息论在多天线系统中的数学抽象,是容量计算在矩阵领域的推广。
¹ 闭环容量也可用行列式表达,但需显式包含功率分配矩阵。在代码实现中,这通过 np.diag(Gamma)
体现。
开环和闭环信道容量的数学表达式推导过程:
1. MIMO系统模型
假设一个 n T × n R n_T \times n_R nT×nR的 MIMO 系统,信道矩阵为 H \mathbf{H} H,其建模为:
H = R rx 1 / 2 H w R tx 1 / 2 \mathbf{H} = \mathbf{R}_{\text{rx}}^{1/2} \mathbf{H}_w \mathbf{R}_{\text{tx}}^{1/2} H=Rrx1/2HwRtx1/2
其中:
- H w \mathbf{H}_w Hw是独立同分布(i.i.d.)的复高斯信道矩阵,元素服从 C N ( 0 , 1 ) \mathcal{CN}(0,1) CN(0,1)。
- R tx \mathbf{R}_{\text{tx}} Rtx和 R rx \mathbf{R}_{\text{rx}} Rrx是发射端和接收端的相关矩阵(代码中为指数衰减相关模型)。
2. 开环信道容量(Channel Unknown)
假设条件:
- 发射端 不知道 信道状态信息(CSI),功率均匀分配到所有天线上。
数学推导:
-
等效信道协方差矩阵:
H H H = U Λ U H \mathbf{H}^H \mathbf{H} = \mathbf{U} \mathbf{\Lambda} \mathbf{U}^H HHH=UΛUH
其中 Λ = diag ( λ 1 , λ 2 , … , λ n T ) \mathbf{\Lambda} = \text{diag}(\lambda_1, \lambda_2, \dots, \lambda_{n_T}) Λ=diag(λ1,λ2,…,λnT), λ i \lambda_i λi是奇异值的平方。 -
容量公式:
开环容量由以下公式给出:
C OL = E [ log 2 det ( I + SNR n T H H H ) ] C_{\text{OL}} = \mathbb{E} \left[ \log_2 \det \left( \mathbf{I} + \frac{\text{SNR}}{n_T} \mathbf{H}^H \mathbf{H} \right) \right] COL=E[log2det(I+nTSNRHHH)]- 由于功率均匀分配,每个天线的功率为 SNR n T \frac{\text{SNR}}{n_T} nTSNR。
- 公式中的期望 E [ ⋅ ] \mathbb{E}[\cdot] E[⋅]是对信道矩阵 H \mathbf{H} H的统计平均(代码中通过蒙特卡洛仿真实现)。
-
代码对应:
tmp = H.conj().T @ H / nT C_44_OL[i] += np.log2(np.linalg.det(I + SNR_linear[i] * tmp))
tmp
对应 1 n T H H H \frac{1}{n_T} \mathbf{H}^H \mathbf{H} nT1HHH,因此容量公式中为 I + SNR ⋅ H H H n T \mathbf{I} + \text{SNR} \cdot \frac{\mathbf{H}^H \mathbf{H}}{n_T} I+SNR⋅nTHHH。
3. 闭环信道容量(Channel Known)
假设条件:
- 发射端 知道 信道状态信息(CSI),通过注水算法优化功率分配。
数学推导:
-
奇异值分解(SVD):
对信道矩阵进行 SVD 分解:
H = U Σ V H \mathbf{H} = \mathbf{U} \mathbf{\Sigma} \mathbf{V}^H H=UΣVH
- Σ = diag ( σ 1 , σ 2 , … , σ n T ) \mathbf{\Sigma} = \text{diag}(\sigma_1, \sigma_2, \dots, \sigma_{n_T}) Σ=diag(σ1,σ2,…,σnT),其中 σ i = λ i \sigma_i = \sqrt{\lambda_i} σi=λi是奇异值。 -
注水算法优化功率分配:
- 优化目标:最大化信道容量:
C CL = max { p i } ∑ i = 1 n T log 2 ( 1 + p i σ i 2 n T ) C_{\text{CL}} = \max_{\{p_i\}} \sum_{i=1}^{n_T} \log_2 \left( 1 + \frac{p_i \sigma_i^2}{n_T} \right) CCL={ pi}maxi=1∑nTlog2(1+nTpiσi2)
约束条件为:
∑ i = 1 n T p i = SNR , p i ≥ 0 \sum_{i=1}^{n_T} p_i = \text{SNR}, \quad p_i \ge 0 i=1∑nTpi=SNR,pi≥0 - 注水算法解:
p i = ( μ − n T σ i 2 ) + p_i = \left( \mu - \frac{n_T}{\sigma_i^2} \right)^+ pi=(μ−σi2nT)+
其中 μ \mu μ是注水水平,满足 ∑ p i = SNR \sum p_i = \text{SNR} ∑pi=SNR。
- 优化目标:最大化信道容量:
-
闭环容量公式:
优化后的容量为:
C CL = E [ ∑ i = 1 n T log 2 ( 1 + p i σ i 2 n T ) ] C_{\text{CL}} = \mathbb{E} \left[ \sum_{i=1}^{n_T} \log_2 \left( 1 + \frac{p_i \sigma_i^2}{n_T} \right) \right] CCL=E[i=1∑nTlog2(1+nTpiσi2)]
或等价地:
C CL = E [ log 2 det ( I + SNR n T Γ Σ 2 ) ] C_{\text{CL}} = \mathbb{E} \left[ \log_2 \det \left( \mathbf{I} + \frac{\text{SNR}}{n_T} \mathbf{\Gamma} \mathbf{\Sigma}^2 \right) \right] CCL=E[log2det(I+nTSNRΓΣ2)]
其中 Γ = diag ( p 1 , p 2 , … , p n T ) \mathbf{\Gamma} = \text{diag}(p_1, p_2, \dots, p_{n_T}) Γ=diag(p1,p2,…,pnT)。 -
代码对应:
Gamma = water_pouring(SV, SNR_linear[i], nT) C_44_CL[i] += np.log2(np.linalg.det(I + SNR_linear[i]/nT * np.diag(Gamma) @ np.diag(SV)))
SV
是奇异值 σ i \sigma_i σi的数组,对应 Σ \mathbf{\Sigma} Σ。Gamma
是注水算法计算出的功率分配系数 p i p_i pi,对应 Γ \mathbf{\Gamma} Γ。
4. 注水算法的数学核心
-
问题形式化:
max { p i } ∑ i = 1 r log 2 ( 1 + p i λ i n T ) , s.t. ∑ i = 1 r p i = SNR , p i ≥ 0 \max_{\{p_i\}} \sum_{i=1}^{r} \log_2 \left( 1 + \frac{p_i \lambda_i}{n_T} \right), \quad \text{s.t.} \quad \sum_{i=1}^{r} p_i = \text{SNR}, \quad p_i \ge 0 { pi}maxi=1∑rlog2(1+nTpiλi),s.t.i=1∑rpi=SNR,pi≥0
其中 λ i = σ i 2 \lambda_i = \sigma_i^2 λi=σi2, r r r是有效子信道数(取决于信道秩)。 -
拉格朗日乘数法:
构造拉格朗日函数:
L = ∑ i = 1 r log 2 ( 1 + p i λ i n T ) − μ ( ∑ i = 1 r p i − SNR ) \mathcal{L} = \sum_{i=1}^{r} \log_2 \left( 1 + \frac{p_i \lambda_i}{n_T} \right) - \mu \left( \sum_{i=1}^{r} p_i - \text{SNR} \right) L=i=1∑rlog2(1+nTpiλi)−μ(i=1∑rpi−SNR)
对 p i p_i pi求导并令导数为零,得到:
λ i / n T 1 + p i λ i n T = μ ⇒ p i = ( 1 μ − n T λ i ) + \frac{\lambda_i / n_T}{1 + \frac{p_i \lambda_i}{n_T}} = \mu \quad \Rightarrow \quad p_i = \left( \frac{1}{\mu} - \frac{n_T}{\lambda_i} \right)^+ 1+nTpiλiλi/nT=μ⇒pi=(μ1−λinT)+
其中 μ \mu μ是注水阈值,需满足总功率约束。
5. 关键区别总结
场景 | 功率分配 | 容量公式 |
---|---|---|
开环 | 均匀分配 p i = SNR / n T p_i = \text{SNR}/n_T pi=SNR/nT | C OL = E [ log 2 det ( I + SNR n T H H H ) ] C_{\text{OL}} = \mathbb{E} \left[ \log_2 \det \left( \mathbf{I} + \frac{\text{SNR}}{n_T} \mathbf{H}^H \mathbf{H} \right) \right] COL=E[log2det(I+nTSNRHHH)] |
闭环 | 注水算法优化 p i p_i pi | C CL = E [ ∑ i = 1 r log 2 ( 1 + p i λ i n T ) ] C_{\text{CL}} = \mathbb{E} \left[ \sum_{i=1}^{r} \log_2 \left( 1 + \frac{p_i \lambda_i}{n_T} \right) \right] CCL=E[∑i=1rlog2(1+nTpiλi)] |
6. 物理意义
-
开环:
- 功率均匀分配,适用于信道快速变化或反馈受限的场景。
- 容量由信道矩阵的奇异值分布决定,无法主动优化。
-
闭环:
- 通过注水算法将更多功率分配给质量更好的子信道(奇异值大的方向)。
- 在高SNR时,容量增益显著,体现了信道状态信息的重要性。
# time: 2025/2/20 19:54
# author: YanJP
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import sqrtm # 用于计算矩阵的平方根
# 注水算法函数
def water_pouring(Lamda, SNR, nT):
Gamma = np.zeros_like(Lamda)
r = len(Lamda)
index = np.arange(r)
index_temp = index.copy()
p = 1
while p < r:
irp = np.arange(r - p + 1)
temp = np.sum(1 / Lamda[index_temp[irp]])
mu = nT / (r - p + 1) * (1 + 1 / SNR * temp)
Gamma[index_temp[irp]] = mu - nT / (SNR * Lamda[index_temp[irp]])
if np.min(Gamma[index_temp]) < 0:
i = np.argmin(Gamma)
ii = np.where(index_temp == i)[0][0]
index_temp = np.concatenate((index_temp[:ii], index_temp[ii + 1:]))
p += 1
Gamma = np.zeros_like(Lamda)
else:
p = r
Gamma_t = np.zeros_like(Lamda)
Gamma_t[index_temp] = Gamma[index_temp]
return Gamma_t
# 程序功能说明
# 观察MIMO在开环和闭环下的信道容量,注水算法的理论
SNR_dB = np.arange(0, 21, 5)
SNR_linear = 10 ** (SNR_dB / 10)
N_iter = 1000
# 4x4 MIMO配置
nT = 4
nR = 4
n = min(nT, nR)
I = np.eye(n)
rho = 0.2
sq2 = np.sqrt(0.5)
# 发射端和接收端相关矩阵
Rtx = np.array([
[1, rho, rho**2, rho**3],
[rho, 1, rho, rho**2],
[rho**2, rho, 1, rho],
[rho**3, rho**2, rho, 1]
])
Rrx = np.array([
[1, rho, rho**2, rho**3],
[rho, 1, rho, rho**2],
[rho**2, rho, 1, rho],
[rho**3, rho**2, rho, 1]
])
C_44_OL = np.zeros(len(SNR_dB))
C_44_CL = np.zeros(len(SNR_dB))
for iter in range(N_iter):
Hw = sq2 * (np.random.randn(nR, nT) + 1j * np.random.randn(nR, nT))
# 使用 scipy.linalg.sqrtm 计算矩阵的平方根
H = sqrtm(Rrx) @ Hw @ sqrtm(Rtx)
tmp = H.conj().T @ H / nT
SV = np.linalg.svd(H.conj().T @ H, compute_uv=False)
for i in range(len(SNR_dB)):
# 开环容量
C_44_OL[i] += np.log2(np.linalg.det(I + SNR_linear[i] * tmp))
# 闭环容量(使用注水算法)
Gamma = water_pouring(SV, SNR_linear[i], nT)
C_44_CL[i] += np.log2(np.linalg.det(I + SNR_linear[i] / nT * np.diag(Gamma) @ np.diag(SV)))
C_44_OL = np.real(C_44_OL) / N_iter
C_44_CL = np.real(C_44_CL) / N_iter
# 绘制结果
plt.figure()
plt.plot(SNR_dB, C_44_OL, '-o', label='Channel Unknown')
plt.plot(SNR_dB, C_44_CL, '-<', label='Channel Known')
plt.xlabel('SNR [dB]')
plt.ylabel('bps/Hz')
plt.grid(True)
plt.legend()
plt.show()