
简介这份资源面向无线通信与OFDM系统方向的学习者和研究者聚焦降低信号峰均功率比PAPR这一经典难题围绕SLM选择性映射与PTS部分传输序列两种技术的单独使用及联合策略展开并涉及PSK、QAM等调制方式下的性能分析。压缩包内共1个文件为MATLAB脚本.m整体约1KB可用于仿真验证SLM-PTS在QAM/PSK系统中的PAPR抑制效果并观察候选符号数量、子载波分组策略等参数对系统性能的影响。目前已有194人学习下载说明该方向具备一定关注度。读者可借助脚本理解SLM与PTS的算法流程、相位旋转与候选序列选择机制并在此基础上调整参数、对比不同组合的PAPR分布为课程设计、论文复现或工程实践提供可运行的参考代码与排错思路。1. 从一次功放烧毁说起这个 slm_psk_qam.rar 到底装了什么前年帮一个做专网基站的朋友调发射链路他们的 OFDM 样机在实验室跑得好好的一到外场满功率发射频谱仪上邻道泄漏直接爆表功放模块烫得能煎蛋。查了三天最后定位到 PAPR——峰值功率比平均功率高出 11 dB 以上功放被迫工作在回退区效率掉到 20% 都不到。那次之后我对降 PAPR 的算法就格外上心今天拆的这个slm_psk_qam.rar就是干这事的。压缩包里核心是一个slm_psk_qam.m文件用 MATLAB 实现了 SLM选择性映射和 PTS部分传输序列两种降 PAPR 方案并且把两者做了结合跑在 PSK/QAM 调制的 OFDM 系统上。它解决的就是上面那种场景OFDM 多载波叠加导致高峰均比功放不敢开足、能耗高、非线性失真大。适合通信算法工程师、做物理层仿真的研究生以及需要快速验证降 PAPR 方案再决定要不要上 FPGA 的从业者。你不需要从零推导公式但得看得懂 OFDM 基带链路知道 CCDF 曲线在比什么。2. SLM 与 PTS 的降 PAPR 原理为什么单用一种不够2.1 从 OFDM 的峰均比来源讲起OFDM 把数据分散到 N 个正交子载波上时域信号是这 N 个子载波调制后叠加的结果。当多个子载波的相位在某个时刻恰好对齐瞬时功率就会远高于平均功率这就是 PAPR 的物理来源。数学上 PAPR 定义为PAPR(dB) 10 * log10( max(|x[n]|^2) / mean(|x[n]|^2) )其中x[n]是 IFFT 之后的时域样点。子载波数越多出现同相叠加的概率越大PAPR 越高。一个 256 子载波的 OFDM 信号PAPR 轻松到 10~12 dB而功放的线性区间通常只有 6~8 dB中间这段差距就得靠算法来填。SLM 的思路很直白同一组频域数据乘上 U 个不同的相位旋转序列得到 U 个候选时域符号选 PAPR 最低的那个发出去。接收端只要知道用了哪个序列就能恢复。PTS 则是把频域数据切成 V 个子块每个子块独立做 IFFT然后给每个子块乘一个相位因子再叠加通过搜索最优相位组合来压低峰值。2.2 为什么要把 SLM 和 PTS 结合单用 SLM候选符号数等于相位序列数 U想压到 1 dB 以下的 PAPR 改善U 往往要开到 16 甚至 32意味着 16 次 IFFT计算量线性增长。单用 PTS搜索空间是W^(V-1)W 是相位因子候选数V 是子块数V8、W4 时就是 4^716384 种组合暴力搜索根本跑不动。SLM-PTS 结合的逻辑是先用 PTS 把子块相位调一轮得到一组已经降过峰的候选再对这组候选做 SLM 的相位旋转相当于在两级维度上同时搜索。这样在相同 IFFT 次数下能覆盖更大的候选空间CCDF 曲线在 10^-3 概率点上的 PAPR 改善通常比单 SLM 多 1~2 dB。代价是接收端需要额外的边带信息来告诉它用了哪组 PTS 相位和哪个 SLM 序列这部分开销在脚本里一般用理想边带假设带过实际工程里得单独设计。2.3 脚本里的关键参数怎么对应打开slm_psk_qam.m你会看到几个核心变量控制整个仿真。下面这张表是我读脚本时整理的参数映射方便你改的时候知道动哪个脚本变量常见命名含义典型取值改动影响N/Nfft子载波数 / IFFT 点数64 / 128 / 256越大 PAPR 越高降峰难度越大M调制阶数4(QPSK) / 16 / 64QAM 阶数越高PAPR 分布略变USLM 相位序列数4 / 8 / 16越大降峰越好IFFT 次数线性增VPTS 子块数4 / 8越大搜索空间指数增WPTS 相位因子数2 / 4常用 {1,-1} 或 {1,-1,j,-j}ovs过采样倍数4必须≥4 才能准确捕捉峰值过采样这个参数特别容易被忽略。如果不做过采样只在一个符号周期内取 N 个点很可能漏掉真正的峰值算出来的 PAPR 偏低仿真结果好看但上板就翻车。脚本里一般用 IFFT 补零到ovs*N来实现你改的时候别把这个省了。3. 跑通 slm_psk_qam.m从环境配置到 CCDF 曲线3.1 环境准备与脚本结构速览这个脚本是纯 MATLAB 实现不依赖任何工具箱MATLAB R2016b 及以上都能跑Octave 大部分语法也兼容。把 rar 解压后直接cd到目录在命令行敲脚本名即可。脚本整体分四段参数初始化、OFDM 调制与 PAPR 计算、SLM/PTS/SLM-PTS 三种方案循环、CCDF 绘图与对比。先看参数初始化段这是你每次实验都要动的部分% 系统参数 N 256; % 子载波数 M 16; % 16-QAM ovs 4; % 过采样倍数别低于4 numSym 2000; % 蒙特卡洛符号数越大CCDF越平滑 % SLM 参数 U 8; % 相位序列个数 % PTS 参数 V 8; % 子块数 W 4; % 相位因子候选数 {1,-1,j,-j}numSym直接决定 CCDF 曲线的平滑度和跑的时间。2000 个符号在普通笔记本上大概几十秒想看到 10^-4 概率点建议加到 10000 以上。ovs4是经验值再高收益递减但时间翻倍。3.2 生成 OFDM 符号并计算原始 PAPR这一段是基准先搞清楚不降峰时 PAPR 长什么样papr_ori zeros(1, numSym); for s 1:numSym % 随机生成频域数据并做 QAM 映射 dataIdx randi([0 M-1], N, 1); X qammod(dataIdx, M, UnitAveragePower, true); % 过采样 IFFT补零到 ovs*N X_os [X(1:N/2); zeros(ovs*N - N, 1); X(N/21:end)]; x ifft(X_os) * sqrt(ovs*N); % 计算 PAPR pwr abs(x).^2; papr_ori(s) 10*log10(max(pwr) / mean(pwr)); end这里有两个细节值得说。一是qammod的UnitAveragePower选项保证平均功率归一否则 PAPR 算出来没有可比性。二是过采样 IFFT 的补零位置——必须补在频域中间对应时域的内插补在两端会破坏频谱结构。sqrt(ovs*N)是能量归一化因子不同 ovs 下保持平均功率一致。3.3 SLM 方案的实现与相位序列设计SLM 的核心是那组相位旋转序列。脚本里通常用随机相位或固定相位表% 生成 U 个 SLM 相位序列每个长度 N phaseSet exp(1j * 2*pi * randi([0 3], U, N) / 4); % {1,j,-1,-j} papr_slm zeros(1, numSym); for s 1:numSym dataIdx randi([0 M-1], N, 1); X qammod(dataIdx, M, UnitAveragePower, true); bestPAPR inf; for u 1:U Xu X .* phaseSet(u, :).; % 频域乘相位 Xu_os [Xu(1:N/2); zeros(ovs*N-N,1); Xu(N/21:end)]; xu ifft(Xu_os) * sqrt(ovs*N); p 10*log10(max(abs(xu).^2) / mean(abs(xu).^2)); if p bestPAPR bestPAPR p; bestIdx u; % 记录选中的序列号接收端需要 end end papr_slm(s) bestPAPR; end相位因子取 {1, j, -1, -j} 是常见做法因为只用加减和虚实交换硬件实现时不需要乘法器。bestIdx这个变量在仿真里没用到但实际系统必须把它作为边带信息传过去否则接收端无法解调。脚本里如果没处理边带开销你心里要清楚这部分在实际链路里是省不掉的。3.4 PTS 子块划分与相位搜索PTS 这段是计算量最大的子块怎么分、相位怎么搜都有讲究papr_pts zeros(1, numSym); phaseCand [1, -1, 1j, -1j]; % W4 的相位候选 for s 1:numSym dataIdx randi([0 M-1], N, 1); X qammod(dataIdx, M, UnitAveragePower, true); % 相邻划分把 N 个子载波切成 V 块 blkLen N / V; x_sub zeros(ovs*N, V); for v 1:V Xv zeros(N, 1); idx (v-1)*blkLen (1:blkLen); Xv(idx) X(idx); Xv_os [Xv(1:N/2); zeros(ovs*N-N,1); Xv(N/21:end)]; x_sub(:, v) ifft(Xv_os) * sqrt(ovs*N); end % 遍历相位组合V8,W4 时是 4^716384 次可改用次优搜索 bestPAPR inf; for combo 0:(W^(V-1) - 1) ph phaseCand(1); tmp combo; b zeros(1, V); b(1) 1; for v 2:V b(v) mod(tmp, W) 1; tmp floor(tmp / W); end x_sum zeros(ovs*N, 1); for v 1:V x_sum x_sum phaseCand(b(v)) * x_sub(:, v); end p 10*log10(max(abs(x_sum).^2) / mean(abs(x_sum).^2)); if p bestPAPR bestPAPR p; end end papr_pts(s) bestPAPR; end子块划分方式有相邻、交织、随机三种。相邻划分实现最简单但降峰效果一般交织划分把子载波按间隔分到不同块峰值分散更均匀代价是 IFFT 后叠加时相关性变强。脚本里如果用的是相邻划分你可以试着改成交织CCDF 通常能再改善 0.3~0.5 dB。另外W^(V-1)这个搜索空间在 V8 时已经 16384 次每个符号都这么搜2000 个符号就是三千多万次循环MATLAB 里跑起来会很慢。实际工程里常用次优搜索比如只搜部分组合或者用迭代翻转法脚本里如果没做优化你跑之前先把numSym降下来验证逻辑。3.5 绘制 CCDF 曲线做对比最后把三组 PAPR 数据画成 CCDF这是判断降峰效果的唯一标准figure; semilogy(sort(papr_ori), 1 - (1:numSym)/numSym, k-, LineWidth, 1.5); hold on; semilogy(sort(papr_slm), 1 - (1:numSym)/numSym, b--, LineWidth, 1.5); semilogy(sort(papr_pts), 1 - (1:numSym)/numSym, r-., LineWidth, 1.5); grid on; xlabel(PAPR (dB)); ylabel(CCDF); legend(Original, SLM, PTS); xlim([4 13]);看曲线时盯住y10^-3那条水平线读出各方案对应的 PAPR 值差值就是降峰增益。原始信号一般在 11 dB 左右SLMU8能压到 8.5 dB 上下PTSV8,W4大概 8 dBSLM-PTS 结合能到 7 dB 附近。如果你的曲线在 10^-3 处改善不到 1 dB先检查过采样是不是忘了开再看相位序列是不是退化了。4. 避坑与排查跑这个脚本最容易翻车的五个地方4.1 CCDF 曲线尾部翘起或不平滑现象画出来的 CCDF 在 10^-3 以后突然上翘或者阶梯感很重看不出明显趋势。原因numSym太小。2000 个符号在 10^-3 概率点只有 2 个样本统计涨落极大。另外如果 PAPR 计算时没做过采样峰值被漏掉曲线整体偏低且形状失真。解决把numSym加到 10000 以上ovs确保为 4。跑之前先rng(42)固定随机种子保证每次结果可复现不然你改个参数都不知道是参数起作用还是随机波动。4.2 PTS 搜索跑一整晚还没出结果现象V8、W4 时脚本卡在 PTS 循环里CPU 风扇狂转进度条不动。原因W^(V-1)的暴力搜索在 MATLAB 解释执行下极慢16384 次组合乘以 2000 个符号每次还要做ovs*N长度的向量加法和 max 运算计算量爆炸。解决先把numSym降到 200 验证逻辑确认曲线趋势对了再往上加。或者把 V 降到 4搜索空间变成 4^364速度快两个数量级。工程上更常用的是次优搜索比如只保留前几个幅度最大的子块做相位优化脚本里没实现的话可以自己加。4.3 SLM 降峰效果远不如预期现象U8 的 SLM 跑出来只比原始信号好 0.5 dB跟理论值差很远。原因相位序列之间相关性太强。如果phaseSet是用randi生成的但没检查可能出现多个序列几乎相同的情况候选多样性不够。另一个可能是相位因子取值太密比如用了连续相位而不是 {1,j,-1,-j} 这种离散集合导致搜索空间虽大但有效候选少。解决生成相位序列后加一句corr abs(phaseSet * phaseSet / N)检查非对角元素是否接近 0。如果相关性高换用 Hadamard 矩阵的行作为相位序列正交性有保证。相位因子坚持用 {1,-1,j,-j}硬件友好且效果稳定。4.4 接收端解调误码率异常高现象PAPR 是降下来了但加上解调环节后 BER 比不加降峰还高。原因边带信息没传或传错。SLM 需要告诉接收端选了哪个相位序列PTS 需要传每个子块的相位因子。脚本里如果直接用bestIdx在接收端做逆旋转但没模拟边带信息的传输错误那 BER 是理想值一旦边带信息出错整个符号全错。解决仿真时把边带信息单独编码用低阶调制加信道编码保护或者接受一定的边带开销。评估性能时要算上边带占用的子载波或时隙不能只看数据部分的 BER。4.5 换调制阶数后 PAPR 分布变了现象QPSK 下调好的参数换成 64-QAM 后 CCDF 曲线整体右移降峰增益缩水。原因高阶 QAM 的星座点幅度分布更广IFFT 后时域信号的幅度动态范围更大峰值出现的概率和幅度都增加。同样的相位旋转序列对高阶调制的峰值分散能力相对减弱。解决换调制阶数后重新调 U 和 V。经验上 64-QAM 比 QPSK 需要多 2~4 个 SLM 序列才能达到相近的降峰效果。另外高阶调制对非线性失真更敏感降 PAPR 的收益在系统级反而更大别因为单看 CCDF 改善变小就放弃。5. 进阶玩法把 SLM-PTS 结合跑出该有的增益脚本里 SLM 和 PTS 是分开跑的真正有意思的是把两者串起来。我一般会这么改先做 PTS 相位优化得到一组候选时域符号再对这组候选做 SLM 相位旋转取全局最优。这样在 U4、V4、W2 的轻量配置下候选空间是 4×2^332 个比单 SLM 的 U8 只多 4 倍计算量但 CCDF 在 10^-3 处能多压 0.8~1.2 dB。具体改法是在 PTS 循环内部对每个相位组合生成的x_sum再乘上 SLM 相位序列记录全局最小 PAPR。代码结构大概是这样bestGlobal inf; for combo 0:(W^(V-1)-1) % ... 生成 x_sum同 3.4 节 for u 1:U xu x_sum .* slmPhase(u, :).; % 时域乘相位等价于频域循环移位 p 10*log10(max(abs(xu).^2) / mean(abs(xu).^2)); if p bestGlobal bestGlobal p; bestCombo combo; bestSLM u; end end end注意这里时域乘相位序列和频域乘是等价的但时域操作省了一次 IFFT计算量更小。bestCombo和bestSLM两个索引都要作为边带信息传给接收端边带开销比单用 SLM 或 PTS 都大这是结合方案的实际代价。验证结合方案有没有跑对我有个习惯固定随机种子分别跑原始、单 SLM、单 PTS、SLM-PTS 四组把四条 CCDF 画在一张图上。如果 SLM-PTS 的曲线没有明显低于另外两条先检查bestGlobal是不是在循环外被重置了再确认 SLM 相位序列有没有正确作用到 PTS 的每个候选上。这个坑我踩过——当时把 SLM 循环写在了 PTS 循环外面等于只对最后一个 PTS 候选做了 SLM曲线当然不对。从那以后我每次改这种嵌套搜索的代码都强制在循环里加一句fprintf打印当前最优 PAPR跑前 10 个符号确认数值在下降再放开跑全量。这个习惯帮我省了至少两个通宵的无效等待。希望帮到你。本文还有配套的精品资源点击获取