Back to skills
extension
Category: Development & EngineeringNo API key required

EEADO-OFDM 光通信仿真技术

Reproduce the EEADO-OFDM (Energy-Efficient Asymmetrically Clipped DC-biased Optical OFDM) optical wireless communication simulation from Wei-Wen Hu's paper. Provides complete Node.js and Python dual implementations covering ADO/EEADO transmitters, adaptive DC bias, interference cancellation receivers, AWGN/nonlinear LED/VLC LOS channel models, and BER/optical power figure generation. Use when reproducing or extending EEADO-OFDM VLC simulations, debugging signal processing pipelines, or comparing ADO-OFDM vs EEADO-OFDM performance.

personAuthor: yanggg1133hubModelScope

EEADO-OFDM 光通信仿真技术 Skill

An Energy-Efficient ADO-OFDM System for Optical Wireless Communication 论文复现 — 完整仿真技术手册(Node.js + Python 双版本)

论文作者: Wei-Wen Hu | 仿真实现: JS(1106行) + Python(893行)

1. 系统背景

1.1 什么是 EEADO-OFDM?

EEADO-OFDM(Energy-Efficient Asymmetrically Clipped Optical OFDM)是一种用于 可见光通信 (VLC / Optical Wireless Communication) 的调制方案。

核心创新:用 自适应 DC 偏置(Adaptive DC Bias) 替代传统 ADO-OFDM 中的固定 DC 偏置, 在保持相同平均光功率的前提下降低能耗。

1.2 调制方案对比

| 方案 | 奇载波 | 偶载波 | DC偏置 | 特点 | |------|--------|--------|--------|------| | ACO-OFDM | ✅ 数据 | ❌ | 无 | 非对称削波,效率低 | | DCO-OFDM | ❌ | ✅ 数据 | 固定高偏置 | 需大偏置防削波,能耗高 | | ADO-OFDM | ✅ ACO数据 | ✅ DCO数据 | 固定 DC | 混合方案,但偏置浪费能量 | | EEADO-OFDM | ✅ ACO+干扰 | ✅ DCO数据 | 自适应 DC | 🎯 本文提出,按需最小化偏置 |

1.3 关键参数 I(子块数)

$$G = N/I \quad \text{(每个子块的样本数)}$$

I 越大 → 子块越小 → 自适应偏置越精细 → 但可用的 ACO 数据子载波越少

| Case | I | 子块大小 G(N=128) | 干扰子载波数 N_int | ACO数据子载波 | |------|---|-------------------|---------------------|---------------| | Case I | 4 | 32 | 16 | 15 | | Case II | 8 | 16 | 8 | 23 | | Case III | 16 | 8 | 4 | 27 | | Case IV | 32 | 4 | 2 | 29 |

2. 文件结构 & 函数映射表

2.1 项目文件清单

项目根目录: F:\WorkBuddy_work\2026-05-07-task-5\

claude修复/                          # 主工作目录(修复后的版本)
├── eesdo_simulation.js              # JS 版仿真主程序 (1106 行)
├── eesdo_ofdm_simulation.py         # Python 版仿真主程序 (893 行)
├── chart.umd.min.js                 # 本地 Chart.js v4 (JS HTML 引用)
├── figure3_data.csv                 # Fig3 原始数据导出
├── figure_3_optical_power.html/png  # Fig3: 所需光功率 vs 子载波数
├── figure_4_ber_case1.html/png      # Fig4: BER (I=4)
├── figure_5_ber_case2.html/png      # Fig5: BER (I=8)
├── figure_6_ber_case3.html/png      # Fig6: BER (I=16)
├── figure_7_ber_case4.html/png      # Fig7: BER (I=32)
├── figure_8_same_spectral_efficiency.html/png  # Fig8: 同频谱效率对比
├── figure_9_nonlinear_led.html/png            # Fig9: 非线性 LED
└── figure_10_nonlinear_led.html/png           # Fig10: 非线性 LED (另一组)
├── figure_11_vlc_los.html/png                 # **Fig11: VLC LOS (I=4)** ⭐新增
├── figure_12_vlc_los.html/png                 # **Fig12: VLC LOS (I=8)** ⭐新增
└── figure_13_vlc_los.html/png                 # **Fig13: VLC LOS (I=16)** ⭐新增

2.2 核心函数对照表(JS ↔ Python)

| 功能模块 | JavaScript 函数 | Python 函数 | 行号(JS) | 行号(Py) | |----------|-----------------|-------------|----------|----------| | 复数运算 | class Complex | numpy.complex128 (原生) | 20-45 | — | | FFT/IFFT | fft() / ifft() (Cooley-Tukey 手写) | np.fft.fft() / np.fft.ifft() | 50-101 | — | | QAM 星座图 | generateQAMConstellation(M) | _get_qam_constellation(M) + 缓存 | 106-127 | 45-62 | | QAM 调制 | qamModulate(bits, M) | qam_modulate(bits, M) | 146-158 | 73-84 | | QAM 解调 | qamDemodulate(symbols, M) | qam_demodulate(symbols, M) | 160-180 | 87-97 | | 随机数 | randn() (Box-Muller) | np.random.randn() (原生) | 187-193 | — | | ADO 发射机 | adoOfdmTransmit(...) | ado_ofdm_transmit(...) | 198-252 | 103-159 | | ADO 接收机 | adoOfdmReceive(...) | ado_ofdm_receive(...) | 265-313 | 165-215 | | EEADO 发射机 | eesdoOfdmTransmit(...) | eesdo_ofdm_transmit(...) | 317-406 | 218-297 | | EEADO 接收机 | eesdoOfdmReceive(...) | eesdo_ofdm_receive(...) | 411-497 | 303-384 | | BER 仿真(AWGN) | runBerSimulation(...) | run_ber_simulation(...) | 501-564 | 504-559 | | BER 仿真(LED) | runBerSimulationLED(...) | run_ber_simulation_led(...) | 1040-1104 | 564-618 | | VLC LOS 信道 | vlcLosChannel(...) | vlc_los_channel(...) | ~1200-1270 | ~623-700 | | BER 仿真(VLC) | runBerSimulationVLC(...) | run_ber_simulation_vlc(...) | ~1272-1344 | ~702-766 | | VLC 缩放信道 | applyVlcChannelScaled(...) | _apply_vcl_scaled(...) | ~1346-1376 | ~768-797 | | 光功率计算(ADO) | calcOpticalPowerADO(...) | required_optical_power_ado(...) | 569-609 | 388-428 | | 光功率计算(EEADO) | calcOpticalPowerEEADO(...) | required_optical_power_eesdo(...) | 610-682 | 429-500 | | HTML 图生成 | generateHTMLPlot(...) | matplotlib (plt.savefig) | 687-730 | 内嵌各figure函数 | | 入口函数 | async main() | def main() | 739-1039 | 863-893 |

2.3 输出格式差异

| | Node.js 版 | Python 版 | |---|-----------|-----------| | 图表格式 | HTML (Chart.js v4 scatter) | PNG (matplotlib) | | 交互性 | 可缩放、悬停查看数值 | 静态图片 | | 依赖 | 无外部库(纯手写 FFT) | numpy + matplotlib | | 适用场景 | 浏览器展示、嵌入网页 | 论文投稿、打印 |

3. 信号处理流水线详解

3.1 完整发射链路 (以 EEADO-OFDM 为例)

输入比特流 ──┬──→ ACO 分支          ┌─────────────────────────────┐
(bitsAco)    │   QAM调制             │  EEADO-OFDM Transmitter     │
             │   映射到奇子载波       │                             │
             │   Hermitian对称        │  bitsAco ──→ QAM ──→ Z[k]  │
             │   IFFT                │    (奇载波: 干扰+数据)       │
             │   非对称削波(max(x,0)) │              ↓ IFFT + clip  │
             │                       │           z_aco[n]          │
输入比特流 ──┤                       │                             │
(bitsDco)    │   DCO 分支            │  bitsDco ──→ QAM ──→ X[k]  │
             │   QAM调制             │    (偶载波: 数据)           │
             │   映射到偶子载波       │              ↓ IFFT         │
             │   Hermitian对称        │           x_n[n]           │
             │   IFFT                │              ↓ 自适应偏置    │
             │   计算自适应DC偏置 s_n │           v_dco[n]          │
             │   v_dco = x_n + s_n    │                             │
             │                       └─────────────────────────────┘
             │
             └──→ 合并: t[n] = z_aco[n] + v_dco[n]  ←── 发送信号
                  ↑
                  └── t[n] ≥ 0 保证(非负光强信号)

3.2 ADO-OFDM 发射机(固定偏置版)

// JS: adoOfdmTransmit(bitsAco, bitsDco, N, M_aco, M_dco, biasDB)
// Py: ado_ofdm_transmit(bits_aco, bits_dco, N, M_aco, M_dco, bias_dB)

步骤:
1. ACO分支: bitsAco → QAM调制 → 奇子载波 k=1,3,5,... → Hermitian对称 → IFFT → 非对称削波 y_aco = max(x_aco, 0)
2. DCO分支: bitsDco → QAM调制 → 偶子载波 k=2,4,6,... → Hermitian对称 → IFFT → x_dco
3. 固定DC偏置: B_dc = σ_x × √(10^(bias_dB/10) - 1)
   其中 σ_x = std(x_dco) (DCO信号标准差)
4. 削波: x_dco_clipped = max(x_dco + B_dc, 0)
5. 合并: t_ado = y_aco + x_dco_clipped

3.3 EEADO-OFDM 发射机(自适应偏置版)⭐ 核心算法

// JS: eesdoOfdmTransmit(bitsAco, bitsDco, N, M_aco, M_dco, I)
// Py: eesdo_ofdm_transmit(bits_aco, bits_dco, N, M_aco, M_dco, I)

关键参数:
  G = N / I          // 子块样本数
  Nint = N / (2*I)   // 用于承载干扰的奇子载波数
  nAcoData = N/4 - Nint // 剩余可用于ACO数据的奇子载波数

步骤:

═══ DCO 分支 ═══
1. DCO数据 → QAM → 偶子载波(k=2,4,6...) → HermitianIFFT → x_n

═══ 自适应偏置计算(核心创新点)═══
2. 将 x_n 分成 I 个子块,每块 G 个样本:
   子块 i: x_n[i*G ... (i+1)*G - 1]
3. 对每个位置 g ∈ [0, G-1],取 I 个子块在该位置的 min:
   m_g = min{ x_n[i*G + g], for i = 0..I-1 }
4. 构建自适应偏置序列:
   s_n[g_mod] = -m_g  if m_g < 0, else 0
   即:只对有负值的列加刚好够的偏置
5. 偏置后DCO信号: v_dco[n] = x_n[n] + s_n[n]

═══ 干扰映射 ═══
6. 对 s_n 做 FFT 得到频域 S_k = fft(s_n)
7. 将 S_k 的非零频率分量 (k=I, 2I, 3I, ...) 映射到奇子载波:
   Z[2i+1] = S_k[(i+1)*I]    for i = 0..Nint-1
   这些子载波专门承载"偏置干扰",接收端已知可消除

═══ ACO 数据子载波 ═══
8. ACO数据 → QAM → 放入剩余奇子载波:
   Z[2*Nint+1 + 2*i] = symAco[i]    for i = 0..nAcoData-1
9. Hermitian对称 → IFFT → 非对称削波 z_aco = max(z_n, 0)

═══ 合并发送 ═══
10. t_eeado = z_aco + v_dco    // 最终发送信号(保证非负)

3.4 EEADO-OFDM 接收机(干扰消除)

// JS: eesdoOfdmReceive(rxSignal, N, M_aco, M_dco, I)
// Py: eesdo_ofdm_receive(rx_signal, N, M_aco, M_dco, I)

步骤:
1. R = FFT(rxSignal)                    // 频域接收信号

2. 从前 Nint 个奇子载波提取干扰信息:
   sym_interference[i] = R[2i+1] × 2    // ×2 因非对称削波导致幅值减半

3. 从剩余奇子载波提取 ACO 数据符号:
   sym_aco[i] = R[2*Nint+1+2i] × 2

4. 用提取的全部奇子载波重建时域 ACO 信号:
   Z_est → Hermitian对称 → IFFT → z_est
   (包含干扰+数据的完整ACO信号估计)

5. 从接收信号中减去ACO成分得到DCO估计:
   r_dco = rxSignal - z_est

6. 对 r_dco 做 FFT 提取偶子载波上的 DCO 符号

7. 分别对 ACODCO 符号做 QAM 硬判决解调

3.5 ADO 接收机(参考对比用)

// JS: adoOfdmReceive(rxSignal, N, M_aco, M_dco)
// Py: ado_ofdm_receive(rx_signal, N, M_aco, M_dco)

步骤:
1. R = FFT(rxSignal)
2. 奇子载波 × 2ACO 解调 (ACO-OFDM 的标准接收: 削波损失一半)
3. 重建完整 ACO 时域信号 → 从 rx 中减去
4. 剩余信号做 FFT → 偶子载波 → DCO 解调

4. 信道模型

4.1 AWGN 信道(Figures 4–8)

$$y[n] = x[n] + w[n], \quad w[n] \sim \mathcal{N}(0, \sigma_w^2)$$

$$\text{SNR} = \frac{E_s}{\sigma_w^2} = \frac{\frac{1}{N}\sum|x[n]|^2}{\sigma_w^2}$$

// JS 实现 (runBerSimulation, 行 529-533)
const signalPower = mean(txSignal.map(v => v * v));  // 信号功率
const noisePower = signalPower / snrLinear;           // 由SNR算噪声功率
const noiseStd = Math.sqrt(noisePower);
const rxSignal = txSignal.map(v => v + randn() * noiseStd);

// Python 实现 (run_ber_simulation, 类似)
signal_power = np.mean(rx ** 2)
noise_power = signal_power / snr_linear
rx_noisy = rx + np.random.randn(N) * np.sqrt(noise_power)

4.2 非线性 LED + AWGN(Figures 9–10)

$$y[n] = \underbrace{\min(x[n], \varepsilon_{upper})}_{\text{LED上削波}} + w[n]$$

// JS (runBerSimulationLED, 行 1068-1075)
txSignal = txSignal.map(v => Math.min(v, epsUpper));  // 上限削波
// ... 然后和上面一样的AWGN代码

// Python (run_ber_simulation_led, 类似)
tx_signal = np.minimum(tx_signal, eps_upper)
# ... 然后 AWGN

物理含义: LED 有最大亮度限制($\varepsilon_{upper}$),超过此值的信号被削波, 引入非线性失真。这是实际 VLC 系统必须考虑的非理想因素。

4.3 VLC 直视链路(LOS)信道(Figures 11–13)⭐ 新增

$$y[n] = \gamma \cdot H_0 \cdot x[n] + w_{\text{total}}[n]$$

其中信道增益和噪声均来自物理模型:

4.3.1 Lambertian 辐射模式

LED 发光强度服从 Lambertian 分布:

$$R(\phi) = \frac{m+1}{2\pi} \cos^m(\phi), \quad m = -\frac{\ln 2}{\ln(\cos\Phi_{1/2})}$$

| 参数 | 符号 | 默认值 | 说明 | |------|------|--------|------| | 半功率角 | $\Phi_{1/2}$ | 60° | 典型白光 LED | | Lambertian 阶数 | $m$ | ≈1.0 (Φ=60°) | 由半功率角计算 |

4.3.2 DC 信道增益

$$H_0 = \frac{(m+1)A_{pd}}{2\pi d^2} \cos^m(\phi) \cos(\psi) \cdot \text{rect}\left(\frac{\psi}{\Psi_c}\right)$$

| 参数 | 符号 | 默认值 | 单位 | |------|------|--------|------| | 接收面积 | $A_{pd}$ | $10^{-4}$ | m² (1 cm²) | | 收发距离 | $d$ | 3.0 | m | | 发送仰角 | $\phi$ | 0 | deg (正对) | | 接收入射角 | $\psi$ | 0 | deg (正对) | | 视场角 | $\Psi_c$ | 90 | deg | | 总直流增益 | $\gamma H_0$ | ≈2.9×10⁻⁵ | — |

4.3.3 噪声模型(与纯 AWGN 的关键区别!)

| 噪声类型 | 公式 | 特性 | |----------|------|------| | 散粒噪声 | $\sigma_{shot}^2 = 2q\gamma P_r B$ | 信号相关! ∝ 接收光功率 | | 热噪声 | $\sigma_{th}^2 = 4k_B T B / R_L$ | 常值,与环境温度相关 | | 总噪声方差 | $\sigma^2 = \sigma_{shot}^2 + \sigma_{th}^2$ | — |

| 物理常数 | 符号 | 值 | |----------|------|-----| | 电子电荷 | $q$ | $1.602\times10^{-19}$ C | | 玻尔兹曼常数 | $k_B$ | $1.381\times10^{-23}$ J/K | | 光电响应度 | $\gamma$ | 0.54 A/W (典型 Si PD) | | 环境温度 | $T$ | 300 K | | 负载电阻 | $R_L$ | 1000 Ω | | 噪声带宽 | $B$ | 20 MHz |

4.3.4 与 AWGN 的本质区别

纯 AWGN:          y = x + N(0, σ²)           → σ 恒定,高SNR时 BER→0
VLC LOS:          y = γH₀·x + N(0, σ²_shot+σ²_th)
                  ↑______↑   ↑__________↑
                 路径损耗    散粒(∝信号)+热噪声
                                    → 高 SNR 时散粒噪声仍存在 → BER 出现噪声底!

仿真实现: runBerSimulationVLC() / run_ber_simulation_vlc()

  • 先计算 baseline gain γ·H₀(只算一次)
  • 每个 SNR 点按目标电 SNR 缩放噪声方差(保留 VLC 增益结构)
  • 输出: Figs 11-13 (JS: HTML, Py: PNG),I=[4,8,16] 三组对比

5. 仿真参数配置

5.1 全局参数

| 参数 | 值 | 说明 | |------|-----|------| | N (FFT 点数) | 128 | OFDM 子载波总数 | | SNR 范围 | [0, 5, 10, 15, 20, 25, 30, 35, 40] dB | BER 曲线横轴 | | 每个 SNR 点符号数 | 50 (Py) / 200 (JS) | Monte Carlo 试验次数 | | N (Fig3 扫描) | [64, 128, 256, 512] | 光功率曲线横轴 | | Fig3 试验次数 | 800-2000 | 光功率统计稳定性 |

5.2 Table I: 各 Case 的 ADO-OFDM 固定偏置

论文要求:ADO 和 EEADO 在相同平均光功率条件下比较 BER

| Case | I | B_DC_DCO (dB) | 含义 | |------|---|---------------|------| | Case I | 4 | 0.25 | I 小 → EEADO 偏置小 → ADO 也只需很小偏置即可匹配 | | Case II | 8 | 3.10 | | | Case III | 16 | 4.95 | | | Case IV | 32 | 6.33 | I 大 → EEADO 偏置更精细 → ADO 需要更大固定偏置来追赶 |

5.3 Figure 8: 同频谱效率对比配置

| 配置 | 调制方式 | QAM阶数 | 偏置 Φ (dB) | I | |------|---------|---------|-------------|---| | ADO baseline | ADO-OFDM | 64QAM-64QAM | 3 | — | | EEADO | EEADO-OFDM | 256QAM-256QAM | 3 | 4 | | ADO baseline | ADO-OFDM | 128QAM-128QAM | 3.5 | — | | EEADO | EEADO-OFDM | 256QAM-256QAM | 3.5 | 8 |

设计思路: EEADO 用更大的 QAM 补偿因干扰损失的子载波, 在相同频谱效率下比较 BER 性能。

5.4 Figures 9–10: 非线性 LED 参数

| 参数 | Fig 9 | Fig 10 | |------|-------|--------| | QAM 阶数 | 16QAM-16QAM | 16QAM-16QAM | | I | [4, 8, 16, 32] | [4, 8, 16, 32] | | ε_upper | 不同值 | 另一组不同值 |

6. JS vs Python 实现差异(踩坑记录)

⚠️ Bug #1 [CRITICAL]: FFT 归一化不一致

| | JS (Cooley-Tukey 手写) | Python (numpy) | |---|------------------------|----------------| | fft() | 无归一化 | 无归一化 ✓ 一致 | | ifft() | 结果 ÷ N | 结果 ÷ N ✓ 一致 |

历史错误: Python 早期版本多写了 * np.sqrt(N)/ np.sqrt(N), 导致信号幅度被错误放大/缩小 √N 倍。已修复。

教训: 当从手写 FFT 移植到 numpy 时,务必确认:

  • np.fft.ifft() 已内置 1/N 归一化 → 不需要额外除
  • np.fft.fft() 无归一化 → 和手写版一致

⚠️ Bug #2 [CRITICAL]: 噪声方差差 2 倍

// JS 正确: randn() * sqrt(noisePower)  →  方差 = noisePower
// Python 错误旧版: randn() * sqrt(noisePower/2)  →  方差 = noisePower/2 (少了一半!)

原因: 误将实噪声当复噪声处理(复噪声实部虚部各占一半功率)。 本仿真是实值信号 → 噪声方差就是 noisePower,不需要除以 2。

⚠️ Bug #3 [HIGH]: EEADO 干扰子载波频率映射错误

错误: 将 S_k 直接按奇索引 Z[k_odd] = S_k[k_odd] 映射 正确: S_k 的非零值在频率 k = I, 2I, 3I, ... 处, 应映射为 Z[2i+1] = S_k[(i+1)*I]

因为 s_n 是周期为 G = N/I 的序列 → 其 FFT 只有 k 为 I 整数倍处非零。

⚠️ Bug #4 [HIGH]: ADO-OFDM 固定偏置未按 Table I 设置

错误: 所有 Case 都用 bias_dB = 7 正确: 每个Case有不同的bias_dB(见 §5.2 Table I), 否则"相同平均光功率"的比较前提不成立。

⚠️ Bug #5 [MEDIUM]: 死代码残留

早期 Python 版 eesdo_ofdm_receive() 中有手动重建 s_n 的循环代码, 逻辑复杂且结果未使用。已清理。

7. 图表输出技术

7.1 JS 版: Chart.js v4 HTML

生成方式: 在 Node.js 中用模板字符串动态拼接 HTML

function generateHTMLPlot(data, filename, title, xLabel, yLabel, logY = false){
    const dsItems = [];  // 构建 datasets
    // ...
    const html = `<!DOCTYPE html><html>...<script src="chart.umd.min.js"></script>
    <script>new Chart(ctx,{type:'scatter',data:{datasets:ds},...})</script>...</html>`;
    fs.writeFileSync(filename, html);
}

关键技术点:

  • 使用本地 chart.umd.min.js 而非 CDN(避免网络依赖)
  • scatter 类型 + showLine: true 画连续曲线
  • 对数Y轴需 clampForLog() 保护零值
  • 数据通过 JSON.stringify() 安全注入模板

7.2 Python 版: matplotlib PNG

fig, ax = plt.subplots(figsize=(9, 7))
ax.semilogy(snr_range, ber_ado, 'o-', label='ADO-OFDM')
ax.set_xlabel('SNR (dB)'); ax.set_ylabel('BER')
ax.legend(); ax.grid(True, alpha=0.3)
plt.savefig('figure_X.png', dpi=150)

优势: semilogy() 天然处理零值(matplotlib 会自动跳过 ≤0 的点), 不存在 Chart.js log(0) 崩溃问题。

8. 运行命令

JS 版

cd claude修复/
node eesdo_simulation.js
# 输出: 8 个 HTML 文件 + 8 个 PNG 截图 + figure3_data.csv
# 耗时: 约 5-15 分钟(取决于 Monte Carlo 次数)

Python 版

cd claude修复/
pip install numpy matplotlib
python eesdo_ofdm_simulation.py
# 输出: 8 个 PNG 文件
# 耗时: 比 JS 快(numpy 向量化加速)

验证输出完整性

# 检查所有期望文件是否存在
ls -la figure_*.html figure_*.png

# 检查 HTML 中是否有零值风险
grep -c '\[.*,0\]' figure_*.html

9. 扩展与二次开发指南

9.1 添加新的调制方案

  1. 在发射链中新增 xxxOfdmTransmit() 函数
  2. 在接收链中新增 xxxOfdmReceive() 函数
  3. main() / figures_X_Y() 中添加调用
  4. JS: 用 generateHTMLPlot() 输出; Py: 用 matplotlib 绑制

9.2 修改信道模型

  • 新增信道函数(如多径、光散射等)
  • runBerSimulation() 的发射和接收之间插入信道处理
  • 参考 runBerSimulationLED() 的模式(在 AWGN 前添加非线性)

9.3 加速仿真技巧

| 方法 | JS | Python | |------|-----|--------| | 减少 Monte Carlo 次数 | 降低 nSymbols | 降低 n_symbols | | 并行 SNR 点 | Worker Threads | multiprocessing | | 向量化内层循环 | 难(JS无矩阵运算) | numpy broadcasting 大幅加速 | | 减少 SNR 点密度 | 缩短 snrRange 数组 | 同左 | | 缓存 QAM 星座图 | ✅ 可缓存 generateQAMConstellation | ✅ _QAM_CACHE 字典 |

10. 论文原图对照

预期曲线特征

| Figure | 预期趋势 | 判断依据 | |--------|----------|----------| | Fig 3 | P_ado > P_eesdo(I越大越省功) 且都随N增大而增 | EEADO自适应偏置节省能量 | | Figs 4-7 | EEADO BER < ADO BER (同QAM), 高SNR差距明显 | EEADO干扰消除有效 | | Fig 8 | 同频谱效率下 EEADO 优于或持平 ADO | 更大QAM补偿了子载波损失 | | Figs 9-10 | 非线性下所有曲线性能退化,低I受影响更大 | I小→子块大→峰值概率高→削波严重 |

如果仿真结果不符合上述趋势,检查:

  1. Table I 偏置是否正确设置
  2. 干扰映射 (Bug #3) 是否正确
  3. 噪声方差 (Bug #2) 是否正确