一、SLM(选择性映射)算法原理
1.1 为什么OFDM的PAPR高?
OFDM时域信号是多子载波叠加:
\[x[n] = \frac{1}{\sqrt{N}}\sum_{k=0}^{N-1} X[k]\, e^{j2\pi kn/N}
\]
当多个子载波同相相加时,峰值功率远大于平均功率 → PAPR飙升。
1.2 SLM的核心思想
不改变原始数据信息,只对频域符号乘上不同的恒模相位旋转序列 \(P^{(u)} = [e^{j\phi_0}, e^{j\phi_1}, \dots, e^{j\phi_{N-1}}]\),生成 \(U\) 个候选时域信号,挑 PAPR最小 的那个发出。
\[\tilde{X}^{(u)}[k] = X[k] \cdot \exp\big(j\phi_k^{(u)}\big), \quad u=1,2,\dots,U
\]
因为 \(|P^{(u)}[k]|=1\),所以 不破坏星座映射,只是旋转相位,信息无损。
1.3 代价
- 需要计算 \(U\) 次 IFFT → 复杂度 ↑
- 接收端必须知道用了哪组相位 → 需传 边带信息(side info)\(\lceil\log_2 U\rceil\) bit/symbol
二、MATLAB代码
主脚本:ofdm_slm_papr.m
%% =============================================================
% OFDM系统 + SLM算法 PAPR抑制仿真
% 包含:信号生成 → 调制 → IFFT(过采样) → CP → SLM候选选择 → CCDF
% 输出:原始 vs SLM 的 PAPR 统计对比 + 时域波形对比
% =============================================================
clc; clear; close all;%% ===================== 1. 系统参数 =====================
Nfft = 64; % 子载波数(不含DC,不含保护)
Ncp = 16; % 循环前缀长度
L = 4; % 过采样因子(频域补零,L=4是常用值)
Nfft_os = Nfft * L; % 过采样后IFFT点数
Nsym = 10000; % OFDM符号数(用于CCDF统计,越大越平滑)
M = 4; % 调制阶数:4=QPSK, 16=16QAM, 64=64QAM% SLM候选数
U_set = [1, 4, 8, 16]; % U=1表示无SLM(原始),其余为SLM候选数
% U=1 留作基准;实际SLM从U>=2开始%--- 调制映射 -----------------------------
if M == 4constel = [1+1j, -1+1j, -1-1j, 1-1j]/sqrt(2); % QPSK (单位平均功率)bits_per_sym = 2;
elseif M == 16% 16QAM (单位平均功率归一化)alpha = [-3 -1 1 3];[A,B] = meshgrid(alpha,alpha);constel = (A(:) + 1j*B(:)) / sqrt(mean(abs(A(:)+1j*B(:)).^2));bits_per_sym = 4;
elseerror('仅演示 M=4 或 M=16,可自行扩展');
end
Nconst = length(constel);fprintf('====== OFDM-SLM PAPR 仿真 ======\n');
fprintf('子载波数 Nfft=%d | 过采样 L=%d | 调制=M=%d | 符号数=%d\n',...Nfft, L, M, Nsym);%% ===================== 2. 生成相位序列池 =====================
% 相位因子取自 {0, π}(即 ±1),或 {0,π/2,π,3π/2}
% 这里用 BPSK set {+1, -1} → 每个子载波相位 = 0 或 pi
phase_set = [0, pi]; % 弧度% 为每种U预生成相位序列(每行为一个候选的Nfft个相位因子)
maxU = max(U_set);
% 注意:第1个候选恒为单位向量(即原始信号本身),便于统一处理
Phi = zeros(maxU, Nfft); % Phi(u,k) = phi for candidate u, subcarrier k
Phi(1,:) = 0; % 候选1 = 不做旋转(原始)rng(2025); % 固定种子,便于复现
for u = 2:maxU% 随机从 {0, pi} 选取(DC子载波可固定为0相位,不影响PAPR)idx = randi([1,2], 1, Nfft);Phi(u,:) = phase_set(idx);Phi(u,1) = 0; % 可固定DC位置相位为0(惯例,不影响信息)
end%% ===================== 3. 主仿真:逐符号处理,收集PAPR =====================
% 为每个U值准备PAPR数组
papr_cell = cell(length(U_set),1);
for ui = 1:length(U_set)papr_cell{ui} = zeros(Nsym,1);
endfprintf('仿真OFDM符号中...\n');
for ns = 1:Nsym% ---- 3.1 随机数据 → 调制(频域符号)----data_idx = randi([1,Nconst], 1, Nfft);X_freq = constel(data_idx); % Nfft个频域符号(行向量)% ---- 3.2 过采样:频域补零到 Nfft_os ----% 将X_freq放到频域中心(Indices: L/2*Nfft ... L/2*Nfft+Nfft-1 等)% 简便做法:X_zpad(k) 对应 k=0..Nfft_os-1% 我们把X_freq(0..Nfft/2-1)放低频,其余镜像(共轭对称)做实数IFFT% → 更简单:直接做 Nfft 的IFFT,然后在时域插值;但标准做法是频域零填充%% 标准过采样:令% X_os[0..Nfft/2-1] = X_freq(1..Nfft/2)% X_os[Nfft/2] = 0 (DC可放这里)% X_os[Nfft_os-Nfft/2 .. ] = conj(flip(X_freq(2+Nfft/2:end)))% 其实对PAPR来说用 Hermitian对称是为了真实基带实信号;% 许多文献为简化取:X_zpad中间放X_freq,两边补零 → 做ifft即得复包络%% ★ 简化且广泛接受的做法(复基带,不做共轭对称):X_zpad = zeros(1,Nfft_os);half = floor(Nfft/2);X_zpad(1:half) = X_freq(1:half); % 负频部分X_zpad(half+1) = 0; % DCX_zpad(Nfft_os-half+1:end) = X_freq(half+2:end); % 正频部分% 上面这种"非对称补零"会产生复时域(包络),对PAPR计算完全合法% (实际射频会再上变频,PAPR由复包络幅度决定)% ---- 对每个候选u = 1..U 算PAPR ----for ui = 1:length(U_set)Uu = U_set(ui);best_papr = inf;for u = 1:Uu% 相位旋转ph = Phi(u,:);% 把相位扩展到补零后的频域(只在有数据的位置上乘,补零位置不管)ph_pad = ones(1,Nfft_os);ph_pad(1:half) = exp(1j * ph(1:half));ph_pad(half+1) = 1; % DCph_pad(Nfft_os-half+1:end) = exp(1j * ph(half+2:end));X_rot = X_zpad .* ph_pad;x = ifft(X_rot, Nfft_os); % 过采样时域信号% PAPRinst_power = abs(x).^2;papr_u = 10*log10( max(inst_power)/mean(inst_power) );if papr_u < best_paprbest_papr = papr_u;endendpapr_cell{ui}(ns) = best_papr;end% 进度if mod(ns, round(Nsym/10))==0fprintf(' 已完成 %d/%d 符号\n', ns, Nsym);end
end%% ===================== 4. 计算CCDF =====================
% CCDF(PAPR0) = Prob( PAPR > PAPR0 )
papr_db_vec = 0:0.1:15; % PAPR横坐标(dB)figure('Position',[150 150 650 480]);
hold on;colors = {'k', 'r', 'b', 'g', 'm'};
marks = {'-', '--', '-.', '-', ':'};for ui = 1:length(U_set)papr_vals = papr_cell{ui};ccdf = zeros(size(papr_db_vec));for k = 1:length(papr_db_vec)ccdf(k) = mean(papr_vals > papr_db_vec(k));endsemilogy(papr_db_vec, ccdf, ...[colors{mod(ui-1,5)+1} marks{mod(ui-1,4)+1}], ...'LineWidth', 2, ...'DisplayName', sprintf('U=%d %s', U_set(ui), ui==1?' (原始)':'(SLM)'));
endgrid on;
xlabel('PAPR_0 (dB)','FontSize',11);
ylabel('CCDF = Prob(PAPR > PAPR_0)','FontSize',11);
title(sprintf('OFDM Nfft=%d L=%d M=%d | SLM PAPR抑制效果',Nfft,L,M),'FontSize',12);
legend('Location','best','FontSize',10);
xlim([0 14]); ylim([1e-4 1]);
hold off;%% ===================== 5. 打印关键点对比 =====================
fprintf('\n========== CCDF @ 10^{-2} 处的PAPR值 ==========\n');
for ui = 1:length(U_set)papr_vals = papr_cell{ui};% 找 Prob(PAPR > x) ≈ 0.01 的xxx = sort(papr_vals);idx = round(0.01 * length(xx));if idx < 1, idx = 1; endpapr_at_1pct = xx(end-idx);fprintf(' U=%2d : PAPR|_{CCDF=1%%} ≈ %.2f dB\n', U_set(ui), papr_at_1pct);
end%% ===================== 6. 时域包络对比(单个符号可视化) =====================
% 单独画一个典型符号的时域幅度包络:原始 vs SLM选优
figure('Position',[150 400 700 280]);
Nsamp_show = Nfft_os;% 重新生成一个符号
rng(99);
data_idx = randi([1,Nconst], 1, Nfft);
X_freq = constel(data_idx);
X_zpad = zeros(1,Nfft_os);
half = floor(Nfft/2);
X_zpad(1:half) = X_freq(1:half);
X_zpad(half+1) = 0;
X_zpad(Nfft_os-half+1:end) = X_freq(half+2:end);% 原始(无相位旋转)
x_orig = ifft(X_zpad, Nfft_os);
env_orig = abs(x_orig);% SLM选优(U=8)
U_show = 8;
cand_papr = zeros(1,U_show);
x_cand = zeros(U_show, Nsamp_show);
for u = 1:U_showph_pad = ones(1,Nfft_os);ph_pad(1:half) = exp(1j * Phi(u,1:half));ph_pad(half+1) = 1;ph_pad(Nfft_os-half+1:end) = exp(1j * Phi(u,half+2:end));Xr = X_zpad .* ph_pad;xt = ifft(Xr, Nfft_os);x_cand(u,:) = xt;cand_papr(u) = 10*log10( max(abs(xt).^2)/mean(abs(xt).^2) );
end
[~, best_u] = min(cand_papr);
env_slm = abs(x_cand(best_u,:));t_axis = (0:Nsamp_show-1)/Nsamp_show * (Nfft+L*Ncp)/Nfft; % 归一化时间轴subplot(1,2,1);
plot(env_orig, 'k', 'LineWidth',1.2); hold on;
plot(env_slm, 'r', 'LineWidth',1.2);
xlabel('采样点'); ylabel('|x[n]|');
title('时域幅度包络对比(单符号)');
legend(sprintf('原始 PAPR=%.1f dB', cand_papr(1)), ...sprintf('SLM-U%d PAPR=%.1f dB',U_show,cand_papr(best_u)), ...'Location','northwest');
grid on;subplot(1,2,2);
bar(cand_papr, 'FaceColor',[0.3 0.5 0.9]);
xlabel('候选序号 u'); ylabel('PAPR (dB)');
title(sprintf('U=%d 候选信号的PAPR(选最小)',U_show));
grid on;
yline(cand_papr(best_u), 'r--', 'LineWidth',1.5, 'DisplayName','选中');
yline(cand_papr(1), 'k:', 'LineWidth',1, 'DisplayName','原始');
legend('Candidate','Selected','Original','Location','northwest');sgtitle('SLM算法:从U个候选中选最低PAPR信号');
三、运行结果解读
运行后会得到两张图:
图1 — CCDF曲线(核心结论图)
Prob(PAPR > PAPR₀)
↑
| ──────── U=1 (原始) ← 最高,曲线最右
| ------ U=4 (SLM)
| ---- U=8 (SLM) ← 左移 = PAPR被压下去了
| --- U=16(SLM) ← 更左 = 更优,但收益递减
|___|___________|______________________→ PAPR₀(dB)
典型数值(Nfft=64, QPSK):
| 方法 | PAPR @ CCDF=1% | 说明 |
|---|---|---|
| 原始 OFDM | ≈ 10.5 dB | 峰值出现概率不可忽略 |
| SLM U=4 | ≈ 8.8 dB | ↓ 1.7 dB |
| SLM U=8 | ≈ 8.0 dB | ↓ 2.5 dB |
| SLM U=16 | ≈ 7.5 dB | ↓ 3.0 dB,再增U收益递减 |
图2 — 单符号时域包络
左侧显示原始信号包络有明显尖峰(高PAPR),SLM选出的候选包络更"平坦";右侧柱状图列出所有候选的PAPR值,红色虚线标记选中的最低者。
四、关键实现细节
1. 为什么需要过采样(L≥4)
直接对 Nfft 点做 IFFT,时域只有 Nfft 个采样点,会漏掉峰之间的真实峰值,算出的PAPR偏低且不准。正确做法是在频域两侧补零到 Nfft×L,再做IFFT。
% 频域补零(简化写法,非共轭对称版,对PAPR包络有效)
X_zpad = zeros(1, Nfft*L);
X_zpad(1:Nfft/2) = X(1:Nfft/2); % 低频
X_zpad(end-Nfft/2+2:end) = X(Nfft/2+2:end); % 高频镜像位置
% DC: X_zpad(Nfft*L/2+1) = X(Nfft/2+1)
x = ifft(X_zpad, Nfft*L); % 过采样时域
2. 相位序列怎么取才对
- 恒模性必须满足:
|exp(jφₖ)| = 1→ 只改变相位,不改变星座点幅度 - 常用取法:{0, π}(即乘 +1 或 -1),等价于随机符号翻转
- 更高级:从 {0, π/2, π, 3π/2} 选 → 每载波2bit相位信息,候选更多
3. DC子载波
实际WiFi/LTE等标准中 DC子载波不传数据(固定为0),相位旋转时DC位置 φ_DC=0 即可。
4. 边带信息(Side Information)
接收端要知道发的是哪个 u,否则解不出来。通常:
- 用几个bit明文传
index(最常用) - 或用 盲检测:接收端自己试所有U个相位逆旋转,看哪个星座点最"干净"(复杂度高)
参考代码 使用SLM算法,在OFDM系统上的峰均功率比抑制 www.youwenfan.com/contentcnv/81612.html
五、复杂度分析
| 项目 | 原始OFDM | SLM (U个候选) |
|---|---|---|
| IFFT次数/符号 | 1 | U 次 |
| 计算复杂度 | O(NlogN) | O(U·NlogN) |
| 额外开销 | — | ⌈log₂U⌉ bit/符号(边带) |
工程折中:常用 U=4~8,再大收益递减(CCDF曲线渐近),而IFFT算力线性增长。
六、扩展方向
| 扩展 | 思路 |
|---|---|
| 低复杂度SLM | 用分段相位(只旋转部分子载波)/ 提前剪枝 |
| 盲SLM(无side info) | 接收端穷举U个逆相位尝试解码,选BER最小 |
| 联合削波+SLM | 先SLM压主体,再轻度削波处理尾部残余 |
| 5G/OFDMA适配 | 每个RU(资源单元)独立做SLM相位向量 |
