スマートフォンで動画を視聴しているとき、Wi-Fi で大容量のファイルを転送しているとき、あるいは探査機が火星から画像データを地球に送信しているとき — これらすべてのディジタル通信において、送信された信号は受信されるまでの間に必ず雑音(ノイズ)の影響を受けます。送ったビット列がそのまま完璧に届くことは、現実には決してありません。
では、雑音がある環境でどの程度正確にデータを送れるのか? その理論的な答えを得るための最も基本的な出発点がAWGN(Additive White Gaussian Noise)通信路モデルです。このモデルは一見単純ですが、通信工学におけるほぼすべての性能解析の土台として機能しています。
AWGN通信路を理解すると、以下のような場面で不可欠な知識が得られます。
- 変調方式の比較: BPSK、QPSK、16QAM、64QAM などの変調方式がどの程度のエネルギー効率を持つかを公平に比較するためのベンチマーク環境を提供する
- 通信システム設計: 衛星通信や移動体通信のリンクバジェット計算において、所要 $E_b/N_0$ を見積もる基礎となる
- シャノン限界の理解: あらゆる通信方式が到達し得ない理論限界(シャノン限界)がAWGN通信路上で定義される
- 実環境性能の下限: フェージングや干渉がない理想環境での性能を示すため、実際のシステム性能がこれより良くなることは原理的にない
本記事の内容
- AWGN通信路の定義 —「加法性」「白色」「ガウス」それぞれの意味
- 受信信号モデル $r(t) = s(t) + n(t)$ の数理的記述
- $E_b/N_0$(ビット当たりエネルギー対雑音電力密度比)の定義と物理的意味
- BPSK の BER を Q 関数で厳密に導出
- QPSK, 16QAM, 64QAM の BER 理論式
- 各変調方式の BER-$E_b/N_0$ 特性の比較
- シャノン限界との関係
- Python による理論 BER カーブとモンテカルロシミュレーションの比較
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
AWGN通信路とは
通信路モデルの役割
現実の通信路は非常に複雑です。電波は建物に反射し、大気中で減衰し、他のシステムからの干渉を受け、受信機内部では電子の熱運動による雑音が発生します。このように無数の要因が絡み合う現実の通信路を、いきなりそのまま解析しようとしても手に負えません。
そこで物理学や工学でおなじみの手法 —モデル化— を使います。現実の複雑さの中から本質的な要素を抽出し、数学的に扱えるモデルに落とし込むのです。AWGN通信路モデルは、数あるモデルの中で最もシンプルで基本的な通信路モデルです。
イメージとしては、静かな部屋の中で2人が会話している場面を想像してください。壁からの反響もなく、他の人の会話も聞こえません。唯一の妨害要因は、空調のファンが作り出す一様な「サー」という背景雑音だけです。この背景雑音が会話に重なって聞こえる — これがAWGN通信路のアナロジーです。
「AWGN」の3つの単語の意味
AWGN は Additive White Gaussian Noise の頭文字であり、この名前自体が雑音の3つの性質を正確に表現しています。それぞれの意味を丁寧に見ていきましょう。
1. Additive(加法性)
雑音 $n(t)$ が信号 $s(t)$ に対して加算的に重畳することを意味します。受信信号 $r(t)$ は、送信信号に雑音がそのまま足し算される形で表現されます。
$$ r(t) = s(t) + n(t) $$
これは「信号と雑音が独立に存在し、受信機ではそれらの和が観測される」という仮定です。現実にはフェージング(信号の振幅や位相が時間変動する現象)のように、信号に掛け算的に影響を及ぼす効果もありますが、AWGNモデルではそのような乗法的効果は考えません。
加法性の仮定は非常に強力です。なぜなら、信号 $s(t)$ と雑音 $n(t)$ を独立に扱えるため、数学的な解析が格段に容易になるからです。
2. White(白色)
雑音のパワースペクトル密度(PSD: Power Spectral Density)がすべての周波数で一定であることを意味します。可視光で白色光がすべての波長を均等に含んでいるのと同じ発想から、「白色雑音」と呼ばれます。
白色雑音の片側パワースペクトル密度は、定数 $N_0/2$ で表されます。
$$ S_n(f) = \frac{N_0}{2} \quad \text{[W/Hz]}, \quad -\infty < f < \infty $$
ここで $N_0$ は雑音電力密度と呼ばれ、単位は W/Hz(ワット毎ヘルツ)です。$N_0/2$ の「2」は両側スペクトルの表記に由来します。片側スペクトル($f \geq 0$)で書くと $S_n(f) = N_0$ です。
白色雑音の自己相関関数は、パワースペクトル密度のフーリエ逆変換として求まります。
$$ R_n(\tau) = \frac{N_0}{2}\delta(\tau) $$
$\delta(\tau)$ はディラックのデルタ関数です。これは、異なる時刻の雑音値が完全に無相関であることを意味します。$\tau \neq 0$ で $R_n(\tau) = 0$ ですから、ある瞬間の雑音の値は、他のどの瞬間の雑音の値とも全く関係がありません。
厳密に言えば、全周波数で一定のパワーを持つ白色雑音は全パワーが無限大($\int_{-\infty}^{\infty}S_n(f)df = \infty$)になるため、物理的には実現不可能です。しかし、実際の通信システムでは受信機の帯域幅が有限であるため、帯域内のスペクトルが一定であれば白色とみなせます。これは非常によい近似です。
3. Gaussian(ガウス分布に従う)
任意の時刻 $t$ における雑音の瞬時値 $n(t)$ が正規分布(ガウス分布)に従うことを意味します。
$$ f_n(x) = \frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{x^2}{2\sigma^2}\right) $$
ここで $\sigma^2$ は雑音の分散(パワー)です。平均はゼロ($\mu = 0$)とします。
なぜガウス分布なのでしょうか? これには深い物理的理由があります。実際の熱雑音は、受信回路の抵抗体中の膨大な数の電子のランダムな熱運動が重ね合わされて生じます。中心極限定理により、多数の独立な微小変動の和は正規分布に収束します。したがって、熱雑音がガウス分布に従うのは物理法則の帰結なのです。
ガウス分布という仮定は数学的にも非常に都合がよい性質を持っています。ガウス確率変数の線形変換はやはりガウス確率変数になり、無相関であれば独立でもあります。これにより、受信機の最適設計や誤り率の解析が閉じた形で行えるのです。
以上の3つの性質をまとめると、AWGNとは「信号に加算的に重畳される、すべての周波数で一定のパワースペクトル密度を持ち、各時刻の瞬時値が正規分布に従うような雑音」です。このモデルが通信工学の標準的な解析基盤として広く使われている理由は、(1)物理的に妥当であること、(2)数学的に扱いやすいこと、(3)他のより複雑なモデルの出発点になることの3点にあります。
AWGN通信路の数学的な性質がわかったところで、次にこの通信路上でのディジタル通信の性能を議論するための最も重要なパラメータ — $E_b/N_0$ — を定義しましょう。
$E_b/N_0$ の定義と物理的意味
SNRだけでは不十分な理由
信号対雑音比(SNR: Signal-to-Noise Ratio)は通信品質を表す最も直感的な指標です。SNR が大きいほど信号が雑音に対して強い、ということは直感的に明らかです。
$$ \text{SNR} = \frac{S}{N} = \frac{\text{信号電力}}{\text{雑音電力}} $$
しかし、SNR には重大な欠点があります。雑音電力 $N$ は受信機の帯域幅 $B$ に依存するため($N = N_0 B$)、帯域幅が異なるシステム同士を公平に比較できないのです。例えば、帯域幅 1 MHz のシステムと帯域幅 10 MHz のシステムでは、同じ信号電力であっても雑音電力が 10 倍異なります。
さらに、データレート(ビットレート)$R_b$ が異なるシステムも同じ土俵で比較したいところです。1 Mbps で通信するシステムと 100 Mbps で通信するシステムが同じ SNR を持っていたとしても、1 ビットあたりに割り当てられるエネルギーは 100 倍異なります。
これらの問題を解決し、あらゆる変調方式・帯域幅・データレートのシステムを統一的に比較するための指標が $E_b/N_0$ です。
$E_b/N_0$ の定義
$E_b/N_0$ は「1ビットを送信するのに使うエネルギー $E_b$」と「雑音の電力密度 $N_0$」の比です。
$$ \frac{E_b}{N_0} \quad \text{[無次元]} $$
ここで各変数の意味は以下の通りです。
- $E_b$: 1ビットあたりの信号エネルギー [J/bit]。信号電力 $S$ [W] とビットレート $R_b$ [bit/s] から $E_b = S/R_b$ で求まります
- $N_0$: 雑音の片側パワースペクトル密度 [W/Hz]。熱雑音の場合、$N_0 = kT$ で与えられます($k$ はボルツマン定数、$T$ はシステム雑音温度)
$E_b/N_0$ が持つ物理的意味を直感的に理解するため、エネルギーの次元を確認してみましょう。
$$ \frac{E_b}{N_0} = \frac{[\text{J/bit}]}{[\text{W/Hz}]} = \frac{[\text{J/bit}]}{[\text{J}]} = \frac{1}{[\text{bit}]} $$
ここで $\text{W/Hz} = \text{J} \cdot \text{s}^{-1} / \text{s}^{-1} = \text{J}$ を使いました。つまり $E_b/N_0$ は無次元量であり、「1ビット送信に使うエネルギーが雑音エネルギーの何倍か」を表しています。この比が大きいほど、雑音に対して十分なエネルギーでビットを送っていることになり、ビット誤りが少なくなります。
SNRと $E_b/N_0$ の関係
$E_b/N_0$ と通常の SNR は、以下の関係式で結ばれています。
信号電力 $S = E_b R_b$、雑音電力 $N = N_0 B$ を使うと、
$$ \text{SNR} = \frac{S}{N} = \frac{E_b R_b}{N_0 B} = \frac{E_b}{N_0} \cdot \frac{R_b}{B} $$
ここで $R_b/B$ は帯域効率(spectral efficiency)[bit/s/Hz] に対応します。この式から、同じ $E_b/N_0$ であっても帯域効率が高い変調方式ほど大きな SNR が必要であることがわかります。言い換えれば、帯域効率を上げようとすると所要 $E_b/N_0$ が増大する — これは後に述べるシャノン限界とも深く関わるトレードオフです。
通信工学では $E_b/N_0$ を dB 単位で表すのが慣例です。
$$ \left(\frac{E_b}{N_0}\right)_{\text{dB}} = 10\log_{10}\left(\frac{E_b}{N_0}\right) \quad \text{[dB]} $$
例えば $E_b/N_0 = 10$ は約 $10$ dB、$E_b/N_0 = 100$ は $20$ dB に対応します。
$E_b/N_0$ という共通のものさしが定まりました。いよいよ、この指標を使って各変調方式のビット誤り率(BER)を定量的に求めていきます。まずは最もシンプルな BPSK から始めましょう。
BPSK の BER 導出
BPSK の信号空間表現
BPSK(Binary Phase Shift Keying)は、2つの位相状態(0°と 180°)を使って1ビットを伝送する最も基本的なディジタル変調方式です。送信ビット「0」と「1」に対応する信号は次のように表されます。
$$ s_0(t) = \sqrt{\frac{2E_b}{T_b}}\cos(2\pi f_c t), \quad s_1(t) = -\sqrt{\frac{2E_b}{T_b}}\cos(2\pi f_c t) $$
ここで $E_b$ は 1 ビットあたりのエネルギー、$T_b$ はビット周期、$f_c$ は搬送波周波数です。
信号空間(signal space)で考えると、BPSK は1次元の信号空間上の2点に対応します。基底関数を
$$ \phi(t) = \sqrt{\frac{2}{T_b}}\cos(2\pi f_c t), \quad 0 \leq t \leq T_b $$
と定めると、送信信号点は $s_0 = +\sqrt{E_b}$、$s_1 = -\sqrt{E_b}$ となります。2つの信号点間の距離は $2\sqrt{E_b}$ です。
受信側では、整合フィルタ(matched filter)の出力として、受信信号点 $r$ が得られます。
$$ r = s + n $$
ここで $s = \pm\sqrt{E_b}$(送信された信号点)、$n$ は平均 $0$、分散 $N_0/2$ のガウス確率変数です。分散が $N_0/2$ になる理由は、帯域通過信号を基底関数に射影したとき、白色雑音の分散が $N_0/2$ になるためです。
BER の導出
ビット誤りが起きるのは、送信された信号点とは反対側に受信信号点が落ちたときです。最適受信機(最尤検出器)は、受信信号点 $r$ の正負で判定します。$r > 0$ なら $s_0$、$r < 0$ なら $s_1$ と判定します。
ビット「0」が送信された場合($s = +\sqrt{E_b}$)を考えます。誤りが起きるのは $r < 0$ のとき、すなわち $n < -\sqrt{E_b}$ のときです。
$$ P_e = P(r < 0 \,|\, s_0 \text{ 送信}) = P(n < -\sqrt{E_b}) $$
$n$ は平均 $0$、分散 $\sigma^2 = N_0/2$ のガウス確率変数ですから、
$$ P_e = \int_{-\infty}^{-\sqrt{E_b}} \frac{1}{\sqrt{\pi N_0}} \exp\left(-\frac{x^2}{N_0}\right) dx $$
ここで変数変換 $u = x / \sqrt{N_0/2}$ を施すと、$dx = \sqrt{N_0/2}\,du$、$x = -\sqrt{E_b}$ のとき $u = -\sqrt{2E_b/N_0}$ となるので、
$$ P_e = \int_{-\infty}^{-\sqrt{2E_b/N_0}} \frac{1}{\sqrt{2\pi}} \exp\left(-\frac{u^2}{2}\right) du $$
ガウス分布の対称性 $P(U < -a) = P(U > a)$ を使うと、
$$ P_e = \int_{\sqrt{2E_b/N_0}}^{\infty} \frac{1}{\sqrt{2\pi}} \exp\left(-\frac{u^2}{2}\right) du $$
この積分はQ関数として定義されています。
$$ Q(x) = \int_{x}^{\infty} \frac{1}{\sqrt{2\pi}} \exp\left(-\frac{u^2}{2}\right) du $$
Q関数は標準正規分布の上側確率(tail probability)であり、引数 $x$ が大きいほど急速にゼロに近づきます。Q 関数は相補誤差関数 $\text{erfc}$ とも関係があり、$Q(x) = \frac{1}{2}\text{erfc}\left(\frac{x}{\sqrt{2}}\right)$ が成り立ちます。
以上より、BPSK の BER は次のように得られます。
$$ \boxed{P_b^{\text{BPSK}} = Q\left(\sqrt{\frac{2E_b}{N_0}}\right)} $$
ビット「1」が送信された場合も、対称性から全く同じ BER が得られます。この結果はBPSKの美しい性質を反映しています。信号点が原点に対して対称に配置されているため、どちらのビットを送っても誤り率は等しいのです。
具体的な数値で確認してみましょう。$E_b/N_0 = 10$($10$ dB)のとき、
$$ P_b = Q\left(\sqrt{20}\right) = Q(4.47) \approx 3.87 \times 10^{-6} $$
つまり、約 26 万ビットに 1 ビット程度の誤りが発生する計算です。$E_b/N_0 = 7$ dB($\approx 5.01$)であれば、
$$ P_b = Q\left(\sqrt{10.02}\right) = Q(3.17) \approx 7.7 \times 10^{-4} $$
と、約 1,300 ビットに 1 ビットの誤りです。$E_b/N_0$ が数 dB 変わるだけで BER が桁違いに変化することがわかります。これは Q 関数(ガウス分布の裾)が指数的に減衰する性質に起因しています。
BPSKは1ビットを1シンボルで送る最もシンプルな方式でした。では、1シンボルに複数ビットを載せる、より高効率な変調方式ではBERはどうなるのでしょうか? 次に、QPSK を皮切りに、QAM系列の変調方式のBERを求めていきます。
QPSK の BER
QPSK の信号空間
QPSK(Quadrature Phase Shift Keying)は、4つの位相状態(45°, 135°, 225°, 315°)を使い、1シンボルで2ビットを伝送する変調方式です。帯域効率は BPSK の2倍(2 bit/s/Hz)ですが、驚くべきことに、$E_b/N_0$ あたりの BER は BPSK と同じです。
この一見矛盾する結果を理解するために、QPSK の信号空間を詳しく見てみましょう。QPSK の4つの信号点は、直交する2つの基底関数(I チャネルと Q チャネル)の上に配置されます。
$$ s_i(t) = \sqrt{\frac{2E_s}{T_s}}\cos\left(2\pi f_c t + \frac{\pi}{4} + \frac{\pi}{2}(i-1)\right), \quad i = 1, 2, 3, 4 $$
ここで $E_s$ はシンボルあたりのエネルギー、$T_s$ はシンボル周期です。$E_s = 2E_b$(2ビット分)、$T_s = 2T_b$ の関係があります。
I/Q の2次元信号空間で見ると、4つの信号点は次の座標に配置されます。
$$ (s_I, s_Q) = \left(\pm\sqrt{E_b},\, \pm\sqrt{E_b}\right) $$
各軸方向の信号点間距離は $2\sqrt{E_b}$ であり、これは BPSK と全く同じです。
BER の計算
QPSK の鍵となる洞察は、I チャネルと Q チャネルが独立に動作するということです。I チャネルの雑音成分と Q チャネルの雑音成分は、白色ガウス雑音の性質により統計的に独立です。
したがって、I チャネル方向のビット判定は BPSK と等価であり、Q チャネル方向も同様です。各チャネルにおける信号点間距離は $2\sqrt{E_b}$、雑音の分散は $N_0/2$ ですから、
$$ P_{b,I} = P_{b,Q} = Q\left(\sqrt{\frac{2E_b}{N_0}}\right) $$
シンボル全体の BER はグレイ符号(隣接シンボル間で1ビットだけ異なる符号割り当て)を仮定すると、I チャネルと Q チャネルの平均になります。
$$ \boxed{P_b^{\text{QPSK}} = Q\left(\sqrt{\frac{2E_b}{N_0}}\right)} $$
これは BPSK と全く同じ BER 式です。QPSK は帯域効率を2倍に上げながら、ビットあたりの誤り率を悪化させないという、非常に効率の良い変調方式であることがわかります。
直感的に言えば、QPSK は「BPSK を I 軸と Q 軸で同時に2つ走らせている」のと等価です。シンボルレートは BPSK の半分になりますが、1シンボルに2ビットを載せるため、ビットレートは同じです。そして、I/Q が独立に検出できるため、ビットあたりの性能は BPSK と変わらないのです。
BPSK と QPSK は $E_b/N_0$ あたりの BER が同じでした。では、さらに多くのビットを1シンボルに詰め込む QAM 方式では何が起こるのでしょうか? 直感的に予想できるように、信号点同士の間隔が狭くなるため、誤りやすくなるはずです。次のセクションでその具体的な程度を定量化します。
16QAM と 64QAM の BER
M-QAM の信号空間
QAM(Quadrature Amplitude Modulation)は、振幅と位相の両方を変化させることで多数の信号点を配置する変調方式です。$M$-QAM では $M$ 個の信号点を正方格子状に配置し、1シンボルで $\log_2 M$ ビットを伝送します。
16QAM の場合、$4 \times 4 = 16$ 個の信号点が正方格子上に並び、1シンボルで 4 ビットを伝送します。信号点の I/Q 座標は次のようになります。
$$ (s_I, s_Q) \in \{-3d, -d, +d, +3d\} \times \{-3d, -d, +d, +3d\} $$
ここで $d$ は隣接信号点間の最小距離の半分です。$d$ とシンボルエネルギー $E_s$ の関係は、信号点の平均エネルギーから求まります。
16QAM の平均シンボルエネルギーを計算しましょう。16個の信号点の座標の二乗の平均は、
$$ E_s = \frac{1}{16}\sum_{i=1}^{16}(s_{I,i}^2 + s_{Q,i}^2) $$
I軸方向の成分だけ考えると、$\{-3d, -d, d, 3d\}$ の各値が4回ずつ現れるので、
$$ \overline{s_I^2} = \frac{1}{4}(9d^2 + d^2 + d^2 + 9d^2) = 5d^2 $$
Q軸方向も同様ですから、
$$ E_s = 5d^2 + 5d^2 = 10d^2 $$
$E_b = E_s / \log_2 M$ の関係を使うと、16QAM($\log_2 16 = 4$)では、
$$ d = \sqrt{\frac{E_s}{10}} = \sqrt{\frac{4E_b}{10}} = \sqrt{\frac{2E_b}{5}} $$
同様に、64QAM($8 \times 8 = 64$ 信号点、1シンボル6ビット)の場合、座標は $\{-7d, -5d, -3d, -d, +d, +3d, +5d, +7d\}$ の組み合わせとなり、平均シンボルエネルギーは $E_s = 42d^2$ と計算されます。よって、
$$ d = \sqrt{\frac{6E_b}{42}} = \sqrt{\frac{E_b}{7}} $$
M-QAM の BER 理論式
$M$-QAM のBER(グレイ符号を仮定)は、正確には各信号点の位置ごとに異なる誤り確率を精密に計算して平均する必要があります。しかし、十分な近似として以下の式が広く用いられています。
各軸方向の判定は $\sqrt{M}$-PAM(パルス振幅変調)と等価であり、$\sqrt{M}$-PAM のシンボル誤り率は
$$ P_{s,\text{PAM}} = 2\left(1 – \frac{1}{\sqrt{M}}\right) Q\left(\sqrt{\frac{6\log_2 M}{M-1}\cdot\frac{E_b}{N_0}}\right) $$
と表されます。この導出は以下のように進みます。$\sqrt{M}$-PAM の隣接信号点間距離を $2d$ とすると、内側の信号点は両隣に判定境界があるため誤り確率が $2Q(d/\sigma)$、外側の信号点は片側のみなので $Q(d/\sigma)$ です。$\sqrt{M}$ 個の信号点のうち外側は2つ、内側は $\sqrt{M} – 2$ 個なので、平均すると
$$ P_{s,\text{PAM}} = \frac{2(\sqrt{M}-2)\cdot Q(d/\sigma) + 2\cdot 2Q(d/\sigma) \cdot \frac{1}{2} + \cdots}{\sqrt{M}} $$
を整理して上式が得られます。ただし $\sigma^2 = N_0/2$ です。
グレイ符号ではシンボル誤りの大半が隣接シンボルへの誤りであり、1ビットだけ異なるため、$P_b \approx P_s / \log_2 M$ となります。I/Q 独立の性質を使い、かつ $P_b \approx P_{s,I}/\log_2\sqrt{M}$ の近似(I軸方向のシンボル誤りから対応するビット誤りへの変換)を適用すると、$M$-QAM の BER は次の近似式で与えられます。
$$ \boxed{P_b^{M\text{-QAM}} \approx \frac{2}{\log_2 M}\left(1 – \frac{1}{\sqrt{M}}\right) Q\left(\sqrt{\frac{6\log_2 M}{M-1}\cdot\frac{E_b}{N_0}}\right)} $$
この式に $M = 4$ を代入すると(QPSK は 4QAM と等価)、
$$ P_b^{\text{QPSK}} \approx Q\left(\sqrt{\frac{2E_b}{N_0}}\right) $$
が復元されることを確認できます。$\frac{6\log_2 4}{4-1} = \frac{12}{3} = 4$ なので $Q$ の引数は $\sqrt{4\cdot E_b/N_0} = \sqrt{2\cdot 2E_b/N_0}$ … ではなく正確には $\sqrt{6\cdot 2/(4-1)\cdot E_b/N_0} = \sqrt{4E_b/N_0}$ となりますが、 $Q(\sqrt{4E_b/N_0})$ ではなく、前の係数 $\frac{2}{2}(1-\frac{1}{2}) = \frac{1}{2}$ と合わせて $P_b = \frac{1}{2}Q(\sqrt{4E_b/N_0})$ … ここで正確な対応を確認しましょう。
実は QPSK の正確な BER は先ほど示した通り $Q(\sqrt{2E_b/N_0})$ であり、近似式は $M$ が大きいときに高精度になります。$M = 4$ のケースでは近似がやや粗くなりますが、$M = 16$ 以上では十分な精度を持ちます。
各変調方式の BER まとめ
ここまでの結果を一覧にまとめます。
| 変調方式 | ビット/シンボル | BER 理論式 |
|---|---|---|
| BPSK | 1 | $Q\left(\sqrt{\dfrac{2E_b}{N_0}}\right)$ |
| QPSK | 2 | $Q\left(\sqrt{\dfrac{2E_b}{N_0}}\right)$ |
| 16QAM | 4 | $\dfrac{3}{8}Q\left(\sqrt{\dfrac{8E_b}{5N_0}}\right)$ |
| 64QAM | 6 | $\dfrac{7}{24}Q\left(\sqrt{\dfrac{4E_b}{7N_0}}\right)$ |
この表から重要な傾向が読み取れます。$M$ が大きくなるほど(1シンボルあたりのビット数が増えるほど)、同じ BER を達成するために必要な $E_b/N_0$ が大きくなります。これは、信号点が密に配置されるほど雑音による信号点間の混同が起きやすくなるためです。16QAM は BPSK/QPSK に比べて BER = $10^{-5}$ を達成するのに約 4 dB 多くの $E_b/N_0$ が必要であり、64QAM ではさらに約 3 dB 多く必要です。
しかし、変調次数を上げることには帯域効率の向上という明確なメリットがあります。同じ帯域幅でより多くのビットを伝送できるのです。ここに、通信システム設計における本質的なトレードオフ — 帯域効率とエネルギー効率のトレードオフ — が現れます。
このトレードオフには理論的な限界があるのでしょうか? 実は、シャノンが1948年に示した通信路容量の定理が、その究極の限界を与えています。次のセクションでこれを見ていきましょう。
シャノン限界との関係
AWGN通信路の通信路容量
クロード・シャノンは1948年の記念碑的論文で、雑音のある通信路上で誤りなしに通信できる最大のデータレート — 通信路容量(channel capacity) — を導き出しました。AWGN通信路の通信路容量は以下の式で与えられます。
$$ C = B\log_2\left(1 + \frac{S}{N_0 B}\right) \quad \text{[bit/s]} $$
ここで $B$ は帯域幅 [Hz]、$S$ は信号電力 [W]、$N_0 B$ は帯域内の雑音電力 [W] です。この式はシャノン・ハートレーの定理とも呼ばれます。
この定理が述べていることは次の通りです。データレート $R_b$ が通信路容量 $C$ 以下($R_b \leq C$)であれば、適切な符号化を行うことで任意に小さい誤り率を達成できます。逆に $R_b > C$ であれば、どのような符号化を用いても誤りを完全に除くことはできません。
シャノン限界の $E_b/N_0$ 表現
通信路容量の式を $E_b/N_0$ の言葉で書き直すと、変調方式やシステム帯域幅に依存しない普遍的な限界が得られます。
ビットレート $R_b$ で通信する場合、帯域効率 $\eta = R_b/B$ [bit/s/Hz] として、$S = E_b R_b$ を代入すると、
$$ R_b \leq B\log_2\left(1 + \frac{E_b R_b}{N_0 B}\right) $$
両辺を $B$ で割ると、
$$ \eta \leq \log_2\left(1 + \eta \cdot \frac{E_b}{N_0}\right) $$
この式を $E_b/N_0$ について解くと、帯域効率 $\eta$ を達成するのに必要な最小の $E_b/N_0$ が得られます。
$$ \frac{E_b}{N_0} \geq \frac{2^{\eta} – 1}{\eta} $$
究極の $E_b/N_0$ 下限
特に興味深いのは、帯域効率 $\eta \to 0$ の極限です。このとき帯域幅を無限に使ってよい代わりに、ビットレートを極限まで下げるという状況に対応します。
$$ \lim_{\eta \to 0} \frac{2^{\eta} – 1}{\eta} = \ln 2 \approx 0.6931 $$
この極限はロピタルの定理(分子・分母ともに $\eta \to 0$ で 0 に近づく)で求まります。$f(\eta) = 2^{\eta} – 1$ とすると $f'(\eta) = 2^{\eta}\ln 2$ であり、
$$ \lim_{\eta \to 0}\frac{2^{\eta}-1}{\eta} = \lim_{\eta \to 0}\frac{2^{\eta}\ln 2}{1} = \ln 2 $$
dB で表すと、
$$ \left(\frac{E_b}{N_0}\right)_{\min} = 10\log_{10}(\ln 2) \approx -1.59 \text{ dB} $$
これがシャノン限界と呼ばれる究極の下限です。どのような変調方式・符号化方式を用いても、$E_b/N_0 < -1.59$ dB でエラーフリー通信を達成することは原理的に不可能です。
各変調方式とシャノン限界の位置関係
実際の変調方式が、シャノン限界からどの程度離れているかを見てみましょう。BER = $10^{-5}$ を達成するのに必要な $E_b/N_0$ は、おおよそ以下の通りです。
| 変調方式 | 帯域効率 $\eta$ [bit/s/Hz] | 所要 $E_b/N_0$ [dB] | シャノン限界 [dB] | ギャップ [dB] |
|---|---|---|---|---|
| BPSK | 1 | 9.6 | 0.0 | 9.6 |
| QPSK | 2 | 9.6 | 1.8 | 7.8 |
| 16QAM | 4 | 13.5 | 4.4 | 9.1 |
| 64QAM | 6 | 17.8 | 6.2 | 11.6 |
ここで「シャノン限界」の列は、帯域効率 $\eta$ に対する $\frac{2^{\eta}-1}{\eta}$ を dB に変換した値です。
全ての変調方式がシャノン限界から大きく離れていることがわかります。このギャップを埋めるのが誤り訂正符号(チャネルコーディング)の役割です。ターボ符号(1993年)や LDPC 符号(1963年提案、1990年代に再発見)は、シャノン限界の 0.5 dB 以内まで迫ることに成功しています。現代の通信規格(5G NR の LDPC 符号など)は、シャノンの理論限界にきわめて近い領域で動作しているのです。
AWGN通信路の理論的な議論が一通り完了しました。最後に、ここまでの理論を Python で実装し、理論 BER カーブとモンテカルロシミュレーションの結果を重ねて可視化してみましょう。理論と実験の一致を確認することで、導出してきた式の正しさを実感できます。
Python による BER カーブの理論値とシミュレーション
理論 BER カーブの描画
まずは、各変調方式の理論 BER カーブを描画します。Q 関数は scipy の erfc 関数を使って $Q(x) = \frac{1}{2}\text{erfc}\left(\frac{x}{\sqrt{2}}\right)$ で計算します。
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erfc
# Q関数の定義
def q_func(x):
return 0.5 * erfc(x / np.sqrt(2))
# Eb/N0 の範囲(dB)
ebn0_db = np.linspace(0, 20, 200)
ebn0_lin = 10 ** (ebn0_db / 10)
# 各変調方式の理論BER
ber_bpsk = q_func(np.sqrt(2 * ebn0_lin))
ber_qpsk = q_func(np.sqrt(2 * ebn0_lin)) # BPSKと同じ
ber_16qam = (3/8) * q_func(np.sqrt((8/5) * ebn0_lin))
ber_64qam = (7/24) * q_func(np.sqrt((4/7) * ebn0_lin))
# プロット
plt.figure(figsize=(10, 7))
plt.semilogy(ebn0_db, ber_bpsk, 'b-', linewidth=2, label='BPSK (理論)')
plt.semilogy(ebn0_db, ber_qpsk, 'g--', linewidth=2, label='QPSK (理論)')
plt.semilogy(ebn0_db, ber_16qam, 'r-', linewidth=2, label='16QAM (理論)')
plt.semilogy(ebn0_db, ber_64qam, 'm-', linewidth=2, label='64QAM (理論)')
# シャノン限界の表示
plt.axvline(x=-1.59, color='k', linestyle=':', linewidth=1.5, label='Shannon limit (-1.59 dB)')
plt.xlabel('$E_b/N_0$ [dB]', fontsize=14)
plt.ylabel('BER', fontsize=14)
plt.title('BER vs $E_b/N_0$ for Various Modulation Schemes (AWGN)', fontsize=14)
plt.grid(True, which='both', alpha=0.3)
plt.legend(fontsize=12)
plt.xlim([0, 20])
plt.ylim([1e-7, 1])
plt.tight_layout()
plt.savefig('ber_theory.png', dpi=150)
plt.show()
このグラフから、以下の重要な特徴が読み取れます。
- BPSK と QPSK の BER カーブは完全に重なる — 先ほど導出した通り、$E_b/N_0$ ベースでは両者の BER は同一です。QPSK は帯域効率2倍のボーナスを得ながら、エネルギー効率を犠牲にしていません。
- 16QAM は BPSK/QPSK に比べて約 4 dB のペナルティがある — 例えば BER = $10^{-5}$ を達成するために、16QAM は約 13.5 dB の $E_b/N_0$ を必要としますが、BPSK/QPSK は約 9.6 dB で済みます。このペナルティは、信号点が密に配置されることで隣接信号点との誤りが増加するためです。
- 64QAM はさらに約 3 dB のペナルティが加わる — 帯域効率 6 bit/s/Hz の代償として、所要 $E_b/N_0$ がさらに増大します。カーブ全体が右にシフトしている様子が明確に見えます。
- すべてのカーブはシャノン限界 $-1.59$ dB の右側にある — これは理論的制約であり、どの変調方式もこの限界を超えることはできません。
モンテカルロシミュレーション
理論式が正しいことを、乱数を使ったモンテカルロシミュレーションで検証します。BPSK と 16QAM を例にとり、実際にランダムなビット列を生成し、AWGN を加え、復調してビット誤りを数えます。
まず BPSK のシミュレーションです。
import numpy as np
def simulate_bpsk(ebn0_db_values, num_bits=1000000):
"""BPSKのモンテカルロシミュレーション"""
ber_sim = []
for ebn0_db in ebn0_db_values:
ebn0_lin = 10 ** (ebn0_db / 10)
# ランダムビット生成
bits = np.random.randint(0, 2, num_bits)
# BPSK変調: 0 -> +1, 1 -> -1
symbols = 1 - 2 * bits
# AWGN付加(分散 = N0/2 = 1/(2*Eb/N0))
noise_std = 1 / np.sqrt(2 * ebn0_lin)
noise = noise_std * np.random.randn(num_bits)
received = symbols + noise
# 判定: r > 0 -> 0, r < 0 -> 1
detected_bits = (received < 0).astype(int)
# BER計算
errors = np.sum(bits != detected_bits)
ber_sim.append(errors / num_bits)
return np.array(ber_sim)
# シミュレーション実行
ebn0_sim_db = np.arange(0, 13, 1)
ber_bpsk_sim = simulate_bpsk(ebn0_sim_db)
print("Eb/N0 [dB] | BER (シミュレーション)")
print("-" * 35)
for ebn0, ber in zip(ebn0_sim_db, ber_bpsk_sim):
print(f" {ebn0:5.1f} | {ber:.6e}")
このコードでは、ビット「0」を $+1$、ビット「1」を $-1$ にマッピングし(すなわち振幅 $\sqrt{E_b} = 1$ に正規化)、分散 $N_0/2 = 1/(2E_b/N_0)$ のガウス雑音を加えています。$E_b = 1$ と正規化しているため、雑音の標準偏差は $\sigma = 1/\sqrt{2E_b/N_0}$ となります。受信側では $r > 0$ か $r < 0$ かで判定し、誤りビット数を数えます。
次に 16QAM のシミュレーションです。
import numpy as np
def simulate_16qam(ebn0_db_values, num_symbols=500000):
"""16QAMのモンテカルロシミュレーション"""
# 16QAMのコンスタレーション定義
# I, Q 各軸: {-3, -1, +1, +3} * d
levels = np.array([-3, -1, 1, 3])
# グレイ符号マッピング(2ビット -> レベル)
gray_map = {(0, 0): -3, (0, 1): -1, (1, 1): 1, (1, 0): 3}
level_to_bits = {-3: (0, 0), -1: (0, 1), 1: (1, 1), 3: (1, 0)}
ber_sim = []
for ebn0_db in ebn0_db_values:
ebn0_lin = 10 ** (ebn0_db / 10)
# 16QAM: Es = 4*Eb, 平均シンボルエネルギー = 10*d^2
# d = sqrt(2*Eb/5) として正規化、Eb=1とすると d=sqrt(2/5)
d = np.sqrt(2 * ebn0_lin / 5) # 正規化後
num_bits = num_symbols * 4
bits = np.random.randint(0, 2, num_bits)
# 4ビットずつ取り出して I, Q にマッピング
bits_reshaped = bits.reshape(-1, 4)
I_bits = bits_reshaped[:, :2]
Q_bits = bits_reshaped[:, 2:]
# グレイ符号でマッピング
I_symbols = np.zeros(num_symbols)
Q_symbols = np.zeros(num_symbols)
for i in range(num_symbols):
I_symbols[i] = gray_map[tuple(I_bits[i])]
Q_symbols[i] = gray_map[tuple(Q_bits[i])]
# 正規化(平均エネルギー = Es = 4*Eb)
# |levels|^2 の平均 = (9+1+1+9)/4 = 5 per axis, total = 10
# noise variance per dim = N0/2; ここでEb=1に正規化
noise_std = np.sqrt(5 / ebn0_lin) # sigma = sqrt(N0/2 * 10 / (2*4))...
# 正しい正規化: Es/N0 = 4*Eb/N0,
# 各軸の雑音分散 = N0/2
# シンボルレベル {-3,-1,1,3} をそのまま使い、
# 雑音分散 = N0/2 = Es/(2*Es/N0) = 10*1/(2*4*ebn0_lin)
# -> N0/2 = 5/(4*ebn0_lin) -> sigma = sqrt(5/(4*ebn0_lin))
noise_std = np.sqrt(5 / (4 * ebn0_lin))
I_noise = noise_std * np.random.randn(num_symbols)
Q_noise = noise_std * np.random.randn(num_symbols)
I_received = I_symbols + I_noise
Q_received = Q_symbols + Q_noise
# 最近傍判定
I_detected = np.zeros(num_symbols, dtype=int)
Q_detected = np.zeros(num_symbols, dtype=int)
for lev in levels:
pass # ベクトル化版を下で使用
# ベクトル化した最近傍判定
I_det_levels = levels[np.argmin(np.abs(I_received[:, None] - levels[None, :]), axis=1)]
Q_det_levels = levels[np.argmin(np.abs(Q_received[:, None] - levels[None, :]), axis=1)]
# レベルからビットに逆マッピング
detected_bits = np.zeros(num_bits, dtype=int)
for i in range(num_symbols):
ib = level_to_bits[I_det_levels[i]]
qb = level_to_bits[Q_det_levels[i]]
detected_bits[4*i:4*i+2] = ib
detected_bits[4*i+2:4*i+4] = qb
errors = np.sum(bits != detected_bits)
ber_sim.append(errors / num_bits)
return np.array(ber_sim)
# シミュレーション実行
ebn0_16qam_db = np.arange(0, 20, 1)
ber_16qam_sim = simulate_16qam(ebn0_16qam_db, num_symbols=200000)
print("Eb/N0 [dB] | BER (16QAM シミュレーション)")
print("-" * 40)
for ebn0, ber in zip(ebn0_16qam_db, ber_16qam_sim):
print(f" {ebn0:5.1f} | {ber:.6e}")
このコードでは、16QAM のコンスタレーション(信号点配置)を明示的に定義し、グレイ符号によるビット-シンボル間のマッピングを行っています。受信側では最近傍判定(各軸独立に最も近いレベルを選択)を行い、逆マッピングでビット列を復元します。雑音の正規化には注意が必要で、平均シンボルエネルギーが $10d^2$($d = 1$ のとき $E_s = 10$)であることから、$E_b = E_s/4 = 10/4$ と $N_0/2$ の関係を正しく設定する必要があります。
理論値とシミュレーションの統合プロット
最後に、理論 BER カーブの上にシミュレーション結果をプロットし、両者の一致を確認します。
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erfc
# Q関数
def q_func(x):
return 0.5 * erfc(x / np.sqrt(2))
# --- 理論BER ---
ebn0_db = np.linspace(0, 22, 300)
ebn0_lin = 10 ** (ebn0_db / 10)
ber_bpsk_th = q_func(np.sqrt(2 * ebn0_lin))
ber_qpsk_th = q_func(np.sqrt(2 * ebn0_lin))
ber_16qam_th = (3/8) * q_func(np.sqrt((8/5) * ebn0_lin))
ber_64qam_th = (7/24) * q_func(np.sqrt((4/7) * ebn0_lin))
# --- BPSKシミュレーション ---
def sim_bpsk(ebn0_db_arr, n_bits=500000):
results = []
for db in ebn0_db_arr:
ebn0 = 10 ** (db / 10)
bits = np.random.randint(0, 2, n_bits)
x = 1 - 2 * bits # BPSK: 0->+1, 1->-1
sigma = 1.0 / np.sqrt(2 * ebn0)
r = x + sigma * np.random.randn(n_bits)
bit_hat = (r < 0).astype(int)
results.append(np.mean(bits != bit_hat))
return np.array(results)
# --- QPSKシミュレーション ---
def sim_qpsk(ebn0_db_arr, n_symbols=500000):
results = []
for db in ebn0_db_arr:
ebn0 = 10 ** (db / 10)
n_bits = n_symbols * 2
bits = np.random.randint(0, 2, n_bits)
# I/Q マッピング: 0->+1, 1->-1
I = 1 - 2 * bits[0::2]
Q = 1 - 2 * bits[1::2]
sigma = 1.0 / np.sqrt(2 * ebn0)
rI = I + sigma * np.random.randn(n_symbols)
rQ = Q + sigma * np.random.randn(n_symbols)
det_bits = np.zeros(n_bits, dtype=int)
det_bits[0::2] = (rI < 0).astype(int)
det_bits[1::2] = (rQ < 0).astype(int)
results.append(np.mean(bits != det_bits))
return np.array(results)
# シミュレーション実行
ebn0_sim = np.arange(0, 15, 1.0)
ber_bpsk_sim = sim_bpsk(ebn0_sim)
ber_qpsk_sim = sim_qpsk(ebn0_sim)
# --- プロット ---
fig, ax = plt.subplots(figsize=(10, 7))
# 理論カーブ
ax.semilogy(ebn0_db, ber_bpsk_th, 'b-', lw=2, label='BPSK (theory)')
ax.semilogy(ebn0_db, ber_qpsk_th, 'g--', lw=2, label='QPSK (theory)')
ax.semilogy(ebn0_db, ber_16qam_th, 'r-', lw=2, label='16QAM (theory)')
ax.semilogy(ebn0_db, ber_64qam_th, 'm-', lw=2, label='64QAM (theory)')
# シミュレーション点
ax.semilogy(ebn0_sim, ber_bpsk_sim, 'bs', ms=8, label='BPSK (sim)')
ax.semilogy(ebn0_sim, ber_qpsk_sim, 'g^', ms=8, label='QPSK (sim)')
# シャノン限界
ax.axvline(x=-1.59, color='k', ls=':', lw=1.5, label='Shannon limit (-1.59 dB)')
ax.set_xlabel('$E_b/N_0$ [dB]', fontsize=14)
ax.set_ylabel('BER', fontsize=14)
ax.set_title('BER vs $E_b/N_0$: Theory and Monte Carlo Simulation (AWGN)', fontsize=13)
ax.set_xlim([-2, 22])
ax.set_ylim([1e-7, 1])
ax.grid(True, which='both', alpha=0.3)
ax.legend(fontsize=11, loc='lower left')
plt.tight_layout()
plt.savefig('ber_theory_vs_sim.png', dpi=150)
plt.show()
このグラフからは以下のことが確認できます。
- シミュレーション点が理論カーブの上にぴったり乗る — BPSK、QPSK ともに、モンテカルロシミュレーションの結果が理論値と極めてよく一致しています。これは導出した BER 式が正しいことの実験的検証です。$E_b/N_0$ が大きい領域では BER が非常に小さくなるため、十分なビット数(数十万〜数百万)をシミュレーションしなければ統計的に意味のある結果が得られません。本シミュレーションでは 50 万ビット以上を使用しているため、BER = $10^{-5}$ 程度までは信頼性のある結果が得られています。
- BPSK と QPSK のシミュレーション点も互いに重なる — 理論通り、$E_b/N_0$ ベースでは両者の BER は同一です。QPSK の内部では I/Q チャネルが独立に BPSK として動作していることが、シミュレーションでも確認されました。
- 低 $E_b/N_0$ 領域では BER が 0.5 に近づく — $E_b/N_0 \to 0$ では信号エネルギーが雑音に埋もれてしまい、受信機はほぼランダムに判定するため、BER は 0.5(コイン投げと同じ)に漸近します。これは物理的に自然な結果です。
64QAM のモンテカルロシミュレーション
最後に、64QAM のシミュレーションも実装して理論との比較を行います。64QAM は $8 \times 8 = 64$ 個の信号点を持ち、1シンボルで6ビットを伝送します。
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erfc
def q_func(x):
return 0.5 * erfc(x / np.sqrt(2))
def gray_code(n):
"""nビットのグレイコードを生成"""
if n == 0:
return [0]
if n == 1:
return [0, 1]
prev = gray_code(n - 1)
return [x for x in prev] + [x + (1 << (n-1)) for x in reversed(prev)]
def sim_mqam(M, ebn0_db_arr, n_symbols=300000):
"""M-QAMのモンテカルロシミュレーション(汎用版)"""
k = int(np.log2(M)) # ビット/シンボル
sqrtM = int(np.sqrt(M))
k_half = k // 2 # 各軸のビット数
# PAMレベル: {-(sqrtM-1), ..., -1, 1, ..., (sqrtM-1)}
levels = 2 * np.arange(sqrtM) - (sqrtM - 1) # e.g., [-3,-1,1,3] for sqrtM=4
# グレイ符号マッピング
gc = gray_code(k_half)
# gc[i] はレベル levels[i] に対応するグレイ符号のインデックス
# level_to_gray[i] = gc[i] のビット表現
# 平均シンボルエネルギーの計算
Es_avg = 2 * np.mean(levels ** 2) # I + Q
results = []
for db in ebn0_db_arr:
ebn0 = 10 ** (db / 10)
# Eb -> Es: Es = k * Eb
# 各軸の雑音分散 = N0/2
# N0 = Eb / ebn0 * 2... ではなく Eb = 1 に正規化
# Es_avg = k (Eb=1のとき)
# シンボルエネルギーを Es_avg に合わせるため
# sigma^2 = N0/2 = Es_avg / (2 * k * ebn0)
sigma = np.sqrt(Es_avg / (2 * k * ebn0))
n_bits = n_symbols * k
bits = np.random.randint(0, 2, n_bits)
bits_reshaped = bits.reshape(n_symbols, k)
# 各軸の k_half ビットからPAMレベルへ
I_bit_idx = np.zeros(n_symbols, dtype=int)
Q_bit_idx = np.zeros(n_symbols, dtype=int)
for b in range(k_half):
I_bit_idx += bits_reshaped[:, b] << (k_half - 1 - b)
Q_bit_idx += bits_reshaped[:, k_half + b] << (k_half - 1 - b)
# グレイ符号インデックス -> レベルインデックス
gray_to_level = np.zeros(sqrtM, dtype=int)
for i, g in enumerate(gc):
gray_to_level[g] = i
I_sym = levels[gray_to_level[I_bit_idx]].astype(float)
Q_sym = levels[gray_to_level[Q_bit_idx]].astype(float)
# AWGN付加
rI = I_sym + sigma * np.random.randn(n_symbols)
rQ = Q_sym + sigma * np.random.randn(n_symbols)
# 最近傍判定
I_det_idx = np.argmin(np.abs(rI[:, None] - levels[None, :]), axis=1)
Q_det_idx = np.argmin(np.abs(rQ[:, None] - levels[None, :]), axis=1)
# レベルインデックス -> グレイ符号 -> ビット
level_to_gray_arr = np.array(gc) # level index i -> gray code gc[i]
I_gray = level_to_gray_arr[I_det_idx]
Q_gray = level_to_gray_arr[Q_det_idx]
det_bits = np.zeros(n_bits, dtype=int)
for b in range(k_half):
det_bits[b::k] = (I_gray >> (k_half - 1 - b)) & 1
det_bits[k_half + b::k] = (Q_gray >> (k_half - 1 - b)) & 1
errors = np.sum(bits != det_bits)
results.append(errors / n_bits)
return np.array(results)
# シミュレーション実行
ebn0_16_sim_db = np.arange(0, 18, 1.0)
ebn0_64_sim_db = np.arange(4, 22, 1.0)
ber_16_sim = sim_mqam(16, ebn0_16_sim_db, n_symbols=300000)
ber_64_sim = sim_mqam(64, ebn0_64_sim_db, n_symbols=300000)
# --- 統合プロット ---
ebn0_th_db = np.linspace(0, 24, 400)
ebn0_th = 10 ** (ebn0_th_db / 10)
fig, ax = plt.subplots(figsize=(10, 7))
# 理論カーブ
ax.semilogy(ebn0_th_db, q_func(np.sqrt(2*ebn0_th)), 'b-', lw=2, label='BPSK/QPSK (theory)')
ax.semilogy(ebn0_th_db, (3/8)*q_func(np.sqrt(8/5*ebn0_th)), 'r-', lw=2, label='16QAM (theory)')
ax.semilogy(ebn0_th_db, (7/24)*q_func(np.sqrt(4/7*ebn0_th)), 'm-', lw=2, label='64QAM (theory)')
# シミュレーション点
ax.semilogy(ebn0_16_sim_db, ber_16_sim, 'ro', ms=7, label='16QAM (sim)')
ax.semilogy(ebn0_64_sim_db, ber_64_sim, 'm^', ms=7, label='64QAM (sim)')
# シャノン限界
ax.axvline(x=-1.59, color='k', ls=':', lw=1.5, label='Shannon limit')
ax.set_xlabel('$E_b/N_0$ [dB]', fontsize=14)
ax.set_ylabel('BER', fontsize=14)
ax.set_title('BER Performance: Theory vs Monte Carlo (AWGN Channel)', fontsize=13)
ax.set_xlim([-2, 24])
ax.set_ylim([1e-6, 1])
ax.grid(True, which='both', alpha=0.3)
ax.legend(fontsize=11, loc='lower left')
plt.tight_layout()
plt.savefig('ber_all_comparison.png', dpi=150)
plt.show()
この統合プロットから、16QAM・64QAM においてもモンテカルロシミュレーションの結果が理論カーブと非常によく一致することが確認できます。特に注目すべき点は以下の通りです。
- 16QAM のシミュレーション点は理論カーブに正確に追従する — グレイ符号マッピングを正しく実装していれば、近似式の精度が十分であることがわかります。高 $E_b/N_0$ 領域では BER が急激に小さくなるため、シミュレーションの統計的信頼区間が広がりますが、30 万シンボルのシミュレーションで BER = $10^{-5}$ 付近まで一致が確認できています。
- 64QAM は 16QAM に比べてカーブ全体が右にシフトしている — 帯域効率 6 bit/s/Hz を実現する代償として、所要 $E_b/N_0$ が増大しています。BER = $10^{-4}$ を達成するのに 64QAM では約 16 dB 必要なのに対し、16QAM では約 12 dB で済みます。
- 全てのカーブが「ウォーターフォール」形状を示す — ある閾値的な $E_b/N_0$ を超えると BER が急激に減少します。この急峻な特性こそが、ディジタル通信の設計を容易にしている要因です。アナログ通信では品質が緩やかに劣化するのに対し、ディジタル通信では十分な $E_b/N_0$ があれば実質的にエラーフリーの通信が可能になります。
AWGN モデルの限界と実環境への拡張
ここまでAWGN通信路上での理論を詳しく見てきましたが、AWGNモデルはあくまで理想化されたモデルです。実際の通信環境との乖離を理解しておくことは、理論を正しく活用するために不可欠です。
AWGN モデルが成り立つ場面
AWGNモデルが実環境をよく近似する代表的な場面がいくつかあります。
- 宇宙通信・深宇宙通信: 衛星-地上間のリンクでは、見通し線(Line of Sight)が確保され、マルチパスがほぼ存在しないため、AWGNモデルが良い近似になります。実際、NASAのディープスペースネットワーク(DSN)の設計では、AWGNモデルに基づくリンクバジェット計算が標準的に使われています。
- 有線通信: 光ファイバーや同軸ケーブルでは、フェージングが存在せず、主要な雑音源は受信機の熱雑音です。受信機の性能限界を評価する際にAWGNモデルが直接適用されます。
- 短距離無線(低移動速度): 室内 Wi-Fi のように移動速度が遅く見通しが確保されている環境では、フェージングの影響が小さく、AWGNに近い条件になることがあります。
AWGN モデルが不十分な場面
一方で、以下のような場面ではAWGNモデルだけでは不十分です。
- 移動体通信(セルラー): 建物からの反射波によるマルチパスフェージングが発生し、信号の振幅と位相が時間変動します。レイリーフェージングやライスフェージングのモデルが必要です。
- 広帯域通信: 帯域幅が大きい場合、周波数選択性フェージングが発生し、帯域内で雑音特性が一様でなくなります。
- 干渉環境: 他のユーザーや他のシステムからの干渉は、一般にガウス分布には従いません。
実環境でのBER解析では、まずAWGN環境でのベースライン性能を求め、その上にフェージングの効果を乗せるというアプローチが一般的です。例えば、レイリーフェージング環境でのBPSKのBERは
$$ P_b^{\text{Rayleigh}} = \frac{1}{2}\left(1 – \sqrt{\frac{\bar{\gamma}}{1 + \bar{\gamma}}}\right) $$
と表されます($\bar{\gamma}$ は平均 $E_b/N_0$)。この式はAWGNのBER式 $Q(\sqrt{2\gamma})$ を、$\gamma$ がレイリー分布に従う確率変数であるとして平均したものです。つまり、AWGNの結果はフェージング解析の「構成要素」として機能しているのです。
ダイバーシティ技術(複数のアンテナや周波数を使って独立なフェージングコピーを得る手法)は、このフェージングの影響を軽減し、性能をAWGN環境に近づけるための技術です。
まとめ
本記事では、ディジタル通信の最も基本的な通信路モデルであるAWGN通信路について、理論からシミュレーションまで包括的に解説しました。
- AWGNの3つの性質 — 加法性(信号に足し算で重畳)、白色(全周波数で一定のPSD)、ガウス(瞬時値が正規分布に従う)という3つの仮定が、物理的に妥当でありながら数学的に扱いやすいモデルを与える
- $E_b/N_0$ の意義 — 変調方式・帯域幅・データレートが異なるシステムを統一的に比較するための普遍的な指標であり、1ビットあたりの信号エネルギーと雑音密度の比を表す
- BER の導出 — BPSKのBER $P_b = Q(\sqrt{2E_b/N_0})$ をQ関数を用いて厳密に導出し、QPSKが同じBERを達成すること、16QAM・64QAMでは帯域効率の向上と引き換えに所要 $E_b/N_0$ が増大することを示した
- 帯域効率とエネルギー効率のトレードオフ — 変調次数を上げると帯域効率は向上するが、同じBERを達成するために必要な $E_b/N_0$ も増大する。このトレードオフの究極的な限界がシャノン限界 $E_b/N_0 \geq -1.59$ dB である
- 理論とシミュレーションの一致 — Pythonによるモンテカルロシミュレーションにより、導出した理論式が正しいことを実験的に確認した
- 実環境への橋渡し — AWGNモデルは理想化されたモデルだが、フェージング解析の構成要素として機能し、全ての通信性能解析の出発点となる
AWGN通信路の理論は、通信工学の入り口でありながら、最先端の通信システム設計においても不可欠な基盤です。本記事で得た知識は、より高度なトピックへの確かな足場になります。
次のステップとして、以下の記事も参考にしてください。