雑音・SNR・通信路容量
−174 dBm/Hzの熱雑音フロアの由来、雑音指数と多段構成の縦続接続が受信感度をどう決めるか、そしてシャノン容量が帯域幅と電力について何を示すかを解説します
このレッスンで学ぶこと
- 任意の帯域幅について熱雑音電力kTBをdBmで計算し、シミュレーションした雑音サンプルから同じ値を再現する
- 受信機の多段構成の雑音指数を計算し、LNAを先頭に置く理由を説明する
- 帯域幅・雑音指数・所要SNRから受信感度を計算する
- シャノンの通信路容量の式を使い、電力を増やした場合と帯域幅を広げた場合とで、達成可能なデータレートへの効果を比較する
レッスン03では、リンクバジェットの最後に受信感度を置き、その値を所与のものとして扱いました。このレッスンでは、その値を導出します。受信感度は三つの要素で決まります。すべての受信機が拾う熱雑音、受信機自身の回路が加える雑音、そして復調器が必要とする信号対雑音比(SNR)です。続いて、与えられたSNRと帯域幅で毎秒何ビットを運べるかを考えます。これはシャノンが立てた問いです。その答えから、現代のシステムが電力よりも帯域幅を追い求める理由がわかります。
熱雑音
絶対零度より高い温度の導体では、電子がランダムな熱運動をしています。この運動によって、端子間にランダムな電圧が生じます。ジョンソン(John B. Johnson)は1928年にこの揺らぎを測定しました。同じ年に発表された対となる論文で、ナイキスト(Harry Nyquist)は熱力学と統計力学からその大きさを計算しました。無線エンジニアにとっての結論は単純です。整合負荷に接続された抵抗器が供給する雑音電力は次のとおりです。
N = k T B
ここで、kはボルツマン定数、Tはケルビン単位の温度、Bはヘルツ単位の帯域幅です。2018年に合意されたSIの改定以降、kは厳密に1.380 649 × 10⁻²³ J/Kと定められています。この雑音は白色です。どの1 Hzにも同じ電力があるため、受信する電力は受け入れる帯域幅に比例して増えます。
無線工学では基準温度をT0 = 290 Kと定めます。無線雑音に関するITU-Rの基準文書である勧告ITU-R P.372-18も同じ290 Kを用いており、10 log10(k T0)が−204 dBW/Hzであると記しています。dBmでは−174 dBm/Hzとなり、受信機設計で最もよく使われる数値です。これは室温における熱雑音の電力密度です。
最初のブロックはこの値を計算します。続いて、ソフトウェア無線(SDR)が1 MS/sで出力する場合と同じように、その電力をもつ複素白色ガウス雑音を生成し、サンプルが式の予測どおりの電力をもつことを確認します。
import numpy as np
K_B = 1.380649e-23 # Boltzmann constant, J/K (exact since the 2019 SI)
T0 = 290.0 # reference temperature for noise figure, K
n0_dbm_hz = 10 * np.log10(K_B * T0 / 1e-3)
print(f"kT0 = {K_B * T0:.4e} W/Hz = {n0_dbm_hz:.2f} dBm/Hz")
for b_hz in [125e3, 1e6, 20e6, 100e6]:
print(f"B = {b_hz / 1e6:7.3f} MHz: noise floor {n0_dbm_hz + 10 * np.log10(b_hz):7.1f} dBm")
# The same number from samples: complex Gaussian noise of power kT0 B at fs = B
rng = np.random.default_rng(7)
fs = 1e6 # complex sample rate, Hz (noise bandwidth 1 MHz)
p_noise_w = K_B * T0 * fs
w = np.sqrt(p_noise_w / 2) * (rng.standard_normal(1_000_000) + 1j * rng.standard_normal(1_000_000))
print(f"measured over 1e6 complex128 samples: {10 * np.log10(np.mean(np.abs(w)**2) / 1e-3):.2f} dBm")
kT0 = 4.0039e-21 W/Hz = -173.98 dBm/Hz
B = 0.125 MHz: noise floor -123.0 dBm
B = 1.000 MHz: noise floor -114.0 dBm
B = 20.000 MHz: noise floor -101.0 dBm
B = 100.000 MHz: noise floor -94.0 dBm
measured over 1e6 complex128 samples: -113.98 dBm
kT0は−173.98 dBm/Hzとなり、丸めるとおなじみの−174 dBm/Hzになります。帯域幅が10倍になるごとに、雑音は10 dB増えます。1 MHzの受信機では−114.0 dBm、100 MHzの受信機では−94.0 dBmです。IとQに等分したシミュレーション雑音の測定値は−113.98 dBmです。シミュレーションのコードでは、指定した電力の雑音を通常この方法で生成します。電力の半分を実部に、残りの半分を虚部に割り当てます。
信号対雑音比
信号対雑音比は、同じ帯域幅における信号電力を雑音電力で割った値です。dBでは引き算になります。帯域幅1 MHzで−90 dBmの信号は、−114 dBmの雑音フロアに対して24 dBのSNRをもちます。これは受信機自身が雑音を加える前の値です。
SNRは、ビット誤り率とデータレートを決める量です。関連する二つの指標が頻繁に登場します。Es/N0は、シンボルあたりのエネルギーを雑音電力密度で割った値です。Eb/N0は、ビットあたりのエネルギーを雑音電力密度で割った値です。どちらもシンボルレートと帯域幅を介してSNRと関係します。レッスン05では、Eb/N0を使って変調方式を公平に比較します。
雑音指数
実際の受信機は、自身でも雑音を加えます。トランジスタ、バイアス回路の抵抗、損失のあるフィルタがすべて寄与します。その量を表すのが雑音指数です。雑音係数(noise factor)Fは、入力のSNRを出力のSNRで割った値です。このとき入力雑音は290 Kの信号源で与えます。雑音指数は10 log10(F)で、単位はdBです。理想的な受信機はF = 1、つまり雑音指数0 dBです。雑音指数5 dBの受信機は、入力雑音がkT0Bより5 dB高いかのように振る舞います。
受信機は、フィルタ、低雑音増幅器(LNA)、ミキサ、さらに続くアンプといった段の連なりです。各段には利得Gと雑音係数Fがあります。縦続接続の式は、チェーン全体の雑音係数を与えます。
F_total = F1 + (F2 − 1)/G1 + (F3 − 1)/(G1 G2) + ...
各段の過剰雑音は、その段より前にある総利得で割られます。先頭に高利得の段があれば、それ以降の段の影響はほとんど無視できるようになります。先頭に損失のある段(フィルタや長いケーブル)があると、それは1未満の利得として働きます。その損失は雑音指数にそのまま加わり、後続のすべての段の寄与を損失の分だけ大きくします。
次のブロックは、例として示す受信チェーンにこの式を適用し、さらに二つの並べ替えを試します。フィルタをLNAの前に移した場合と、LNAを取り除いた場合です。各段の値は説明用に仮定したもので、特定の製品の数値ではありません。
import numpy as np
def db(x: float) -> float:
return 10 * np.log10(x)
def lin(x_db: float) -> float:
return 10 ** (x_db / 10)
def cascade_nf_db(stages: list[tuple[str, float, float]]) -> float:
"""Friis formula for noise factor. Each stage is (name, gain dB, noise figure dB)."""
f_total, g_before = 0.0, 1.0
for i, (_, g_db, nf_db) in enumerate(stages):
f = lin(nf_db)
f_total += f if i == 0 else (f - 1) / g_before
g_before *= lin(g_db)
return db(f_total)
# Example receive chain (assumed values, not a particular product)
lna_first = [("LNA", 20.0, 1.5), ("filter", -2.0, 2.0), ("mixer", -7.0, 7.0), ("IF amp", 20.0, 4.0)]
filter_first = [("filter", -2.0, 2.0), ("LNA", 20.0, 1.5), ("mixer", -7.0, 7.0), ("IF amp", 20.0, 4.0)]
no_lna = [("filter", -2.0, 2.0), ("mixer", -7.0, 7.0), ("IF amp", 20.0, 4.0)]
for name, chain in [("LNA first", lna_first), ("filter first", filter_first), ("no LNA", no_lna)]:
print(f"{name:>12}: system noise figure {cascade_nf_db(chain):5.2f} dB")
# Sensitivity: noise floor + noise figure + the SNR the demodulator needs
b_hz, snr_req_db = 1e6, 10.0
for name, chain in [("LNA first", lna_first), ("no LNA", no_lna)]:
sens = -173.98 + db(b_hz) + cascade_nf_db(chain) + snr_req_db
print(f"{name:>12}: sensitivity {sens:6.1f} dBm in {b_hz / 1e6:.0f} MHz for {snr_req_db:.0f} dB SNR")
LNA first: system noise figure 2.05 dB
filter first: system noise figure 3.84 dB
no LNA: system noise figure 13.00 dB
LNA first: sensitivity -101.9 dBm in 1 MHz for 10 dB SNR
no LNA: sensitivity -91.0 dBm in 1 MHz for 10 dB SNR
先頭に20 dBのLNAを置くと、チェーン全体の雑音指数は2.05 dBとなり、LNA単体より0.55 dB悪いだけです。2 dBのフィルタを前に置くと、システム雑音指数は3.84 dBに上がります。フィルタ損失の2 dBがほぼそのまま上乗せされた形です。LNAを取り除くと雑音指数は13.00 dBとなり、IFアンプより前にあるフィルタとミキサの損失で決まります。これは11 dBの劣化で、自由空間のリンクでは到達距離にして3.5倍の差になります。このため、LNAは設計が許す限りアンテナの近くに置かれます。長い給電ケーブルに対してタワー設置型アンプが存在するのも同じ理由です。
フィルタを先頭に置く構成も、相応の理由があって今でも一般的です。所望帯域外の強い信号がLNAを過負荷にすることがあるため、雑音指数の面で不利でも帯域フィルタを先頭に置くことがよくあります。このトレードオフはRFフロントエンドのハブで扱います。
受信感度
受信感度は、受信機が目標の誤り率で復調できる最も弱い信号の電力です。雑音フロアに、雑音指数と、復調器が必要とするSNRを加えたものになります。
sensitivity (dBm) = −174 + 10 log10(B) + NF + SNR_required
前のブロックで実際に計算しました。帯域幅1 MHz、所要SNR 10 dBの場合、LNAありのチェーンは−101.9 dBm、LNAなしのチェーンは−91.0 dBmに達します。各項は互いにトレードオフの関係にあります。帯域幅を半分にすると、受信感度は3 dB改善します。所要SNRが6 dB低い変調方式を選ぶと、6 dB改善します。低消費電力広域システムが非常に低い受信感度を実現するのは、この方法によります。極めて狭い帯域幅と低SNRで動作する変調を使い、その代償として低いデータレートを受け入れます。例はLPWANとIoTのハブにあります。
シャノン容量
通信路は、そもそもどれだけのデータを運べるのでしょうか。シャノン(Claude Shannon)は、帯域幅Bで白色ガウス雑音のある通信路について、この問いに答えました。1949年の論文の定理2によれば、十分に精巧な符号化を用いると、次の速度までなら任意に小さい誤り率で2進数字を送ることができます。
C = B log2(1 + S/N) bit/s
また、これを上回る方式は存在しません。Cがシャノン容量です。Bで割ると、与えられたSNRで達成できる最良の周波数利用効率がbit/s/Hz単位で得られます。この式は、そのような符号の作り方については何も述べていません。この限界に迫る実用的な符号、たとえばLDPC符号は、チャネル符号化のハブで扱います。
import numpy as np
# Shannon capacity per hertz of bandwidth against SNR
snr_db = np.arange(-10, 31, 2)
eff = np.log2(1 + 10 ** (snr_db / 10)) # bit/s/Hz
for s, e in zip(snr_db, eff):
if s % 10 == 0:
print(f"SNR {s:3d} dB: {e:5.2f} bit/s/Hz")
print("chart:", ", ".join(f"[{s}, {e:.3f}]" for s, e in zip(snr_db, eff)))
high = snr_db >= 0
approx = np.log2(10 ** (snr_db[high] / 10)) # high-SNR approximation log2(SNR)
print("approx:", ", ".join(f"[{s}, {a:.3f}]" for s, a in zip(snr_db[high], approx)))
# Fixed received power, growing bandwidth: capacity saturates
p_rx_dbm, nf_db = -90.0, 5.0
n0_w_hz = 10 ** ((-173.98 + nf_db) / 10) * 1e-3 # noise density including the noise figure
p_rx_w = 10 ** (p_rx_dbm / 10) * 1e-3
for b_hz in [1e5, 1e6, 1e7, 1e8, 1e9]:
snr = p_rx_w / (n0_w_hz * b_hz)
c = b_hz * np.log2(1 + snr)
print(f"B = {b_hz / 1e6:7.1f} MHz: SNR {10 * np.log10(snr):6.1f} dB, C = {c / 1e6:6.2f} Mbit/s")
print(f"wideband limit P/(N0 ln 2) = {p_rx_w / (n0_w_hz * np.log(2)) / 1e6:.2f} Mbit/s")
print(f"minimum Eb/N0 for reliable transmission: {10 * np.log10(np.log(2)):.2f} dB")
SNR -10 dB: 0.14 bit/s/Hz
SNR 0 dB: 1.00 bit/s/Hz
SNR 10 dB: 3.46 bit/s/Hz
SNR 20 dB: 6.66 bit/s/Hz
SNR 30 dB: 9.97 bit/s/Hz
chart: [-10, 0.138], [-8, 0.212], [-6, 0.323], [-4, 0.483], [-2, 0.706], [0, 1.000], [2, 1.370], [4, 1.812], [6, 2.316], [8, 2.870], [10, 3.459], [12, 4.075], [14, 4.707], [16, 5.351], [18, 6.002], [20, 6.658], [22, 7.317], [24, 7.978], [26, 8.641], [28, 9.304], [30, 9.967]
approx: [0, 0.000], [2, 0.664], [4, 1.329], [6, 1.993], [8, 2.658], [10, 3.322], [12, 3.986], [14, 4.651], [16, 5.315], [18, 5.979], [20, 6.644], [22, 7.308], [24, 7.973], [26, 8.637], [28, 9.301], [30, 9.966]
B = 0.1 MHz: SNR 29.0 dB, C = 0.96 Mbit/s
B = 1.0 MHz: SNR 19.0 dB, C = 6.32 Mbit/s
B = 10.0 MHz: SNR 9.0 dB, C = 31.55 Mbit/s
B = 100.0 MHz: SNR -1.0 dB, C = 84.05 Mbit/s
B = 1000.0 MHz: SNR -11.0 dB, C = 109.79 Mbit/s
wideband limit P/(N0 ln 2) = 114.07 Mbit/s
minimum Eb/N0 for reliable transmission: -1.59 dB
SNRが0 dBのとき、限界はちょうど1 bit/s/Hzです。10 dBでは3.46 bit/s/Hz、20 dBでは6.66 bit/s/Hz、30 dBでは9.97 bit/s/Hzです。SNRが約10 dBを超えると、曲線はほぼ直線になります。SNRを3 dB増やすごとに、1 bit/s/Hz増えます。電力を2倍にしても、容量は一定量だけしか増えません。一方、高SNRでは帯域幅を2倍にすると容量はほぼ2倍になります。この非対称性があるため、システム設計者は電力を増やす前に、より広いチャネルや、並列の空間チャネルを加える多入力多出力(MIMO)を選びます。
同じ電力で帯域幅を広げる
ブロックの後半では、受信電力を−90 dBm、雑音指数を5 dBに固定し、帯域幅を広げていきます。帯域幅を広げると雑音も多く入るため、帯域幅が増えるにつれてSNRは下がります。1 MHzではSNRは19.0 dB、容量は6.32 Mbit/sです。10 MHzではSNRは9.0 dBに下がりますが、容量は31.55 Mbit/sに増えます。1000 MHzではSNRは−11.0 dB、容量は109.79 Mbit/sです。これは、どれだけ帯域幅を広げても超えられない限界値114.07 Mbit/sに近い値です。
この限界はP / (N0 ln 2)で、Pは受信電力、N0は雑音電力密度です。これをビットあたりに書き直すと、エネルギーに対する厳密な下限が得られます。Eb/N0はln 2、すなわち−1.59 dBを上回らなければなりません。どれほど巧妙な変調と符号を使っても、これより下では信頼性のある通信はできません。強力な符号化や拡散によって負のSNRで動作するよう設計されたリンクは、曲線のこの電力制限領域で動作しています。ここでは帯域幅は安く、エネルギーは高くつきます。
実際のシステムは、シャノン曲線より数dB下で動作します。変調・符号化方式は有限個であり、受信機には実装損失があり、実際のチャネルではフェージングが起こるためです。実際のリンクと曲線との差は、有用な性能指標になります。関連する式は通信路容量と周波数利用効率のチートシートで確認できます。
演習
- ある衛星受信機のシステム雑音温度は、290 Kではなく150 Kです。雑音電力密度はdBm/Hzでいくつになりますか。最初のブロックを、Tを引数として受け取るように書き直してください。
- 縦続接続のブロックで、アンテナとLNAの間に3 dBのケーブルを追加してください。システム雑音指数はどう変わりますか。ケーブルをLNAの後ろに移して比較してください。
- 雑音指数7 dB、帯域幅200 kHzの受信機があり、復調器には4 dBのSNRが必要です。受信感度はいくつですか。
- シャノンの式を使い、5 bit/s/Hzに必要な最小SNRを求めてください。それを、高SNR近似と厳密値との差が0.1 bit/s/Hz以内に収まるSNRと比較してください。
- −90 dBm固定の例で、容量が広帯域極限の90%に達する帯域幅を求めてください。
まとめ
- 熱雑音電力はkTBです。基準温度290 Kでは−174 dBm/Hzとなるため、1 MHzの受信機の雑音フロアは−114 dBmから始まり、帯域幅が10倍になるごとに10 dB増えます。
- 雑音指数は、入力SNRと出力SNRの比をdBで表したものです。縦続接続では、各段の過剰雑音はその前にある利得で割られるため、低雑音・高利得の初段がシステム雑音指数を決めます。
- 受信感度は−174 dBm/Hz + 10 log10(B) + NF + 所要SNRです。帯域幅を狭くする、雑音指数を下げる、より低いSNRに耐える変調を使う、のいずれでも改善します。
- シャノン容量はC = B log2(1 + SNR)です。高SNRでは3 dBごとに1 bit/s/Hz増えます。電力が一定の場合、帯域幅を広げると容量はP / (N0 ln 2)で飽和し、信頼性のある通信にはEb/N0が−1.59 dBを上回る必要があります。
さらに読む
- J. B. Johnson, “Thermal agitation of electricity in conductors”, Physical Review, vol. 32, no. 1, pp. 97-109, 1928:熱雑音の測定。
- H. Nyquist, “Thermal agitation of electric charge in conductors”, Physical Review, vol. 32, no. 1, pp. 110-113, 1928:熱力学と統計力学に基づく、対となる計算。
- C. E. Shannon, “Communication in the presence of noise”, Proceedings of the IRE, vol. 37, no. 1, pp. 10-21, 1949:定理2で、白色熱雑音のある帯域制限通信路の容量を示しています。
- Recommendation ITU-R P.372-18, Radio noise (09/2026):T0 = 290 Kでの雑音係数の定義と、大気・天空・人間活動による外来雑音のデータ。
- D. Tse and P. Viswanath, Fundamentals of Wireless Communication, Cambridge University Press, 2005:第5章「Capacity of wireless channels」で、ここで扱った単純なガウス雑音通信路を超えて通信路容量を論じています。