
简介这份文档面向无线通信、移动信道建模方向的学习者与研究人员系统梳理多径衰落中瑞利分布、莱斯分布与Jakes模型的数学推导过程。内容从多径传播的物理成因切入逐步推导包络概率密度函数并结合MATLAB仿真验证理论曲线帮助读者理解无直射路径与存在直射路径两种场景下的信道统计特性以及多普勒频移对频谱的影响。资源包内含1个docx文档约659KB以推导笔记与仿真程序说明为主结构紧凑便于对照公式与代码逐段研读。目前已有257人学习下载适合需要夯实无线信道理论基础、准备课程设计或开展相关仿真实验的读者参考可据此快速把握三种模型的推导脉络与仿真验证思路。1. 瑞利、莱斯、Jakes 推导进程从无线信道模型到可复现的仿真链路做无线通信仿真的工程师几乎都绕不开一个场景基站和终端之间没有直射路径信号全靠建筑物、车辆、树木反射过来接收端看到的是一个包络忽大忽小、相位随机跳变的波形。这时候翻教材瑞利分布、莱斯分布、Jakes 模型三个词会同时砸过来但真正动手写代码时才发现——公式能看懂参数不知道怎么设仿真出来的自相关函数和理论曲线对不上多普勒谱更是怎么看怎么别扭。这篇笔记就围绕「瑞利、莱斯、Jakes 推导进程」这条线把三个模型之间的数学血缘关系理清楚再给出一套从均匀随机数出发、逐步生成瑞利衰落、莱斯衰落和 Jakes 仿真信道的可复现流程。适合正在做链路级仿真、信道建模验证或者需要给论文补仿真图的从业者。读完你至少能拿到三样东西一条清晰的推导链路、一份能直接跑的 Python 代码、以及几个我踩过的参数坑。2. 从两个高斯变量到瑞利分布推导链路的第一环2.1 为什么瑞利分布是「无直射路径」的默认答案先把这个问题的物理背景说清楚。无线信号在传播过程中遇到障碍物会发生反射、散射和绕射接收端收到的是大量幅度和相位都随机的多径分量叠加。根据中心极限定理当多径分量足够多且相互独立时同相分量和正交分量的联合分布趋近于高斯分布。设同相分量为 $X$正交分量为 $Y$两者独立且均服从 $N(0, \sigma^2)$那么接收信号的包络 $R \sqrt{X^2 Y^2}$ 就服从瑞利分布。这个推导不是数学游戏它直接决定了仿真时怎么生成瑞利衰落。很多人一上来就调np.random.rayleigh()这当然没错但如果你不理解它背后是两个高斯变量的模后面做莱斯分布和 Jakes 模型时就会卡住——因为莱斯只是在同相分量上加了一个直射分量Jakes 则是给这两个高斯分量注入了时间相关性。瑞利分布的概率密度函数为$$f_R(r) \frac{r}{\sigma^2} \exp\left(-\frac{r^2}{2\sigma^2}\right), \quad r \geq 0$$其中 $\sigma$ 是高斯分量的标准差$2\sigma^2$ 是包络的均方值也就是平均功率。这里有个容易翻车的点很多教材用 $\Omega E[R^2] 2\sigma^2$ 表示平均功率如果你在代码里直接把 $\Omega$ 当 $\sigma$ 用仿真出来的包络均值会差 $\sqrt{\pi/2}$ 倍和理论曲线对不上。2.2 用 Python 从高斯变量生成瑞利衰落的最小验证下面这段代码不调现成的瑞利分布函数而是从两个高斯变量出发手动构造包络再和理论 PDF 对比。这样做的好处是每一步都透明后面改造成莱斯和 Jakes 时只需要动其中一两行。import numpy as np import matplotlib.pyplot as plt # 参数设置 N 200000 # 样本数越大统计越平滑 sigma 1.0 # 每个高斯分量的标准差 Omega 2 * sigma**2 # 平均功率注意不是 sigma # 生成同相和正交分量 X np.random.normal(0, sigma, N) Y np.random.normal(0, sigma, N) # 包络 R np.sqrt(X**2 Y**2) # 理论 PDF r_theory np.linspace(0, 6*sigma, 500) pdf_theory (r_theory / sigma**2) * np.exp(-r_theory**2 / (2*sigma**2)) # 直方图对比 plt.hist(R, bins100, densityTrue, alpha0.6, labelSimulation) plt.plot(r_theory, pdf_theory, r-, linewidth2, labelTheory) plt.xlabel(Envelope r) plt.ylabel(PDF) plt.legend() plt.title(Rayleigh Fading: Simulation vs Theory) plt.show() # 验证平均功率 print(fSimulated mean power: {np.mean(R**2):.4f}) print(fTheoretical mean power: {Omega:.4f})这段代码的逻辑很直白先生成两路独立高斯随机变量再取模得到包络。参数说明上sigma控制的是每一路的方差Omega才是最终包络的平均功率。运行后你会看到直方图和理论曲线基本重合mean(R**2)也会稳定在 2.0 附近。如果这两项对不上先检查sigma和Omega的关系有没有搞反。注意样本数 N 建议不低于 10 万否则直方图尾部抖动明显容易误判为模型错误。3. 莱斯分布加一条直射路径后推导进程怎么改3.1 直射分量对包络分布的影响瑞利分布假设所有多径分量都是散射波没有直射路径。但实际场景中比如郊区开阔地、卫星通信、或者基站天线挂高足够时接收端会收到一条明显的直射波。这时候同相分量上要叠加一个确定性的幅度 $A$正交分量不变包络变成$$R \sqrt{(X A)^2 Y^2}$$其中 $X, Y$ 仍然服从 $N(0, \sigma^2)$。这个包络服从莱斯分布PDF 为$$f_R(r) \frac{r}{\sigma^2} \exp\left(-\frac{r^2 A^2}{2\sigma^2}\right) I_0\left(\frac{rA}{\sigma^2}\right), \quad r \geq 0$$$I_0(\cdot)$ 是零阶修正贝塞尔函数。这里引入一个关键参数 $K A^2 / (2\sigma^2)$也就是直射功率与散射功率之比。$K 0$ 时莱斯退化为瑞利$K \to \infty$ 时包络趋近于确定性常量 $A$。工程上常用 $K$ 因子来描述信道有多「硬」。3.2 莱斯衰落的仿真实现与 K 因子扫描下面的代码在瑞利的基础上加了一个直射分量并且扫描不同的 $K$ 值观察 PDF 形状的变化。这里用scipy.special.i0计算贝塞尔函数避免自己写数值积分。import numpy as np import matplotlib.pyplot as plt from scipy.special import i0 N 200000 sigma 1.0 K_dB_list [-10, 0, 6, 12] # K因子单位dB r_theory np.linspace(0, 8, 500) plt.figure(figsize(10, 6)) for K_dB in K_dB_list: K 10**(K_dB / 10) # 由K反推直射幅度AK A^2/(2*sigma^2) A np.sqrt(2 * sigma**2 * K) X np.random.normal(0, sigma, N) Y np.random.normal(0, sigma, N) R np.sqrt((X A)**2 Y**2) # 理论PDF pdf (r_theory / sigma**2) * np.exp(-(r_theory**2 A**2) / (2*sigma**2)) * i0(r_theory * A / sigma**2) plt.hist(R, bins100, densityTrue, alpha0.4, labelfSim K{K_dB}dB) plt.plot(r_theory, pdf, linewidth2) plt.xlabel(Envelope r) plt.ylabel(PDF) plt.legend() plt.title(Rician Fading: K-factor Sweep) plt.show()参数说明上K_dB是工程上更常用的表达方式转换公式是 $K 10^{K_{dB}/10}$。直射幅度 $A$ 由 $K$ 和 $\sigma$ 共同决定不能随便设。运行后你会看到$K -10$ dB 时曲线几乎和瑞利重合$K 12$ dB 时峰值明显右移越来越像高斯分布。这就是莱斯分布的核心行为。提示如果仿真曲线在 $r$ 接近 0 时出现理论值发散而仿真值有限的情况检查i0的参数是否溢出。当 $rA/\sigma^2$ 很大时i0会迅速增大建议用scipy.special.i0e做指数缩放。4. Jakes 模型给瑞利衰落注入时间相关性4.1 从「独立样本」到「时间序列」的跨越前面两章生成的瑞利和莱斯样本都是独立同分布的也就是说相邻两个时刻的衰落值没有任何关系。但真实信道不是这样的——终端移动时信道变化是连续的存在时间相关性表现为多普勒功率谱。Jakes 模型就是用来生成这种具有特定多普勒谱的时间相关瑞利衰落序列的经典方法。Jakes 模型的核心思想是用有限个正弦波叠加来逼近大量散射分量叠加的效果。标准 Jakes 仿真器用 $N_0$ 个振荡器每个振荡器的频率和相位有特定关系最终输出的复包络实部和虚部都是高斯过程且自相关函数满足$$R(\tau) J_0(2\pi f_d \tau)$$$J_0(\cdot)$ 是零阶贝塞尔函数$f_d$ 是最大多普勒频移。这个自相关函数对应的功率谱就是经典的 U 型谱也叫 Jakes 谱在 $f \pm f_d$ 处有尖峰。4.2 标准 Jakes 仿真器的代码实现与自相关验证下面给出一个常用的 Jakes 仿真器实现采用 $N_0 8$ 个振荡器的配置。这个版本在工程上足够用计算量也不大。import numpy as np import matplotlib.pyplot as plt from scipy.special import j0 def jakes_fading(N_samples, fd, fs, N08): 生成Jakes模型瑞利衰落序列 N_samples: 输出样本数 fd: 最大多普勒频移(Hz) fs: 采样率(Hz) N0: 振荡器数量通常取8或16 t np.arange(N_samples) / fs # 振荡器角度 alpha_n 2 * np.pi * np.arange(1, N0 1) / (2 * N0 1) # 多普勒频率分量 omega_n 2 * np.pi * fd * np.cos(alpha_n) # 实部和虚部 real_part np.zeros(N_samples) imag_part np.zeros(N_samples) for n in range(N0): # 每个振荡器贡献两个正弦分量 real_part 2 * np.cos(alpha_n[n]) * np.cos(omega_n[n] * t) imag_part 2 * np.sin(alpha_n[n]) * np.cos(omega_n[n] * t) # 归一化使平均功率为1 norm_factor np.sqrt(2 * (2 * N0 1)) h (real_part 1j * imag_part) / norm_factor return h # 参数 fs 10000 # 采样率10kHz fd 100 # 最大多普勒100Hz N 100000 h jakes_fading(N, fd, fs, N08) envelope np.abs(h) # 验证自相关 max_lag 200 lags np.arange(max_lag) acf_sim np.array([np.mean(envelope[:N-lag] * envelope[lag:]) for lag in lags]) acf_sim / acf_sim[0] # 理论自相关包络平方的自相关与J0的关系需注意这里对比复包络实部 acf_theory j0(2 * np.pi * fd * lags / fs) plt.plot(lags / fs * 1000, acf_sim, b-, labelSimulated ACF) plt.plot(lags / fs * 1000, acf_theory, r--, labelTheory J0) plt.xlabel(Lag (ms)) plt.ylabel(Normalized ACF) plt.legend() plt.title(Jakes Model: Autocorrelation Verification) plt.show() # 验证平均功率 print(fMean power: {np.mean(np.abs(h)**2):.4f})这段代码的逻辑是用 $N_0$ 个振荡器每个振荡器对应一个到达角 $\alpha_n$产生一对正弦分量最后叠加并归一化。参数说明上N0越大仿真越接近理论但计算量线性增长fd由终端移动速度和载波频率决定$f_d v f_c / c$fs要满足采样定理至少大于 $2 f_d$工程上建议 $f_s \geq 10 f_d$。运行后你会看到自相关曲线和 $J_0$ 理论曲线在前几个毫秒内吻合较好但尾部会有偏差——这是 Jakes 模型本身的统计特性决定的不是代码写错了。标准 Jakes 仿真器生成的信号是广义平稳的但不是各态历经的时间平均和统计平均在有限样本下会有差异。注意如果你用np.correlate直接算自相关记得做归一化否则不同长度的序列没法对比。另外包络的自相关和复包络的自相关不是一回事别拿包络去对 $J_0$。5. 避坑与排查推导进程中最容易翻车的五个点5.1 现象仿真 PDF 和理论曲线整体平移原因把平均功率 $\Omega$ 和方差 $\sigma^2$ 搞混了。瑞利分布中 $E[R^2] 2\sigma^2$如果你直接把 $\Omega$ 当 $\sigma$ 用包络会整体缩小 $\sqrt{2}$ 倍。解决在代码里显式写出sigma np.sqrt(Omega / 2)并且用mean(R**2)验证。5.2 现象莱斯分布 K 因子扫描时曲线形状不变原因$K$ 因子和直射幅度 $A$ 的换算写错了。常见错误是 $A \sqrt{K}$ 而不是 $A \sqrt{2\sigma^2 K}$。解决固定 $\sigma$用 $A \sigma \sqrt{2K}$ 计算并且打印 $A$ 和 $K$ 确认。5.3 现象Jakes 模型自相关尾部振荡严重原因$N_0$ 取值太小或者归一化因子不对。标准 Jakes 仿真器的归一化因子是 $\sqrt{2(2N_01)}$不是 $\sqrt{2N_0}$。解决把 $N_0$ 提高到 16 或 32检查归一化公式并用mean(abs(h)**2)确认平均功率为 1。5.4 现象多普勒谱出现对称的伪峰原因采样率 $f_s$ 不够或者振荡器频率映射时用了错误的到达角分布。标准 Jakes 用 $\alpha_n 2\pi n / (2N_01)$不是均匀分布。解决提高 $f_s$ 到至少 $10 f_d$检查 $\alpha_n$ 的公式。5.5 现象仿真速度慢到无法接受原因用 Python 循环逐个样本生成或者 $N_0$ 设得过大。解决把振荡器循环向量化用np.outer一次性生成所有样本$N_0$ 取 8 或 16 足够再大对统计特性改善有限。6. 进阶技巧用谱验证代替自相关验证以及一个我常用的参数习惯前面用自相关验证 Jakes 模型其实还有一个更直观的方法直接看多普勒功率谱。自相关和功率谱是傅里叶变换对但谱的形状更容肉眼判断——标准 Jakes 谱应该在 $\pm f_d$ 处有尖峰中间凹陷。如果你仿真出来的谱是平的或者尖峰位置不对说明振荡器频率映射有问题。下面这段代码在 Jakes 仿真器基础上加一个谱估计用 Welch 方法from scipy.signal import welch # 生成更长的序列以提高谱分辨率 N_long 500000 h_long jakes_fading(N_long, fd, fs, N016) # 计算功率谱 f, Pxx welch(h_long, fsfs, nperseg4096, return_onesidedFalse) f np.fft.fftshift(f) Pxx np.fft.fftshift(Pxx) plt.plot(f, 10*np.log10(Pxx)) plt.xlabel(Frequency (Hz)) plt.ylabel(PSD (dB)) plt.title(Doppler Spectrum of Jakes Model) plt.xlim(-2*fd, 2*fd) plt.show()参数说明nperseg控制频率分辨率越大谱越平滑但时间分辨率下降return_onesidedFalse保留负频率因为多普勒谱是对称的。运行后你应该看到在 $\pm 100$ Hz 附近有两个尖峰中间凹陷这就是 U 型谱。我自己的习惯是每次改完 Jakes 参数先跑谱估计确认尖峰位置和形状对了再去看自相关。因为自相关对尾部偏差不敏感而谱对频率映射错误非常敏感。另外如果你要做链路级仿真Jakes 模型生成的是复包络记得在加噪声之前把功率归一化到 1否则信噪比会算错。最后一个血泪教训不要用np.random.rayleigh生成 Jakes 序列再去做时间相关那样出来的东西自相关是冲激函数和真实信道完全不是一回事。Jakes 的核心价值就在于时间相关性丢了相关性就只剩一个瑞利分布的空壳。希望帮到你。本文还有配套的精品资源点击获取