静止衛星の中継器に載っている進行波管増幅器(TWTA)は、飽和点の近くで動かして初めて 60% を超える電力効率が出ます。バックオフを 6 dB 取れば増幅器は線形になりますが、その代償として直流電力の大半が熱になり、太陽電池パドルの面積とラジエータの質量が跳ね上がります。宇宙機の設計者にとって「増幅器を飽和近くで回せるかどうか」は、そのまま打ち上げ質量に効いてくる死活問題です。
ところが、QPSK の信号をそのまま飽和した増幅器に通すと、送信側で丁寧にルートレイズドコサイン整形して 1.35/T まで絞ったスペクトルが、まるで整形していなかったかのように広がって戻ってきます。隣のチャネルに漏れ出す電力(ACLR)は数十 dB 悪化し、周波数調整で撥ねられます。犯人は「複素包絡線が原点を通過する瞬間」です。
OQPSK(Offset QPSK、オフセット QPSK) は、この問題に対する驚くほど単純な答えです。同相成分(I)と直交成分(Q)を同時に切り替えるのをやめ、Q だけを半シンボル($T/2$)遅らせる。たったこれだけで、包絡線は原点に落ちなくなり、飽和増幅器を通したあとの帯域外輻射が桁で改善します。しかもビット誤り率(BER)は QPSK と完全に同じ — 情報理論的には何も失っていません。

この 1 枚に記事の全体像が入っています。上段は I と Q のデータが切り替わるタイミングで、QPSK では両者の切り替え時刻が揃っているのに対し、OQPSK では Q 側だけが半シンボル分ずれています。下段はその結果として描かれる複素平面上の軌跡で、QPSK は原点を何度も突っ切る一方、OQPSK の軌跡は中央に丸い穴を空けたまま外周を回り続けます。この「穴」があるかないかだけで、飽和増幅器を通したときの帯域外輻射が桁で変わる、というのがこれから追いかける話です。
OQPSK を理解すると、次のような場面での見通しが一気に開けます。
- 衛星通信・深宇宙通信: CCSDS の標準変調方式には OQPSK が含まれており、飽和動作する TWTA / SSPA と組み合わせる前提で選ばれています。リンクバジェットの「増幅器バックオフ」の項がなぜ変調方式で変わるのかが説明できるようになります
- 低消費電力無線(IEEE 802.15.4 / ZigBee): 2.4 GHz PHY は半正弦パルス整形の OQPSK を使っており、これは実は MSK と等価です。電池駆動の端末で PA を効率よく回すための選択でした
- 移動体通信の歴史: IS-95(cdmaOne)の逆方向リンクは端末の PA 効率を稼ぐために OQPSK を採用しました。一方 IS-136 や PDC、TETRA は $\pi/4$-QPSK を選んでいます。この分岐の理由が「包絡線がどこまで落ちるか」で説明できます
- PAPR とスペクトル再成長の一般論: OQPSK で身につく「包絡線の谷 → 位相の急変 → 帯域外輻射」という因果の鎖は、OFDM の PAPR 問題や DPD(ディジタルプリディストーション)の設計にもそのまま効きます
本記事の内容
- なぜ包絡線変動が非線形増幅器で問題になるのか(効率とバックオフのトレードオフ)
- QPSK の複素包絡線が原点を通ることの導出(ルートレイズドコサインの偶対称性を使う)
- オフセット $\Delta = T/2$ が最大位相遷移を $\pm 90°$ に制限することの証明
- PAPR・包絡線ダイナミックレンジ・瞬時周波数による定量比較
- Rapp モデル / Saleh モデルによる非線形 PA のモデル化(AM-AM・AM-PM)
- スペクトル再成長と ACLR の実測 — 「近接チャネルでは効かないが遠方で桁違いに効く」という実像
- AWGN 下の BER が QPSK と厳密に一致することの導出と実測
- MSK / GMSK / $\pi/4$-QPSK との位置づけの整理
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
- QPSK・PSK変調完全ガイド — 位相に情報を載せる仕組みとBERをPythonで
- パルス整形とナイキストフィルタ — ルートレイズドコサインで符号間干渉をなくす
- 電力増幅器のA級・B級・C級・D級とは?導通角と効率を図解で解説
- MSK/GMSK変調 — 連続位相で帯域効率と一定包絡線を両立する
なぜ包絡線変動が問題になるのか
増幅器は「線形」と「効率」を同時に満たせない
まず、話の出発点を押さえておきましょう。ディジタル変調そのものは、増幅器の都合など知りません。QPSK は 2 ビットを 4 つの位相に割り当てる、それだけの話です。にもかかわらず変調方式の設計に増幅器の事情が食い込んでくるのは、送信機の最終段が本質的に非線形だからです。
電力増幅器は、入力が小さいうちは出力が入力に比例します。ところが入力を上げていくと、あるところで出力が頭打ちになる。これが飽和(saturation)です。飽和点まで振り切って使えば、電源から取り出した直流電力のうち高周波に変換される割合(電力付加効率、PAE)は最大になります。A 級の理論効率が 50%、B 級が 78.5% というのは、いずれも「出力が飽和点いっぱいまで振れている」条件での値でした。振幅を半分に絞れば、出力電力は 1/4 になるのに直流消費はさほど減らず、効率は激落ちします。
そこで送信機の設計者はバックオフ(back-off)という量を導入します。入力バックオフ(IBO)は「飽和入力レベルから何 dB 下げて動かすか」を表す量です。
$$ \text{IBO [dB]} = 10\log_{10}\frac{P_{\text{in,sat}}}{P_{\text{in,avg}}} $$
IBO を大きく取れば増幅器は線形領域だけを使うので歪みませんが、効率が落ちます。IBO を小さくすれば効率は上がりますが歪みます。この綱引きが送信機設計の中心にあります。
一定包絡線なら、バックオフは要らない
ここで決定的に重要な観察があります。もし信号の包絡線(瞬時振幅)が一定なら、増幅器がどれだけ非線形でも歪みは生じません。
理由は単純です。非線形増幅器の入出力関係を、入力の複素包絡線 $x(t)$ に対して
$$ y(t) = G(|x(t)|)\, e^{j\left[\arg x(t) + \Phi(|x(t)|)\right]} $$
と書きます。$G(\cdot)$ が振幅変換特性(AM-AM 特性)、$\Phi(\cdot)$ が振幅から位相への変換(AM-PM 特性)です。もし $|x(t)| = A$(一定)なら、$G(A)$ も $\Phi(A)$ も定数になります。すると
$$ y(t) = G(A)\, e^{j\Phi(A)} \cdot e^{j\arg x(t)} $$
つまり出力は入力の位相をそのまま保った、単なる定数倍・定数位相回転にすぎません。歪みはゼロです。増幅器をどれだけ深く飽和させても、スペクトルは一切広がりません。
これが FM 放送や GMSK(GSM)が「一定包絡線変調」を選んだ理由であり、C 級のような極端に非線形な増幅器を平気で使える理由でもあります。逆に言えば、包絡線が変動する瞬間だけが歪みの源です。
変動のうち「谷」が本当の敵
包絡線変動というと、多くの人はまずピークを思い浮かべます。PAPR(Peak-to-Average Power Ratio、ピーク対平均電力比)
$$ \text{PAPR} = \frac{\max_t |s(t)|^2}{\mathbb{E}\left[|s(t)|^2\right]} $$
が大きいほど、平均電力を上げるとピークが飽和点にぶつかってクリップされる、という話です。これは正しい。しかし QPSK と OQPSK を比べるとき、実は PAPR の差はごくわずかです(後で実測しますが、$\beta=0.35$ のルートレイズドコサインで 3.89 dB 対 3.63 dB、たった 0.26 dB)。それでも両者の帯域外輻射は桁で違う。なぜでしょうか。
答えは谷にあります。包絡線が原点に近づくと、複素平面上の軌跡が原点の近傍を通過します。原点のごく近くを通る軌跡は、短時間で位相 $\arg s(t)$ を大きく回します。極端な話、軌跡が原点をぴたりと通れば、その瞬間に位相は $180°$ 不連続に飛びます。
そして増幅器の AM-AM 特性は、振幅の絶対値を圧縮こそすれ、位相は保存します(AM-PM がなければ)。つまり、包絡線の谷で起きた位相の急変は、増幅器を通しても消えません。それどころか、谷では振幅が小さいので AM-AM の圧縮によって相対的に持ち上げられ、位相の急変が全振幅で送信されてしまいます。位相の不連続は周波数領域では無限の広がりを持つ成分です。これがスペクトル再成長(spectral regrowth)の正体です。

この 3 段のグラフが「谷 → 位相の急変 → 帯域外輻射」という因果の鎖をそのまま見せています。上段で包絡線が実効値の $0.0036$ 倍まで落ち込んだ瞬間(赤い破線)に、中段では位相が $+51°$ から $-122°$ へ一気に反転しています(孤立した対角遷移での理想値 $+45° \to -135°$ に近い値です)。決定的なのは下段で、増幅前の波形(灰色の点線)は谷でなめらかにゼロを横切るだけなのに、理想リミッタを通した波形(赤)は同じ時刻で $+0.83$ から $-0.53$ へ垂直に跳んでいます。振幅がゼロだったから無害だった位相の急変が、振幅を持たされた瞬間に不連続に化けているわけです。
ここまでで「包絡線の谷こそが帯域外輻射の源だ」という筋道が見えました。では、QPSK の包絡線は本当に原点まで落ちるのでしょうか。次はそれを式で確かめます。
QPSK の複素包絡線はなぜ原点を通るのか
送信信号の一般形
QPSK と OQPSK を同じ枠組みで扱うために、複素包絡線を次の形で書きます。
$$ \begin{equation} s(t) = \sum_{k} a_k\, g(t – kT) \; + \; j \sum_{k} b_k\, g(t – kT – \Delta) \end{equation} $$
ここで各記号の意味は次の通りです。
- $a_k, b_k \in \{+1, -1\}$: 第 $k$ シンボルの I 側・Q 側のデータ(各 1 ビット、合計 2 ビット/シンボル)
- $T$: シンボル周期。シンボルレートは $R_s = 1/T$
- $g(t)$: パルス整形フィルタのインパルス応答。ここではロールオフ率 $\beta$ のルートレイズドコサイン(RRC)を使います
- $\Delta$: I 系列に対する Q 系列の時間オフセット
この $\Delta$ ただ一つが、QPSK と OQPSK を分ける唯一のパラメータです。
$$ \Delta = 0 \;\Rightarrow\; \text{QPSK}, \qquad \Delta = \frac{T}{2} \;\Rightarrow\; \text{OQPSK} $$
拍子抜けするほど小さな違いですが、この後見るように帰結は大きい。
ルートレイズドコサインの性質を確認しておく
導出に入る前に、$g(t)$ について 2 点だけ確認します。
第一に、RRC は実の偶関数です。$g(-t) = g(t)$ が成り立ちます。これは RRC の周波数応答 $\sqrt{H_{\text{RC}}(f)}$ が実の偶関数だからで、その逆フーリエ変換は必ず実偶関数になります。この偶対称性が、これから示す「原点通過」の鍵になります。
第二に、RRC 単体はナイキスト条件を満たしません。よくある誤解なのでここで潰しておきます。符号間干渉(ISI)がゼロになるナイキスト条件 $p(kT) = \delta_{k0}$ を満たすのはレイズドコサイン $p = g * g$ のほうであって、その平方根である RRC ではありません。実際、$\beta = 0.35$ の RRC を $g(0) = 1$ に正規化すると
$$ g(0) = 1, \quad g(T/2) = 0.5547, \quad g(T) = -0.0773, \quad g(2T) = 0.0521 $$
となり、$g(T)$ はゼロではなく $-0.0773$ です。送受で RRC を縦続して初めて $p(T) = 0$ になります。この $g(T) \ne 0$ という事実は、後で OQPSK の包絡線下限を評価するときに効いてきます。

左のグラフで、青の RRC と赤破線の RC は中央付近こそ似た形をしていますが、シンボル点 $t = \pm T, \pm 2T, \dots$ での振る舞いが決定的に違います。赤の四角(RC)は $t=0$ 以外すべて軸上にぴたりと乗っているのに対し、青の丸(RRC)は $t=T$ で $-0.077$、$t=2T$ で $+0.052$ と、はっきりゼロから外れています。右の棒グラフはこれを数値で並べたもので、RC 側の棒は $k=0$ 以外まったく見えません。ISI をゼロにするのはあくまで送受を縦続した後の RC であって、送信側の RRC 単体ではない、という区別がここで目に見える形になります。
対角遷移で原点を通ることの導出
QPSK のコンステレーションは複素平面上の 4 点 $(\pm 1 \pm j)/\sqrt{2}$ です。あるシンボルから次のシンボルへの遷移は 3 種類あります。
- 同じ点に留まる($a$ も $b$ も変わらない): 位相変化 $0°$
- 隣の点へ移る($a$ か $b$ の片方だけ反転): 位相変化 $\pm 90°$
- 対角の点へ移る($a$ と $b$ の両方が反転): 位相変化 $180°$
問題は 3 番目、対角遷移です。ランダムデータなら $a$ と $b$ が独立に反転するので、対角遷移は 1/4 の確率で起こります。
これがなぜ原点通過を生むのかを、いちばんきれいに見える設定 — 孤立した対角遷移 — で示します。$k=0$ と $k=1$ の 2 シンボルだけを考え、
$$ a_0 = +1,\quad a_1 = -1,\qquad b_0 = +1,\quad b_1 = -1 $$
とし、それ以外のシンボルはゼロとします(実際には隣接シンボルがありますが、まず本質を見ます)。$\Delta = 0$ を式 (1) に代入すると、I 成分と Q 成分はそれぞれ次のようになります。
$$ I(t) = g(t) – g(t – T) $$
Q 側もまったく同じ係数列なので、
$$ Q(t) = g(t) – g(t – T) = I(t) $$
つまりこの遷移では $I(t)$ と $Q(t)$ が完全に同一の波形になります。したがって軌跡は複素平面上の直線 $\mathrm{Im} = \mathrm{Re}$ の上だけを動きます。これが「対角遷移」という名前の幾何学的な意味です。
ここで遷移のちょうど中間時刻 $t = T/2$ を代入してみます。第 2 項の引数は $T/2 – T = -T/2$ になるので、
$$ I\!\left(\frac{T}{2}\right) = g\!\left(\frac{T}{2}\right) – g\!\left(-\frac{T}{2}\right) $$
ここで先ほど確認した偶対称性 $g(-t) = g(t)$ を使うと、右辺の第 2 項は $g(T/2)$ に等しくなります。したがって
$$ I\!\left(\frac{T}{2}\right) = g\!\left(\frac{T}{2}\right) – g\!\left(\frac{T}{2}\right) = 0 $$
$Q(t) = I(t)$ でしたから $Q(T/2) = 0$ も同時に成り立ちます。よって
$$ \begin{equation} s\!\left(\frac{T}{2}\right) = 0 + j\cdot 0 = 0 \end{equation} $$
複素包絡線は厳密に原点を通ります。 使ったのは「$g$ が偶関数であること」ただ一つで、ロールオフ率にもフィルタの詳細にもよりません。ナイキスト条件を満たす偶対称パルスなら何を使っても同じ結論になります。これは QPSK という変調の構造そのものに由来する性質なのです。

左のグラフでは $I(t)$(赤)と $Q(t)$(青破線)が完全に重なっており、$Q(t) = I(t)$ という上の式がそのまま絵になっています。両者は $t = T/2$ で同時に軸を横切ります。中央の包絡線 $|s(t)|$ はその時刻で鋭くゼロまで刺さり、右の軌跡は $45°$ 方向の直線として原点を貫いています。ここで効いているのは $g$ の偶対称性だけなので、ロールオフ率を変えても、パルスを別のナイキストフィルタに替えても、この 3 枚の絵は形を変えません。
位相はそこで 180 度飛ぶ
原点通過の何がまずいのか、位相の側から見てみましょう。$t < T/2$ では $I(t) = Q(t) > 0$ なので $\arg s(t) = 45°$、$t > T/2$ では $I(t) = Q(t) < 0$ なので $\arg s(t) = -135°$(つまり $225°$)です。$t = T/2$ を境に位相が $180°$ 跳びます。
位相が有限時間で $180°$ 変わること自体は珍しくありません。まずいのは、それが振幅ゼロの点で起きることです。振幅がゼロなら、そこで位相がどう飛ぼうと元の信号 $s(t)$ は連続なので何も起きません($0 \cdot e^{j\theta} = 0$ でどんな $\theta$ でも同じ)。ところが増幅器を飽和させると振幅が持ち上がり、この位相の不連続が振幅を伴って現れてしまう。極限として理想リミッタ $y(t) = e^{j\arg s(t)}$ を考えれば、出力は $t = T/2$ でジャンプする不連続関数です。不連続関数のスペクトルは $1/f^2$ でしか減衰しません。丁寧に $1.35/T$ に絞ったはずのスペクトルが台無しになる理由がこれです。
ランダムデータでの実像 — 「厳密にゼロ」ではないが「いくらでも近い」
ここで正確を期しておきます。実際の通信ではシンボル列はランダムで、注目する 2 シンボルの周りにも符号が並んでいます。それらのテールが $t=T/2$ における $I$ と $Q$ をわずかにずらすので、対角遷移が起きるたびに毎回きれいに $s = 0$ になるわけではありません。
しかしこれは何の慰めにもなりません。重要なのは包絡線に下限が存在しないことです。$\beta = 0.35$、30,000 シンボルのランダムデータで実測すると、包絡線の最小値は $A_{\text{rms}}$ の $10^{-17}$ 倍 — 倍精度演算の丸め誤差そのもののレベルまで落ち、ゼロと区別がつきません。分位点で見ても、$0.01\%$ 点で $0.0040 A_{\text{rms}}$($-48$ dB)、$1\%$ 点で $0.135 A_{\text{rms}}$。振幅が $0.3 A_{\text{rms}}$ を下回る時間の割合は 4.07%、$0.1 A_{\text{rms}}$ を下回る時間でも 0.695% にもなります。包絡線ダイナミックレンジ(最大 / 最小)には実質的に上限がなく、観測を長くすればいくらでも大きくなります。「原点を通る」というのは、正確には「原点にいくらでも近づく、下限が存在しない」という意味だと理解してください。
QPSK の病理が特定できました。$a_k$ と $b_k$ が同時に反転できることが原因です。ならば同時に反転できなくしてやればよい — これが OQPSK の発想です。
OQPSK — 半シンボルずらすという処方箋
アイデア
OQPSK がやることは、式 (1) で $\Delta = T/2$ と置くこと、それだけです。
$$ \begin{equation} s_{\text{OQPSK}}(t) = \sum_{k} a_k\, g(t – kT) \; + \; j \sum_{k} b_k\, g\!\left(t – kT – \frac{T}{2}\right) \end{equation} $$
送信機の実装で言えば、I 系列と Q 系列を作ったあと、Q 側の DAC に入るデータを半シンボル分だけ遅延させるだけです。追加のハードウェアはシフトレジスタ 1 段。符号化も何も変わりません。
比喩で言えば、二人三脚で両足を同時に出そうとして転んでいたのを、片足ずつ交互に出すように変えた、という話です。片足ずつなら重心が地面から浮く瞬間がありません。
最大位相遷移が 90 度になることの証明
まず、理想的な矩形パルス(NRZ)の場合で、位相がどう動くかを厳密に押さえます。パルス整形を入れると波形は滑らかになりますが、位相の「行き先」の系列は変わらないので、この解析が骨格になります。
QPSK の場合($\Delta = 0$)。区間 $[kT, (k+1)T)$ で送信される信号点は $a_k + j b_k$ です。次の区間では $a_{k+1} + j b_{k+1}$。$a$ と $b$ が独立に反転するので、位相差 $\Delta\phi$ の分布は
| 遷移の種類 | $\Delta\phi$ | 確率 |
|---|---|---|
| どちらも変化なし | $0°$ | $1/4$ |
| 片方だけ反転 | $\pm 90°$ | $1/2$ |
| 両方反転(対角) | $180°$ | $1/4$ |
OQPSK の場合($\Delta = T/2$)。ここが本質です。I 系列の切り替わり時刻は $t = kT$、Q 系列の切り替わり時刻は $t = kT + T/2$ です。両者は決して一致しません。したがって時間軸を半シンボル $T/2$ 刻みに区切ると、各区間で送信される信号点は
$$ \cdots \to (a_k, b_{k-1}) \to (a_k, b_k) \to (a_{k+1}, b_k) \to (a_{k+1}, b_{k+1}) \to \cdots $$
という順に並びます。隣り合う項では、必ず 2 つの座標のうち片方しか変わりません。 変わる側は $\pm 1$ から $\mp 1$ に反転するか、そのままか。よって位相差は
| 遷移の種類 | $\Delta\phi$ | 確率 |
|---|---|---|
| 変化なし | $0°$ | $1/2$ |
| 片方の座標が反転 | $\pm 90°$ | $1/2$ |
対角遷移($180°$)は構造的に起こり得ません。$a$ と $b$ の切り替わり時刻がずれている以上、同じ瞬間に両方が反転することが不可能だからです。20 万シンボルのランダムデータで数値確認すると、位相ステップは $0°$ が 50.1%、$90°$ が 49.9%、最大値はちょうど $90.0°$ でした。理論通りです。
幾何学的に言えば、QPSK の信号点は正方形の対角線を横切って移動できるのに対し、OQPSK は正方形の辺に沿ってしか移動できない、ということです。対角線は原点を通りますが、辺は通りません。

左と中央の遷移図が、いま述べた「対角線か辺か」の違いそのものです。QPSK では赤い対角矢印が原点(黒い $\times$)の上で交差しているのに対し、OQPSK の矢印は正方形の辺だけをたどり、中央部には一切入り込みません。右の棒グラフは 20 万シンボルの実測で、QPSK は $0°$ が 25.2%、$90°$ が 49.9%、$180°$ が 24.9% と理論の $1/4 : 1/2 : 1/4$ に一致し、OQPSK は $0°$ が 50.1%、$90°$ が 49.9%、そして $180°$ がちょうど 0.0% です。「起こりにくい」のではなく「構造上起こり得ない」ことが、この 0.0% に表れています。
包絡線の下限を評価する
$180°$ 遷移がなくなったのだから原点は通らないはずですが、それを式で確認しましょう。先ほどと同じ孤立対角データ $a_0 = b_0 = +1$, $a_1 = b_1 = -1$ を、今度は $\Delta = T/2$ で流します。I 成分は変わりません。
$$ I(t) = g(t) – g(t-T) $$
Q 成分は全体が $T/2$ 遅れるので、
$$ Q(t) = g\!\left(t – \frac{T}{2}\right) – g\!\left(t – \frac{3T}{2}\right) $$
$t = T/2$(I が原点を通る時刻)を代入します。第 1 項の引数は $T/2 – T/2 = 0$、第 2 項の引数は $T/2 – 3T/2 = -T$ になるので、
$$ Q\!\left(\frac{T}{2}\right) = g(0) – g(-T) = g(0) – g(T) $$
最後の等号で再び偶対称性を使いました。ここに先ほどの RRC の値 $g(0) = 1$, $g(T) = -0.0773$ を代入すると、
$$ Q\!\left(\frac{T}{2}\right) = 1 – (-0.0773) = 1.0773 $$
$I(T/2) = 0$ は変わらないので、
$$ \left|s\!\left(\frac{T}{2}\right)\right| = \left|0 + j\,1.0773\right| = 1.0773 $$
I がゼロを通るまさにその瞬間、Q はほぼ最大値を取っています。 これは偶然ではありません。$\Delta = T/2$ という選び方は、I の零交差時刻($T/2$ ずれた位置)と Q のパルス頂点時刻をわざと一致させるものだからです。オフセットを $T/2$ にする理由がここにあります。$\Delta$ が 0 に近ければ QPSK に戻り、$T$ に近ければやはり同時反転が復活する。二つの零交差を最も遠ざける値がちょうど中間の $T/2$ なのです。
数値でも確認できます。この孤立遷移の区間($-T/2 \le t \le 3T/2$)で $|s(t)|$ の最小値は最大値の $0.535$ 倍にとどまり、$t=T/2$ では $0.835$ 倍もあります。QPSK が $0.000$ だったのと対照的です。
ランダムデータ 30,000 シンボルでは、OQPSK の包絡線の下限は $0.4264\, A_{\text{rms}}$ でした。これは統計的なゆらぎで下に伸びる裾ではなく、明確な床です。最小 5 サンプルを並べても $0.4264, 0.4301, 0.4336, 0.4343, 0.4347$ とほぼ同じ値に張り付いており、下限が構造的に決まっていることがわかります。$0.3 A_{\text{rms}}$ を下回る時間は 0.000%、$0.5 A_{\text{rms}}$ を下回る時間でも 0.226% しかありません(QPSK はそれぞれ 4.07%、7.74%)。

左のグラフが、いま式で追った状況の絵です。$I(t)$(赤)が $t=T/2$ でゼロを横切るまさにその時刻に、$Q(t)$(青破線)は頂点付近の $1.0773$ にいます。結果として包絡線(橙)はその時刻でも $1.07$ 付近の高さを保ち、区間全体でも最大値の $0.535$ 倍までしか下がりません。右のグラフは 30,000 シンボルの実測で、横軸のしきい値を下げていったときに各方式の曲線がどこで途切れるかを見たものです。QPSK(赤)は左端まで曲線が伸び続けて下限を持たないのに対し、OQPSK(青)は $0.4264$ で、$\pi/4$-QPSK(緑)は $0.1417$ で垂直に切れています。この「切れる位置」こそが非線形増幅器での振る舞いを決める量です。
包絡線ダイナミックレンジ(最大 / 最小)で比較すると、
$$ \text{QPSK}: \; \infty \quad \text{(下限なし)}, \qquad \text{OQPSK}: \; \frac{1}{0.4264} \times \frac{A_{\max}}{A_{\text{rms}}} = 3.56 \;\;(11.0\ \text{dB}) $$
無限大と 11 dB。これが OQPSK の本当の利得です。
瞬時周波数で見ると差が一目瞭然
包絡線の谷が位相の急変を生む、という因果を直接測る量が瞬時周波数です。
$$ f_{\text{inst}}(t) = \frac{1}{2\pi}\frac{d}{dt}\arg s(t) $$
軌跡が原点の近くを通るほど、同じ距離を動くのに大きな角度を掃くので、この値は跳ね上がります。$\beta = 0.35$、64 倍オーバーサンプリングで実測した最大値をシンボルレート $R_s$ で正規化すると、
| 方式 | $\max\lvert f_{\text{inst}}\rvert / R_s$ | 99.9% 点 | rms |
|---|---|---|---|
| QPSK | 31.93 | 12.30 | 0.873 |
| OQPSK | 1.08 | 0.92 | 0.332 |
| $\pi/4$-QPSK | 3.07 | 2.06 | 0.391 |
QPSK の $31.93$ という値には意味がありません — これはサンプリング間隔で決まる数字で、オーバーサンプリング率を上げればいくらでも大きくなります(原点通過では真に発散します)。重要なのは OQPSK が $1.08 R_s$ という有限の上限を持つことです。信号の瞬時周波数が信号帯域と同程度に収まっているのだから、リミッタに通しても帯域はほとんど広がらない。この一つの数字が、これから見るスペクトルの結果をすべて予告しています。
ここまでで、OQPSK が包絡線の谷を消す仕組みを幾何・代数・瞬時周波数の三方向から確認しました。次は「では PAPR はどれだけ改善するのか」を測ります。答えは、期待するほどではありません。
PAPR と包絡線分布の定量比較
PAPR の差はごくわずか
PAPR は瞬時電力の最大値と平均値の比です。実測結果を並べます(RRC $\beta=0.35$、16 倍オーバーサンプリング、30,000 シンボル)。
| 方式 | PAPR(最大) | PAPR@0.1% | $A_{\min}/A_{\text{rms}}$ | ダイナミックレンジ |
|---|---|---|---|---|
| QPSK | 3.89 dB | 3.56 dB | $\approx 0$ | $\infty$ |
| OQPSK | 3.63 dB | 3.26 dB | 0.4264 | 11.0 dB |
| $\pi/4$-QPSK | 3.19 dB | 2.97 dB | 0.1417 | 20.2 dB |
QPSK と OQPSK の PAPR 差は 0.26 dB。CCDF の 0.1% 点で見ても 0.30 dB です。「OQPSK は PAPR が低いから増幅器に優しい」という説明をよく見かけますが、少なくとも RRC 整形の QPSK/OQPSK に関して言えば、その説明はほとんど間違いです。0.26 dB のバックオフ削減では、TWTA の効率はせいぜい数 % しか変わりません。
なぜ差が小さいのでしょうか。PAPR のピークを作るのは、同符号のシンボルが連続して RRC のテールが同相で足し合わさる場面です。この現象は I と Q を半シンボルずらしても変わりません。オフセットが効くのは「I と Q が同時に反転する」ケースだけであり、それは谷を作るメカニズムであって山を作るメカニズムではないのです。
効いているのは分布の下側
一方、包絡線の分布の下側を見ると景色が一変します。振幅がしきい値を下回る時間の割合を測ると次のようになります。
| しきい値 | QPSK | OQPSK | $\pi/4$-QPSK |
|---|---|---|---|
| $A < 0.5\,A_{\text{rms}}$ | 7.74% | 0.226% | 6.54% |
| $A < 0.3\,A_{\text{rms}}$ | 4.07% | 0.000% | 0.87% |
| $A < 0.1\,A_{\text{rms}}$ | 0.695% | 0.000% | 0.000% |
QPSK は全時間の 4% で振幅が 0.3 倍を切り、0.7% では 0.1 倍すら切っています。OQPSK は 0.3 倍を一度も切りません。
$\pi/4$-QPSK が中間の性質を示しているのも興味深い点です。$\pi/4$-QPSK は毎シンボル コンステレーションを $45°$ 回転させることで位相変化を $\{\pm 45°, \pm 135°\}$ に制限する方式で、$180°$ 遷移は起きません。しかし $135°$ 遷移は依然として原点の「そこそこ近く」を通るため、下限は $0.14 A_{\text{rms}}$(ダイナミックレンジ 20.2 dB)にとどまります。OQPSK の $0.43$(11.0 dB)には及びません。
「$180°$ を消す」だけでなく「$90°$ まで下げる」ことが効いている、というのがこの表の読み方です。
PAPR という指標の限界
ここから引き出すべき教訓は、PAPR は包絡線変動の一面しか測っていないということです。PAPR は分布の上側の裾しか見ません。非線形増幅器に対する信号の「たちの悪さ」を測るなら、下側の裾、あるいは包絡線ダイナミックレンジ、さらに言えば瞬時周波数の広がりを見るべきです。
OFDM の PAPR 低減が難しい問題として語られるのは、OFDM の包絡線がレイリー分布に近く上下ともに大きく振れるからで、そちらでは PAPR が主指標として妥当です。しかし QPSK 系の比較では PAPR だけを見ると本質を見誤ります。
包絡線の統計がわかったところで、次はそれを実際に非線形増幅器へ通したときに何が起きるかを見ます。まず増幅器のモデルを用意しましょう。
非線形増幅器のモデル化
Rapp モデル(固体増幅器向け)
固体電力増幅器(SSPA)の AM-AM 特性としてよく使われるのが Rapp モデルです。
$$ \begin{equation} G(r) = \frac{r}{\left[1 + \left(\dfrac{r}{A_{\text{sat}}}\right)^{2p}\right]^{1/(2p)}} \end{equation} $$
$r = |x(t)|$ が入力振幅、$A_{\text{sat}}$ が飽和振幅、$p > 0$ が平滑度パラメータです。この式の振る舞いを両極限で確認しておきます。
$r \ll A_{\text{sat}}$ のとき、分母の括弧内は $1$ に近いので $G(r) \approx r$、すなわち線形です。$r \gg A_{\text{sat}}$ のときは括弧内で $(r/A_{\text{sat}})^{2p}$ が支配的になるので、
$$ G(r) \approx \frac{r}{\left[(r/A_{\text{sat}})^{2p}\right]^{1/(2p)}} = \frac{r}{r/A_{\text{sat}}} = A_{\text{sat}} $$
きれいに飽和します。$p$ を大きくすると遷移が鋭くなり、$p \to \infty$ で理想リミッタ $G(r) = \min(r, A_{\text{sat}})$ に一致します。実測の SSPA は $p = 2 \sim 3$ 程度です。Rapp モデルは AM-PM を含まない($\Phi \equiv 0$)ので、純粋に振幅圧縮だけの効果を切り分けて見るのに適しています。
Saleh モデル(進行波管増幅器向け)
TWTA は AM-PM が無視できません。標準的なのが Saleh モデルです。
$$ G(r) = \frac{\alpha_a r}{1 + \beta_a r^2}, \qquad \Phi(r) = \frac{\alpha_\phi r^2}{1 + \beta_\phi r^2} $$
AM-AM のほうは $r$ が大きくなると $G(r) \to \alpha_a/(\beta_a r) \to 0$ と、飽和を過ぎてむしろ落ちる(オーバードライブ)という TWTA の実態を再現します。飽和点は $dG/dr = 0$ から $r_{\text{sat}} = 1/\sqrt{\beta_a}$ です。AM-PM のほうは、振幅が上がるほど位相が回る特性を表します。$\Phi(r)$ は $r^2$ に比例して立ち上がり、大振幅で $\alpha_\phi/\beta_\phi$ に飽和します。
AM-PM が入ると話がややこしくなります。振幅の変動がそのまま位相雑音に変換されるため、包絡線変動が大きい信号ほど位相が汚れるからです。ここでも包絡線が一定であれば AM-PM は定数位相回転にすぎず、無害です。
バックオフの定義
以降のシミュレーションでは、入力バックオフ IBO を「入力信号の rms 振幅を飽和振幅から何 dB 下げるか」で定義します。
$$ x_{\text{in}}(t) = \frac{A_{\text{sat}}\, 10^{-\text{IBO}/20}}{A_{\text{rms}}}\; s(t) $$
IBO $= 0$ dB は「rms がちょうど飽和点」という、かなり深く飽和させた条件です。PAPR が 3.6 dB あるので、ピークは飽和点を 3.6 dB 超えて激しくクリップされます。IBO $= 6$ dB ならピークがようやく飽和点に届く程度で、ほぼ線形動作です。
モデルが揃いました。いよいよ本題 — 飽和増幅器を通したときのスペクトルを比べます。
スペクトル再成長と ACLR の実測
何を測るか
隣接チャネル漏洩電力比(ACLR、または ACPR)を次のように定義します。主チャネル帯域幅を占有帯域 $B = (1+\beta)/T = 1.35/T$ とし、チャネル間隔も $B$ とします。
$$ \text{ACLR}_n = 10\log_{10} \frac{\displaystyle\int_{-B/2}^{B/2} S(f)\, df}{\displaystyle\int_{nB – B/2}^{nB + B/2} S(f)\, df} $$
$n = 1$ が第 1 隣接(直近の隣)、$n=2, 3$ が第 2・第 3 隣接です。値が大きいほど漏れが少なく良好です。
なお、この種のシミュレーションはオーバーサンプリング率が足りないと結果が完全に嘘になります。飽和増幅器は帯域を数倍に広げるので、16 倍程度のサンプリングでは広がった成分がエイリアシングで折り返して主チャネルや隣接チャネルに混入し、方式間の差が消えてしまいます。以下では 64 倍オーバーサンプリングを使っています。
理想リミッタ極限 — 最も差が出る条件
まず、理論の予測が最も鮮明に出る極限、理想リミッタ $y(t) = e^{j\arg s(t)}$ を見ます。振幅情報を完全に捨て、位相だけを一定振幅で送る操作です。
| 方式 | ACLR$_1$ | ACLR$_2$ | ACLR$_3$ | $6R_s$ での PSD | 99% 帯域幅 |
|---|---|---|---|---|---|
| (線形時) | 50.2 dB | 69.3 dB | 73.3 dB | — | $1.17/T$ |
| QPSK | 16.6 dB | 23.3 dB | 28.3 dB | $-34.7$ dBc | $\mathbf{5.19/T}$ |
| OQPSK | 19.2 dB | 39.4 dB | 56.2 dB | $\mathbf{-81.3}$ dBc | $\mathbf{1.81/T}$ |
| $\pi/4$-QPSK | 17.3 dB | 28.7 dB | 38.5 dB | $-53.1$ dBc | $2.78/T$ |
99% 帯域幅に注目してください。線形時は 3 方式とも $1.17/T$ です。リミッタを通すと、QPSK は $5.19/T$ に膨れ上がります。4.4 倍。パルス整形フィルタの努力が完全に無効化されたことを意味します。一方 OQPSK は $1.81/T$ で、1.5 倍にとどまっています。
第 3 隣接チャネルでは QPSK の 28.3 dB に対し OQPSK は 56.2 dB。差は 27.9 dB、およそ 600 倍です。$6R_s$ 離れた地点の PSD で見れば $-34.7$ dBc 対 $-81.3$ dBc で、差は 46.6 dB。これが「包絡線の谷が位相の不連続を生み、リミッタがそれを増幅する」というメカニズムの、そのままの帰結です。
$\pi/4$-QPSK が両者の中間に位置しているのも予想通りです。$135°$ 遷移は $180°$ よりましだが $90°$ には及ばない — 包絡線下限 $0.14$、瞬時周波数最大 $3.07 R_s$ という中間的な数字が、そのままスペクトルの中間的な位置に反映されています。包絡線下限・瞬時周波数・帯域外輻射の 3 つが、きれいに同じ順序で並ぶことに注目してください。因果の鎖が実測で追えたことになります。
現実的な増幅器(Rapp モデル)— ここで意外な事実が出る
理想リミッタは極端な条件です。実際の SSPA($p=3$)でバックオフを振ってみます。
| 条件 | QPSK (ACLR$_1$/$_2$/$_3$) | OQPSK (ACLR$_1$/$_2$/$_3$) |
|---|---|---|
| 線形 | 50.2 / 69.3 / 73.3 | 50.2 / 69.3 / 73.3 |
| IBO = 0 dB | 26.8 / 49.8 / 63.0 | 26.2 / 54.6 / 70.9 |
| IBO = 1 dB | 29.6 / 50.4 / 67.5 | 28.9 / 57.0 / 73.0 |
| IBO = 3 dB | 37.1 / 55.3 / 73.6 | 36.2 / 61.8 / 73.7 |
| IBO = 6 dB | 48.4 / 66.7 / 73.5 | 48.1 / 68.3 / 73.4 |
ここで、多くの解説書が触れない事実がはっきり出ます。
第 1 隣接チャネルでは、OQPSK に利得がありません。 それどころか一貫して 0.3〜0.9 dB ほど QPSK に劣っています。第 2 隣接では逆転して OQPSK が有利になり、IBO $= 0 \sim 3$ dB では 4.8〜6.6 dB の差がつきます(IBO $= 6$ dB まで戻すと差は 1.6 dB に縮みますが、そもそもそこでは再成長自体が小さくなっています)。第 3 隣接では IBO $= 0$ dB で 7.9 dB 有利です(IBO を上げると両者とも 73 dB 台の測定の底に張り付きます)。
なぜこうなるのか、これまでの議論から説明できます。第 1 隣接チャネルの再成長は、主にピークのクリッピングで生じる 3 次相互変調積によるものです。ピークの統計は QPSK と OQPSK でほぼ同じ(PAPR 差 0.26 dB)ですから、差が出ないのは当然です。むしろ OQPSK は I/Q のずれによってピーク近傍の波形がわずかに広がるため、ごく僅かに不利になることさえある。
一方、第 2・第 3 隣接以遠の遠方スプラッタは、包絡線の谷での位相急変が生む成分です。ここは QPSK だけが持つ病理なので、OQPSK が圧勝します。
この切り分けを、必要バックオフという実務的な形に翻訳してみましょう。Rapp $p=3$ で目標を満たす最小の IBO を探索すると、
- 第 2 隣接 ACLR $\ge$ 55 dB: QPSK は IBO $= 3.00$ dB 必要、OQPSK は IBO $= 0.25$ dB で足りる → 2.75 dB のバックオフ削減
- 第 1 隣接 ACLR $\ge$ 45 dB: QPSK は IBO $= 5.00$ dB、OQPSK は IBO $= 5.25$ dB → 削減なし(むしろ 0.25 dB 悪化)
つまり、OQPSK が効くかどうかは、そのシステムの周波数調整上のボトルネックがどこにあるかで決まります。 遠方スプラッタや広帯域スプリアスの規定が厳しいシステム(衛星系のように、離れた周波数の別サービスを保護しなければならない場合や、深く飽和させた増幅器を使う場合)では 2〜3 dB のバックオフを稼げます。第 1 隣接だけが問題で、かつ増幅器を線形寄りに使うシステムでは、OQPSK に切り替えても得るものはありません。
2.75 dB のバックオフ削減は、増幅器の出力電力に直せば約 1.9 倍です。衛星の中継器 1 台あたりでこれが効くなら、設計への影響は決して小さくありません。
AM-PM がある場合(Saleh モデル)
AM-PM を含む TWTA(Saleh モデル)でも傾向は同じですが、絶対値は全体に悪化します。IBO $= 0$ dB での第 1 隣接 ACLR は QPSK 18.8 dB、OQPSK 19.3 dB。AM-PM が振幅変動を位相雑音に変換するぶん、Rapp モデル(26 dB 台)より 8 dB ほど悪くなっています。ここでも第 1 隣接での差はほとんどありません(0.5 dB)。
一方、第 2 隣接では QPSK 34.2 dB に対し OQPSK 44.5 dB(10.3 dB 差)、第 3 隣接では 46.0 dB 対 66.3 dB(20.3 dB 差)と、Rapp モデルのときよりむしろ差が開きます。AM-PM は包絡線の谷での位相急変に、さらに振幅起因の位相回転を上乗せするので、谷を持つ QPSK がより強く罰せられるためです。
AM-PM に対する本質的な対策は「包絡線を一定にする」ことであり、$0.43 A_{\text{rms}}$ の床を作る OQPSK は完全な解ではありません。完全な解が欲しければ、次に述べる MSK/GMSK まで行く必要があります。
スペクトルの話が終わりました。ここで当然の疑問が湧きます — これだけ波形をいじって、受信性能は劣化しないのでしょうか。
BER は QPSK と厳密に同じ
なぜ変わらないのか
結論から言うと、AWGN 通信路で整合フィルタ受信する限り、OQPSK の BER は QPSK と完全に同一です。
$$ \begin{equation} P_b = Q\!\left(\sqrt{\frac{2E_b}{N_0}}\right) \end{equation} $$
理由は、QPSK も OQPSK も I 系列と Q 系列が完全に独立した 2 本の BPSK であるという構造を共有しているからです。
順に確認します。受信信号を $r(t) = s(t) + n(t)$($n$ は複素白色ガウス雑音、片側電力密度 $N_0$)とします。受信機は実部・虚部それぞれに整合フィルタ $g(-t) = g(t)$ を通し、
$$ y_I(t) = \left[\mathrm{Re}\, r\right] * g\,(t), \qquad y_Q(t) = \left[\mathrm{Im}\, r\right] * g\,(t) $$
を作ります。$p = g * g$ はレイズドコサインなのでナイキスト条件 $p(kT) = \delta_{k0}$ を満たします。したがって $t = kT$ で $y_I$ を標本化すると、
$$ y_I(kT) = a_k \cdot p(0) + n_I(kT) = a_k + n_I(kT) $$
他のシンボルからの寄与は $p(mT) = 0$ ($m \ne 0$) で消えます。Q 側は標本化時刻が $T/2$ ずれるだけで、
$$ y_Q\!\left(kT + \frac{T}{2}\right) = b_k + n_Q\!\left(kT + \frac{T}{2}\right) $$
判定に使う 2 つの標本値の形が、QPSK とまったく同じになりました。違うのは Q 側を読み取る時刻だけです。
ここで押さえるべきポイントが 2 つあります。第一に、$g$ は実関数なので、実部の雑音は $y_I$ に、虚部の雑音は $y_Q$ にしか影響しません。I と Q は独立です。第二に、白色雑音を整合フィルタに通した出力の相関関数は $R(\tau) = \frac{N_0}{2} p(\tau)$ であり、$p$ がナイキストなので $R(kT) = 0$($k \ne 0$)— 異なる標本時刻の雑音は無相関です。$T/2$ ずらして標本化しても、その時刻での雑音分散は $\frac{N_0}{2}p(0) = \frac{N_0}{2}$ で変わりません。
つまり OQPSK の I/Q オフセットは、受信側から見れば「Q 側を読むタイミングが $T/2$ 遅い」以外の意味を持たないのです。エネルギーも雑音分散も一切変化しません。あとは通常の BPSK と同じで、$a_k = \pm 1$、雑音分散 $\sigma^2 = N_0/2$(1 シンボルあたりのエネルギー $E_s = 2E_b$、I 側の成分エネルギーは $E_b$)から誤り確率は式 (5) になります。
ちなみにこれは「タダで得をした」わけではありません。OQPSK はシンボルレートも占有帯域も QPSK と同一です。得たのは包絡線特性だけで、帯域効率も電力効率も変えていない。だからこそ「使わない理由がない」変調方式なのです。
実測で確認する
400,000 シンボル、RRC 整合フィルタ、$\beta = 0.35$ で実測した結果です。
| $E_b/N_0$ | QPSK | OQPSK | 理論値 $Q(\sqrt{2E_b/N_0})$ |
|---|---|---|---|
| 0 dB | $7.894\times 10^{-2}$ | $7.887\times 10^{-2}$ | $7.865\times 10^{-2}$ |
| 2 dB | $3.766\times 10^{-2}$ | $3.761\times 10^{-2}$ | $3.751\times 10^{-2}$ |
| 4 dB | $1.248\times 10^{-2}$ | $1.247\times 10^{-2}$ | $1.250\times 10^{-2}$ |
| 6 dB | $2.419\times 10^{-3}$ | $2.476\times 10^{-3}$ | $2.388\times 10^{-3}$ |
| 8 dB | $1.775\times 10^{-4}$ | $1.900\times 10^{-4}$ | $1.909\times 10^{-4}$ |
3 列が有効数字 2〜3 桁で一致しています。高 $E_b/N_0$ でのばらつきは誤り数が少ないことによる統計誤差です(8 dB で誤り約 150 個)。理論の予測通り、OQPSK に BER のペナルティはありません。
ただし復調側には注意点がある
BER は同じでも、受信機の実装にはいくつか差があります。
タイミング同期: Q 側を $T/2$ ずらして標本化する必要があるため、シンボルタイミング再生アルゴリズムは OQPSK 対応のものを使わなければなりません。Gardner 法など一部の TED(Timing Error Detector)は OQPSK 向けの変形が必要です。
差動復調・搬送波再生: OQPSK は 4 乗ループのような一般的な QPSK 用搬送波再生回路と相性が悪い場合があります。I/Q がずれているため、$s(t)^4$ を取っても QPSK のようにきれいな $4f_c$ の線スペクトルが立たないからです。
位相曖昧性の解消: これは QPSK と共通の課題ですが、差動符号化を併用する場合、OQPSK では差動符号化を I/Q オフセットの前に置くか後に置くかで挙動が変わります。
これらは実装上の手間であって、性能上のペナルティではありません。ここまでで OQPSK の全体像が見えました。最後に、他の「包絡線に優しい変調」との関係を整理しておきます。
MSK / GMSK / $\pi/4$-QPSK との位置づけ
OQPSK から MSK へ — 実は連続体
ここまで $g(t)$ を RRC としてきましたが、式 (3) の $g$ は何でも構いません。ここで $g(t)$ を、幅 $2T$ の半正弦パルスに取り替えてみます。
$$ g_{\text{MSK}}(t) = \sin\!\left(\frac{\pi t}{2T}\right), \qquad 0 \le t \le 2T $$
すると何が起きるか。I 側の隣り合うパルスは $T$ ずつずれ、Q 側も同様、そして I と Q は $T/2$ ずれています。この配置で振幅を計算すると、任意の時刻で
$$ |s(t)|^2 = \left[\pm\sin\frac{\pi t}{2T}\right]^2 + \left[\pm\cos\frac{\pi t}{2T}\right]^2 = 1 $$
という具合に $\sin^2 + \cos^2 = 1$ が効いて、包絡線が厳密に一定になります。これが MSK(Minimum Shift Keying)です。
つまり MSK は「半正弦パルス整形をした OQPSK」に他なりません。OQPSK が包絡線の下限を $0$ から $0.43 A_{\text{rms}}$ に引き上げたのに対し、MSK はそれを $1.00 A_{\text{rms}}$ まで持ち上げた — 変動そのものを消し去った、というわけです。IEEE 802.15.4 の 2.4 GHz PHY が「半正弦整形の OQPSK」と規定されているのは、まさにこの等価性を使っています。
GMSK はさらに一歩進んで、パルスをガウス関数で平滑化することで帯域外輻射を抑えたもので、GSM で採用されました。詳細は MSK/GMSK変調 — 連続位相で帯域効率と一定包絡線を両立する を参照してください。
何を失うのか — 帯域効率とのトレードオフ
一定包絡線がそれほど良いなら、なぜ全部 MSK にしないのでしょうか。答えは帯域効率です。
半正弦パルスは RRC $\beta=0.35$ に比べてスペクトルの主ローブが広く、MSK の 99% 帯域幅は約 $1.2/T$、電力の 99.9% を含めようとすると急に広がります。RRC 整形の OQPSK は $\beta$ を下げれば $1.0/T$ に漸近するまで帯域を絞れます。帯域が高価な衛星通信では、この差は無視できません。
整理すると次のようになります。
| 方式 | 最大位相遷移 | 包絡線下限 | 帯域の絞り込み | 非線形耐性 |
|---|---|---|---|---|
| QPSK | $180°$ | $0$ | $\beta$ で自由 | 最悪 |
| $\pi/4$-QPSK | $135°$ | $0.14 A_{\text{rms}}$ | $\beta$ で自由 | 中 |
| OQPSK | $90°$ | $0.43 A_{\text{rms}}$ | $\beta$ で自由 | 良 |
| MSK / GMSK | 連続(不連続なし) | $1.00 A_{\text{rms}}$ | パルス形状に固定 | 完全 |
上から下へ行くほど非線形に強くなり、その代わり帯域整形の自由度を失っていきます。OQPSK は「RRC の帯域整形の自由度を保ったまま、位相遷移を $90°$ に抑える」という位置にいて、このバランスの良さが衛星系で選ばれる理由です。
$\pi/4$-QPSK が選ばれる場面
$\pi/4$-QPSK は包絡線特性では OQPSK に劣ります。それでも IS-136、PDC、TETRA といった移動体システムで採用されたのには理由があります。
第一に、$\pi/4$-QPSK は差動復調が可能です。$\pi/4$-DQPSK として実装すれば、搬送波位相を再生せずに前シンボルとの位相差だけで判定できます。フェージングで位相が高速に変動する移動体環境では、これが決定的な利点になります。OQPSK は原理的にコヒーレント検波が必要です。
第二に、$\pi/4$-QPSK は通常の QPSK 受信機とタイミング構造が同じなので、同期回路の設計が素直です。
つまり、「非線形耐性」だけで変調方式は決まりません。伝搬路の性質(AWGN なのかフェージングなのか)、受信機の複雑さの許容度、周波数調整の制約 — これらの総合で決まります。OQPSK が選ばれるのは、伝搬路が素直(衛星の見通し内リンク)で、増幅器を飽和させたい、という条件が揃った場面です。
理論と設計上の位置づけが揃いました。最後に、ここまでの主張をすべて再現できる Python コードを示します。
Python による実装と検証
ルートレイズドコサインと 3 方式の波形生成
まず共通の土台を作ります。RRC のインパルス応答は、$t=0$ と $t = \pm T/(4\beta)$ で分母がゼロになるので、その 2 点は極限値を別扱いします。
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
def rrc(beta, sps, span):
"""ルートレイズドコサインのインパルス応答(エネルギー1に正規化)"""
N = span * sps
t = np.arange(-N / 2, N / 2 + 1) / sps # 単位: シンボル周期T
h = np.zeros_like(t)
for i, ti in enumerate(t):
if abs(ti) < 1e-12: # t=0 の極限値
h[i] = 1 - beta + 4 * beta / np.pi
elif beta > 0 and abs(abs(ti) - 1 / (4 * beta)) < 1e-9: # 分母0の特異点
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:
num = (np.sin(np.pi * ti * (1 - beta))
+ 4 * beta * ti * np.cos(np.pi * ti * (1 + beta)))
den = np.pi * ti * (1 - (4 * beta * ti) ** 2)
h[i] = num / den
return h / np.sqrt(np.sum(h ** 2))
SPS, BETA, SPAN = 16, 0.35, 12 # 16倍オーバーサンプリング
h = rrc(BETA, SPS, SPAN)
g = h / h.max() # g(0)=1 に正規化して値を確認
c = len(h) // 2
print(f"g(0)={g[c]:.4f} g(T/2)={g[c+SPS//2]:.4f} "
f"g(T)={g[c+SPS]:.5f} g(2T)={g[c+2*SPS]:.5f}")
出力は g(0)=1.0000 g(T/2)=0.5547 g(T)=-0.07730 g(2T)=0.05213 となります。本文で述べた通り $g(T) \ne 0$ であり、RRC 単体はナイキスト条件を満たしていません。この $-0.0773$ という値は、後で OQPSK の $Q(T/2) = g(0) – g(T) = 1.0773$ を計算するときに使った数字そのものです。
次に 3 方式の複素包絡線を作ります。QPSK と OQPSK の違いが np.roll の 1 行だけであることに注目してください。
import numpy as np
def upsample(sym, sps):
"""シンボル列をsps倍にゼロ挿入アップサンプル"""
x = np.zeros(len(sym) * sps)
x[::sps] = sym
return x
def make_signals(nsym, sps, h, seed=0):
rng = np.random.default_rng(seed)
bits = rng.integers(0, 2, 2 * nsym)
a = 2 * bits[0::2] - 1.0 # I側 ±1
b = 2 * bits[1::2] - 1.0 # Q側 ±1
I = np.convolve(upsample(a, sps), h, "same")
Q = np.convolve(upsample(b, sps), h, "same")
qpsk = I + 1j * Q # Δ=0
oqpsk = I + 1j * np.roll(Q, sps // 2) # Δ=T/2 ← これだけ
# π/4-QPSK: 位相差を {±45°, ±135°} に制限(180°遷移が消える)
tab = {(0, 0): np.pi / 4, (0, 1): 3 * np.pi / 4,
(1, 1): -3 * np.pi / 4, (1, 0): -np.pi / 4}
ph, sym = 0.0, np.zeros(nsym, complex)
for k in range(nsym):
ph += tab[(bits[2 * k], bits[2 * k + 1])]
sym[k] = np.exp(1j * ph)
pi4 = (np.convolve(upsample(sym.real, sps), h, "same")
+ 1j * np.convolve(upsample(sym.imag, sps), h, "same"))
gd = len(h) # 過渡部を捨てる
return qpsk[gd:-gd], oqpsk[gd:-gd], pi4[gd:-gd]
sq, so, sp4 = make_signals(30000, SPS, h, seed=0)
for name, s in [("QPSK", sq), ("OQPSK", so), ("π/4-QPSK", sp4)]:
env = np.abs(s)
rms = np.sqrt(np.mean(env ** 2))
print(f"{name:9s} PAPR={10*np.log10(env.max()**2/rms**2):5.2f}dB "
f"Amin/Arms={env.min()/rms:.4f} "
f"P(A<0.3Arms)={np.mean(env < 0.3*rms)*100:6.3f}%")
実行すると次の出力が得られます。
QPSK PAPR= 3.89dB Amin/Arms=0.0000 P(A<0.3Arms)= 4.067%
OQPSK PAPR= 3.63dB Amin/Arms=0.4264 P(A<0.3Arms)= 0.000%
π/4-QPSK PAPR= 3.19dB Amin/Arms=0.1417 P(A<0.3Arms)= 0.866%
この 3 行に本記事の主張が凝縮されています。PAPR の差はわずか 0.26 dB しかないのに、包絡線の下限は「実質ゼロ」対 $0.4264$ と比較にならない。そして QPSK は全時間の 4% で振幅が rms の 3 割を切るのに対し、OQPSK は一度も切りません。ピーク(PAPR)を見ていては両者の差は見えず、谷を見て初めて見える、ということです。
IQ 軌跡と包絡線波形の可視化
包絡線の谷を目で確認します。IQ 平面の軌跡を描けば、QPSK だけが原点を通ることが一目でわかります。
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 3, figsize=(15, 9))
seg = slice(0, 200 * SPS) # 200シンボル分
for j, (name, s) in enumerate([("QPSK(Δ=0)", sq), ("OQPSK(Δ=T/2)", so),
("π/4-QPSK", sp4)]):
rms = np.sqrt(np.mean(np.abs(s) ** 2))
z = s[seg] / rms
ax = axes[0, j]
ax.plot(z.real, z.imag, lw=0.4, color="tab:blue", alpha=0.7)
ax.plot(0, 0, "rx", ms=12, mew=2.5, label="原点")
ax.add_patch(plt.Circle((0, 0), 0.3, fill=False, ls="--", color="red"))
ax.set_title(f"{name}\nIQ軌跡(赤破線=0.3×実効値)")
ax.set_xlabel("同相成分 I"); ax.set_ylabel("直交成分 Q")
ax.set_aspect("equal"); ax.grid(alpha=0.3); ax.legend(loc="upper right")
ax = axes[1, j]
t = np.arange(30 * SPS) / SPS
ax.plot(t, np.abs(z[:30 * SPS]), color="tab:orange")
ax.axhline(0.3, ls="--", color="red", label="0.3×実効値")
ax.set_ylim(0, 2.0)
ax.set_title(f"{name} の包絡線 |s(t)|")
ax.set_xlabel("時刻 t / T(シンボル周期)"); ax.set_ylabel("振幅(実効値で正規化)")
ax.grid(alpha=0.3); ax.legend()
plt.tight_layout(); plt.show()

上段の IQ 軌跡を見ると、QPSK では軌跡が赤い破線の円($0.3 A_{\text{rms}}$)の内側を何度も通り、原点の $\times$ 印の上を横切る線が濃く見えます。OQPSK では円の内部が完全に空白で、軌跡は正方形の辺に沿ったループを描いています。$\pi/4$-QPSK は円の内側に薄く入り込むものの、原点そのものは避けています。
下段の包絡線波形では、QPSK に $0.1$ を切る深い切れ込みが周期的に現れるのに対し、OQPSK の波形はこの 30 シンボルの区間では $0.49$ が底で、切れ込みらしい切れ込みがありません(30,000 シンボル全体で見ても下限は $0.4264$ です)。この「床」があることが、後のスペクトル特性を決定づけます。
PAPR の CCDF と包絡線ヒストグラム
分布の上側(PAPR)と下側(谷)を同時に見比べます。
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 左: PAPRのCCDF(分布の上側)
for name, s in [("QPSK", sq), ("OQPSK", so), ("π/4-QPSK", sp4)]:
p = np.abs(s) ** 2
papr_db = 10 * np.log10(p / p.mean())
xs = np.sort(papr_db)
ccdf = 1 - np.arange(len(xs)) / len(xs)
axes[0].semilogy(xs, ccdf, label=name, lw=1.8)
axes[0].set_xlim(-2, 5); axes[0].set_ylim(1e-5, 1)
axes[0].set_xlabel("瞬時電力 / 平均電力 [dB]")
axes[0].set_ylabel("超過確率(CCDF)")
axes[0].set_title("PAPRのCCDF — 上側の裾はほとんど差がない")
axes[0].grid(alpha=0.3, which="both"); axes[0].legend()
# 右: 振幅のヒストグラム(分布の下側)
for name, s in [("QPSK", sq), ("OQPSK", so), ("π/4-QPSK", sp4)]:
env = np.abs(s) / np.sqrt(np.mean(np.abs(s) ** 2))
axes[1].hist(env, bins=200, range=(0, 2), density=True,
histtype="step", lw=1.8, label=name)
axes[1].axvline(0.3, ls="--", color="red", label="0.3×実効値")
axes[1].set_xlabel("包絡線振幅(実効値で正規化)")
axes[1].set_ylabel("確率密度")
axes[1].set_title("振幅の分布 — 下側の裾で決定的に差がつく")
axes[1].grid(alpha=0.3); axes[1].legend()
plt.tight_layout(); plt.show()

左の CCDF では 3 本の曲線がほぼ重なり、$10^{-4}$ の点でも横方向の差は 1 dB 未満です。PAPR という指標では OQPSK の利点がほとんど見えないことが視覚的に確認できます。
対して右のヒストグラムでは景色が一変します。QPSK の分布は振幅ゼロ付近まで裾を引いており、原点近傍に有限の密度があります。OQPSK の分布は $0.43$ 付近でぷつりと途切れ、それより左には確率密度がまったくありません。$\pi/4$-QPSK は $0.14$ 付近まで裾を引いています。この「どこで途切れるか」が、非線形増幅器での振る舞いを決めます。
瞬時周波数 — 谷が位相の急変を生む証拠
包絡線の谷と位相の急変を結びつける鎖を、瞬時周波数として直接測ります。ここはオーバーサンプリングを 64 倍に上げます(位相の急変を分解するため)。
import numpy as np
import matplotlib.pyplot as plt
SPS_HI = 64
h_hi = rrc(BETA, SPS_HI, 16)
sq_h, so_h, sp4_h = make_signals(8000, SPS_HI, h_hi, seed=3)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
t = np.arange(40 * SPS_HI) / SPS_HI
for name, s in [("QPSK", sq_h), ("OQPSK", so_h), ("π/4-QPSK", sp4_h)]:
rms = np.sqrt(np.mean(np.abs(s) ** 2))
# 瞬時周波数 = 位相の時間微分 / 2π(シンボルレートで正規化)
finst = np.diff(np.unwrap(np.angle(s))) / (2 * np.pi) * SPS_HI
axes[0].plot(t[:-1], finst[:40 * SPS_HI - 1], lw=1.0, label=name)
print(f"{name:9s} max|f_inst|/Rs = {np.abs(finst).max():7.2f} "
f"99.9%点 = {np.percentile(np.abs(finst), 99.9):6.3f} "
f"rms = {np.sqrt(np.mean(finst**2)):6.3f}")
axes[0].set_ylim(-6, 6)
axes[0].set_xlabel("時刻 t / T(シンボル周期)")
axes[0].set_ylabel("瞬時周波数 / シンボルレート")
axes[0].set_title("瞬時周波数 — QPSKだけが飛び出す")
axes[0].grid(alpha=0.3); axes[0].legend()
# 包絡線と瞬時周波数の相関(QPSK)
rms = np.sqrt(np.mean(np.abs(sq_h) ** 2))
env = np.abs(sq_h)[:-1] / rms
fi = np.abs(np.diff(np.unwrap(np.angle(sq_h))) / (2 * np.pi) * SPS_HI)
axes[1].loglog(env, fi + 1e-6, ",", alpha=0.3, color="tab:blue")
# 振幅ビンごとの |瞬時周波数| の99%点(右下がりの関係を実測で描く)
edges = np.logspace(np.log10(max(env.min(), 1e-4)), np.log10(env.max()), 25)
cen, p99 = [], []
for lo, hi in zip(edges[:-1], edges[1:]):
m = (env >= lo) & (env < hi)
if m.sum() > 30:
cen.append(np.sqrt(lo * hi))
p99.append(np.percentile(fi[m], 99))
axes[1].loglog(cen, p99, "-", color="tab:red", lw=2.5,
label="振幅ごとの |瞬時周波数| の99%点(実測)")
axes[1].set_xlabel("包絡線振幅(実効値で正規化)")
axes[1].set_ylabel("|瞬時周波数| / シンボルレート")
axes[1].set_title("QPSK: 振幅が小さいほど瞬時周波数が発散する")
axes[1].grid(alpha=0.3, which="both"); axes[1].legend()
plt.tight_layout(); plt.show()
出力される数値は本文の表と一致します(QPSK: 31.93、OQPSK: 1.08、$\pi/4$: 3.07)。

左のグラフでは、QPSK の瞬時周波数が周期的に画面外へ突き抜けているのに対し、OQPSK は $\pm 1.1$ の帯に完全に収まっています。右の散布図は因果関係を直接示しており、包絡線振幅が小さいサンプルほど瞬時周波数が大きいという右下がりの関係が両対数上ではっきり見えます。振幅ビンごとに $|f_{\text{inst}}|$ の 99% 点を取ると、振幅 $0.10$ での $6.4 R_s$ から振幅 $0.97$ での $0.51 R_s$ へと、両対数上で傾き約 $-1.2$ の直線状に落ちていきます(振幅 $0.05$ 以下では標本間隔による頭打ちが効いて $31 R_s$ 付近で曲線が寝ます)。谷が位相の急変を生むという主張の、これが直接的な証拠です。
非線形増幅器の AM-AM / AM-PM 特性
Rapp モデルと Saleh モデルを実装し、特性曲線を描きます。
import numpy as np
import matplotlib.pyplot as plt
def rapp(x, p=3.0, a_sat=1.0):
"""Rappモデル(SSPA向け、AM-PMなし)"""
r = np.abs(x)
return r / (1 + (r / a_sat) ** (2 * p)) ** (1 / (2 * p)) * np.exp(1j * np.angle(x))
def saleh(x, aa=2.1587, ba=1.1517, ap=4.0033, bp=9.1040):
"""SalehモデルのTWTA標準パラメータ(AM-AM + AM-PM)"""
r = np.abs(x)
amp = aa * r / (1 + ba * r ** 2)
pha = ap * r ** 2 / (1 + bp * r ** 2)
return amp * np.exp(1j * (np.angle(x) + pha))
r = np.linspace(0, 2.5, 500)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
for p in [1, 2, 3, 10]:
axes[0].plot(r, np.abs(rapp(r + 0j, p=p)), label=f"Rapp p={p}")
axes[0].plot(r, np.minimum(r, 1.0), "k--", label="理想リミッタ(p→∞)")
axes[0].plot(r, np.abs(saleh(r + 0j)), color="tab:red", label="Saleh(TWTA)")
axes[0].plot(r, r, ":", color="gray", label="線形(理想)")
axes[0].set_xlabel("入力振幅(飽和振幅で正規化)")
axes[0].set_ylabel("出力振幅")
axes[0].set_title("AM-AM特性 — pが大きいほど飽和が鋭い")
axes[0].set_ylim(0, 1.6); axes[0].grid(alpha=0.3); axes[0].legend()
pha = 4.0033 * r ** 2 / (1 + 9.1040 * r ** 2) * 180 / np.pi
axes[1].plot(r, pha, color="tab:red", label="Saleh(TWTA)")
axes[1].axhline(0, ls=":", color="gray", label="Rapp(AM-PMなし)")
axes[1].set_xlabel("入力振幅(飽和振幅で正規化)")
axes[1].set_ylabel("出力位相のずれ [度]")
axes[1].set_title("AM-PM特性 — 振幅変動が位相雑音に化ける")
axes[1].grid(alpha=0.3); axes[1].legend()
plt.tight_layout(); plt.show()

左の AM-AM 特性から、$p$ が大きいほど線形領域と飽和領域の遷移が鋭くなり、$p=10$ ではほぼ理想リミッタ(黒破線)に重なることがわかります。Saleh モデル(赤)は飽和点を過ぎると出力が下がるという TWTA 特有の挙動を示しており、Rapp モデルとは質的に違います。
右の AM-PM 特性は、Saleh モデルでは入力振幅が飽和点に近づくと出力位相が最大 $25°$ 程度ずれることを示しています。包絡線が変動する信号では、この振幅→位相変換がそのまま位相雑音になります。 包絡線一定の信号なら定数位相回転にすぎず無害、という本文の主張がこのグラフの読み方です。
スペクトル再成長の測定
いよいよ本丸です。オーバーサンプリング率に注意しながら PSD を測ります。
import numpy as np
import matplotlib.pyplot as plt
from numpy.fft import fft, fftshift, fftfreq
def psd(s, sps, nfft=8192):
"""Welch法によるPSD推定(周波数単位はシンボルレート)"""
win = np.hanning(nfft)
nseg = len(s) // nfft
P = np.zeros(nfft)
for i in range(nseg):
P += np.abs(fftshift(fft(s[i * nfft:(i + 1) * nfft] * win, nfft))) ** 2
return fftshift(fftfreq(nfft, d=1.0 / sps)), P / nseg
def backoff(s, ibo_db, a_sat=1.0):
"""入力バックオフibo_db [dB] になるよう振幅を調整"""
return s * (a_sat * 10 ** (-ibo_db / 20) / np.sqrt(np.mean(np.abs(s) ** 2)))
plt.figure(figsize=(11, 6))
IBO = 0.0
for name, s, col in [("QPSK", sq_h, "tab:red"), ("OQPSK", so_h, "tab:blue"),
("π/4-QPSK", sp4_h, "tab:green")]:
y = rapp(backoff(s, IBO), p=3.0)
f, P = psd(y, SPS_HI)
plt.plot(f, 10 * np.log10(P / P.max()), color=col, lw=1.3, label=f"{name}(飽和PA通過後)")
f, P = psd(backoff(sq_h, IBO), SPS_HI) # 線形時の基準
plt.plot(f, 10 * np.log10(P / P.max()), "k--", lw=1.2, label="線形時(PAなし)")
plt.axvspan(-0.675, 0.675, color="gray", alpha=0.15)
for n in [1, 2, 3]:
for sgn in [1, -1]:
plt.axvspan(sgn * 1.35 * n - 0.675, sgn * 1.35 * n + 0.675,
color="orange", alpha=0.10)
plt.xlim(-6, 6); plt.ylim(-90, 3)
plt.xlabel("周波数 / シンボルレート")
plt.ylabel("電力スペクトル密度 [dBc]")
plt.title(f"スペクトル再成長(Rapp p=3, IBO={IBO:.0f}dB)\n"
"灰=主チャネル、橙=第1〜第3隣接チャネル")
plt.grid(alpha=0.3); plt.legend()
plt.tight_layout(); plt.show()

このグラフが本記事の核心です。左が理想リミッタ、右が現実的な固体増幅器(Rapp $p=3$、IBO $= 0$ dB)を通した後のスペクトルです。まず右の Rapp を見ると、3 本の曲線は主チャネル(灰色帯)と第 1 隣接(最初の橙色帯)でほぼ完全に重なっています。近接チャネルでは OQPSK に利点がありません。 ところが第 2 隣接以遠になると曲線が分離し、QPSK(赤)と $\pi/4$-QPSK(緑)が $-55$ dBc 付近の台地を保ったまま伸びるのに対し、OQPSK(青)だけが $-70$ dBc 台へ急峻に落ちていきます。左の理想リミッタではこの構図がさらに極端になり、$f = 6R_s$ で QPSK $-34.7$ dBc に対し OQPSK $-81.3$ dBc と 46.6 dB もの差がつきます($\pi/4$-QPSK $-53.1$ dBc はちょうど中間です)。黒破線(線形時)と比べれば、いずれも近接では大きく再成長しているものの、遠方では OQPSK だけが線形時に近い傾きを保っていることがわかります。
ACLR とバックオフの関係
数値として ACLR を出し、必要バックオフに翻訳します。
import numpy as np
import matplotlib.pyplot as plt
BW = 1 + BETA # 占有帯域 = チャネル間隔 = 1.35/T
def aclr(s, sps, n):
"""第n隣接チャネル漏洩電力比 [dB](上下平均)"""
f, P = psd(s, sps)
band = lambda c: P[(f > c - BW / 2) & (f < c + BW / 2)].sum()
return 10 * np.log10(band(0) / ((band(n * BW) + band(-n * BW)) / 2))
ibos = np.arange(0, 8.01, 0.5)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
for k, n in enumerate([1, 2]):
for name, s, col in [("QPSK", sq_h, "tab:red"), ("OQPSK", so_h, "tab:blue"),
("π/4-QPSK", sp4_h, "tab:green")]:
vals = [aclr(rapp(backoff(s, ib), p=3.0), SPS_HI, n) for ib in ibos]
axes[k].plot(ibos, vals, "o-", color=col, ms=4, label=name)
axes[k].set_xlabel("入力バックオフ IBO [dB]")
axes[k].set_ylabel(f"第{n}隣接チャネル ACLR [dB]")
axes[k].set_title(f"第{n}隣接チャネルのACLR(Rapp p=3)")
axes[k].grid(alpha=0.3); axes[k].legend()
axes[0].axhline(45, ls="--", color="k", lw=1, label="目標45dB")
axes[1].axhline(55, ls="--", color="k", lw=1, label="目標55dB")
axes[0].legend(); axes[1].legend()
plt.tight_layout(); plt.show()
for n, target in [(1, 45), (2, 55)]:
print(f"--- 第{n}隣接 ACLR ≥ {target}dB を満たす最小IBO ---")
for name, s in [("QPSK", sq_h), ("OQPSK", so_h), ("π/4-QPSK", sp4_h)]:
for ib in np.arange(0, 10.01, 0.25):
v = aclr(rapp(backoff(s, ib), p=3.0), SPS_HI, n)
if v >= target:
print(f" {name:9s} IBO = {ib:.2f} dB (ACLR={v:.1f}dB)")
break
出力は次のようになります。
--- 第1隣接 ACLR ≥ 45dB を満たす最小IBO ---
QPSK IBO = 5.00 dB (ACLR=45.5dB)
OQPSK IBO = 5.25 dB (ACLR=45.9dB)
π/4-QPSK IBO = 4.75 dB (ACLR=45.1dB)
--- 第2隣接 ACLR ≥ 55dB を満たす最小IBO ---
QPSK IBO = 3.00 dB (ACLR=55.3dB)
OQPSK IBO = 0.25 dB (ACLR=55.2dB)
π/4-QPSK IBO = 2.75 dB (ACLR=55.2dB)

左のグラフ(第 1 隣接)では 3 本の曲線がほぼ重なり、必要バックオフに差が出ません(OQPSK はむしろ 0.25 dB 不利)。右のグラフ(第 2 隣接)では OQPSK の曲線だけが大きく上方にシフトし、同じ ACLR を 2.75 dB 少ないバックオフで達成できます。
この 2 枚の対比が、OQPSK を採用すべきかどうかの判断基準そのものです。システムの制約が第 1 隣接だけなら OQPSK に移る意味はありません。遠方スプラッタや広帯域スプリアスが効くシステム、あるいは増幅器を IBO 1 dB 以下で深く飽和させたいシステムでは、2〜3 dB の電力が浮きます。
BER の検証
最後に、ここまでの波形改善が受信性能を一切劣化させないことを確認します。
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erfc
def qfunc(x):
return 0.5 * erfc(x / np.sqrt(2))
def ber_sim(mode, ebn0_db, nsym=400000, sps=16, seed=7):
"""RRC送信整形 + 整合フィルタ + AWGN でBERを実測"""
h = rrc(BETA, sps, SPAN)
rng = np.random.default_rng(seed)
bits = rng.integers(0, 2, 2 * nsym)
a, b = 2 * bits[0::2] - 1.0, 2 * bits[1::2] - 1.0
I = np.convolve(upsample(a, sps), h, "full")
Q = np.convolve(upsample(b, sps), h, "full")
if mode == "oqpsk":
Q = np.roll(Q, sps // 2) # Q側を半シンボル遅延
# Es=2Eb, I成分あたりのエネルギーEb=1 → 雑音分散 σ²=N0/2=1/(2·Eb/N0)
sigma = 1 / np.sqrt(2 * 10 ** (ebn0_db / 10))
nI = sigma * rng.standard_normal(len(I))
nQ = sigma * rng.standard_normal(len(Q))
yI = np.convolve(I + nI, h, "full") # 整合フィルタ
yQ = np.convolve(Q + nQ, h, "full")
d = SPAN * sps # 2回のfull畳み込みによる遅延
k = np.arange(nsym - 2 * SPAN)
iI = d + k * sps
iQ = iI + (sps // 2 if mode == "oqpsk" else 0) # Q側は半シンボル後に標本化
err = (np.sum((yI[iI] > 0) != bits[0::2][:len(k)])
+ np.sum((yQ[iQ] > 0) != bits[1::2][:len(k)]))
return err / (2 * len(k))
ebn0 = np.arange(0, 9, 1.0)
ber_q = [ber_sim("qpsk", e) for e in ebn0]
ber_o = [ber_sim("oqpsk", e) for e in ebn0]
plt.figure(figsize=(8, 6))
plt.semilogy(ebn0, ber_q, "o-", label="QPSK(実測)", ms=7)
plt.semilogy(ebn0, ber_o, "s--", label="OQPSK(実測)", ms=7)
xf = np.linspace(0, 8, 200)
plt.semilogy(xf, qfunc(np.sqrt(2 * 10 ** (xf / 10))), "k:", lw=2,
label=r"理論 $Q(\sqrt{2E_b/N_0})$")
plt.xlabel(r"$E_b/N_0$ [dB]"); plt.ylabel("ビット誤り率 BER")
plt.title("AWGN下のBER — OQPSKにペナルティはない")
plt.ylim(1e-5, 1); plt.grid(alpha=0.3, which="both"); plt.legend()
plt.tight_layout(); plt.show()

3 本の曲線が完全に重なります。実測値は $E_b/N_0 = 4$ dB で QPSK $1.248\times 10^{-2}$、OQPSK $1.247\times 10^{-2}$、理論値 $1.250\times 10^{-2}$ と有効数字 3 桁で一致しました。高 $E_b/N_0$ 側でのわずかなばらつきは誤り事象が少ないことによる統計誤差で、系統的な差ではありません。
波形の包絡線特性を大幅に改善したのに、AWGN 性能は 1 ビットも損なわれていない — これが OQPSK の最も美しい点です。前節で導出した「I/Q オフセットは受信側から見れば標本化時刻の違いにすぎない」という主張が、実測で裏づけられました。
まとめ
本記事では、OQPSK(オフセット QPSK)が包絡線変動を抑える原理を、式の導出と実測の両面から解説しました。
- QPSK は対角遷移で複素包絡線が原点を通る。孤立した対角遷移では、パルス $g$ の偶対称性 $g(-t)=g(t)$ だけから $I(T/2) = Q(T/2) = 0$ が厳密に導かれます。ランダムデータでも下限は存在せず、振幅が $0.3A_{\text{rms}}$ を切る時間が 4.07% に達します
- オフセット $\Delta = T/2$ は最大位相遷移を $\pm 90°$ に制限する。I と Q の切り替わり時刻が構造的に一致しないため、$180°$ 遷移が起こり得ません。20 万シンボルの実測でも位相ステップは $0°$ と $90°$ のみで、最大値はちょうど $90.0°$ でした
- $\Delta = T/2$ が最適な理由は、I の零交差時刻に Q のパルス頂点が来るからです。実際 $Q(T/2) = g(0) – g(T) = 1.0773$ となり、I がゼロの瞬間に Q はほぼ最大です。結果として包絡線に $0.4264 A_{\text{rms}}$ という明確な床ができます
- PAPR で見ると差はほとんどない(3.89 dB 対 3.63 dB、わずか 0.26 dB)。「OQPSK は PAPR が低い」という説明は誤りに近く、効いているのは分布の下側です。PAPR は包絡線変動の一面しか測っていません
- 谷は瞬時周波数の発散を生む。最大瞬時周波数は QPSK が発散するのに対し OQPSK は $1.08 R_s$ で頭打ちになります。この一つの数字がスペクトル特性を予告します
- 理想リミッタを通すと、QPSK の 99% 帯域幅は $1.17/T$ から $5.19/T$ へ 4.4 倍に膨張します。OQPSK は $1.81/T$ にとどまり、第 3 隣接チャネルでは 27.9 dB、$6R_s$ 地点の PSD では 46.6 dB の差がつきます
- ただし第 1 隣接チャネルでは利得がない。近接再成長はピーククリッピングが支配的で、これは両方式に共通だからです。Rapp $p=3$ での必要バックオフは、第 2 隣接 ACLR $\ge$ 55 dB なら 2.75 dB 削減できますが、第 1 隣接 ACLR $\ge$ 45 dB では削減ゼロ(0.25 dB 悪化)でした。採用の是非はシステムのボトルネックがどこにあるかで決まります
- BER は QPSK と厳密に同一。I/Q オフセットは受信側から見れば Q 側の標本化時刻が $T/2$ 遅いだけで、エネルギーも雑音分散も変わりません。実測でも $Q(\sqrt{2E_b/N_0})$ と 3 桁一致しました
- MSK は「半正弦パルス整形の OQPSK」であり、$\sin^2+\cos^2=1$ によって包絡線が厳密に一定になります。QPSK → $\pi/4$-QPSK → OQPSK → MSK/GMSK は、非線形耐性と帯域整形の自由度のトレードオフ上に並ぶ一つの系列として理解できます
ここから先の学習ルートを 2 つ挙げておきます。一つは一定包絡線変調の方向で、OQPSK の先にある MSK/GMSK、さらに連続位相変調(CPM)の一般論へ進む道。もう一つは包絡線変動を許したまま増幅器側で対処する方向で、OFDM の PAPR 低減技術やディジタルプリディストーション(DPD)へ進む道です。後者は本記事で見た「谷が位相の急変を生み、それが帯域外輻射になる」という因果を、逆向きに補正で打ち消す技術だと理解すると見通しが良くなります。
次のステップとして、以下の記事も参考にしてください。