十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

超奈奎斯特(FTN)容量仿真的MATLAB实现与参数边界解析

超奈奎斯特(FTN)容量仿真的MATLAB实现与参数边界解析 简介面向通信专业研究人员与高年级学生的超奈奎斯特FTN信道容量仿真资源包聚焦在不增加带宽的前提下突破奈奎斯特速率极限的理论验证与算法实现。压缩包共18个文件37.36MB以MATLAB脚本.m为核心附带滤波/脉冲成型参数.mat与结果图.fig可支撑信道建模、信号调制、误码率分析及容量计算等环节的复现实验。当前已有149人学习下载。通过运行capacity系列脚本与on_orthogonal示例可直观查看alpha、beta、脉冲成型因子等参数对FTN系统容量与性能的影响并对比传统奈奎斯特系统的差异尤其适合用于科研预研、课程设计或毕业设计中的仿真验证。资源内包含RRC、RC脉冲成型的多组系数和波形图便于研究非正交信号条件下的信道容量优化策略。1. 超奈奎斯特容量仿真先从一组反直觉参数说起压缩包里反复出现alpha 0.8, beta [0.2 0.5], T 0.5这样一组参数乍看之下T 0.5很容易被理解成“把符号速率翻一倍”但真正跑过 FTN 仿真的人都知道这里提速的幅度远没有想象中大。因为奈奎斯特速率对应的符号间隔不是 1而是(1 alpha) / 2B这个与滚降系数强相关的值。alpha 0.8意味着频谱占用被撑得很宽留给 FTN 压缩的空间反而变小了。这个压缩包里的on capacity系列脚本和capacity0/1/2.m处理的正是这套参数下“脉冲不再正交时信道容量该怎么算”的问题。适合波形设计、物理层仿真和需要复现超奈奎斯特结果的工程师阅读下文会从准则本身一路拆到 MATLAB 实现和参数边界。2. 奈奎斯特第一准则、根升余弦与 FTN 的符号间干扰模型2.1 先厘清奈奎斯特速率的准确定义很多资料把奈奎斯特准则写成C 2B这其实混淆了“符号速率上限”和“信道容量”两个概念。奈奎斯特第一准则说的是在带宽为B的理想低通信道中若要实现无符号间干扰ISI传输符号速率Rs不能超过2B且要求脉冲响应在整数倍符号间隔处过零。至于单位时间内能可靠传输多少比特还要在这个基础上叠加上信噪比因素由香农容量公式给出。所以更严谨的描述是Rs 2B是无 ISI 传输的符号速率上限而容量是C B * log2(1 SNR)这一层。超奈奎斯特Faster-than-Nyquist, FTN打破的正是第一准则里的“整数倍符号间隔过零”这一条件。当符号间隔T小于奈奎斯特间隔时相邻脉冲的拖尾会在采样点处互相叠加形成可控的符号间干扰。这个压缩包里的.fig文件标题比如alpha 0.8, beta [0.2 0.5], T 0.5(2).fig记录的便是不同参数组合下这种干扰对容量的影响。理解这一点是跑通后面所有脚本的前提FTN 并没用更高阶调制而是用“允许串扰 接收端补偿”换取了额外的符号速率。2.2 RRC/RC 脉冲与 L100 截断的工程取舍压缩包里的RRC_L_100_alpha_03_order_1E6_win_rec.mat和RC_L_100_alpha_03_order_1E6_win_rec.mat给出了两组不同的脉冲波形数据。RRC是根升余弦RC是升余弦两者在 FTN 仿真中的作用不同。下表列出二者的工程差异脉冲类型频带占用有无 ISI典型用途根升余弦 RRC(1alpha)/2T有发射成型滤波器升余弦 RC(1alpha)/2T无发射接收级联后的等效响应RRC之所以叫“根”升余弦是因为发射端和接收端各放一个 RRC级联后的频谱乘积正好等于升余弦频谱。压缩包里同时存在 RC 和 RRC 的.mat文件说明作者在对比两种做法一种是用 RRC 成型再用 RRC 匹配滤波另一种是直接观察 RC 脉冲在 FTN 采样点上的串扰能量。L100表示滤波器单边抽头数总抽头数2L1 201在order 1E6个符号的仿真里滤波器截断引入的边界效应大约占符号总数的2L/order 2e-4可以忽略。win_rec和win_hamming则代表滤波器截断时加的窗类型矩形窗旁瓣高但主瓣窄汉明窗相反这在 FTN 场景下会直接影响远端串扰的估计精度。2.3 把 beta 纳入串扰模型压缩包参数里alpha和beta成对出现我理解beta在这里是接收端频域处理相关的一个滚降参数常见做法是把它定义为接收端匹配滤波器带宽边缘的过渡带占比或者用来控制频域加窗后的残余串扰水平。alpha控制发射成型脉冲的滚降而beta控制的是接收端对频谱边缘的加权方式。当beta小于alpha时接收窗会主动削掉一部分信号边带导致信噪比损失当beta大于alpha时接收窗保留更多频谱但也会引入更多邻道干扰。在 FTN 仿真里需要把这种干扰量化成具体的功率值。常见做法是直接计算整体脉冲响应的旁瓣能量占比% isi_power_check.m % 计算 RRC 成型 RRC 匹配滤波后的整体脉冲响应旁瓣能量 alpha 0.8; L 100; sps 32; % 每符号采样点数 T 0.5; h rrc_design(alpha, L, sps); % 需要自行实现或从 mat 文件加载 g conv(h, h(end:-1:1)); % 整体脉冲响应发射成型 匹配滤波 % 采样点对应的索引目标时刻在正中间 center (length(g) 1) / 2; isi_idx center round((1:50) * T * sps); % 相邻 50 个符号位置 isi_pow sum(g(isi_idx).^2); total_pow sum(g.^2); fprintf(ISI 能量占比: %.4f\n, isi_pow / total_pow);这段代码先把发射和接收的 RRC 脉冲做卷积得到级联后的等效脉冲响应g然后在距离中心点k*T*sps的位置采样把这些旁瓣能量和全部能量相比得到的就是 FTN 场景下相邻符号串扰占总信号能量的比例。sps 32在alpha 0.8时可以保证成形滤波器的频谱不会因为采样率不足而混叠。跑完这段脚本如果 ISI 能量占比超过 0.1就需要考虑在接收端引入串扰消除否则容量计算会明显偏低。3. 用 MATLAB 跑通 on capacity 容量仿真主线3.1 capacity0 / capacity1 / capacity2 三条主线的分工压缩包里有三个名字相近的脚本capacity0.m、capacity1.m、capacity2.m。从命名规律和on_orthogonal.m系列脚本来看这三者应该是容量计算的三级递进脚本关注对象是否建模 ISI输出形式capacity0.m奈奎斯特基线容量否香农极限点capacity1.m匹配滤波后的容量点部分高斯近似下的可达速率capacity2.m含残余串扰的最终容量是修正后的容量曲线capacity0.m通常只算一个理论基线即相同带宽和 SNR 下奈奎斯特传输的香农容量。capacity1.m开始把 FTN 发射端引入但假设接收端匹配滤波器能完全对齐只计算理想同步下的容量上界。capacity2.m则把 ISI 当作噪声功率的一部分计入 SINR得到更接近实际接收机的容量值。我跑这类脚本的习惯是先用capacity0.m确认信道模型与 SNR 的定义理顺了再逐步打开 FTN 开关。3.2 完整脚本骨架从脉冲生成到容量点估计下面这个脚本整合了capacity2.m的核心计算流程把 FTN 容量点的估计拆成发送、加噪、匹配滤波、采样、ISI 功率估计和容量计算六步% ftn_capacity_point.m % FTN 容量点估计主流程 alpha 0.8; beta [0.2 0.5]; % 接收端滚降参数按压缩包原始参数保持 T 0.5; % FTN 符号间隔 sps 32; % 每符号采样点数 L 100; % 滤波器单边抽头数 order 1e6; % 仿真符号数 snr_dB 10; % 1) 根升余弦成形滤波器 h rrc_design(alpha, L, sps); h h / sqrt(sum(h.^2)); % 能量归一化保证滤波器增益为 1 % 2) 发射端BPSK 符号上采样后经过成型滤波器 sym 2 * randi([0 1], order, 1) - 1; x upsample(sym, sps); x conv(x, h, same); % 3) 加噪 Pn 10^(-snr_dB/10); r x sqrt(Pn) * randn(size(x)); % 4) 接收端匹配滤波 按 T 间隔采样 z conv(r, h(end:-1:1), same); y z(L*sps 1 : sps : end); % 丢弃边界抽头避免截断效应 y y(1:order); % 5) 无噪声通道下估计 ISI 功率 z0 conv(x, h(end:-1:1), same); y0 z0(L*sps 1 : sps : end); y0 y0(1:order); isi_pow var(y0 - sym); % 理想符号与实际采样值之差的方差 % 6) 容量点估计高斯干扰近似 SINR 1 / (Pn isi_pow); % 信号功率归一化为 1 C 0.5 * log2(1 SINR); fprintf(SNR %.1f dB, SINR %.2f dB, C %.4f bit/symbol\n, ... snr_dB, 10*log10(SINR), C);逻辑说明如下。第一步的rrc_design负责生成根升余弦时域脉冲能量归一化很关键否则后面信号功率不是 1SINR 会带一个固定偏差。第二步用upsample把符号映射到采样域再和滤波器卷积模拟发射端的成型过程。第三步加噪时噪声功率Pn是按 SNR 反推的这里隐含了信号功率为 1 的约定。第四步匹配滤波后从L*sps 1开始采样目的是跳过滤波器截断造成的无效边界区。第五步通过一次无噪声运行来估计 ISI 功率无噪声时采样值和理想符号的偏差完全来自相邻符号串扰这个方差的估计比从理论公式推导更贴近实际滤波器实现。第六步把 ISI 功率和噪声功率一起放到 SINR 的分母里用0.5 * log2(1 SINR)得到每符号容量。需要说明的是0.5 * log2(1 SINR)是一个高斯干扰近似下的可达速率下界不是 BPSK 在 AWGN 信道下的精确互信息。对工程仿真来说它的价值在于能直观对比不同 FTN 参数组合下的容量变化趋势且和误码率曲线有明确的对应关系。若要更精确的值需要用数值积分计算I(s; y) 1 - E[log2(1 exp(-2y/σ^2))]但那个计算量在order 1E6下会显著变慢。3.3 结果怎么读alpha0.8 与 beta 组合下的容量曲线压缩包里alpha 0.8, beta [0.2 0.5], T 0.5.fig和(2).fig两个图我判断是通过get_figdata.m从仿真结果里提取数据后绘制的容量曲线。读图时先看容量曲线在 SNR 轴上的起点再看它和香农极限曲线的间距。间距小于 0.1 bit 说明 FTN 的串扰代价很小间距大于 0.3 bit 就要检查是不是接收窗参数beta取得太小把信号边带削掉了。alpha 0.8时频谱占用宽beta 0.2意味着接收端只保留中心区域频谱这种组合下容量曲线会明显低于beta 0.5。另一个值得关注的细节是fm_alpha_08.fig里的眼图或散点图。FTN 的眼图在采样点处不会像奈奎斯特传输那样收成一个点而是有一条很宽的“眼皮”。这条眼皮的厚度大致对应 ISI 功率的均方根可以直接和isi_pow的估计值互相印证。如果眼图眼皮厚度远大于仿真估计的sqrt(isi_pow)优先怀疑同步偏移或采样时刻没对准。4. 复现过程中最容易翻车的五个参数边界4.1 过采样率不足导致的奈奎斯特混叠FTN 仿真的一个典型误区是沿用普通 QAM 仿真的sps 8或sps 16。当alpha 0.8时RRC 滤波器的频谱在(1alpha)/(2T)处仍有能量而采样率fs sps / T必须大于两倍信号最高频率否则频谱会折叠回基带等效于额外注入了一部分噪声。判断方法是画出滤波器的幅频响应在fs/2处能量应该低于 -60 dB% check_sps.m alpha 0.8; L 100; T 0.5; for sps [8 16 32] h rrc_design(alpha, L, sps); [H, f] freqz(h, 1, 4096, sps/T); idx find(f (1alpha)/(2*T), 1, last); edge_db 20*log10(abs(H(idx)) eps); fprintf(sps%2d, 频谱边缘能量 %.1f dB\n, sps, edge_db); endsps8时频谱边缘能量往往只能到 -20 dB 左右折合到功率就是 1% 的混叠失真对容量估计的影响在alpha0.8这种宽谱场景下会被明显放大。我一般把sps32作为 FTN 仿真的默认值sps64也不过分只是内存和仿真时间会成倍增加。4.2 滤波器截断 L100 与首尾符号剔除L100在 1E6 个符号的场景下看起来足够但要注意conv的边界处理。使用same选项时卷积输出和输入等长但两端的L*sps个采样点实际上是滤波器未完全覆盖的边界区数据不可信。如果直接把这部分采样纳入容量估计ISI 功率会被严重高估因为边界处的脉冲拖尾是残缺的。正确做法是从L*sps 1开始抽样并丢弃末尾同样长度的点。如果仿真符号数较少比如order 1E4边界占比达到 2%这时需要把order增大或在结果里标注这部分损失。4.3 蒙特卡洛阶数与容量估计的置信区间order 1E6的容量点估计并非没有抖动。isi_pow var(y0 - sym)里用的是样本方差在 1E6 个符号下方差估计的相对波动大约在1/sqrt(order)量级也就是 0.1% 左右。但容量估计对 SINR 误差的敏感度取决于工作点SNR 较高时SINR 的微小波动会被log2放大。实践中如果对比两个beta值下的容量差异小于 0.005 bit/symbol需要先用rng(固定种子)把噪声流固定下来再比较否则分不清差异来自参数还是随机波动。4.4 alpha 与 beta 反向搭配导致的容量塌陷压缩包的参数alpha 0.8, beta 0.2是一个很特别的组合。alpha 0.8意味着成型脉冲的频谱延伸到1.8/(2T)的位置而beta 0.2若代表接收端频域窗的过渡带占比则接收窗的有效带宽只有约1.2/(2T)。此时信号边带能量被接收窗大量抑制等效于主动引入了约10*log10(1.8/1.2) ≈ 1.8 dB的信噪比损失。这个坑的特点是误码率曲线看起来还行但容量曲线明显低于理论值。排查方法是固定alpha把beta从 0.2 扫到 0.8观察容量曲线是否有一个明显的拐点拐点位置通常在beta ≈ alpha附近。4.5 窗函数选择对远端串扰估计的影响win_rec和win_hamming两个.mat文件的存在说明作者比较了矩形窗和汉明窗截断滤波器的影响。矩形窗的频谱旁瓣只以1/f衰减远端串扰能量不可忽略汉明窗旁瓣衰减快但主瓣宽会让脉冲的有效时域长度变长。在 FTN 场景下这直接影响isi_pow的估计值。我建议仿真的两种窗都跑一遍如果两种窗下的容量差异超过 0.02 bit/symbol说明滤波器截断长度不够需要同时增大L而不是纠结哪个窗更优。5. 用 PSD 积分和 fig 数据反查验证容量损失5.1 用 calcRcPSD.m 的思路复核能量守恒压缩包里的calcRcPSD.m是计算升余弦脉冲功率谱密度的工具。FTN 仿真里它有一个容易被忽略的用途验证滤波器实现是否损失了能量。对一个实现正确的 RC 脉冲其 PSD 在带内的积分应该等于时域能量。如果积分结果明显小于 1比如 0.95说明滤波器的频域采样点不够密或截断窗把一部分边带切掉了% rc_psd_integral.m alpha 0.3; T 0.5; N 4096; fs 64/T; f linspace(-fs/2, fs/2, N); G zeros(size(f)); inband abs(f) (1-alpha) / (2*T); edge abs(f) (1-alpha)/(2*T) abs(f) (1alpha)/(2*T); G(inband) T; G(edge) T/2 * (1 cos(pi*T/alpha * ... (abs(f(edge)) - (1-alpha)/(2*T)))); energy sum(G) * (fs/N); fprintf(RC 脉冲带内能量占比: %.4f\n, energy / T);这段代码用解析表达式直接生成升余弦 PSD 并做数值积分。如果输出接近 1说明滤波器实现没有额外损耗如果偏差超过 1%需要回到rrc_design检查时域采样点数是否足够。这个检查对win_rec和win_hamming两个版本分别做一遍就能解释为什么压缩包里两个.mat文件的容量结果会存在差异。5.2 用 get_figdata.m 的思路把 fig 变成可对比的数据作者留下的.fig文件是判断仿真环境的参照物。用get_figdata.m相同的思路可以把fm_alpha_08.fig里的曲线数据导出和本地重算的结果做数值对比% extract_fig_curve.m fig openfig(fm_alpha_08.fig, invisible); ax findobj(fig, Type, axes); ln findobj(ax(1), Type, line); snr_orig get(ln(1), XData); cap_orig get(ln(1), YData); close(fig); % 固定随机种子重算同一组参数 rng(42); cap_local zeros(size(snr_orig)); for k 1:length(snr_orig) cap_local(k) ftn_capacity_point(snr_orig(k)); end max_diff max(abs(cap_orig - cap_local)); fprintf(和原 fig 曲线最大偏差: %.4f bit/symbol\n, max_diff);openfig的invisible参数让 MATLAB 在后台打开图形而不弹窗适合批量处理。提取出Line对象的坐标后就能把作者当时的仿真结果当成基准。最大偏差在 0.01 以内说明仿真环境和原脚本基本一致偏差较大时优先检查Pn的 SNR 定义是否一致——有的脚本把 SNR 定义为每比特能量Eb/N0有的是每符号能量Es/N0两者相差log2(M)倍这个是最常见的系统性偏差来源。最后跑仿真时把随机种子固定在rng(42)不同平台间的randn序列可能有细微差异对曲线抖动的影响远小于beta参数变化产生的容量差这样对比出来的结论才站得住。本文还有配套的精品资源点击获取
返回列表