OFDM系统PAPR抑制:SLM与PTS算法MATLAB仿真对比

📅 2026/8/21 7:37:13
OFDM系统PAPR抑制:SLM与PTS算法MATLAB仿真对比
1. 项目背景与PAPR问题的由来搞通信系统仿真尤其是OFDM正交频分复用的几乎没人能绕开PAPR峰均功率比这个老大难问题。我第一次在MATLAB里跑出一个标准的OFDM信号看着时域波形图上那些偶尔冲得老高的尖峰心里就咯噔一下这玩意儿送到功放里不得把功放给逼疯了现实中的功率放大器PA都有个线性工作区输入信号幅度太大超出了这个范围就会产生非线性失真导致信号畸变、频谱再生带外频谱泄露整个系统的误码率BER性能就会一塌糊涂。PAPR高就意味着为了不畸变你得让功放工作在很大的功率回退Power Back-Off状态下效率极低对于基站和终端设备来说都是电量和成本的噩梦。所以抑制PAPR就成了OFDM系统从理论走向实际的关键一步。标题里提到的SLM选择性映射和PTS部分传输序列就是两种经典且主流的“主动”抑制算法。它们不像削波Clipping那样简单粗暴地砍掉高峰值会引入失真和带外干扰而是通过一些“技巧”在发送端从多个可能的信号中选出一个PAPR最低的送出去。这个项目就是用MATLAB来仿真对比这两种算法的性能看看在同样的条件下谁更能“压住”那些讨厌的峰值。2. OFDM信号生成与PAPR的基础评估在对比SLM和PTS之前我们得先把“靶子”——也就是原始的OFDM信号及其PAPR——给建立起来。很多教程一上来就讲公式咱们换个方式直接从MATLAB脚本的角度看看一个OFDM信号是怎么“变”出来的以及PAPR是怎么算的。2.1 从比特流到时域波形的完整链条假设我们要仿真一个最简单的OFDM系统。首先得确定系统参数比如子载波数N 我这里用N64做个例子其中可能有一部分比如中间部分作为直流和虚载波不用实际用的子载波数N_used52。调制方式常用QPSK四相相移键控因为它比较抗干扰且计算量适中。% 参数设置 N 64; % FFT/IFFT点数子载波总数 N_used 52; % 实际使用的子载波数 cp_len 16; % 循环前缀长度 num_symbols 1000; % 仿真的OFDM符号数 mod_order 4; % QPSK调制阶数为4第一步生成随机数据。randi函数生成0和1的随机序列。% 生成随机比特流 data_bits randi([0, 1], N_used * log2(mod_order) * num_symbols, 1);第二步进行QPSK调制。这里要注意MATLAB的qammod函数默认是产生复数符号对于QPSK其星座点通常是(11j)/sqrt(2)这种归一化形式。我们需要将比特流每2个一组因为log2(4)2映射成一个复数符号。% 将比特流重塑为每 log2(mod_order) 比特一组 data_bits_reshaped reshape(data_bits, log2(mod_order), []); % 将二进制转换为十进制作为调制索引 data_symbols_index bi2de(data_bits_reshaped, left-msb); % 进行QPSK调制归一化能量为1 modulated_data qammod(data_symbols_index, mod_order, UnitAveragePower, true); % 重塑为每OFDM符号 N_used 个子载波 modulated_data reshape(modulated_data, N_used, num_symbols);第三步映射到子载波上。我们生成了N_used个调制符号但要进行N点的IFFT所以需要把它们放到N个子载波对应的位置上。通常为了保持信号的共轭对称性以产生实信号或者避免直流分量我们会把数据放在中间的子载波上两边补零。这里我们采用更常见的做法将数据放在从第2个到第N_used/21个以及从第N-N_used/22到第N个子载波上中间是直流第1个和第N/21个以及一些保护带。% 创建空的频域数据矩阵 fd_data zeros(N, num_symbols); % 将调制数据映射到正频率子载波低一半 fd_data(2 : N_used/2 1, :) modulated_data(1:N_used/2, :); % 将调制数据映射到负频率子载波高一半需要满足共轭对称性以得到实信号吗 % 注意对于基带复数信号我们通常不强制共轭对称。这里我们简单地将剩余数据放到高频部分。 fd_data(N - N_used/2 1 : end, :) modulated_data(N_used/2 1 : end, :); % 更常见的做法是将数据放在索引 [N/2-N_used/2 : N/2N_used/2-1] 附近避开直流。 % 但为了简化我们采用上述映射。实际上PAPR评估主要关心时域幅度频域映射细节影响不大。第四步进行IFFT变换将频域符号转换为时域波形。这是OFDM的核心。% 进行N点IFFT得到时域OFDM符号复数 td_symbols ifft(fd_data, N, 1); % 对每一列每个符号做IFFT第五步添加循环前缀CP。为了对抗多径时延扩展我们把每个时域符号末尾的cp_len个采样点复制到开头。% 添加循环前缀 td_symbols_with_cp [td_symbols(end-cp_len1:end, :); td_symbols];现在td_symbols_with_cp就是一个完整的时域OFDM信号矩阵每一列代表一个带CP的OFDM符号。我们可以把它按列拼接起来形成一个长的时间序列用于评估PAPR。% 将多个符号的时域信号拼接成一个长序列 tx_signal td_symbols_with_cp(:);2.2 PAPR的计算与统计方法PAPR的定义很简单一个信号在一个观察窗口内通常是一个OFDM符号周期的峰值功率与平均功率的比值通常用dB表示。% 计算原始信号的PAPR按符号计算 % 首先将长序列重新按符号长度Ncp_len分段 symbol_length N cp_len; num_total_symbols length(tx_signal) / symbol_length; tx_signal_matrix reshape(tx_signal, symbol_length, num_total_symbols); papr_original zeros(1, num_total_symbols); for idx 1:num_total_symbols symbol tx_signal_matrix(:, idx); peak_power max(abs(symbol).^2); avg_power mean(abs(symbol).^2); papr_original(idx) 10 * log10(peak_power / avg_power); end光看一个符号的PAPR没意义因为它是随机的。我们更关心它的统计特性也就是CCDF互补累积分布函数。CCDF描述的是PAPR超过某个门限值的概率。比如我们说“PAPR的CCDF在9dB处为0.01”意思就是有1%的OFDM符号其PAPR值超过了9dB。这个指标对于系统设计至关重要因为它告诉你为了保障99%的符号不被失真你的功放需要留出多大的回退余量。计算CCDF的MATLAB代码可以这样写% 计算CCDF papr_values_dB 0:0.1:12; % 定义要评估的PAPR门限范围 ccdf_original zeros(size(papr_values_dB)); for i 1:length(papr_values_dB) ccdf_original(i) sum(papr_original papr_values_db(i)) / num_total_symbols; end % 画图 figure; semilogy(papr_values_dB, ccdf_original, b-, LineWidth, 1.5); grid on; xlabel(PAPR0 (dB)); ylabel(Pr(PAPR PAPR0)); title(原始OFDM信号的PAPR CCDF曲线);跑一下这段代码你大概率会得到一条曲线显示在PAPR超过8-10dB后概率迅速下降但“尾巴”拖得比较长。这意味着总有少数“倒霉”的符号PAPR特别高。我们的目标就是用SLM和PTS算法把这根CCDF曲线尽可能地往左压。3. SLM算法原理与MATLAB实现细节SLM算法的思想非常巧妙它有点像“换件衣服试试看”。对于同一个要发送的信息我生成U个不同的“候选信号”然后从中挑出PAPR最低的那个发出去。怎么生成不同的候选信号呢核心是在频域数据上乘上不同的“相位旋转因子”。3.1 相位旋转因子的设计与候选信号生成假设我们原始的频域数据向量是X一个OFDM符号对应的N个频点数据。我们准备U个不同的相位旋转向量P_u每个P_u的长度也是N其每个元素都是一个复数模为1即只改变相位不改变幅度例如exp(1j * phi)其中phi从预设的相位集合如{0, pi}或{0, pi/2, pi, 3*pi/2}中随机选取。那么第u个候选信号的频域表示就是X_u X .* P_u。然后对每个X_u做IFFT得到时域候选信号x_u ifft(X_u)。最后计算所有x_u的PAPR选出最小的那个记下其对应的相位旋转向量索引u_opt发送x_{u_opt}。这里有个关键点接收端要知道你发的是哪个u_opt对应的信号才能用正确的P_{u_opt}的共轭去恢复原始数据X。这个u_opt索引就是需要传送的“边带信息”Side Information, SI。边带信息的可靠传输和额外开销是SLM以及PTS算法在实际系统中必须考虑的成本。在MATLAB里实现我们可以这样构建相位旋转因子。为了简单我们常采用二进制相位集合{1, -1}也就是phi只能是0或pi。这样乘法操作就简化成了取正负号。function [candidate_signals, phase_sequences] generate_slm_candidates(td_symbol, U, N) % td_symbol: 一个OFDM符号的时域信号列向量长度N % U: 候选信号数量 % N: FFT点数 % 返回所有候选时域信号和对应的相位序列 % 先将时域符号转换回频域 fd_symbol fft(td_symbol, N); candidate_signals zeros(N, U); phase_sequences zeros(N, U); for u 1:U % 生成随机相位序列元素为 1 或 -1 phase_seq (randi([0, 1], N, 1) * 2 - 1); % 将0/1映射为-1/1 phase_sequences(:, u) phase_seq; % 频域相乘相位旋转 fd_candidate fd_symbol .* phase_seq; % 转换回时域 td_candidate ifft(fd_candidate, N); candidate_signals(:, u) td_candidate; end end3.2 最优候选选择与边带信息处理生成了U个候选信号后接下来就是“选美大赛”——计算每个候选的PAPR并选出冠军。function [optimal_signal, optimal_index, min_papr] select_optimal_candidate(candidate_signals) % candidate_signals: N x U 矩阵 % 返回最优时域信号、其索引和最小PAPR值 [N, U] size(candidate_signals); papr_list zeros(1, U); for u 1:U signal candidate_signals(:, u); peak_power max(abs(signal).^2); avg_power mean(abs(signal).^2); papr_list(u) 10 * log10(peak_power / avg_power); end [min_papr, optimal_index] min(papr_list); optimal_signal candidate_signals(:, optimal_index); end在实际仿真中我们需要对大量的OFDM符号逐个进行SLM处理。这里就引出一个效率问题U越大找到低PAPR信号的概率越高性能越好但计算量也线性增长每个符号要做U次IFFT。这是一个典型的性能与复杂度的折衷。边带信息optimal_index需要被编码并发送给接收端。通常只需要log2(U)个比特。在仿真中我们常常假设边带信息被完美传输和接收无误差以专注于评估PAPR抑制性能本身。但在实际系统分析中必须考虑这部分开销和误码对整体性能的影响。3.3 SLM算法的性能仿真与参数影响让我们写一个完整的循环来仿真SLM算法处理多个OFDM符号并绘制其CCDF曲线与原始信号对比。% SLM算法主仿真参数 U_slm 4; % 候选信号数量 num_sym_slm 1000; % 仿真的符号数用于CCDF统计 papr_slm zeros(1, num_sym_slm); optimal_indices zeros(1, num_sym_slm); % 记录每个符号的最优索引边带信息 for sym_idx 1:num_sym_slm % 1. 生成一个原始OFDM符号的时域信号不含CP用于PAPR计算 % 这里复用第2部分生成频域数据并做IFFT的流程生成一个td_symbol_original % ... (生成单个符号的代码假设得到 td_symbol_orig) % 2. 生成该符号的SLM候选信号 [candidates, phase_seq] generate_slm_candidates(td_symbol_orig, U_slm, N); % 3. 选择最优候选 [td_symbol_slm, opt_idx, papr_val] select_optimal_candidate(candidates); % 4. 存储结果 papr_slm(sym_idx) papr_val; optimal_indices(sym_idx) opt_idx; end % 计算SLM处理后的CCDF ccdf_slm zeros(size(papr_values_dB)); for i 1:length(papr_values_dB) ccdf_slm(i) sum(papr_slm papr_values_dB(i)) / num_sym_slm; end % 画图对比 figure; semilogy(papr_values_dB, ccdf_original, b-, LineWidth, 1.5); hold on; semilogy(papr_values_dB, ccdf_slm, r--, LineWidth, 1.5); grid on; xlabel(PAPR0 (dB)); ylabel(Pr(PAPR PAPR0)); legend(原始OFDM, [SLM, U, num2str(U_slm)]); title(SLM算法PAPR抑制效果对比);运行这段代码你会发现U4的SLM算法已经能将CCDF曲线显著向左移动。例如原始信号PAPR超过10dB的概率可能是0.1%CCDF1e-3而SLM处理后这个概率可能会降到0.01%甚至更低。U越大曲线左移越明显但收益是递减的。U从4增加到8带来的增益可能远小于从1即原始信号增加到4的增益。注意相位序列的生成。上面我们用完全随机的1/-1序列。在实际中为了降低边带信息开销或简化接收端处理有时会采用一组固定的、接收端已知的相位序列集。这样边带信息只需要指定用了哪一组固定的序列。我们的仿真中采用随机序列更能体现算法在“搜索”意义上的潜力。4. PTS算法原理、分区策略与MATLAB实现PTS部分传输序列是另一种非常聪明的算法。它的思路是“分而治之”。不像SLM那样动整个频域向量的相位PTS先把频域数据X分割成V个互不重叠的子块Partition。然后对每个子块独立地乘以一个相位因子b_v最后把加权后的子块加起来再做IFFT。4.1 子块分割的三种经典策略如何分割这V个子块是PTS算法的第一个关键点主要有三种策略相邻分割把连续的若干个子载波分到一个块。比如N64,V4那么每个块包含16个连续的子载波。这种方法最简单但PAPR抑制效果通常最差。交织分割像发牌一样第1, V1, 2V1,...个子载波分到块1第2, V2, 2V2,...个子载波分到块2以此类推。这种方法能获得比相邻分割更好的性能。随机分割子载波随机地分配到V个块中。从理论上讲这种分割方式能提供最好的PAPR抑制性能因为它最大化了信号的随机性。但在实际中需要额外的边带信息来告诉接收端分割的图案开销较大所以不如交织分割常用。在MATLAB中我们可以实现交织分割。假设X是频域向量V是子块数。function subblocks interleave_partition(X, V) % X: 频域数据向量 (N x 1) % V: 子块数 % 返回一个 cell 数组每个元素是一个子块的频域数据 N length(X); subblocks cell(1, V); for v 1:V % 交织选取索引从v开始步长为V indices v:V:N; subblocks{v} zeros(N, 1); subblocks{v}(indices) X(indices); % 只有对应位置的子载波有值其余为0 end end4.2 相位因子优化与最优组合搜索分割好子块后对每个子块X_v乘以一个相位因子b_v。b_v通常从一个有限的相位集合中选取比如{1, -1}二进制PTS或者{1, -1, j, -j}四进制PTS。然后将所有加权后的子块相加得到组合后的频域信号X sum_{v1}^{V} b_v * X_v。接着做IFFT得到时域信号x。我们的目标就是找到一组最优的相位因子{b_v}使得x的PAPR最小。这里就遇到了PTS算法的核心挑战搜索复杂度。如果每个b_v有W种可能例如二进制时W2那么总共有W^V种组合。当V稍大时比如V82^8256种组合每个符号都要计算256次IFFT和PAPR计算量巨大。而SLM的复杂度是U次IFFT。因此PTS虽然理论上性能上限更高因为搜索空间更大但它的计算复杂度是指数增长的。为了降低复杂度人们提出了很多次优搜索算法比如迭代翻转、阈值判断等。但在我们的基础仿真中为了对比理论最佳性能可以先实现一个穷举搜索当V不大时比如V42^416种组合计算量尚可接受。function [optimal_signal, optimal_phases, min_papr] pts_exhaustive_search(subblocks, phase_set) % subblocks: cell数组包含V个子块的频域数据N x 1向量 % phase_set: 相位因子的可选集合例如 [1, -1] 或 [1, -1, 1j, -1j] % 返回最优时域信号、最优相位因子组合和最小PAPR V length(subblocks); N length(subblocks{1}); phase_combinations combvec(phase_set, phase_set, ...); % 需要生成所有组合 % 注意combvec函数需要Deep Learning Toolbox。我们可以自己写个循环。 % 生成所有相位组合的索引 W length(phase_set); num_combos W^V; % 一种生成所有组合索引的方法适用于W2 if W 2 isequal(phase_set, [1, -1]) % 用0/1代表相位索引然后映射 all_indices dec2bin(0:num_combos-1) - 0; % 生成0/1矩阵 all_indices(all_indices 0) -1; % 将0映射为-1 all_indices(all_indices 1) 1; % 将1映射为1 else % 更通用的方法使用ndgrid当V不大时 grids cell(1, V); [grids{:}] ndgrid(1:W); all_indices zeros(num_combos, V); for v 1:V all_indices(:, v) grids{v}(:); end % 将索引映射为实际的相位值 phase_vals phase_set(all_indices); % 这里all_indices是索引矩阵 end min_papr inf; optimal_signal zeros(N, 1); optimal_phases zeros(1, V); for combo_idx 1:num_combos current_phases phase_vals(combo_idx, :); % 当前相位组合 % 组合加权后的频域信号 X_combined zeros(N, 1); for v 1:V X_combined X_combined current_phases(v) * subblocks{v}; end % IFFT x_candidate ifft(X_combined, N); % 计算PAPR peak_power max(abs(x_candidate).^2); avg_power mean(abs(x_candidate).^2); papr_candidate 10 * log10(peak_power / avg_power); % 更新最优解 if papr_candidate min_papr min_papr papr_candidate; optimal_signal x_candidate; optimal_phases current_phases; end end end4.3 PTS算法的完整仿真流程与性能观察现在我们将PTS算法集成到OFDM符号处理流程中。% PTS算法主仿真参数 V_pts 4; % 子块数量 phase_set_pts [1, -1]; % 二进制相位集合 num_sym_pts 1000; % 仿真的符号数 papr_pts zeros(1, num_sym_pts); optimal_phase_combos zeros(num_sym_pts, V_pts); % 记录每个符号的最优相位组合 for sym_idx 1:num_sym_pts % 1. 生成一个原始OFDM符号的频域数据 X_fd N x 1 % ... (生成单个符号频域数据的代码) % 2. 对频域数据进行交织分割 subblocks interleave_partition(X_fd, V_pts); % 3. 穷举搜索最优相位组合 [td_symbol_pts, opt_phases, papr_val] pts_exhaustive_search(subblocks, phase_set_pts); % 4. 存储结果 papr_pts(sym_idx) papr_val; optimal_phase_combos(sym_idx, :) opt_phases; end % 计算PTS处理后的CCDF ccdf_pts zeros(size(papr_values_dB)); for i 1:length(papr_values_dB) ccdf_pts(i) sum(papr_pts papr_values_dB(i)) / num_sym_pts; end % 画图对比原始、SLM和PTS figure; semilogy(papr_values_dB, ccdf_original, b-, LineWidth, 1.5); hold on; semilogy(papr_values_dB, ccdf_slm, r--, LineWidth, 1.5); semilogy(papr_values_dB, ccdf_pts, g:, LineWidth, 2); grid on; xlabel(PAPR0 (dB)); ylabel(Pr(PAPR PAPR0)); legend(原始OFDM, [SLM, U, num2str(U_slm)], [PTS, V, num2str(V_pts), (二进制)]); title(SLM与PTS算法PAPR抑制效果对比);运行这个仿真你会看到PTS的曲线通常比相同复杂度VU的SLM更靠左也就是说在同样的计算量IFFT次数下PTS的PAPR抑制效果更好。这是因为PTS的搜索空间是W^V而SLM是U。当W2,V4时PTS搜索了16种组合而U4的SLM只搜索了4种。但PTS的复杂度也更高16次IFFT vs 4次。为了公平比较我们应该让两者的计算量IFFT次数相近。例如比较U8的SLM和V4的PTS16次IFFT或者U16的SLM和V4但采用四进制相位W4的PTS256次IFFT。5. 算法对比、复杂度分析与实际应用考量画出了CCDF曲线我们就能直观地对比SLM和PTS的性能。但性能不是唯一的评价标准在实际通信系统中我们必须在性能、复杂度和系统开销之间做权衡。5.1 性能对比CCDF曲线与计算量权衡为了进行公平对比我们需要固定计算复杂度即每个符号平均的IFFT运算次数。假设我们允许每个符号最多进行C次IFFT运算。对于SLM候选信号数U就等于C。对于PTS总组合数W^V可能远大于C。我们无法进行穷举搜索。这时就需要采用次优搜索算法比如迭代翻转算法从一个初始相位组合开始比如全1依次尝试翻转每个子块的相位乘以-1如果PAPR降低就保留这次翻转否则恢复。遍历所有子块一次或多次直到PAPR不再改善。这种方法只需要大约V或2V次IFFT运算复杂度是O(V)远低于穷举的O(W^V)。阈值法设定一个PAPR目标门限随机生成相位组合并计算PAPR一旦找到低于门限的组合就停止搜索。这种方法的计算量不确定但平均下来可能比穷举小。在MATLAB中实现迭代翻转算法function [optimal_signal, optimal_phases, min_papr] pts_iterative_flipping(subblocks, phase_set) % 使用迭代翻转的次优PTS算法 V length(subblocks); N length(subblocks{1}); % 初始相位组合设为全1或phase_set的第一个元素 current_phases ones(1, V) * phase_set(1); % 计算初始信号的PAPR [X_init, x_init, papr_init] combine_and_calc_papr(subblocks, current_phases, N); min_papr papr_init; optimal_signal x_init; optimal_phases current_phases; improved true; while improved improved false; for v 1:V % 尝试翻转第v个子块的相位 trial_phases current_phases; % 找到当前相位在集合中的位置翻转到下一个 current_idx find(phase_set trial_phases(v)); next_idx mod(current_idx, length(phase_set)) 1; % 循环到下一个 trial_phases(v) phase_set(next_idx); % 计算新组合的PAPR [~, x_trial, papr_trial] combine_and_calc_papr(subblocks, trial_phases, N); if papr_trial min_papr min_papr papr_trial; optimal_signal x_trial; optimal_phases trial_phases; current_phases trial_phases; % 接受这次翻转 improved true; % 可以break出来进行下一轮全局迭代也可以继续尝试翻转其他块 % 这里选择继续尝试本轮的后续块 else % 翻转无效恢复原相位 trial_phases(v) phase_set(current_idx); end end % 如果一轮遍历下来没有任何改善则退出循环 end end function [X_combined, x_combined, papr_val] combine_and_calc_papr(subblocks, phases, N) X_combined zeros(N, 1); V length(subblocks); for v 1:V X_combined X_combined phases(v) * subblocks{v}; end x_combined ifft(X_combined, N); peak_power max(abs(x_combined).^2); avg_power mean(abs(x_combined).^2); papr_val 10 * log10(peak_power / avg_power); end用迭代翻转算法重新运行PTS仿真V4或V8你会发现其性能会比穷举搜索差一些但计算量IFFT次数约为2V大大降低。此时再与U2V的SLM对比就能在相近复杂度下评估两者的优劣。通常即使采用次优搜索PTS在相同计算量下仍可能略优于SLM尤其是当V较大、子块分割方式更优时。5.2 边带信息开销与系统影响无论是SLM还是PTS接收端都需要知道发送端选择了哪个相位组合来恢复原始数据。SLM需要传送一个索引u_opt占用log2(U)比特。例如U4需要2比特U8需要3比特。这部分信息必须被高可靠性编码如用强纠错码因为一旦出错整个OFDM符号的解调都会失败。PTS需要传送最优相位因子组合{b_v}。如果采用二进制相位W2每个子块需要1比特总共V比特。如果V4就是4比特开销可能比U4的SLM2比特大。如果采用四进制相位每个子块需要2比特开销更大。在实际系统设计中边带信息的开销和传输可靠性必须纳入整体频谱效率和误码率的考量。一种常见的做法是将边带信息嵌入到OFDM符号本身中例如使用特定的、接收端已知的导频子载波来隐含地传递相位信息但这会增加系统的复杂性。5.3 计算复杂度与硬件实现考量从计算复杂度看SLM每个符号需要U次完整的N点IFFT运算。IFFT的复杂度是O(N log N)所以总复杂度是O(U * N log N)。U通常较小4, 8, 16。PTS穷举每个符号需要W^V次IFFT运算复杂度O(W^V * N log N)指数增长不可行。PTS迭代翻转每个符号大约需要2V次IFFT运算每轮遍历所有子块复杂度O(V * N log N)。与U2V的SLM处于同一量级。在硬件实现如FPGA或ASIC时IFFT是主要资源消耗单元。SLM需要U个并行的IFFT核或者一个IFFT核重复使用U次增加时延。PTS的迭代翻转算法可以串行执行硬件结构相对简单但控制逻辑稍复杂。选择哪种算法需要根据具体的性能要求、硬件资源、功耗和时延预算来决定。5.4 仿真中的注意事项与扩展方向在完成基础仿真后有几个点值得深入过采样为了更准确地评估PAPR时域信号需要进行过采样例如4倍过采样因为连续时间的OFDM信号峰值可能高于其Nyquist采样点。在MATLAB中可以通过在IFFT前对频域数据补零来实现。不同的调制方式尝试QPSK、16QAM、64QAM。高阶调制如64QAM的幅度变化更大原始PAPR可能更高SLM/PTS的抑制效果也可能不同。子载波数的影响仿真不同的N如128, 256, 512。子载波数越多原始信号的PAPR统计特性越差峰值更高但SLM/PTS的搜索空间也更大抑制效果相对增益可能更明显。结合其他技术SLM/PTS可以与其他PAPR抑制技术结合如预编码、压扩变换等研究联合使用的效果。对系统性能的最终影响PAPR降低后最终要看的是整个通信系统的误码率BER在非线性功放模型下的改善情况。这需要建立包含功放非线性特性如Saleh模型、Rapp模型的完整链路仿真。在我自己的仿真经历中最容易出错的地方是相位因子的应用和边带信息的假设。一定要在代码里清晰地分开“发送端处理”和“接收端处理”两个部分。在发送端我们选择了最优相位因子并发送了对应的时域信号。在接收端仿真BER时必须假设完美同步和信道估计然后使用接收到的边带信息在仿真中就是存储的optimal_indices或optimal_phase_combos对接收到的频域信号进行逆相位旋转才能正确解调出原始数据比特。忽略这一步BER仿真结果将是错误的。最后没有一种算法是万能的。SLM实现简单边带信息开销小但性能提升相对有限。PTS潜力更大但复杂度高边带信息开销大。在实际的通信标准如Wi-Fi, 5G NR中可能会采用更工程化的简化方案或者将PAPR抑制作为整体设计的一部分如选择特定的导频图案、加扰序列来考虑。我们这个仿真项目的目的正是通过亲手实现和对比深刻理解这两种经典算法背后的权衡与设计哲学为将来遇到更复杂的通信信号处理问题打下基础。