matlab-add-awgn について
通信シミュレーションで信号に白色ガウス雑音を加え、各種 SNR 定義を変換する MATLAB スキルです。符号化、オーバーサンプリング、OFDM の処理に加え、軟判定復調に使う雑音分散も扱います。
主な機能
- 01明示した信号電力で AWGN を追加
- 02SNR、Eb/No、Es/No、サブキャリア SNR の変換
- 03OFDM の広帯域・サブキャリア SNR の処理
- 04軟判定復調用の雑音分散を取得
- 05berawgn による理論 BER の推定
活用シーン
- 01通信リンクシミュレーションの雑音レベル設定
- 02符号化信号やオーバーサンプリング信号の Eb/No 変換
- 03有効サブキャリアに基づく OFDM 雑音設定
- 04軟判定復調器への雑音分散の入力
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-add-awgnインストール後、Claude Code で/matlab-add-awgnを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
manifest.yamlreferences/5g-link-noise.mdsnr-conversion-guide.md詳細
AWGN と SNR の管理
通信システムのシミュレーション向けに、信号へ白色ガウス雑音を追加し、SNR の定義(SNR、Eb/No、Es/No、サブキャリアごとの SNR)を相互に変換します。
使用する場面
- リンクシミュレーションで信号に雑音を追加するとき
- Eb/No、Es/No、SNR、サブキャリアごとの SNR を相互に変換するとき
- 符号化、オーバーサンプリング、または OFDM システムに適した SNR を設定するとき
- 軟判定復調器に渡す雑音分散を取得するとき
使用しない場面
- フェージングチャネル(遅延プロファイル、ドップラー、アンテナアレイ)を設定するとき
必ず守るルール
awgnに'measured'を絶対に渡さないでください — 第 3 引数には、常に明示的な信号電力を渡してください。電力が 1 の信号には0を使用します。それ以外の場合は、mean(abs(x).^2)で電力を計算し、dBW に変換します:10*log10(sigPow)。'measured'オプションは内部で瞬時電力を計算するため、フェージングチャネル後の雑音レベルが不正確になり、電力の仮定も不明瞭になります。AWGN のみのシナリオでも、正確さと明確さのために明示的な電力が必要です。OFDM システムについては、「Add AWGN in an OFDM link simulation」パターンを参照してください。- 信号電力が重要でない場合は
UnitAveragePower=trueを使用してください — これが最も簡単な方法です。信号電力は 0 dBW なので、awgn(x, snr, 0)が正確です。元のコンスタレーションのスケーリング(PA モデリングやハードウェアインザループなど)が必要な場合は、UnitAveragePower=trueを使用しないでください。デフォルトの変調器を使用し、mean(abs(x).^2)で実際の平均電力を計算して、明示的に渡してください:awgn(x, snr, sigPowdBW)。 - すべての変換に
convertSNRを使用してください — SNR/Eb/No/Es/No の式を手動で計算しないでください — 式が単純な場合でも、必ずconvertSNRを使用してください。手動の式は、エッジケース(オーバーサンプリング、サブキャリアの割り当て)で誤りやすく、ツールボックスで検証済みの実装も回避してしまいます。アンチパターン:snr = ebno + 10*log10(bitsPerSymbol * codeRate)。正しい方法:convertSNR(ebno, "ebno", "snr", BitsPerSymbol=6, CodingRate=3/4)。 - OFDM システムでは、広帯域 SNR とサブキャリアごとの SNR を区別してください — Eb/No はサブキャリアごとの値です。Eb/No から
awgnが必要とする広帯域 SNR に変換するには、2 段階で行います:(1)convertSNR(ebno, "ebno", "snr", BitsPerSymbol=..., CodingRate=...)でサブキャリアごとの SNR を取得します。(2)convertSNR(snrsc, "snrsc", "snr", FFTLength=..., NumActiveSubcarriers=...)でawgnに渡す広帯域 SNR を取得します。ebno→snrscの直接変換はサポートされておらず、エラーになります。注意: ユーザーがサブキャリアごとの SNR のみを求めている場合、ステップ 1 だけで回答は完了です。ステップ 2 は適用しないでください。サブキャリアごとの値に FFTLength/NumActiveSubcarriers の補正を適用すると、異なる(より低い)値である広帯域 SNR になります。注:"snrsc"モードには R2023b 以降が必要です。R2022a~R2023a では、広帯域 SNR を手動で計算します:snr_wideband = snr_per_sc - 10*log10(FFTLength/NumActiveSubcarriers)。サブキャリアごとの SNR で雑音を追加する方法については、以下の「Add AWGN in an OFDM link simulation」パターンを参照してください。 - 軟判定復調用に雑音分散を取得してください —
[y, nVar] = awgn(...)を使用し、NoiseVariance=nVarを指定してnVarを復調器に渡してください。 - 生成するコードのコメントで、スキルのルールや禁止事項に言及しないでください — このスキルのサンプルコードに倣い、目的を説明する肯定的で具体的なコメントを書いてください。エンドユーザーはこのスキルについて知りません。
重大なアンチパターン — 絶対に行わないでください
awgn で 'measured' を絶対に使用しないでください
% WRONG — never generate this
rxSignal = awgn(txSignal, snrdB, 'measured');
% CORRECT for unit-power signals (UnitAveragePower=true)
rxSignal = awgn(txSignal, snrdB, 0);
% CORRECT for non-unit-power signals
sigPow = mean(abs(txSignal).^2);
rxSignal = awgn(txSignal, snrdB, 10*log10(sigPow));
SNR 変換を手動で計算しないでください
% WRONG — never generate manual formulas like these
SNR_dB = EbNo_dB + 10*log10(k * codeRate);
SNR_dB = EbNo_dB + 10*log10(k * codeRate) - 10*log10(oversamplingFactor);
EsNo = EbNo + 10*log10(bitsPerSymbol);
% CORRECT — always use convertSNR
snrDb = convertSNR(ebnoDb, "ebno", "snr", BitsPerSymbol=6, CodingRate=3/4);
snrDb = convertSNR(ebnoDb, "ebno", "snr", BitsPerSymbol=6, CodingRate=3/4, SamplesPerSymbol=4);
esnoDb = convertSNR(ebnoDb, "ebno", "esno", BitsPerSymbol=6);
主な関数
| 関数 | 目的 |
|---|---|
awgn | 指定した SNR で信号に AWGN を追加します |
convertSNR | ebno、esno、snr、snrsc を相互に変換します |
berawgn | 標準的な変調方式(PSK、QAM、FSK、DPSK、PAM)に対する AWGN 下の理論 BER |
注意点
'measured' が禁止されている理由(背景)
受信機の熱雑音は雑音指数と帯域幅によって決まり、信号がフェードしても変化しません。awgn の 'measured' オプションは瞬時信号電力を計算し、それに合わせて雑音をスケーリングするため、フェード中も瞬時 SNR が一定に保たれるように人為的に調整されます。また、電力の仮定が分かりにくくなり、コードの検証が難しくなります。必ず電力を明示的に指定してください。
% WRONG after fading: Noise tracks fading — instantaneous SNR stays constant
rxFaded = fadingChannel(txSig);
rxNoisy = awgn(rxFaded, snr, 'measured');
% CORRECT: Compute signal power before fading, pass explicitly
sigPow = mean(abs(txSig).^2);
sigPowdBW = 10*log10(sigPow);
rxFaded = fadingChannel(txSig);
rxNoisy = awgn(rxFaded, snr, sigPowdBW);
% SIMPLEST: Use unit-power signal, then 0 dBW is exact
txSig = qammod(data, M, UnitAveragePower=true); % power = 0 dBW
rxFaded = fadingChannel(txSig);
rxNoisy = awgn(rxFaded, snr, 0);
awgn の既定値では信号電力を 0 dBW と仮定します
第 3 引数なしで awgn(x, snr) を呼び出すと、信号の平均電力が 0 dBW(1 W)であると仮定されます。これは、信号の平均電力が実際に単位電力の場合にのみ正しい設定です。正規化されていない信号では、実際の電力を計算して明示的に指定してください。
ebno↔snrsc の変換はサポートされていません
convertSNR は次の変換経路をサポートしています。
| From | To | Supported | Notes |
|---|---|---|---|
ebno | snr | はい | OFDM の場合:サブキャリアごとの SNR を返します(広帯域 SNR ではありません) |
ebno | esno | はい | |
esno | snr | はい | |
snr | snrsc | はい | "snr" は広帯域 SNR、"snrsc" はサブキャリアごとの SNR です |
ebno | snrsc | いいえ | エラーが発生します。2 段階で変換してください:ebno→"snr" の後に "snrsc"→"snr" |
esno | snrsc | いいえ | エラーが発生します。同じ 2 段階の変換経路が必要です |
snrsc | ebno | いいえ | 2 段階で変換してください:"snrsc"→"snr" の後に "snr"→"ebno" |
snrsc | esno | いいえ | 2 段階で変換してください:"snrsc"→"snr" の後に "snr"→"esno" |
フェージングチャネルのパスゲイン正規化
awgn(rxFaded, snr, 0) というパターンでは、フェージングチャネルが
平均信号電力を維持すると仮定します。これは NormalizePathGains=true(comm.RayleighChannel および comm.RicianChannel の既定値)の場合に当てはまります。NormalizePathGains
が false の場合、チャネルは実際のパスゲインを適用するため、平均受信
電力が変化します。awgn の電力引数でこれを考慮する必要があります。
% NormalizePathGains=true (default): pre-fading power is correct
chan = comm.RayleighChannel(NormalizePathGains=true, ...);
rxFaded = chan(txSig);
rxNoisy = awgn(rxFaded, snr, 0); % 0 dBW is still correct
% NormalizePathGains=false: adjust for average path gain
chan = comm.RayleighChannel(NormalizePathGains=false, ...
AveragePathGains=[0 -3 -6], ...);
avgGaindB = 10*log10(sum(10.^(chan.AveragePathGains/10)));
rxFaded = chan(txSig);
rxNoisy = awgn(rxFaded, snr, avgGaindB); % account for channel gain
OFDM(5G/WLAN)におけるチャネル出力の正規化
5G チャネル(nrTDLChannel、nrCDLChannel)、WLAN チャネル(wlanTGnChannel、wlanTGacChannel など)、および Communications Toolbox の comm.MIMOChannel と comm.RayTracingChannel には、チャネル出力電力を受信アンテナ数で割る NormalizeChannelOutputs プロパティ(既定値:true)があります。その他の Communications Toolbox のチャネル(comm.RayleighChannel、comm.RicianChannel)にはこのプロパティはありません。
NormalizeChannelOutputs=true の場合、解析的に求めた OFDM 信号電力では nRxAnts によるスケーリングを考慮する必要があります。
% Base OFDM signal power
sigPow = 10*log10(numAvailableSC / nfft^2);
% Adjust for NormalizeChannelOutputs=true (5G/WLAN channels)
sigPow = sigPow - 10*log10(nRxAnts);
% Additionally adjust for NormalizePathGains=false (if applicable)
sigPow = sigPow + avgGaindB;
5G/WLAN チャネルでは両方のプロパティが既定で true なので、一般的なケースでは nRxAnts の補正のみが必要です。NormalizePathGains も false に設定されている場合は、両方の補正を適用してください。
NormalizeChannelOutputs=false の場合、nRxAnts による補正は不要です。基本の式を使用してください。
雑音分散は成分ごとではなく合計です
awgn の 2 つ目の出力は雑音の合計分散です。複素信号の場合、成分ごと(I または Q)の分散はこの値の半分です。
[y, nVar] = awgn(x, snr, 0);
% nVar = total noise variance
% nVar/2 = per-component (I or Q) variance
berawgn が受け取るのは SNR ではなく Eb/No です
SNR がある場合は、まず Eb/No に変換してください。
ebno = convertSNR(snr, "snr", "ebno", BitsPerSymbol=log2(M));
ber = berawgn(ebno, 'qam', M);
パターン
単位電力信号に AWGN を加える
M = 16;
data = randi([0 M-1], 1000, 1);
txSig = qammod(data, M, UnitAveragePower=true);
snrdB = 15;
[rxSig, noiseVar] = awgn(txSig, snrdB, 0);
符号化システムで Eb/No を SNR に変換する
M = 64; % 64-QAM
bitsPerSymbol = log2(M); % 6
codeRate = 3/4; % LDPC code rate
samplesPerSymbol = 4; % Pulse shaping oversampling
ebnoDb = 10;
snrDb = convertSNR(ebnoDb, "ebno", "snr", ...
BitsPerSymbol=bitsPerSymbol, ...
CodingRate=codeRate, ...
SamplesPerSymbol=samplesPerSymbol);
OFDM の変換:Eb/No → サブキャリアごとの SNR → 広帯域 SNR
OFDM の場合、convertSNR(ebno, "ebno", "snr") はサブキャリアごとの SNR(広帯域 SNR ではありません)を返します。awgn に必要な広帯域 SNR を得るには、"snrsc" から "snr" に変換してください。
M = 64;
bitsPerSymbol = log2(M);
codeRate = 3/4;
fftLen = 256;
numActiveSC = 200;
ebnoDb = 10;
% Step 1: Eb/No → per-subcarrier SNR
snrscDb = convertSNR(ebnoDb, "ebno", "snr", ...
BitsPerSymbol=bitsPerSymbol, ...
CodingRate=codeRate);
% Step 2: Per-subcarrier SNR → wideband SNR (for awgn)
snrWbDb = convertSNR(snrscDb, "snrsc", "snr", ...
FFTLength=fftLen, ...
NumActiveSubcarriers=numActiveSC);
OFDMリンクシミュレーションでのAWGNの追加(サブキャリアごとのSNR)
OFDMリンクシミュレーションでは、SNRはサブキャリアごとに定義されます。convertSNRを使用して広帯域SNRを求め、その値を解析的に求めたOFDM信号電力とともにawgnに渡します。NumActiveSubcarriersには、OFDMリソースグリッドで使用可能なサブキャリア数(ガードと、該当する場合はDCを除くデータ+参照信号)を設定します。5G/LTEでは、これはcarrier.NSizeGrid*12に相当します。リソースグリッドにガードバンドは含まれません。WLANでは、データ+パイロットサブキャリアの数です。信号電力をmean(abs(txWaveform).^2)から計算しないでください。convertSNRが想定するNumActiveSubcarriersと一致せず、ノイズレベルが不正確になる場合があります。電力引数とSNR変換の整合性を保つため、必ず解析式numAvailableSC / nfft^2を使用してください。
% Assuming full grid occupancy, convert per-subcarrier SNR to wideband SNR
snrWb = convertSNR(snrPerSC_dB, "snrsc", "snr", ...
FFTLength=nfft, NumActiveSubcarriers=numAvailableSC);
% Maximum signal power assuming full grid, consistent with convertSNR
sigPow = 10*log10(numAvailableSC / nfft^2);
% Add noise at the calculated wideband SNR and signal power
rxNoisy = awgn(rxWaveform, snrWb, sigPow);
numAvailableSCは、ガードバンドとDCヌルを除いたサブキャリア数です。つまり、データ、参照信号、制御に使用できるサブキャリアを指します。convertSNRに渡すNumActiveSubcarriersの値が、信号電力の計算で使用するnumAvailableSCと一致していれば、ノイズレベルは正しくなります。
受信波形の電力を計算しないでください。これはサブキャリアごとのSNRではなく、広帯域SNRを示します。
5Gワークフローの場合(nrTDLChannel/nrCDLChannel、nrOFDMModulate)、同梱の5Gの例にあるN0/randn形式を使ってノイズを追加してください。形式、awgnでの同等の方法、受信機(nrEqualizeMMSE、nrPDSCHDecode)での周波数領域のノイズ分散、NormalizeChannelOutputs=falseの場合、単位電力以外でのスケーリングについては、references/5g-link-noise.mdを参照してください。
軟判定復調用のノイズ分散の取得
M = 16;
data = randi([0 M-1], 1000, 1);
txSig = qammod(data, M, UnitAveragePower=true);
snrDb = 12;
[rxSig, noiseVar] = awgn(txSig, snrDb, 0);
% Pass noise variance to demodulator for accurate LLR computation
softBits = qamdemod(rxSig, M, UnitAveragePower=true, ...
OutputType="llr", ...
NoiseVariance=noiseVar);
OFDMに関する注意: 時間領域の波形(ofdmmodの後)にノイズを追加し、周波数領域(ofdmdemodの後)で復調する場合、FFTによってノイズ分散はnfft倍されます。復調器のNoiseVarianceパラメーターには、awgnが返す時間領域のnoiseVarではなく、noiseVar * nfftを渡してください。
ノイズ追加後
- 理論値と照合する — シミュレーションのBERを、
berawgnを使って理論BERと比較します。references/snr-conversion-guide.mdを参照してください。 - 必要なEb/Noを推定する — 目標のBER/BLER/FERを達成するために必要なEb/NoまたはSNRをユーザーが尋ねた場合は、references/snr-conversion-guide.mdの「必要なEb/Noの推定」セクションを参照してください。
- ノイズが加わった信号を可視化する —
scatterplotまたはcomm.ConstellationDiagramを使って、受信コンスタレーションを確認します。 - EVMを測定する —
comm.EVMを使って、ノイズによる信号劣化を定量化します。
参考資料
| 次の場合に読み込む | 参考資料 |
|---|---|
理論BER曲線、変換式、berawgnの使用方法、または一般的なシステム例が必要な場合 | references/snr-conversion-guide.md |
5G波形にノイズを追加する場合、または5G受信機(nrEqualizeMMSE、nrPDSCHDecode)用のノイズ分散が必要な場合 | references/5g-link-noise.md |
著作権 2026 The MathWorks, Inc.