MATLABでQPSK変調のBER測定をシミュレーションしてみる
こんにちは。
最近MATLABを購入しました。
MATLABというと、昔は大変高価なもので、とても一個人で購入できるような代物ではなかったのですが、何年か前から個人利用向けの安価なバージョンであるMATLAB Homeが販売されているようです。
さて、以前pythonによるBPSK変調のBER計算のシミュレーションを行いましたが、今回はMATLABを使って、QPSK変調のBER計算のシミュレーションを実施してみたいと思います。
MATLABは高いから頑張ってpythonで信号処理のシミュレーション組めるようにしよう!と以前は意気込んでいましたが、やっぱMATLABの方が楽でいいです(;^_^A
●この記事の目次
1.この記事で説明しないこと
MATLABの使い方を説明することが主目的であるため、BPSK、BERといったディジタル無線通信関連の専門用語の内容についてはこの記事では説明しません。
2.QPSK変調のBER測定シミュレーションのサンプルコード
ではさっそくMATLABによるQPSK変調のBER測定シミュレーションのmファイルのサンプルコードを以下に示します。
clear; close; clc; % 初期パラメータ Ns = 10^7; % 送信ビット数 SNdB = 0:0.5:15; % SNRのベクトル BER = zeros(1, length(SNdB)); % BERのシミュレーション結果を格納するベクトル BER_theory = zeros(1, length(SNdB)); % BERの理論値を格納するベクトル % SNRを変化させながら、BERを計算 for index = 1:length(SNdB) %%%%% 送信ビット列の生成 %%%% TxData = randi([0, 1], 2, Ns/2); %%%%% QPSK変調 %%%%% % 00:1+i, 01:1-i, 11:-1-i, 10:-1+i % Ichの信号生成 Ich = TxData(1, :); Ich(find(Ich == 1)) = -1; Ich(find(Ich == 0)) = 1; Ich = Ich / sqrt(2); % Qchの信号生成 Qch = TxData(2, :); Qch(find(Qch == 1)) = -1; Qch(find(Qch == 0)) = 1; Qch = Qch / sqrt(2); % IQ信号の複素信号の生成 QPSKMod = Ich + Qch*i; %%%%% AWGN信号の生成 %%%%% % ノイズ電力の真値を計算 Pn = 10^(-SNdB(index)/10); % AWGN信号の生成 Noise = (randn(1, Ns/2) + randn(1, Ns/2)*i) * sqrt(Pn/2); %%%%% 受信信号の計算 %%%%% RxSig = QPSKMod + Noise; %%%%% 復調処理 %%%%% % オールゼロの行列を生成 DemodData = zeros(2, Ns/2); % 実部および虚部が負値になっている箇所を1に書き換え DemodData(1, find(real(RxSig) < 0)) = 1; DemodData(2, find(imag(RxSig) < 0)) = 1; % BERの計算 BER(index) = sum(sum(abs(TxData - DemodData))) / Ns; % BER理論値の計算 SN = 10^(SNdB(index)/10); BER_theory(index) = erfc(sqrt(SN/2))/2; % 計算結果の表示 disp("SNdB=" + SNdB(index) + " BER=" + BER(index)); disp("SNdB=" + SNdB(index) + " BER_theory=" + BER_theory(index)); end %%%%% グラフにプロット %%%%% semilogy(SNdB, BER,"o", SNdB, BER_theory); %片対数表示 legend("シミュレーション", "理論値"); %凡例の表示 xlabel("SNR[dB]"); %横軸ラベルの表示 ylabel("BER"); %縦軸ラベルの表示 grid on;
BERのグラフ表示は以下のようになります。
図1-1 SN[dB] 対 BERグラフ
3.ディジタル変復調のシミュレーションで覚えておきたい関数
(1)randi([A, B], X, Y)
0,1のランダムデータ列の生成には、randi()関数を使用します。
上記の引数により、AからBの範囲のランダムな整数を含むX行Y列の行列を生成します。
ここでは、randi([0, 1], 2, Ns/2)とすることで、2行5×10^6列の行列を生成しています。
(2)randn(X, Y)
AWGN信号の生成には、randn()関数を使用します。
上記の引き数により、X行Y列の標準正規分布の乱数データ列を生成します。
(3)find(条件式)
ベクトルまたは行列に対する条件式を入力すると、条件式に対して結果が真となる要素のインデックス番号を返します。
文章だけだとわかりづらいので、具体的な実行結果を↓に例示します。
(要素のインデックス番号は1行1列目(左上)から列方向(下)にカウントされている点に注意)