ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

瑞利衰落与莱斯衰落信道模型:从公式到可运行代码的仿真实现

瑞利衰落与莱斯衰落信道模型:从公式到可运行代码的仿真实现 简介这份资源聚焦无线通信中的瑞利衰落与莱斯衰落信道建模面向通信工程专业学生、科研人员及算法工程师用于理解多径传播环境下信号强度的随机变化规律。压缩包共4个文件以3个m脚本文件和1张jpg示意图为主脚本分别实现瑞利信道与莱斯信道的仿真及对比绘图图片直观展示两种模型的幅度分布差异整体约23KB轻量易运行。目前已有1362人学习下载适合作为课程实验或课题入门的参考素材。通过运行代码读者可调整直射分量、多径增益等参数观察衰落速率与包络分布的变化进而分析分集接收、均衡与编码策略对系统性能的改善效果为OFDM、多址接入等场景下的信道建模与算法验证提供可复用的仿真基础。1. 瑞利衰落和莱斯衰落信道模型从公式到可运行代码一次讲透做无线通信仿真的人迟早会撞上瑞利衰落和莱斯衰落这两个词。做链路级仿真要它做误码率曲线要它做接收机算法验证也要它。但很多人第一次写瑞利信道代码时直接randn一乘就完事结果 BER 曲线跟理论值差了好几个 dB回头查半天不知道错在哪。这个标题指向的就是这件事用可复现的代码把瑞利信道模型和莱斯衰落信道模型搭出来搞清楚包络服从什么分布、相位怎么处理、莱斯因子 K 怎么影响结果。适合正在做通信系统仿真、需要生成信道系数、或者要验证均衡与分集算法的人。下面按“先立住理论、再动手复现、最后排坑”的顺序展开代码以 Python 为主MATLAB 思路一致。2. 瑞利衰落和莱斯衰落到底在描述什么先分清散射环境2.1 瑞利衰落的物理前提没有直射路径瑞利衰落描述的是这样一种场景发射机和接收机之间没有视距分量接收到的信号是大量相互独立的散射波叠加。根据中心极限定理同相分量和正交分量都近似服从零均值高斯分布于是复包络就是一个零均值复高斯随机变量。它的包络服从瑞利分布相位在 $[-\pi, \pi)$ 上均匀分布。这件事的工程含义很直接包络可以深衰落偶尔掉到接近零接收端信噪比波动很大。所以瑞利信道常用来模拟城市密集区、室内非视距等环境。写代码时核心就一句话——生成两个独立零均值高斯序列一个当实部一个当虚部。2.2 莱斯衰落的物理前提有一条主路径莱斯衰落比瑞利多了一个确定性分量也就是视距路径或强主路径。复包络可以写成“主路径 散射分量”的形式。主路径幅度固定散射部分仍然是零均值复高斯。此时包络服从莱斯分布用一个参数 K 来描述主路径功率与散射功率之比。K 趋于零时莱斯退化成瑞利K 越大包络越接近恒定值衰落越浅。这就是为什么视距场景下信道更“稳”而非视距场景下误码率曲线更陡峭地恶化。理解这一点后面调参数就不会盲目。2.3 两种模型的参数对照参数瑞利衰落莱斯衰落说明散射分量零均值复高斯零均值复高斯两者都有直射分量无有幅度 A莱斯独有莱斯因子 K不适用$A^2/(2\sigma^2)$K0 退化为瑞利包络分布瑞利莱斯决定 BER 形状典型场景密集城区、室内郊区、视距链路选型依据选型理由不复杂有明确视距就上莱斯否则用瑞利。别为了“看起来高级”硬套莱斯K 设错反而误导结论。3. 用 Python 生成瑞利信道系数最小可运行代码3.1 复高斯生成法与功率归一化最直接的做法是生成复高斯序列再做功率归一化。下面这段代码可以直接跑输出信道系数和包络分布。import numpy as np import matplotlib.pyplot as plt def rayleigh_channel(N, seed0): rng np.random.default_rng(seed) # 实部和虚部独立零均值高斯方差 0.5 保证总功率为 1 h_real rng.normal(0, np.sqrt(0.5), N) h_imag rng.normal(0, np.sqrt(0.5), N) h h_real 1j * h_imag return h N 100000 h rayleigh_channel(N) envelope np.abs(h) print(平均功率:, np.mean(envelope**2)) # 应接近 1 print(包络均值:, np.mean(envelope)) # 理论 sqrt(pi/4)≈0.886逻辑说明实部虚部方差取 0.5是为了让 $E[|h|^2]1$这是链路仿真里最常见的归一化约定。参数 N 是样本数做分布验证建议不低于 1e5否则直方图毛刺明显。seed 固定保证可复现。运行后平均功率应接近 1包络均值接近 0.886偏离太多说明方差设错了。3.2 用直方图验证包络是否服从瑞利分布生成完不能只看均值要验证分布形状。瑞利分布的概率密度是 $f(r)\frac{r}{\sigma^2}e^{-r^2/(2\sigma^2)}$这里 $\sigma^20.5$。r np.linspace(0, 3, 300) sigma2 0.5 pdf_theory (r / sigma2) * np.exp(-r**2 / (2 * sigma2)) plt.hist(envelope, bins100, densityTrue, alpha0.6, labelsimulation) plt.plot(r, pdf_theory, r, labeltheory) plt.xlabel(envelope) plt.ylabel(pdf) plt.legend() plt.show()参数说明bins 取 100 是经验值样本多可以加到 200。densityTrue 必须开否则直方图是计数不是概率密度跟理论曲线对不上。如果仿真直方图整体右移多半是功率没归一化如果形状不对检查实部虚部是否独立。3.3 把信道作用到 QPSK 符号上看误码光看分布还不够最终要落到 BER。下面把瑞利信道乘到 QPSK 符号上加高斯白噪声做硬判决。def qpsk_ber_rayleigh(EbN0_dB): EbN0 10**(EbN0_dB/10) N 200000 bits np.random.default_rng(1).integers(0, 2, 2*N) sym (2*bits[0::2]-1) 1j*(2*bits[1::2]-1) sym sym / np.sqrt(2) # 归一化符号功率为 1 h rayleigh_channel(N, seed2) noise_var 1 / (2 * EbN0) # 每维噪声方差 noise np.sqrt(noise_var) * (np.random.default_rng(3).normal(sizeN) 1j*np.random.default_rng(4).normal(sizeN)) y h * sym noise y_eq y / h # 理想信道估计下迫零均衡 bits_hat np.zeros(2*N, dtypeint) bits_hat[0::2] (y_eq.real 0).astype(int) bits_hat[1::2] (y_eq.imag 0).astype(int) return np.mean(bits ! bits_hat) for dB in range(0, 21, 5): print(dB, qpsk_ber_rayleigh(dB))逻辑说明这里用了理想信道估计接收端已知 h直接除回去。参数 EbN0_dB 是每比特信噪比噪声方差按 1/(2*EbN0) 算因为 QPSK 每符号两比特且做了功率归一化。跑出来 20 dB 时 BER 大约在 1e-2 量级这就是瑞利信道没有分集时的典型平底跟理论值一致。如果明显偏高先查噪声方差和符号归一化。4. 莱斯信道代码怎么写K 因子怎么设才不翻车4.1 主路径加散射分量的构造方式莱斯信道的复包络写成 $h \sqrt{\frac{K}{K1}} e^{j\phi} \sqrt{\frac{1}{K1}} g$其中 g 是零均值单位功率复高斯$\phi$ 是主路径相位。这样总功率仍然是 1K 就是主路径与散射功率之比。def rician_channel(N, K_dB, seed0): rng np.random.default_rng(seed) K 10**(K_dB/10) los np.sqrt(K/(K1)) * np.exp(1j*2*np.pi*rng.random(N)) nlos np.sqrt(1/(K1)) * (rng.normal(0, np.sqrt(0.5), N) 1j*rng.normal(0, np.sqrt(0.5), N)) return los nlos for K_dB in [-10, 0, 6, 10]: h rician_channel(100000, K_dB) print(K_dB, np.mean(np.abs(h)**2))参数说明K_dB 是莱斯因子以 dB 表示常见取值 0 到 12 dB。K_dB 很小时结果接近瑞利K_dB 很大时包络几乎恒定。主路径相位用均匀随机是因为仿真里通常不关心绝对相位只关心统计特性。平均功率应始终接近 1如果随 K 变化说明归一化写错了。4.2 K 因子对误码率曲线的影响把上面的莱斯信道替换进 QPSK 流程就能看到 K 的作用。def qpsk_ber_rician(EbN0_dB, K_dB): EbN0 10**(EbN0_dB/10) N 200000 bits np.random.default_rng(1).integers(0, 2, 2*N) sym ((2*bits[0::2]-1) 1j*(2*bits[1::2]-1)) / np.sqrt(2) h rician_channel(N, K_dB, seed2) noise_var 1/(2*EbN0) noise np.sqrt(noise_var) * (np.random.default_rng(3).normal(sizeN) 1j*np.random.default_rng(4).normal(sizeN)) y_eq (h*sym noise) / h bits_hat np.zeros(2*N, dtypeint) bits_hat[0::2] (y_eq.real 0).astype(int) bits_hat[1::2] (y_eq.imag 0).astype(int) return np.mean(bits ! bits_hat) for K_dB in [-10, 0, 6, 10]: print(K_dB, qpsk_ber_rician(20, K_dB))逻辑说明K 越大20 dB 处的 BER 越低因为主路径稳定深衰落概率下降。K-10 dB 时结果几乎和瑞利一样这是验证代码正确性的一个好办法。参数设置上做视距场景一般取 K6 到 12 dB做非视距直接退回瑞利模型。4.3 时间相关性怎么加Jakes 模型与滤波法上面生成的都是独立同分布样本真实信道有时间相关性。常见做法是给复高斯序列过一个多普勒滤波器或者用 Jakes 模型的正弦叠加法。工程上更常用滤波法因为实现简单。from scipy.signal import lfilter def correlated_rayleigh(N, fd, fs, seed0): rng np.random.default_rng(seed) # 一阶低通近似截止频率与多普勒频移相关 alpha np.exp(-2*np.pi*fd/fs) b, a [np.sqrt(1-alpha**2)], [1, -alpha] x rng.normal(0, 1, N) 1j*rng.normal(0, 1, N) x x / np.sqrt(2) h lfilter(b, a, x) return h参数说明fd 是最大多普勒频移fs 是采样率alpha 控制相关性强弱。fd/fs 越小相关性越强。这个一阶模型只是近似做严格验证要用 Jakes 或 SUMOF-SINUSOIDS但做算法链路验证足够。注意滤波后功率会变化必要时重新归一化。5. 避坑与排查瑞利和莱斯信道仿真里最容易翻车的 5 个点5.1 现象BER 曲线比理论值低很多甚至为 0原因噪声方差算错或者符号功率没归一化导致实际信噪比偏高。解决固定 EbN0 后打印实际信噪比确认符号平均功率为 1、噪声每维方差为 1/(2*EbN0)。别凭感觉设噪声。5.2 现象包络直方图和瑞利理论对不上原因实部虚部方差设成了 1 而不是 0.5总功率变成 2。解决统一约定 $E[|h|^2]1$实部虚部方差各 0.5。莱斯信道同理主路径和散射分量功率加起来要为 1。5.3 现象莱斯信道 K 调大后 BER 反而变差原因主路径相位固定成 0和某些符号相位对齐后产生系统性偏置或者归一化漏了。解决主路径相位用随机均匀分布并检查平均功率是否恒为 1。K 增大 BER 应单调改善不改善就是代码有问题。5.4 现象加了时间相关性后 BER 曲线抖动剧烈原因滤波器引入瞬态前若干样本未稳态或者相关长度超过仿真块长。解决丢弃前 1000 个样本仿真长度至少是相关长度的 10 倍以上。做块衰落仿真时每块内信道恒定块间独立别混用。5.5 现象换 MATLAB 复现结果对不上原因MATLABrandn和 NumPy 默认随机流不同且randn是方差 1 不是 0.5。解决显式指定方差固定随机种子先对齐平均功率和包络均值再比 BER。别拿不同随机流的单次结果直接对比。6. 进阶技巧用理论 BER 公式反查你的信道代码对不对写完代码怎么确认没写错最可靠的办法是拿理论公式对。瑞利信道下 QPSK 的 BER 有闭式解莱斯信道也有积分形式可以直接算出来跟仿真比。信道QPSK BER 理论用途AWGN$Q(\sqrt{2E_b/N_0})$基准瑞利$\frac{1}{2}(1-\sqrt{\frac{E_b/N_0}{1E_b/N_0}})$验证无分集平底莱斯对瑞利公式做 K 修正积分验证 K 的影响from scipy.special import erfc def qpsk_ber_rayleigh_theory(EbN0_dB): EbN0 10**(EbN0_dB/10) return 0.5*(1 - np.sqrt(EbN0/(1EbN0))) for dB in range(0, 21, 5): print(dB, qpsk_ber_rayleigh_theory(dB))逻辑说明把这段输出和 3.3 的仿真结果并排看20 dB 时理论约 0.0126仿真应在同一量级。如果仿真低一个数量级回去查噪声方差如果高很多查信道是否真的乘进去了。这个反查习惯我用了很多年比盯着代码看有效得多。我自己的习惯是每写一个新信道模型先跑分布验证再跑 BER 对理论两步都过才敢往系统仿真里放。瑞利和莱斯这两个模型看着简单翻车基本都翻在归一化和噪声方差上跟算法本身没关系。希望帮到你。本文还有配套的精品资源点击获取
返回列表