BPSK の受信機を作るとき、必ず一度はぶつかる壁があります。「送信側が位相 $0$ で送ったのか $\pi$ で送ったのか、受信機はどうやって知るのか?」という問題です。受信機は空中を飛んできた電波しか見ていません。そこには「これが位相の原点です」という札は付いていません。搬送波再生ループ(コスタスループなど)を回して搬送波を復元しても、そのループは $0$ にロックすることもあれば $\pi$ にロックすることもあり、どちらにロックしたかを電波そのものから知る手段はないのです。もしループが $\pi$ 側にロックしたら、復調されたビット列は全ビットが反転します。誤り率が 50% になるのではなく、100% 間違えるという最悪の壊れ方をします。
この「位相の絶対基準が存在しない」という根源的な問題に対する、驚くほどシンプルで強力な答えが 差動位相変調(DPSK: Differential Phase Shift Keying) です。発想は一言で言えます — 位相の 値 ではなく、位相の 変化 に情報を載せる。絶対的な基準がないなら、基準を必要としない量を使えばいい、という考え方です。

左の図が問題の本質です。受信機が観測する2つの候補点 A と B は、未知位相 $\theta$ の回転を受けているため、どちらが「送信位相 $0$」なのかを電波だけからは決められません。右の図が DPSK の答えで、1つ前の受信点 $r_{k-1}$ を基準にして角度差を測れば、両方の点に同じだけ乗っている $\theta$ が引き算で消え、位相差 $\Delta\phi = \pi$ という情報だけが残ります。この記事は、この「引き算で消す」という一点を、符号化・受信機構成・誤り率の3つの側面から徹底的に掘り下げていきます。
DPSK を理解すると、以下のような場面で「なぜその方式が選ばれたのか」が腹落ちします。
- 省電力・低コストの無線機: Bluetooth の EDR(2 Mbps モード)は $\pi/4$-DQPSK を使います。搬送波再生ループを省けるため、受信機の消費電力とチップ面積を削れます。RFID や近距離無線でも同じ理由で DPSK 系が好まれます
- 移動体通信・衛星通信: 携帯電話の第2世代方式(日本の PDC、北米の IS-136)や業務無線 TETRA は $\pi/4$-DQPSK を採用しました。高速移動によるドップラーとフェージングで搬送波位相が激しく変動する環境では、位相を「絶対値で追いかける」設計が破綻しやすいためです
- バースト通信・パケット無線: 短いパケットを送るたびに搬送波再生ループを引き込む時間がもったいない、という場面では、遅延検波なら1シンボル前が受信できた瞬間から復調を始められます
- 光通信: 光位相変調でも DPSK は主力です。1ビット遅延干渉計という受動素子だけで復調でき、局部発振レーザーの位相同期という難題を回避できます
本記事の内容
- 搬送波再生ループが抱える「位相あいまいさ」の正体と、それが引き起こす極性反転
- 差動符号化 $d_k = d_{k-1} \oplus b_k$ が極性反転を無効化する仕組み(真理値表と証明)
- 遅延検波の受信機構成と、判定量 $\operatorname{Re}\{r_k r_{k-1}^*\}$ の導出
- DBPSK の誤り率 $P_b = \frac{1}{2}e^{-E_b/N_0}$ を、$|u|^2 – |v|^2$ 分解から厳密に導く
- 位相回転を伴う一般形(Marcum Q 関数)と、そこから DQPSK の BER 式が出てくること
- $\pi/4$-QPSK が原点通過を避ける仕組みと、包絡線変動の実測
- コヒーレント検波に対する損失は本当に「3 dB」なのか — 数値で検証する
- Python 実装: コンステレーションと位相遷移、BER 曲線の比較、周波数オフセット耐性
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
位相の絶対基準という難題
時計の針のたとえ
まず、なぜ絶対位相が手に入らないのかを直感で押さえましょう。腕時計の針だけを見て「いま何時か」を当てる場面を想像してください。針が真上を向いていても、その時計が正しく合わせてあるとは限りません。6時間ずれているかもしれない。針の位置(絶対値)だけからは、正しい時刻を復元できないのです。
ところが、同じ時計でも「30分前と比べて針がどれだけ進んだか」なら確実にわかります。時計がどれだけずれていようと、差 は影響を受けません。針の初期位置という未知量は、引き算で消えてしまうからです。
無線受信機が置かれた状況もこれと同じです。受信信号の位相は、送信側が乗せた情報位相 $\phi_k$ に、伝搬遅延・局部発振器の初期位相・ダウンコンバータの位相といった 未知の定数 $\theta$ が加わったものです。受信機が観測できるのは $\phi_k + \theta$ であって、$\phi_k$ 単体ではありません。
搬送波再生ループの位相あいまいさ
「そのために搬送波再生があるのでは?」と思われるかもしれません。確かに、2乗ループやコスタスループを使えば、変調で消えてしまった搬送波成分を復元し、$\theta$ をかなりの精度で推定できます。しかし、ここに原理的な落とし穴があります。
BPSK 信号は $s(t) = \pm A\cos(2\pi f_c t + \theta)$ です。この信号を2乗すると、
$$ s^2(t) = A^2\cos^2(2\pi f_c t + \theta) = \frac{A^2}{2} + \frac{A^2}{2}\cos(4\pi f_c t + 2\theta) $$
となり、$\pm$ の符号が消えて $2f_c$ の純粋な正弦波が現れます。これを PLL で拾い、2分周すれば搬送波が得られる — という仕組みです。ところがここで、2分周が問題を起こします。周波数 $2f_c$、位相 $2\theta$ の信号を2分周して得られる位相は $\theta$ ですが、$2\theta$ と $2\theta + 2\pi$ は物理的に区別できない同じ信号です。したがって分周器の出力位相は $\theta$ にも $\theta + \pi$ にもなり得ます。
$$ \hat{\theta} \in \{\theta,\; \theta + \pi\} $$
どちらにロックするかは、電源投入時の分周器の初期状態という、まったく情報を持たない要因で決まります。これが 位相あいまいさ(phase ambiguity) です。コスタスループも数学的には同じ構造で、誤差信号が $\sin 2(\theta – \hat\theta)$ に比例するため、$\hat\theta = \theta$ と $\hat\theta = \theta + \pi$ の両方が安定平衡点になります。

左の系統図が示す通り、位相あいまいさは「どこかの回路の出来が悪い」ために生じるのではなく、$2f_c$ を2分周するという処理そのものから必然的に生まれます。右のグラフは、コスタスループの誤差電圧が位相誤差の 2倍角 の関数であることを示しています。誤差がゼロになり、かつ引き戻す向きに働く点(塗りつぶした緑の点)が $0°$ と $\pm180°$ の2箇所に存在するため、ループはそのどちらかに落ち着きます。白抜きの点は不安定点で、わずかな雑音でどちらかの安定点へ滑り落ちます。
QPSK ではもっと深刻です。4つの位相を消すには4乗が必要で、$4\theta$ を4分周するため、あいまいさは $90°$ の整数倍、つまり4通りに増えます。M-PSK 一般では $2\pi/M$ の整数倍、$M$ 通りのあいまいさが生じます。
極性反転がもたらす壊滅
位相が $\pi$ ずれた基準で復調するとどうなるでしょうか。BPSK の判定は「同相成分の符号」で行いますから、基準が $\pi$ 反転すれば、判定される符号もすべて反転します。ビット列 10110010 は 01001101 になります。

図の上段が送信波形、中段が正しい基準 $\hat\theta = \theta$ で復調した結果、下段が $\pi$ ずれた基準で復調した結果です。中段と下段を見比べると、8ビットすべてが逆になっていることがわかります。中段の誤りは0個、下段は 8/8 個で BER は 1.0 です。雑音がまったく無い理想的な条件でこれが起きている点に注意してください。原因は雑音ではなく、基準位相の選び方だけにあります。
これは「たまに間違える」話ではありません。全ビットが確実に間違うのです。しかも受信機自身は何も異常を検知しません。信号対雑音比は良好で、コンステレーションもきれいに2点に分かれています。それでいて出力は完全なゴミです。誤り訂正符号を後段に置いていても救われません。多くの符号は全ビット反転された系列を「別の正しい符号語」または「訂正不能」と解釈するだけで、反転を検出して直してはくれないからです。
もちろん対策はあります。既知のパターン(ユニークワード、プリアンブル)を定期的に挿入し、受信側でそれと照合して反転を検出し、必要なら全体を反転する、という方法です。実際に多くのシステムがこれを併用しています。しかしこの方法には代償があります。既知パターンの分だけ伝送効率が落ちますし、パターンを見つけるまでの区間は復調できません。さらに、フェージングやドップラーで搬送波再生ループが一時的に外れて別のロック点に飛び移ると(サイクルスリップ)、その後のデータが再びすべて反転します。ユニークワードが次に来るまで、データは壊れっぱなしです。
ここで発想を切り替えます。あいまいさを 検出して直す のではなく、そもそもあいまいさの影響を受けない情報の載せ方 に変えられないでしょうか。時計のたとえで言えば「針の位置」ではなく「針の進み」を読む。次のセクションで、その具体的な仕掛けを見ていきます。
差動符号化 — 変化に情報を載せる
エレベータの階数と移動量
高層ビルのエレベータで、「7階に行け」と指示する代わりに「3つ上がれ」と指示する場面を考えてみてください。前者は絶対的な基準(1階がどこか)を共有していないと成立しませんが、後者は現在地がどこであれ正しく実行できます。差動符号化がやっているのは、まさにこの置き換えです。
情報ビット列を $b_1, b_2, \dots$ とし、実際に送信するシンボル(の位相を決める符号語)を $d_0, d_1, d_2, \dots$ とします。差動符号化は次の漸化式で定義されます。
$$ \begin{equation} d_k = d_{k-1} \oplus b_k, \qquad k = 1, 2, 3, \dots \end{equation} $$
ここで $\oplus$ は排他的論理和(XOR、モジュロ2の加算)です。初期値 $d_0$ は任意で構いません(通常は $d_0 = 0$)。この $d_0$ に対応するシンボルが「基準シンボル」で、情報を運ばず、次のシンボルの比較対象になるためだけに送られます。
式が何をしているかを真理値表で確認しましょう。
| $d_{k-1}$ | $b_k$ | $d_k = d_{k-1}\oplus b_k$ | 位相の動き |
|---|---|---|---|
| 0 | 0 | 0 | 変化なし($\Delta\phi = 0$) |
| 0 | 1 | 1 | 反転($\Delta\phi = \pi$) |
| 1 | 0 | 1 | 変化なし($\Delta\phi = 0$) |
| 1 | 1 | 0 | 反転($\Delta\phi = \pi$) |
表を眺めると、規則がはっきり見えます。情報ビットが 0 なら位相を据え置き、1 なら位相を反転させる。$d_k$ の値そのものには意味がなく、意味を持つのは $d_{k-1}$ から $d_k$ への変化だけです。

3段のタイムラインが差動符号化の全てです。上段の情報ビット $b_k$ が 1 のところ($k=1,3,4,7$)では、最下段の送信位相が必ず $0°$ と $180°$ の間で切り替わっています(赤い「反転」の矢印)。逆に $b_k=0$ のところでは位相が据え置かれます(緑の「据置」)。中段の差動符号語 $d_k$ の値そのものを見ても情報は読み取れませんが、隣どうしの差を見れば上段が完全に復元できる、という構造が視覚的に確認できます。
復号側と、反転が消える理由
受信側は、判定した符号語 $\hat{d}_k$ から情報ビットを次のように復元します。
$$ \begin{equation} \hat{b}_k = \hat{d}_k \oplus \hat{d}_{k-1} \end{equation} $$
これが式(1)の逆演算であることは、$d_{k-1}$ を両辺に XOR すればすぐわかります。$d_k \oplus d_{k-1} = (d_{k-1}\oplus b_k)\oplus d_{k-1} = b_k \oplus (d_{k-1}\oplus d_{k-1}) = b_k \oplus 0 = b_k$ です。XOR は自分自身との演算が 0 になる($x \oplus x = 0$)ため、$d_{k-1}$ がきれいに相殺されます。
さて本題です。受信機の位相基準が $\pi$ ずれていた場合、判定される符号語は全ビット反転して $\tilde{d}_k = d_k \oplus 1$ になります。これを復号式に入れてみましょう。まず定義通りに代入します。
$$ \hat{b}_k = \tilde{d}_k \oplus \tilde{d}_{k-1} = (d_k \oplus 1) \oplus (d_{k-1} \oplus 1) $$
XOR は結合則・交換則を満たすので、$1$ どうしを隣り合わせに並べ替えられます。
$$ \hat{b}_k = d_k \oplus d_{k-1} \oplus (1 \oplus 1) = d_k \oplus d_{k-1} \oplus 0 $$
$1 \oplus 1 = 0$ で反転項が消え、残るのは元の復号式そのものです。
$$ \hat{b}_k = d_k \oplus d_{k-1} = b_k $$
位相あいまいさが完全に消えました。 反転は隣接する2つの符号語に同じように作用するため、差を取った瞬間に相殺されるのです。時計の初期ずれが引き算で消えたのと、まったく同じ構造です。

図の上から3段目が「受信機の位相基準が $\pi$ ずれた」結果で、2段目の符号語がすべて反転しています。それにもかかわらず、隣接 XOR を取った最下段は最上段の情報ビットと1ビットの狂いもなく一致します。ここで強調したいのは、受信機が反転の有無を 検出も補正もしていない ことです。反転項 $1 \oplus 1 = 0$ が演算の中で自動的に消えるので、そもそも検出する必要がないのです。
位相の言葉に翻訳する
XOR の式は、位相の言葉で書き直すともっと見通しがよくなります。送信位相を $\phi_k = \pi d_k$ とすると、式(1)は
$$ \phi_k = \phi_{k-1} + \Delta\phi_k \pmod{2\pi}, \qquad \Delta\phi_k = \pi b_k $$
と書けます。つまり DPSK とは「位相の増分 $\Delta\phi_k$ に情報を載せる変調」です。$M$ 値に一般化するのも自然で、$m_k \in \{0,1,\dots,M-1\}$ を $\log_2 M$ ビットに対応させて
$$ \begin{equation} \phi_k = \phi_{k-1} + \frac{2\pi m_k}{M} \pmod{2\pi} \end{equation} $$
とすれば M-DPSK になります。受信機が推定する位相が真値より $\theta_a$ だけずれていても、増分を計算すれば
$$ (\phi_k + \theta_a) – (\phi_{k-1} + \theta_a) = \phi_k – \phi_{k-1} = \frac{2\pi m_k}{M} $$
となり、$\theta_a$ が何であろうと正しい増分が得られます。QPSK の $90°$ あいまいさも、8PSK の $45°$ あいまいさも、この引き算ひとつで無効化されます。ただし条件があります。$\theta_a$ が シンボル間で一定 であることです。この条件が崩れるとどうなるかは、後半の周波数オフセットの節で詳しく調べます。
差動符号化のコスト — 誤り伝播
いいことずくめに見えますが、代償があります。復号式 $\hat{b}_k = \hat{d}_k \oplus \hat{d}_{k-1}$ を見ればわかる通り、ひとつの符号語 $\hat{d}_k$ は 2つの情報ビット $\hat{b}_k$ と $\hat{b}_{k+1}$ の計算に使われます。したがって $\hat{d}_k$ を1個間違えると、情報ビットは2個間違えます。これを 誤り伝播(error propagation) と呼びます。「伝播」という名前ですが、影響が続くのは2ビットだけで、無限に伝わるわけではありません。
符号語の誤り率を $P$ とすると、情報ビットの誤り率は「$\hat{d}_k$ か $\hat{d}_{k-1}$ のちょうど一方だけが誤る確率」なので、
$$ P_b = 2P(1-P) \approx 2P \quad (P \ll 1) $$
となります。BER が単純に2倍になるわけです。「2倍」と聞くと大きく感じますが、BER 曲線は SNR に対して指数関数的に急峻なので、必要な $E_b/N_0$ の増加はごくわずかです。実際に計算すると、コヒーレント検波した BPSK に差動符号化・差動復号だけを追加した場合、BER $10^{-3}$ を得るのに必要な $E_b/N_0$ は 6.79 dB から 7.33 dB へ、わずか 0.55 dB の増加です。BER $10^{-5}$ ではさらに縮まって 0.30 dB にすぎません。高 SNR ほど曲線が立つので、係数2の代償は小さくなっていきます。
ここで重要な区別をしておきます。いま述べたのは「差動符号化 + コヒーレント検波」という組み合わせで、搬送波再生ループは依然として必要です(あいまいさだけを解消している)。これに対し、次に見る 遅延検波 は搬送波再生そのものを不要にします。同じ「差動」でも、狙いも性能もまったく違うので混同しないようにしましょう。
遅延検波 — 前のシンボルを基準に借りる
基準信号を自前で作らない
コヒーレント検波では、受信機が搬送波と同じ周波数・同じ位相の局部信号を作り、それと掛け算して情報を取り出します。この「基準信号を作る」部分が搬送波再生であり、コストとあいまいさの源でした。
遅延検波(differential detection、差動検波)の発想は大胆です。基準信号を作るのをやめて、1シンボル前の受信信号をそのまま基準に使う。前のシンボルにも同じ未知位相 $\theta$ が乗っているのだから、比較すれば $\theta$ は消えるはずだ、という理屈です。
複素ベースバンド表現で書きましょう。第 $k$ シンボルの受信サンプルは
$$ \begin{equation} r_k = A e^{j(\phi_k + \theta)} + n_k \end{equation} $$
です。$A$ は振幅、$\theta$ は未知の定位相、$n_k$ は複素ガウス雑音で、実部・虚部が独立に分散 $N_0/2$ を持ちます($E[|n_k|^2] = N_0$)。
ここで、現在のサンプルと1シンボル前のサンプルの 複素共役積 を作ります。
$$ \begin{equation} z_k = r_k\, r_{k-1}^{*} \end{equation} $$
なぜ共役積なのかは、雑音のない理想の場合を計算すればわかります。$r_k = Ae^{j(\phi_k+\theta)}$, $r_{k-1} = Ae^{j(\phi_{k-1}+\theta)}$ を代入すると、
$$ z_k = A e^{j(\phi_k+\theta)} \cdot A e^{-j(\phi_{k-1}+\theta)} = A^2 e^{j(\phi_k – \phi_{k-1})} = A^2 e^{j\Delta\phi_k} $$
$\theta$ が指数の肩で $+\theta$ と $-\theta$ になって相殺し、位相増分 $\Delta\phi_k$ だけが取り出されました。共役を取るのは、位相の引き算を複素数の掛け算で実現するためだったのです。
DBPSK では $\Delta\phi_k \in \{0, \pi\}$ なので、$z_k$ の実部の符号を見れば判定できます。
$$ \begin{equation} \hat{b}_k = \begin{cases} 0 & \operatorname{Re}\{z_k\} \geq 0 \quad (\Delta\phi_k = 0\ \text{と判定}) \\ 1 & \operatorname{Re}\{z_k\} < 0 \quad (\Delta\phi_k = \pi\ \text{と判定}) \end{cases} \end{equation} $$
M-DPSK では偏角 $\arg z_k$ を $2\pi/M$ 刻みの $M$ 個の扇形に分割して判定します。
アナログ実装 — 遅延線とミキサだけ
この演算がハードウェアでいかに簡単かも見ておきましょう。RF/IF 段で直接やるなら、必要なのは 1シンボル分の遅延線 と ミキサ(掛け算器) と 低域通過フィルタ だけです。受信信号 $\cos(2\pi f_c t + \phi_k + \theta)$ と、その1シンボル遅延版 $\cos(2\pi f_c t + \phi_{k-1} + \theta)$ を掛けると、積和公式より
$$ \frac{1}{2}\cos(\phi_k – \phi_{k-1}) + \frac{1}{2}\cos(4\pi f_c t + \phi_k + \phi_{k-1} + 2\theta) $$
となり、第2項を低域通過フィルタで落とせば $\frac{1}{2}\cos\Delta\phi_k$ が残ります。PLL も VCO も要りません。

ブロック図に現れる部品を数えてみてください。受信信号を2つに分け、片方を1シンボル分だけ遅らせ、掛け算し、低域通過フィルタを通し、符号を見る — これだけです。コヒーレント検波の受信機に必ず存在する VCO・ループフィルタ・位相比較器のセットが、まるごと消えています。基準信号を「作る」のではなく「借りる」という発想が、ハードウェアの規模にそのまま反映されているわけです。光通信の DPSK 受信機で使われる「1ビット遅延干渉計」は、この演算を光の干渉でそのまま実装したものです。マッハツェンダー干渉計の片腕を1ビット分だけ長くしておくだけで、フォトダイオードが自動的に $\cos\Delta\phi_k$ を出力してくれます。能動素子ゼロで復調できるわけです。
タダではない — 雑音が2回入る
さて、うまい話には裏があります。式(5)に雑音込みの式(4)を代入して展開してみましょう。
$$ z_k = \left(A e^{j(\phi_k+\theta)} + n_k\right)\left(A e^{-j(\phi_{k-1}+\theta)} + n_{k-1}^*\right) $$
4つの項に分けて書き下すと、それぞれの意味がはっきりします。
$$ z_k = \underbrace{A^2 e^{j\Delta\phi_k}}_{\text{信号}\times\text{信号}} + \underbrace{A e^{j(\phi_k+\theta)} n_{k-1}^{*}}_{\text{信号}\times\text{雑音}} + \underbrace{A e^{-j(\phi_{k-1}+\theta)} n_k}_{\text{雑音}\times\text{信号}} + \underbrace{n_k n_{k-1}^{*}}_{\text{雑音}\times\text{雑音}} $$

左の散布図は $E_b/N_0 = 6$ dB での $z_k$ の分布で、ビット0の塊が $+A^2$、ビット1の塊が $-A^2$ を中心に広がり、判定境界 $\operatorname{Re}\{z_k\}=0$ の左右に分かれています。右の図は1つの標本を4項に分解したもので、青い信号項が理想点まで届いたあと、オレンジ・緑・紫の3本の雑音関連ベクトルが継ぎ足されて最終的な判定量がずれていく様子が見えます。雑音起因のベクトルが3本もあるのがコヒーレント検波との決定的な違いです。
コヒーレント検波なら、基準信号は雑音を含まない純粋な正弦波なので、判定量に混じる雑音は現在のシンボルの $n_k$ ただ1つです。ところが遅延検波では、基準として使う $r_{k-1}$ 自体が雑音を含んでいます。その結果、$n_k$ と $n_{k-1}$ の2シンボル分の雑音が判定量に流れ込みます。さらに、雑音どうしの積 $n_k n_{k-1}^*$ という非ガウス的な項まで現れます。
直感的には「雑音のパワーが2倍 = 3 dB の損」と言いたくなります。実際そう説明している教科書もあります。しかしこの見積もりは正しくありません。次のセクションで厳密な誤り率を導出すると、損失はもっと小さいことがわかります。なぜ直感が外れるのか、その理由まで含めて追いかけていきましょう。
DBPSK の誤り率を厳密に導く
導出のゴールと戦略
これから示すのは、DBPSK(差動符号化 + 遅延検波)の平均ビット誤り率が次の驚くほど簡潔な閉形式になることです。
$$ \begin{equation} P_{b,\text{DBPSK}} = \frac{1}{2}\exp\left(-\frac{E_b}{N_0}\right) \end{equation} $$
Q 関数も積分記号も出てこない、初等関数だけの式です。コヒーレント BPSK の $Q(\sqrt{2E_b/N_0})$ が Q 関数(誤差関数)を必要とすることを思えば、この簡潔さは印象的です。
判定量 $\operatorname{Re}\{r_k r_{k-1}^*\}$ は2つのガウス変数の積という厄介な形をしています。これをそのまま扱うのは大変なので、和と差に変数変換して2つの二乗の差に書き換える、という戦略を取ります。
鍵となる恒等式
新しい変数を次のように定義します。
$$ u = \frac{r_k + r_{k-1}}{2}, \qquad v = \frac{r_k – r_{k-1}}{2} $$
このとき、次の恒等式が成り立ちます。
$$ \begin{equation} |u|^2 – |v|^2 = \operatorname{Re}\{r_k r_{k-1}^{*}\} \end{equation} $$
証明は素直な展開です。まず $|u|^2 = u u^*$ を書き下します。
$$ |u|^2 = \frac{(r_k + r_{k-1})(r_k^* + r_{k-1}^*)}{4} = \frac{|r_k|^2 + |r_{k-1}|^2 + r_k r_{k-1}^* + r_k^* r_{k-1}}{4} $$
同様に $|v|^2$ は、差の積になるのでクロス項の符号が反転します。
$$ |v|^2 = \frac{|r_k|^2 + |r_{k-1}|^2 – r_k r_{k-1}^* – r_k^* r_{k-1}}{4} $$
両者を引き算すると $|r_k|^2, |r_{k-1}|^2$ が消え、クロス項だけが残ります。
$$ |u|^2 – |v|^2 = \frac{2\left(r_k r_{k-1}^* + r_k^* r_{k-1}\right)}{4} = \frac{r_k r_{k-1}^* + (r_k r_{k-1}^*)^*}{2} $$
最後に、複素数 $w$ について $(w + w^*)/2 = \operatorname{Re}\{w\}$ という基本関係を使えば、式(8)が得られます。判定は「$|u| > |v|$ か $|u| < |v|$ か」という 2つの振幅の大小比較 に化けました。

左のパネル(情報ビット 0、$\Delta\phi=0$)では $r_k$ と $r_{k-1}$ が同じ向きなので、和ベクトル $u$ が振幅 $A$ をそのまま持ち、差ベクトル $v$ は長さ0に潰れています。右のパネル(情報ビット 1、$\Delta\phi=\pi$)では役割が入れ替わり、$|E[u]|=0$、$|E[v]|=A$ になります。つまり和・差への変換は、信号エネルギーを $u$ か $v$ のどちらか一方に全部集める装置として働いており、これが「振幅の大小比較」という単純な判定を可能にしています。
$u$ と $v$ の統計的性質
この変換のありがたみは、$u$ と $v$ が 独立 になることです。$r_k, r_{k-1}$ に含まれる雑音 $n_k, n_{k-1}$ は独立な複素ガウス変数です。$(u,v)$ への変換は $(r_k, r_{k-1})$ の直交変換(回転とスケーリング)なので、ガウス性が保たれ、しかも共分散が消えます。実際、雑音成分だけを取り出すと $u_n = (n_k+n_{k-1})/2$, $v_n = (n_k-n_{k-1})/2$ で、
$$ E[u_n v_n^*] = \frac{E[|n_k|^2] – E[n_k n_{k-1}^*] + E[n_{k-1}n_k^*] – E[|n_{k-1}|^2]}{4} = \frac{N_0 – 0 + 0 – N_0}{4} = 0 $$
となり無相関、ガウス変数なので独立です。分散はそれぞれ
$$ E[|u_n|^2] = E[|v_n|^2] = \frac{E[|n_k|^2] + E[|n_{k-1}|^2]}{4} = \frac{N_0}{2} $$
です。元の雑音の分散 $N_0$ より小さくなっている点に注意してください(平均を取る操作なので当然です)。
次に信号成分です。情報ビットが $b_k = 0$、つまり位相が変化しない場合、$r_k$ と $r_{k-1}$ の信号成分は同じ $Ae^{j(\phi+\theta)}$ です。すると
$$ E[u] = \frac{Ae^{j(\phi+\theta)} + Ae^{j(\phi+\theta)}}{2} = Ae^{j(\phi+\theta)}, \qquad E[v] = \frac{Ae^{j(\phi+\theta)} – Ae^{j(\phi+\theta)}}{2} = 0 $$
$u$ に信号がすべて集まり、$v$ には雑音しか残りません。 和と差に分ける操作が、信号を片方に集中させる「1タップの整合フィルタ」のように働いているわけです。$b_k = 1$(位相反転)の場合は役割がそっくり入れ替わり、$E[u]=0$, $|E[v]| = A$ になります。以下では $b_k = 0$ を仮定し、誤り $P(|v| > |u|)$ を計算します(対称性より $b_k=1$ でも同じ値です)。
誤り確率の積分
$|u|$ は非心(ライス分布)、$|v|$ は中心(レイリー分布)の振幅です。二乗した量で考えると、$X = |u|^2$ は自由度2の非心カイ二乗、$Y = |v|^2$ は自由度2の中心カイ二乗、すなわち指数分布になります。$Y$ の確率密度は、平均 $E[Y] = N_0/2 \equiv \sigma^2$ を使って
$$ p_Y(y) = \frac{1}{\sigma^2}e^{-y/\sigma^2}, \qquad y \geq 0 $$
です。$X$ の密度は非心度 $A^2$ のライス型で、変形ベッセル関数 $I_0$ を含みます。
$$ p_X(x) = \frac{1}{\sigma^2}\exp\left(-\frac{x + A^2}{\sigma^2}\right) I_0\!\left(\frac{2A\sqrt{x}}{\sigma^2}\right) $$
誤り確率は $P_b = P(Y > X)$ なので、$X$ で条件付けてから積分します。$Y$ が指数分布なので内側の積分は一瞬で片付きます。
$$ P(Y > x) = \int_x^{\infty}\frac{1}{\sigma^2}e^{-y/\sigma^2}dy = e^{-x/\sigma^2} $$
これを $X$ について平均します。
$$ P_b = \int_0^{\infty} e^{-x/\sigma^2}\, p_X(x)\, dx = \frac{1}{\sigma^2}\int_0^{\infty}\exp\left(-\frac{2x + A^2}{\sigma^2}\right) I_0\!\left(\frac{2A\sqrt{x}}{\sigma^2}\right) dx $$
この積分は、被積分関数を「別のライス密度」の形に整えると計算せずに済みます。$\exp(-2x/\sigma^2)$ の係数2を吸収するため $\sigma’^2 = \sigma^2/2$ と置き、無理やり密度の形を作ります。ライス密度が全区間で1に積分されるという性質を使うのがポイントです。指数の肩を整理すると
$$ -\frac{2x + A^2}{\sigma^2} = -\frac{x + A^2/2}{\sigma’^2}\cdot\frac{1}{1} – \frac{A^2}{2\sigma^2} $$
と、$\sigma’^2$ を分母とするライス型の指数部と、$x$ に依存しない定数項 $-A^2/(2\sigma^2)$ に分離できます。ベッセル関数の引数も $2A\sqrt{x}/\sigma^2 = 2(A/2)\sqrt{x}/\sigma’^2$ と書けるので、非心度が $A^2/4$ ではなく $A^2/2$ となるライス密度が現れます。結局、密度の全積分が1であることから、残るのは定数因子だけです。
$$ P_b = \frac{1}{2}\exp\left(-\frac{A^2}{2\sigma^2}\right) $$
最後に物理量に戻します。$\sigma^2 = N_0/2$ であり、1シンボルあたりのエネルギーは $E_s = A^2$、DBPSK は1シンボル1ビットなので $E_b = E_s = A^2$ です。したがって
$$ \frac{A^2}{2\sigma^2} = \frac{A^2}{N_0} = \frac{E_b}{N_0} $$
となり、目標だった式(7) $P_b = \frac{1}{2}e^{-E_b/N_0}$ が得られました。
コヒーレント BPSK との比較 — 「3 dB 損失」は本当か
導出できたので、コヒーレント BPSK の $P_b = Q(\sqrt{2E_b/N_0})$ と比べましょう。$\gamma \equiv E_b/N_0$ と書きます。Q 関数の高 SNR 漸近形 $Q(x) \approx e^{-x^2/2}/(x\sqrt{2\pi})$ を使うと、
$$ Q(\sqrt{2\gamma}) \approx \frac{e^{-\gamma}}{\sqrt{4\pi\gamma}} $$
一方 DBPSK は $\frac{1}{2}e^{-\gamma}$ です。指数の肩がまったく同じ $-\gamma$ であることに注目してください。違いは前についている係数だけ、しかも $1/2$ と $1/\sqrt{4\pi\gamma}$ という、SNR に対してゆるやかにしか変わらない量の差です。もし本当に「雑音が2倍で 3 dB 損」なら、DBPSK の指数は $-\gamma/2$ にならなければいけません。そうなっていないのです。
具体的に見ましょう。$\gamma = 10$(10 dB)のとき、コヒーレント BPSK は $3.87\times10^{-6}$、DBPSK は $2.27\times10^{-5}$ で、比はわずか 5.9 倍です。ところが「3 dB 損」を素朴に信じて $Q(\sqrt{\gamma})$ を計算すると $7.83\times10^{-4}$ となり、実際より 34 倍も悲観的な予測になります。
各方式が目標 BER を達成するのに必要な $E_b/N_0$ を数値的に解くと、損失の全体像が見えます。
| 目標 BER | コヒーレントBPSK | DBPSK | 損失 | DQPSK | コヒーレントQPSKからの損失 |
|---|---|---|---|---|---|
| $10^{-2}$ | 4.32 dB | 5.92 dB | +1.60 dB | 6.80 dB | +2.47 dB |
| $10^{-3}$ | 6.79 dB | 7.93 dB | +1.14 dB | 9.20 dB | +2.41 dB |
| $10^{-4}$ | 8.40 dB | 9.30 dB | +0.90 dB | 10.78 dB | +2.38 dB |
| $10^{-5}$ | 9.59 dB | 10.34 dB | +0.75 dB | 11.96 dB | +2.37 dB |
| $10^{-6}$ | 10.53 dB | 11.18 dB | +0.65 dB | 12.89 dB | +2.36 dB |
(コヒーレント QPSK の BER は、Gray 符号なら理論上コヒーレント BPSK と同じ $Q(\sqrt{2E_b/N_0})$ です。)

左の棒グラフは表をそのまま可視化したもので、どの目標 BER でも4本の棒の高さの差が 3 dB より明らかに小さいことが一目でわかります。右の折れ線が本節の主張を最もよく表しています。灰色の破線が「俗に言われる 3 dB 損失」の位置ですが、DBPSK(緑)は 1.60 dB から 0.65 dB へ右下がりに減っていき、破線には一度も届きません。一方 DQPSK(赤)は 2.4 dB 前後でほぼ水平のままで、こちらは「約 3 dB」という目安に近い挙動を示します。紫の「差動符号化のみ」に至っては 0.25〜0.88 dB しかありません。
読み取れることは3点あります。第一に、DBPSK の損失は 1 dB 前後であり、3 dB ではありません。第二に、損失は高 SNR ほど小さくなります。指数部が同じで係数だけ違うため、曲線が急峻になるほど水平方向の差が詰まるからです。第三に、多値化すると損失は大きくなります。DQPSK では約 2.4 dB で、これは高 SNR でもあまり縮みません。よく言われる「DPSK は約 3 dB の損失」という表現は、$M \geq 4$ の場合のややラフな目安と理解するのが正確です。
なぜ素朴な「雑音2倍 = 3 dB」が外れるのでしょうか。理由は、判定が 線形なマッチトフィルタ出力の符号 ではなく、2つの振幅の大小比較 という非線形処理になっているからです。$u$ と $v$ に分解したときに見た通り、和を取る操作が信号を $u$ に集め、$v$ には雑音しか残しません。雑音は確かに2シンボル分入りますが、$u$ の分散も $v$ の分散も $N_0/2$ と、元の $N_0$ より小さくなっていました。「2シンボル分の雑音が入る」ことと「実効 SNR が半分になる」ことは、同じではないのです。
ここまでは位相回転がまったくない理想状態を仮定していました。しかし実際には、周波数オフセットや位相雑音でシンボル間に位相ずれが生じます。次はその一般形を導き、そこから DQPSK の BER 式が自然に出てくる様子を見ていきましょう。
位相回転を伴う一般形と DQPSK の BER
シンボル間に $\theta$ の回転がある場合
いま、隣接シンボル間で位相が $\theta$ だけ余分に回転しているとします(周波数オフセット $\Delta f$ とシンボル周期 $T_s$ に対して $\theta = 2\pi\Delta f T_s$ が典型例です)。先ほどと同じく $u, v$ を計算しましょう。$b_k = 0$(位相変化なし)のとき、信号成分は $r_{k}$ が $Ae^{j\psi}$、$r_{k-1}$ が $Ae^{j(\psi – \theta)}$ です。平均は
$$ E[u] = \frac{Ae^{j\psi}\left(1 + e^{-j\theta}\right)}{2}, \qquad E[v] = \frac{Ae^{j\psi}\left(1 – e^{-j\theta}\right)}{2} $$
ここでオイラーの公式から $1 + e^{-j\theta} = 2e^{-j\theta/2}\cos(\theta/2)$、$1 – e^{-j\theta} = 2je^{-j\theta/2}\sin(\theta/2)$ という半角の関係を使うと、振幅がすっきりします。
$$ |E[u]| = A\left|\cos\frac{\theta}{2}\right|, \qquad |E[v]| = A\left|\sin\frac{\theta}{2}\right| $$
$\theta = 0$ のときは $|E[u]| = A$, $|E[v]| = 0$ で前節と一致します。$\theta$ が大きくなるにつれて信号エネルギーが $v$ 側に漏れ出し、$\theta = \pi$ で完全に逆転します($\theta = \pi/2$ ではちょうど半々になり、判定は当てずっぽうと同じになります)。位相回転の害が数式で見えました。

左のグラフでは、$\theta$ が増えるにつれて正しい側 $u$ の振幅(青)が下がり、誤り側 $v$ の振幅(赤)が上がっていく様子が見えます。2本が交わる $\theta = 90°$ が「判定が当てずっぽうになる」点です。緑の破線で示した $\theta = 45°$ が、次項で扱う Gray 符号 DQPSK と同じ構造を持つ位置です。右のグラフは式(10) の BER を $E_b/N_0$ 別に描いたもので、$E_b/N_0$ が高いほど(赤い曲線ほど)位相回転に対して急峻に、つまり 敏感に 劣化することが読み取れます。高性能な設計ほど位相回転に神経を使う必要がある、ということです。
Marcum Q 関数の登場
$|u|$ と $|v|$ が 両方とも ライス分布になったので、誤り確率は「2つのライス変数の大小比較」という古典的な問題になります。その答えは Marcum の Q 関数で書けます。第1種 Marcum Q 関数は次で定義されます。
$$ \begin{equation} Q_1(a,b) = \int_b^{\infty} x \exp\left(-\frac{x^2 + a^2}{2}\right) I_0(a x)\, dx \end{equation} $$
これは「非心度 $a^2$ のライス分布が $b$ を超える確率」を表します。$a=0$ とすると $I_0(0)=1$ でレイリー分布に退化し、$Q_1(0,b) = e^{-b^2/2}$ という簡単な形になります。この特殊値は後で使います。
この道具を使うと、位相回転 $\theta$ を伴う DBPSK の厳密な誤り率は次のように書けます。
$$ \begin{equation} P_b(\theta) = Q_1(a,b) – \frac{1}{2}I_0(ab)\,e^{-(a^2+b^2)/2} \end{equation} $$
$$ a = \sqrt{2\gamma_s}\,\sin\frac{\theta}{2}, \qquad b = \sqrt{2\gamma_s}\,\cos\frac{\theta}{2}, \qquad \gamma_s = \frac{E_s}{N_0} $$
$a$ が「誤りを起こす側($v$)」の、$b$ が「正しい側($u$)」の規格化された信号振幅に対応しています。式(10)が正しいことは、$\theta = 0$ を入れて確かめられます。このとき $a = 0$, $b = \sqrt{2\gamma_s}$ なので、$Q_1(0,b) = e^{-b^2/2} = e^{-\gamma_s}$、$I_0(0)=1$ より
$$ P_b(0) = e^{-\gamma_s} – \frac{1}{2}e^{-\gamma_s} = \frac{1}{2}e^{-\gamma_s} $$
と、式(7)にきちんと帰着します。
DQPSK の BER が同じ式から出る
ここからが面白いところです。Gray 符号化した DQPSK の BER は、教科書では次の式で与えられます。
$$ \begin{equation} P_{b,\text{DQPSK}} = Q_1(a,b) – \frac{1}{2}I_0(ab)e^{-(a^2+b^2)/2} \end{equation} $$
$$ a = \sqrt{2\frac{E_b}{N_0}\left(1 – \frac{1}{\sqrt{2}}\right)}, \qquad b = \sqrt{2\frac{E_b}{N_0}\left(1 + \frac{1}{\sqrt{2}}\right)} $$
見た目は式(10)とそっくりですが、$a, b$ の中身が違います。……本当に違うのでしょうか。式(10)に $\theta = \pi/4$(45°)を代入してみましょう。半角の公式 $\sin^2(\theta/2) = (1-\cos\theta)/2$ を使うと、
$$ a^2 = 2\gamma_s \sin^2\frac{\pi}{8} = 2\gamma_s\cdot\frac{1 – \cos(\pi/4)}{2} = \gamma_s\left(1 – \frac{1}{\sqrt{2}}\right) $$
QPSK は1シンボルで2ビット運ぶので $\gamma_s = E_s/N_0 = 2E_b/N_0$ です。これを代入すると
$$ a^2 = 2\frac{E_b}{N_0}\left(1 – \frac{1}{\sqrt{2}}\right) $$
となり、式(11)の $a$ と 完全に一致 します。$b$ についても $\cos^2(\pi/8) = (1+\cos(\pi/4))/2$ から同様に一致します。
つまり、Gray 符号 DQPSK の1ビットの判定は、「45° の位相誤差を持った DBPSK の判定」とまったく同じ数学的構造をしているのです。理由を考えると納得できます。Gray 符号 QPSK では、各ビットは I 軸または Q 軸のどちらか一方の符号だけで決まります。DQPSK の位相増分は $\{0°, \pm90°, 180°\}$ ですが、あるビットを決める判定境界から見ると、送信点は境界から最も近くて 45°、最も遠くて 135° の位置にあります。この「最悪 45°」という幾何が、位相誤差 45° の DBPSK と同じ式を生むわけです。
この見方の副産物として、DQPSK の損失が DBPSK より大きい理由も説明できます。DQPSK は常に「45° ずれた状態」で判定しているようなもので、信号エネルギーの一部が構造的に誤り側 $v$ に漏れているのです。表で見た約 2.4 dB という損失は、この漏れの代償です。
位相回転の効果を厳密に扱えるようになったので、この式は後の周波数オフセット実験でも活躍します。その前に、実用面で DQPSK に手を加えた $\pi/4$-QPSK を見ておきましょう。
$\pi/4$-QPSK — 原点を通らせない工夫
包絡線がゼロになると何が困るのか
QPSK や DQPSK で位相が 180° 変化するとき、送信波形はどう動くでしょうか。コンステレーション上で対角の点へ移動するので、軌跡は原点を通過します。原点を通るということは、その瞬間に信号の振幅(包絡線)がゼロになるということです。
これは電力増幅器にとって最悪の入力です。増幅器を効率よく動かすには飽和点近くで使いたいのですが、そこは非線形領域です。包絡線が大きく変動する信号を非線形増幅器に通すと、スペクトルが広がって隣接チャネルに漏れ(スペクトル再生長)、規格の漏洩電力マスクを満たせなくなります。振幅変動が小さければ、増幅器を飽和近くで使っても歪みが少なくて済みます。携帯端末のように電池が命の機器では、この差が動作時間に直結します。
位相増分から 0° と 180° を追放する
$\pi/4$-QPSK($\pi/4$-シフト QPSK、差動検波と組み合わせて $\pi/4$-DQPSK)のアイデアは単純です。位相増分の集合を
$$ \Delta\phi_k \in \left\{+\frac{\pi}{4},\; +\frac{3\pi}{4},\; -\frac{\pi}{4},\; -\frac{3\pi}{4}\right\} $$
に変更します。通常の DQPSK が $\{0, \pm\pi/2, \pi\}$ だったのに対し、0° と 180° を排除し、代わりに 45° の奇数倍だけを使うのです。180° がないので原点通過が起きず、0° がないのでシンボルごとに必ず位相が動きます(後者はクロック再生にも好都合です)。
増分が常に 45° の奇数倍ということは、位相は「45° の偶数倍の集合」と「奇数倍の集合」を交互に行き来します。前者は $\{0°, 90°, 180°, 270°\}$、後者は $\{45°, 135°, 225°, 315°\}$ です。したがってコンステレーションを重ね書きすると 8点 が現れますが、どの時刻でも実際に使われるのは4点だけ、という独特の構造になります。8PSK に見えて情報量は QPSK と同じ2ビット/シンボルです。
実際にルートレイズドコサインフィルタ(ロールオフ 0.35)で帯域制限した波形を数値計算すると、ピーク対平均電力比(PAPR)は通常の QPSK が 3.93 dB なのに対し $\pi/4$-QPSK は 3.24 dB と約 0.7 dB 改善します。さらに劇的なのが包絡線の最小値で、QPSK では実効値の 0.0000 倍(=完全にゼロを通る)まで落ち込むのに対し、$\pi/4$-QPSK では 0.043 倍で下げ止まります。原点を避けるという設計意図が数値にはっきり現れています。
BER の観点では、差動検波した $\pi/4$-DQPSK は通常の DQPSK と同一の性能(式(11))です。位相増分の集合を 45° 回転させただけで、増分どうしの位相間隔は 90° のまま変わっていないからです。性能を落とさずに包絡線特性だけを改善できるという、いいとこ取りの手法だと言えます。日本の PDC、北米の IS-136、欧州の業務用無線 TETRA が揃ってこの方式を採用したのは、当然の選択でした。
コンステレーションの形と実装のポイントが見えたところで、いよいよ数値計算に移ります。まずは手計算で流れを追い、それから Python で確かめましょう。
具体例 — 手を動かして追う
情報ビット列 $b = (1,0,1,1,0,0,1,0)$ を DBPSK で送る場合を追跡します。$d_0 = 0$ から始めて $d_k = d_{k-1}\oplus b_k$ を順に計算します。
- $d_1 = 0 \oplus 1 = 1$
- $d_2 = 1 \oplus 0 = 1$
- $d_3 = 1 \oplus 1 = 0$
- $d_4 = 0 \oplus 1 = 1$
- $d_5 = 1 \oplus 0 = 1$
- $d_6 = 1 \oplus 0 = 1$
- $d_7 = 1 \oplus 1 = 0$
- $d_8 = 0 \oplus 0 = 0$
送信符号語は $d = (0,1,1,0,1,1,1,0,0)$、対応する位相は $(0°, 180°, 180°, 0°, 180°, 180°, 180°, 0°, 0°)$ です。ここで、情報ビットが1のところで必ず位相が切り替わり、0 のところで据え置かれていることを確認してください。たとえば $b_2 = 0$ に対応する $d_1 \to d_2$ は $1 \to 1$ で位相は 180° のまま、$b_3 = 1$ に対応する $d_2 \to d_3$ は $1 \to 0$ で 180° から 0° へ反転しています。
次に、受信機が 180° ずれた基準にロックしたとします。判定される符号語は全反転して $\tilde{d} = (1,0,0,1,0,0,0,1,1)$ です。これを差動復号します。
- $\hat{b}_1 = \tilde d_1 \oplus \tilde d_0 = 0 \oplus 1 = 1$
- $\hat{b}_2 = \tilde d_2 \oplus \tilde d_1 = 0 \oplus 0 = 0$
- $\hat{b}_3 = \tilde d_3 \oplus \tilde d_2 = 1 \oplus 0 = 1$
以下同様に計算すると $\hat{b} = (1,0,1,1,0,0,1,0)$ となり、元の情報ビットと完全に一致します。もし差動符号化を使わず $d$ をそのまま情報ビットとして送っていたら、受信側は $(1,0,0,1,0,0,0,1)$ という全反転した列を出力していたはずです。
誤り率の感覚もつかんでおきましょう。$E_b/N_0 = 8$ dB は線形値で $\gamma = 10^{0.8} = 6.31$ です。式(7)より
$$ P_b = \frac{1}{2}e^{-6.31} = \frac{1}{2}\times 1.82\times10^{-3} = 9.1\times10^{-4} $$
同じ条件でコヒーレント BPSK は $Q(\sqrt{2\times6.31}) = Q(3.55) = 1.9\times10^{-4}$ なので、およそ4.8倍の差です。約1000ビットに1回誤るか、約5000ビットに1回誤るか、という違いになります。
手計算で仕組みと桁感が確認できました。ここからは Python で、コンステレーション・BER 曲線・周波数オフセット耐性を実際に描いて確かめます。
Python による実装と検証
差動符号化と位相あいまいさの実演
まず、位相反転が差動復号で本当に消えるかを確かめます。
import numpy as np
def diff_encode(bits):
"""差動符号化: d_k = d_{k-1} XOR b_k(d_0 = 0 を基準シンボルとする)"""
d = np.zeros(len(bits) + 1, dtype=int)
d[1:] = np.bitwise_xor.accumulate(bits) # 累積XOR = 逐次XORと同じ
return d
def diff_decode(d_hat):
"""差動復号: b_k = d_k XOR d_{k-1}"""
return np.bitwise_xor(d_hat[1:], d_hat[:-1])
bits = np.array([1, 0, 1, 1, 0, 0, 1, 0])
d = diff_encode(bits)
print("情報ビット b_k :", bits)
print("差動符号語 d_k :", d)
print("送信位相 [deg] :", d * 180)
# 受信側が 180 度ずれた基準位相でロックした場合 = 全ビット反転
d_flipped = 1 - d
print("反転した受信語 :", d_flipped)
print("差動復号の結果 :", diff_decode(d_flipped))
print("元のビットと一致? :", np.array_equal(bits, diff_decode(d_flipped)))
実行すると、差動符号語は [0 1 1 0 1 1 1 0 0]、反転後は [1 0 0 1 0 0 0 1 1] となり、差動復号の結果は [1 0 1 1 0 0 1 0] で元の情報ビットと完全に一致します(True が表示されます)。手計算で追った内容がそのまま再現されました。ここで大事なのは、受信機が「反転しているかどうか」をまったく知らないまま、正しい出力を得ている点です。検出も補正もしておらず、引き算という演算の性質だけで反転が消えています。差動符号化なしなら出力は全ビット反転(BER = 1.0)でした。
コンステレーションと位相遷移
次に、DQPSK と $\pi/4$-QPSK の信号点の動きを描きます。位相の「増分」に情報が載っていることを目で確認するのが目的です。
import numpy as np
import matplotlib, matplotlib.pyplot as plt
for cand in ["Hiragino Sans", "Yu Gothic", "Noto Sans CJK JP", "IPAexGothic", "Meiryo"]:
if any(cand == f.name for f in matplotlib.font_manager.fontManager.ttflist):
plt.rcParams["font.family"] = cand
break
plt.rcParams["axes.unicode_minus"] = False
rng = np.random.default_rng(0)
N = 12
# DQPSK: 位相増分は {0, +90, 180, -90} 度
inc_dqpsk = np.array([0, np.pi/2, np.pi, -np.pi/2])[rng.integers(0, 4, N)]
ph_dqpsk = np.cumsum(np.concatenate([[np.pi/4], inc_dqpsk]))
# pi/4-QPSK: 位相増分は {+45, +135, -45, -135} 度
inc_pi4 = np.array([np.pi/4, 3*np.pi/4, -np.pi/4, -3*np.pi/4])[rng.integers(0, 4, N)]
ph_pi4 = np.cumsum(np.concatenate([[0.0], inc_pi4]))
fig, axes = plt.subplots(1, 2, figsize=(11, 5.2))
for ax, ph, title in [(axes[0], ph_dqpsk, "DQPSK(増分 0°/±90°/180°)"),
(axes[1], ph_pi4, "π/4-QPSK(増分 ±45°/±135°)")]:
s = np.exp(1j * ph)
ax.plot(np.real(s), np.imag(s), "-", color="0.7", lw=1.2, zorder=1)
ax.scatter(np.real(s), np.imag(s), c=np.arange(len(s)), cmap="viridis", s=90, zorder=3)
th = np.linspace(0, 2*np.pi, 200)
ax.plot(np.cos(th), np.sin(th), ":", color="0.8")
ax.axhline(0, color="0.85", lw=0.8); ax.axvline(0, color="0.85", lw=0.8)
ax.set_title(title); ax.set_xlabel("同相成分 I"); ax.set_ylabel("直交成分 Q")
ax.set_aspect("equal"); ax.set_xlim(-1.4, 1.4); ax.set_ylim(-1.4, 1.4)
plt.tight_layout(); plt.show()

左の DQPSK では信号点が $\{45°, 135°, 225°, 315°\}$ の4点だけを訪れ、対角どうしを結ぶ直線(原点を通る軌跡)が現れます。一方、右の $\pi/4$-QPSK では信号点が8箇所に散らばり、原点を通る線分が1本もありません。どの遷移も 45° か 135° の回転なので、円周に沿った短めの弦になるからです。この違いが、後で見る包絡線変動の差を生みます。また、どちらの図でも「点の絶対位置」ではなく「点から点への回転角」に情報が載っていることが視覚的に確認できます。
遅延検波の判定量を覗く
判定量 $\operatorname{Re}\{r_k r_{k-1}^*\}$ が実際どんな値を取るのか、統計を見てみます。
import numpy as np
def dbpsk_stat(bits, ebn0_db, rng):
"""DBPSK を送って遅延検波の判定量 Re{r_k r_{k-1}^*} を返す"""
g = 10 ** (ebn0_db / 10)
sigma = np.sqrt(1 / (2 * g)) # 複素雑音の各次元の標準偏差(Es=Eb=1)
s = 1 - 2 * diff_encode(bits) # 0→+1, 1→-1
n = sigma * (rng.standard_normal(len(s)) + 1j * rng.standard_normal(len(s)))
r = s + n
return np.real(r[1:] * np.conj(r[:-1]))
rng = np.random.default_rng(1)
bits = rng.integers(0, 2, 200000)
z = dbpsk_stat(bits, 6.0, rng)
print("同一ビット(b=0)の判定量 平均 :", z[bits == 0].mean().round(3))
print("反転ビット(b=1)の判定量 平均 :", z[bits == 1].mean().round(3))
print("実測BER :", np.mean((z < 0).astype(int) != bits).round(5),
" 理論値 :", round(0.5 * np.exp(-10 ** 0.6), 5))

左のヒストグラムは判定量が $\pm 1$ を中心とする対称な2山になることを示しており、境界 $0$ をまたいで重なっている部分の面積がそのまま誤り率になります。右は同じデータのビット0側だけを対数軸で描き、同じ平均・分散のガウス分布(赤線)を重ねたものです。実測のヒストグラムが両側ともガウス曲線の外側にはみ出しており、裾がガウスより重いことが読み取れます。この重い裾を作っているのが $n_k n_{k-1}^*$ という雑音の積の項です。
出力は「同一ビットの平均 0.999」「反転ビットの平均 -1.002」となり、理論値 $\pm A^2 = \pm 1$ をきれいに再現します。実測 BER は 0.00936 で、理論式 $\frac{1}{2}e^{-\gamma}$ が与える 0.00933 とほぼ一致しました($E_b/N_0 = 6$ dB)。ここで注目したいのは、判定量の分布が対称な2山になっていながら、その広がりがガウス分布ではないことです。$n_k n_{k-1}^*$ という雑音の積の項があるため、裾はガウスより重くなります。それでも最終的な誤り率が $\frac{1}{2}e^{-\gamma}$ という初等関数に収まるのは、$|u|^2 – |v|^2$ 分解のおかげでした。
BER 曲線の比較
理論式とモンテカルロシミュレーションを重ねて、4方式を比較します。
import numpy as np
from scipy.special import erfc, ive
from scipy.stats import ncx2
Qfunc = lambda x: 0.5 * erfc(x / np.sqrt(2))
marcumq1 = lambda a, b: ncx2.sf(b**2, 2, a**2) # 第1種MarcumQ = 非心カイ二乗の上側確率
def ber_dbpsk_phase(g, theta):
"""位相回転 theta を伴う DBPSK の厳密BER(theta=0 で (1/2)exp(-g))"""
a = np.sqrt(2*g) * np.sin(theta/2)
b = np.sqrt(2*g) * np.cos(theta/2)
# ive は指数スケール付きベッセル関数(オーバーフロー回避)
return marcumq1(a, b) - 0.5 * ive(0, a*b) * np.exp(-(a-b)**2/2)
ebn0_db = np.arange(0, 13.1, 0.5)
g = 10 ** (ebn0_db / 10)
ber_bpsk = Qfunc(np.sqrt(2*g)) # コヒーレントBPSK(=コヒーレントQPSK)
ber_dbpsk = 0.5 * np.exp(-g) # DBPSK(遅延検波)
ber_diffcoh = 2 * ber_bpsk * (1 - ber_bpsk) # 差動符号化+コヒーレント検波
ber_dqpsk = ber_dbpsk_phase(2*g, np.pi/4) # DQPSK(Gray符号・遅延検波)
モンテカルロ側も用意します。
def sim_dbpsk(ebn0_db, nbits, rng):
g = 10 ** (ebn0_db / 10); sigma = np.sqrt(1/(2*g))
bits = rng.integers(0, 2, nbits)
s = 1 - 2 * diff_encode(bits)
r = s + sigma*(rng.standard_normal(nbits+1) + 1j*rng.standard_normal(nbits+1))
z = np.real(r[1:]*np.conj(r[:-1]))
return np.mean((z < 0).astype(int) != bits)
def sim_dqpsk(ebn0_db, nsym, rng):
g = 10 ** (ebn0_db / 10); sigma = np.sqrt(1/(2*2*g)) # Es/N0 = 2Eb/N0
b1, b2 = rng.integers(0, 2, nsym), rng.integers(0, 2, nsym)
idx = np.where(b1 == 0, np.where(b2 == 0, 0, 1), np.where(b2 == 1, 2, 3)) # Gray
ph = np.concatenate([[0.0], np.cumsum(idx * np.pi/2)])
s = np.exp(1j*ph)
r = s + sigma*(rng.standard_normal(nsym+1) + 1j*rng.standard_normal(nsym+1))
k = np.mod(np.round(np.angle(r[1:]*np.conj(r[:-1]))/(np.pi/2)), 4).astype(int)
e1 = np.where((k == 0) | (k == 1), 0, 1)
e2 = np.where((k == 0) | (k == 3), 0, 1)
return (np.mean(e1 != b1) + np.mean(e2 != b2)) / 2
rng = np.random.default_rng(2)
pts = np.arange(0, 11, 2)
print("sim DBPSK:", np.round([sim_dbpsk(x, 400000, rng) for x in pts], 5))
print("sim DQPSK:", np.round([sim_dqpsk(x, 400000, rng) for x in pts], 5))
シミュレーション結果は DBPSK が [0.18326, 0.10244, 0.04096, 0.00934, 0.00095, 0.00003]、DQPSK が [0.16438, 0.09902, 0.04861, 0.01713, 0.00358, 0.00036] で、理論値(DBPSK: 0.18394, 0.10248, 0.04056, 0.00933, 0.00091, 0.0000227/DQPSK: 0.16386, 0.09933, 0.04875, 0.01724, 0.00364, 0.00034)と3桁の精度で一致しました。Marcum Q 関数を含む DQPSK の式も、$\theta = 45°$ の一般形から求めたものが実測と合っています。

曲線を描くと、10 dB 付近で DBPSK はコヒーレント BPSK の右にわずか 0.75 dB ほどずれた位置を走り、DQPSK はさらに 1.6 dB ほど右に離れます。「差動符号化 + コヒーレント検波」の破線は BPSK のほぼ真上に重なり、係数2の代償が水平方向にはほとんど効かないことが視覚的にわかります。丸と四角のシミュレーション点が理論曲線の上にきれいに乗っていることも、導出した式(7)と式(11)が正しいことの裏付けになっています。
周波数オフセットへの耐性
最後に、DPSK の実力が最もはっきり出る実験です。搬送波周波数にオフセット $\Delta f$ があるとき、DBPSK と「先頭で位相を推定して以後は追従しないコヒーレント受信機」がどう振る舞うかを比べます。
import numpy as np
def sim_dbpsk_offset(ebn0_db, dfT, nbits, rng):
"""周波数オフセット dfT = Δf * Ts を与えた DBPSK"""
g = 10 ** (ebn0_db/10); sigma = np.sqrt(1/(2*g))
bits = rng.integers(0, 2, nbits)
s = (1 - 2*diff_encode(bits)) * np.exp(1j*2*np.pi*dfT*np.arange(nbits+1))
r = s + sigma*(rng.standard_normal(nbits+1) + 1j*rng.standard_normal(nbits+1))
z = np.real(r[1:]*np.conj(r[:-1]))
return np.mean((z < 0).astype(int) != bits)
def sim_coh_frozen(ebn0_db, dfT, nbits, rng):
"""先頭で位相推定を凍結したコヒーレントBPSK(追従なし)"""
g = 10 ** (ebn0_db/10); sigma = np.sqrt(1/(2*g))
bits = rng.integers(0, 2, nbits)
s = (1 - 2*bits) * np.exp(1j*2*np.pi*dfT*np.arange(nbits))
r = s + sigma*(rng.standard_normal(nbits) + 1j*rng.standard_normal(nbits))
return np.mean((np.real(r) < 0).astype(int) != bits)
rng = np.random.default_rng(3)
for dfT in [0.0, 0.01, 0.05, 0.1]:
print(f"dfT={dfT}: DBPSK={sim_dbpsk_offset(8, dfT, 400000, rng):.5f} "
f"厳密式={ber_dbpsk_phase(10**0.8, 2*np.pi*dfT):.5f} "
f"凍結コヒーレント={sim_coh_frozen(8, dfT, 400000, rng):.5f}")
結果は劇的です($E_b/N_0 = 8$ dB)。
| $\Delta f\,T_s$ | シンボル間の位相回転 | DBPSK(実測) | DBPSK(式(10)) | 凍結コヒーレント |
|---|---|---|---|---|
| 0 | 0° | 0.00099 | 0.00091 | 0.00018 |
| 0.01 | 3.6° | 0.00109 | 0.00096 | 0.49974 |
| 0.05 | 18° | 0.00251 | 0.00247 | 0.50009 |
| 0.10 | 36° | 0.01349 | 0.01352 | 0.50093 |

左のグラフの落差が本節の主題です。赤い四角(凍結コヒーレント)は $\Delta f T_s$ が 0 から 0.01 に変わっただけで BER が $1.8\times10^{-4}$ から 0.5 へ、実に3桁以上も跳ね上がって水平になります。対する緑の DBPSK は、$10^{-3}$ 付近からゆるやかに立ち上がるだけです。白丸のシミュレーション点が緑の理論曲線(式(10))にきちんと乗っていることも確認できます。右のグラフは劣化量を dB で読めるようにしたもので、$\Delta f T_s$ が 0.05 を超えたあたりから曲線が急に立ち上がる様子が見えます。
オフセットがゼロなら、当然コヒーレント検波(0.00018)が DBPSK(0.00099)より優秀です。ところがシンボルレートの 1% というごくわずかなオフセットを与えただけで、追従しないコヒーレント受信機は BER 0.5、つまり完全に無情報 になります。位相が時間とともに回り続けるため、40万シンボルの間に判定境界を何度も跨いでしまうからです。対する DBPSK は 0.00109 とほとんど劣化しません。1シンボルの間に位相が 3.6° しか動かないなら、引き算でほぼ相殺されるためです。実測値が式(10)の予測とよく一致していることも確認できます。
もちろんこれは「追従しない」受信機との比較であり、PLL で周波数オフセットを追い込めばコヒーレント検波が勝ちます。この実験が示しているのは、DPSK は「初期位相の不定」と「ゆっくりした位相ドリフト」に対して構造的に強いということです。1シンボル時間の間に位相がほぼ変わらない限り、$\theta$ は引き算で消えます。逆に言えば、DPSK が弱いのは「1シンボル時間の中で位相が大きく動く」場合です。式(10)で必要 $E_b/N_0$ を計算すると、BER $10^{-3}$ を保つための劣化は $\Delta f T_s = 0.01$ で +0.04 dB、0.03 で +0.31 dB、0.05 で +0.81 dB、0.10 で +2.84 dB と急激に悪化します。実務では オフセットをシンボルレートの数 % 以内に抑える ことが設計指針になります。同じ理由で、位相雑音についても「シンボル周期より速く揺れる成分」には DPSK は無力です。
包絡線変動の比較
$\pi/4$-QPSK の効能を数値で確かめます。
import numpy as np
def rrc(beta, sps, span):
"""ルートレイズドコサインフィルタ係数"""
t = np.arange(-span*sps, span*sps+1)/sps
h = np.empty_like(t)
for i, ti in enumerate(t):
if abs(ti) < 1e-12:
h[i] = 1 - beta + 4*beta/np.pi
elif beta > 0 and abs(abs(ti) - 1/(4*beta)) < 1e-9:
h[i] = beta/np.sqrt(2)*((1+2/np.pi)*np.sin(np.pi/(4*beta))
+ (1-2/np.pi)*np.cos(np.pi/(4*beta)))
else:
h[i] = (np.sin(np.pi*ti*(1-beta)) + 4*beta*ti*np.cos(np.pi*ti*(1+beta))) \
/ (np.pi*ti*(1-(4*beta*ti)**2))
return h/np.sqrt(np.sum(h**2))
def envelope(sym, sps=8, beta=0.35):
up = np.zeros(len(sym)*sps, dtype=complex); up[::sps] = sym
return np.convolve(up, rrc(beta, sps, 8), mode="same")
rng = np.random.default_rng(4)
M = 20000
sq = np.exp(1j*(np.pi/4 + np.pi/2*rng.integers(0, 4, M))) # QPSK
inc = np.array([np.pi/4, 3*np.pi/4, -np.pi/4, -3*np.pi/4])[rng.integers(0, 4, M)]
sp = np.exp(1j*np.cumsum(inc)) # π/4-QPSK
for name, s in [("QPSK", sq), ("π/4-QPSK", sp)]:
x = envelope(s); p = np.abs(x)**2
print(f"{name}: PAPR={10*np.log10(p.max()/p.mean()):.2f} dB, "
f"包絡線最小値/実効値={np.abs(x).min()/np.sqrt(p.mean()):.4f}")

左の時間波形(実効値で規格化)を見ると、赤い QPSK の包絡線が何度も 0.2 以下まで急降下し、$180°$ 遷移が起きるたびにゼロ付近をかすめていることがわかります。青い $\pi/4$-QPSK にも谷はありますが、深さがひとまわり浅く抑えられています。右のヒストグラムはこの差をより明確に示しており、QPSK(赤)の分布が振幅 0 のすぐ右から立ち上がっているのに対し、$\pi/4$-QPSK(青)は 0.05 付近より左に確率がほとんどありません。増幅器から見た「入力が消える瞬間」が構造的に排除されているわけです。
出力は「QPSK: PAPR=3.93 dB, 包絡線最小値/実効値=0.0000」「$\pi/4$-QPSK: PAPR=3.24 dB, 包絡線最小値/実効値=0.0431」です。PAPR の改善は約 0.7 dB ですが、より本質的なのは包絡線最小値です。QPSK は 180° 遷移のたびに振幅がゼロまで落ち込むのに対し、$\pi/4$-QPSK は実効値の 4% 程度で下げ止まります。増幅器から見れば、瞬間的に入力が消えて再び立ち上がる(=深い AM 変動を作る)状況を避けられるわけで、これが非線形歪みとスペクトル再生長の抑制につながります。BER 性能はまったく同じまま、この改善が手に入る点が $\pi/4$-QPSK の価値です。
実装上の判断ポイント
最後に、実際の設計で DPSK を選ぶかどうかの判断材料を整理しておきます。
DPSK が有利な場面。 第一に、位相が短時間で不規則に変わる環境です。高速フェージングでは、搬送波再生ループの追従が間に合わず、推定位相そのものが信用できません。1シンボル前との比較で済む遅延検波なら、チャネルの位相が「1シンボルの間だけ一定」であれば動きます。第二に、短いバーストの通信です。PLL の引き込みには数十〜数百シンボルかかりますが、遅延検波は2シンボル目から復調できます。第三に、消費電力・コスト・実装面積が厳しい場合です。VCO も PLL もループフィルタも不要になります。第四に、位相あいまいさの解消機構(ユニークワード検出とその後の反転処理)を丸ごと省けるので、フレーム設計が単純になります。
DPSK が不利な場面。 第一に、$E_b/N_0$ を 1 dB でも節約したい設計です。深宇宙通信のようにリンクバジェットが極限まで切り詰められている場面では、1 dB は致命的な差になり得ます。第二に、多値化するときです。DQPSK ですでに約 2.4 dB、8DPSK ではさらに損失が広がります。第三に、周波数オフセットが大きい場合。前節で見た通り、$\Delta f T_s$ が数 % を超えると急速に劣化します。第四に、軟判定の誤り訂正符号と組み合わせる場合です。遅延検波の出力から良質な対数尤度比(LLR)を作るのはコヒーレント検波より難しく、符号化利得を取りこぼしやすくなります。
折衷案。 「差動符号化 + コヒーレント検波」という中間の選択肢を忘れないでください。搬送波再生は必要ですが、位相あいまいさだけは差動で消せます。代償は BER の係数2、$E_b/N_0$ にして 0.3〜0.55 dB だけです。実際、衛星通信や地上デジタル放送など、性能を重視しつつ位相あいまいさも避けたいシステムの多くがこの構成を採っています。「差動」という言葉が出てきたら、それが符号化だけの話なのか、検波まで含む話なのかを必ず確認しましょう。
まとめ
本記事では、差動位相変調(DPSK)を、位相あいまいさという実装上の難題から出発して解説しました。
- 問題の根源: 搬送波再生ループは $2f_c$(BPSK)や $4f_c$(QPSK)を分周して位相を作るため、BPSK では 180°、QPSK では 90° の整数倍の 位相あいまいさ が原理的に残る。これは全ビット反転という壊滅的な誤りを生む
- 差動符号化: $d_k = d_{k-1}\oplus b_k$ で情報を「位相の値」から「位相の変化」へ移す。復号は $\hat b_k = \hat d_k \oplus \hat d_{k-1}$ で、全ビット反転 $d_k \oplus 1$ を入れても $1\oplus 1 = 0$ で相殺され、あいまいさが完全に消える
- 遅延検波: 判定量 $\operatorname{Re}\{r_k r_{k-1}^*\}$ は未知位相 $\theta$ を $e^{j\theta}e^{-j\theta}$ の形で消去する。搬送波再生が不要になる代わり、雑音が2シンボル分入り、$n_k n_{k-1}^*$ という雑音積の項も現れる
- BER の厳密解: $|u|^2 – |v|^2 = \operatorname{Re}\{r_k r_{k-1}^*\}$ という分解で「2つの振幅の大小比較」に帰着させ、$P_b = \frac{1}{2}e^{-E_b/N_0}$ を導いた。指数部はコヒーレント BPSK と同じ $-E_b/N_0$ である
- 損失の実際: DBPSK の損失は BER $10^{-3}$ で +1.14 dB、$10^{-5}$ で +0.75 dB と 1 dB 前後。「雑音2倍だから 3 dB」という直感は過大評価で、判定が非線形な振幅比較になっているため当てはまらない。一方 DQPSK は約 2.4 dB と大きく、「約 3 dB」という定説は $M\geq4$ の目安と理解するのが正確
- 一般形と統一的な視点: 位相回転 $\theta$ を伴う BER は Marcum Q 関数で $Q_1(a,b) – \frac{1}{2}I_0(ab)e^{-(a^2+b^2)/2}$、$a=\sqrt{2\gamma_s}\sin(\theta/2)$, $b=\sqrt{2\gamma_s}\cos(\theta/2)$ と書ける。$\theta=0$ で DBPSK、$\theta=45°$ で DQPSK の教科書式が導かれる
- $\pi/4$-QPSK: 位相増分から 0° と 180° を追放して原点通過を回避。PAPR は 3.93→3.24 dB、包絡線最小値は 0.0000→0.0431(実効値比)と改善し、BER は DQPSK と同一
- 周波数オフセット: $\Delta f T_s = 0.01$ で追従なしコヒーレント受信機は BER 0.5 に崩壊するが、DBPSK は 0.00109 とほぼ無傷。ただし $\Delta f T_s$ が数 % を超えると急速に劣化する(0.05 で +0.81 dB、0.10 で +2.84 dB)
DPSK は「絶対的な基準がないなら、基準を必要としない量を使う」という発想の見事な実例です。同じ考え方は、差動符号化された GPS 測位、差動増幅器の同相除去、時系列の差分による定常化など、工学のあちこちに顔を出します。位相の絶対値という「測れないもの」を潔く諦め、位相差という「測れるもの」に情報を載せ替えたことで、受信機からループひとつを丸ごと取り除けたのです。
次のステップとして、以下の記事も参考にしてください。