このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
comm.LinearEqualizer
線形フィルターを使用した変調信号のイコライズ
説明
comm.LinearEqualizer
System object™ は、重み付き和をもつ線形フィルター タップ付き遅延線を使用して、分散チャネルを介して送信される変調信号をイコライズします。イコライザー オブジェクトは、選択されたアルゴリズムに基づいてタップ重みを適応的に調整します。詳細については、アルゴリズムを参照してください。
線形フィルターを使用して変調信号をイコライズするには:
comm.LinearEqualizer
オブジェクトを作成し、そのプロパティを設定します。関数と同様に、引数を指定してオブジェクトを呼び出します。
System object の機能の詳細については、System object とはを参照してください。
作成
プロパティ
特に指定がない限り、プロパティは "調整不可能" です。つまり、オブジェクトの呼び出し後に値を変更することはできません。オブジェクトは呼び出すとロックされ、ロックを解除するには関数 release
を使用します。
プロパティが "調整可能" の場合、その値をいつでも変更できます。
プロパティ値の変更の詳細については、System object を使用した MATLAB でのシステム設計を参照してください。
イコライズに使用される適応アルゴリズム。以下のいずれかの値として指定します。
'LMS'
— 最小平均二乗 (LMS) アルゴリズムを使用してイコライザーのタップ重みを更新します。'RLS'
— 再帰的最小二乗 (RLS) アルゴリズムを使用してイコライザーのタップ重みを更新します。'CMA'
— 定包絡線基準アルゴリズム (CMA)を使用してイコライザーのタップ重みを更新します。
データ型: char
| string
イコライザーのタップ数。正の整数として指定します。イコライザーのタップ数は、InputSamplesPerSymbol
プロパティの値以上でなければなりません。
データ型: double
適応アルゴリズムで使用される忘却係数。範囲 (0, 1] のスカラーとして指定します。忘却係数を小さくすると、イコライザーの収束時間が短縮されますが、イコライザーの出力推定の安定性が低下します。
調整可能: Yes
依存関係
このプロパティを有効にするには、Algorithm を 'RLS'
に設定します。
データ型: double
信号コンスタレーション。ベクトルとして指定します。既定値は、次のコードを使用して生成された QPSK コンスタレーションです: pskmod(0:3,4,pi/4)
。
データ型: double
リファレンス タップ。NumTaps プロパティ値以下の正の整数として指定します。イコライザーは、リファレンス タップ位置を使用してチャネルのメイン エネルギーを追跡します。
データ型: double
シンボルあたりの入力サンプル数。正の整数として指定します。このプロパティを 1 より大きい数値に設定すると、分数間隔イコライザーが効率的に作成されます。詳細については、シンボル タップ間隔を参照してください。
データ型: double
学習制御入力を有効にします。論理値 0
(false
) または 1
(true
) として指定します。このプロパティを true
に設定すると、イコライザーの学習フラグ入力 tf が有効になります。
データ型: logical
学習中でないときにタップ重みを更新します。論理値 1
(true
) または 0
(false
) として指定します。このプロパティが true
に設定されている場合、System object は判定指向モードを使用してイコライザーのタップ重みを更新します。このプロパティが false
に設定されている場合、System object は学習後にイコライザーのタップ重みを変更せずに維持します。
データ型: logical
タップ重みの適応要求のソース。以下のいずれかの値として指定します。
'Property'
— System object がタップ重みをいつ適応させるかを制御するために AdaptWeights プロパティを使用するには、この値を指定します。'Input port'
— System object がタップ重みをいつ適応させるかを制御するためにaw
入力を使用するには、この値を指定します。
依存関係
このプロパティを有効にするには、Algorithm を 'CMA'
に設定します。
データ型: char
| string
タップ重みの適応。論理値 1
(true
) または 0
(false
) として指定します。このプロパティが true
に設定されている場合、System object はイコライザーのタップ重みを更新します。このプロパティが false
に設定されている場合、System object はイコライザーのタップ重みを変更せずに維持します。
依存関係
このプロパティを有効にするには、AdaptWeightsSource を 'Property'
に設定し、AdaptAfterTraining を true
に設定します。
データ型: logical
初期タップ重みのソース。以下で指定します。
'Auto'
— InitialWeights プロパティで説明されているように、タップ重みをアルゴリズム固有の既定値に初期化します。'Property'
— InitialWeights プロパティ値を使用してタップ重みを初期化します。
データ型: char
| string
適応アルゴリズムで使用される初期タップ重み。スカラーまたはベクトルとして指定します。Algorithm プロパティが 'LMS'
または 'RLS'
に設定されている場合、既定は 0
です。Algorithm プロパティが 'CMA'
に設定されている場合、既定は [0;0;1;0;0]
です。
InitialWeights
をベクトルとして指定した場合、ベクトルの長さは NumTaps プロパティ値と等しくなければなりません。InitialWeights
をスカラーとして指定した場合、イコライザーはスカラー拡張を使用して、長さが NumTaps ですべての値が InitialWeights
に設定されたベクトルを作成します。
依存関係
このプロパティを有効にするには、InitialWeightsSource を 'Property'
に設定します。
データ型: double
シンボル単位のタップ重みの更新周期。正の整数として指定します。イコライザーは、この数のシンボルを処理した後にタップ重みを更新します。
データ型: double
使用法
説明
入力引数
入力信号。列ベクトルで指定します。入力信号のベクトルの長さは、InputSamplesPerSymbol プロパティ値の整数倍に等しくなければなりません。詳細については、シンボル タップ間隔を参照してください。
このオブジェクトは可変サイズの入力を受け入れます。オブジェクトがロックされると、各入力チャネルのサイズは変更できますが、チャネルの数は変更できません。詳細については、Variable-Size Signal Support with System Objectsを参照してください。
データ型: double
複素数のサポート: あり
トレーニング シンボル。入力 X
の長さ以下の長さの列ベクトルとして指定します。tf
が false
の場合、入力 tsym
は無視されます。
依存関係
この引数を有効にするには、Algorithm プロパティを 'LMS'
または 'RLS'
に設定します。
データ型: double
複素数のサポート: あり
学習フラグ。論理値 1
(true
) または 0
(false
) として指定します。(立ち上がりエッジで) tf
が false
から true
に変化すると、System object が学習を開始します。System object は、tsym
のすべてのシンボルが処理されるまで学習を続けます。tf
が false
の場合、入力 tsym
は無視されます。
依存関係
この引数を有効にするには、Algorithm プロパティを 'LMS'
または 'RLS'
に設定し、TrainingFlagInputPort プロパティを true
に設定します。
データ型: logical
重みの適応フラグ。論理値 1
(true
) または 0
(false
) として指定します。aw
が true
の場合、System object は重みを適応させます。aw
が false
の場合、System object は重みを変更せずに維持します。
依存関係
この引数を有効にするには、Algorithm プロパティを 'CMA'
に設定し、AdaptWeightsSource プロパティを 'Input port'
に設定します。
データ型: logical
オブジェクト関数
オブジェクト関数を使用するには、System object を最初の入力引数として指定します。たとえば、obj
という名前の System object のシステム リソースを解放するには、次の構文を使用します。
release(obj)
例
8 つのタップをもちステップ サイズが 0.03 の線形 LMS イコライザーを指定して、イコライザー System object™ を作成します。
eqlms = comm.LinearEqualizer( ... 'Algorithm','LMS', ... 'NumTaps',8, ... 'StepSize',0.03);
イコライザーのリファレンス タップ インデックスを変更します。
eqlms.ReferenceTap = 4;
テスト データのセットを作成します。信号の畳み込みを行ってデータを受信します。
M = 2; % BPSK modulate
x = pskmod(randi([0 1],1000,1),M);
rxsig = conv(x,[1 0.8 0.3]);
maxstep
を使用して最大許容ステップ サイズを求めます。
mxStep = maxstep(eqlms,rxsig)
mxStep = 0.1384
受信信号をイコライズします。最初の 200 個のシンボルをトレーニング シーケンスとして使用します。
y = eqlms(rxsig,x(1:200));
最小平均二乗 (LMS) アルゴリズムを使用した線形イコライズを適用して、マルチパス AWGN チャネル経由で渡した QPSK シンボルを復元します。
シミュレーション変数を初期化します。
M = 4; % QPSK
numSymbols = 10000;
numTrainingSymbols = 1000;
chtaps = [1 0.5*exp(1i*pi/6) 0.1*exp(-1i*pi/8)];
QPSK 変調されたシンボルを生成します。シンボルにマルチパス チャネルのフィルター処理と AWGN 障害を適用します。
data = randi([0 M-1],numSymbols,1);
tx = pskmod(data,M,pi/4);
rx = awgn(filter(chtaps,1,tx),25,'measured');
線形イコライザー System object を作成し、既定の構成を表示します。リファレンス タップを 1
に調整します。最大許容ステップ サイズをチェックします。劣化したシンボルをイコライズします。
eq = comm.LinearEqualizer
eq = comm.LinearEqualizer with properties: Algorithm: 'LMS' NumTaps: 5 StepSize: 0.0100 Constellation: [0.7071 + 0.7071i -0.7071 + 0.7071i -0.7071 - 0.7071i 0.7071 - 0.7071i] ReferenceTap: 3 InputDelay: 0 InputSamplesPerSymbol: 1 TrainingFlagInputPort: false AdaptAfterTraining: true InitialWeightsSource: 'Auto' WeightUpdatePeriod: 1
eq.ReferenceTap = 1; mxStep = maxstep(eq,rx)
mxStep = 0.3172
[y,err,weights] = eq(rx,tx(1:numTrainingSymbols));
劣化したシンボルとイコライズされたシンボルのコンスタレーションをプロットします。
constell = comm.ConstellationDiagram('NumInputPorts',2);
constell(rx,y);
イコライザーの誤差信号をプロットし、イコライズされたシンボルのエラー ベクトル振幅 (EVM) を計算します。
plot(abs(err)); grid on; xlabel('Symbols'); ylabel('|e|'); title('Equalizer Error Signal');
errevm = comm.EVM; evm = errevm(tx,y)
evm = 11.8694
イコライザーのタップ重みをプロットします。
subplot(3,1,1); stem(real(weights)); ylabel('real(weights)'); xlabel('Tap'); grid on; axis([0 6 -0.5 1]); title('Equalizer Tap Weights'); subplot(3,1,2); stem(imag(weights)); ylabel('imag(weights)'); xlabel('Tap'); grid on; axis([0 6 -0.5 1]); subplot(3,1,3); stem(abs(weights)); ylabel('abs(weights)'); xlabel('Tap'); grid on; axis([0 6 -0.5 1]);
最小平均二乗 (LMS) アルゴリズムを使用した線形イコライズを示して、AWGN チャネル経由で渡した QPSK シンボルを復元します。異なるイコライザーの学習スキームを適用して、シンボルの誤差の大きさを示します。
システム設定
AWGN の影響を受ける QPSK 変調システムをシミュレートします。200 個のトレーニング シンボルと 1800 個のランダム データ シンボルで構成されるパケットを送信します。パケット データを復元するように線形 LMS イコライザーを構成します。
M = 4; numTrainSymbols = 200; numDataSymbols = 1800; SNR = 20; trainingSymbols = pskmod(randi([0 M-1],numTrainSymbols,1),M,pi/4); numPkts = 10; lineq = comm.LinearEqualizer( ... Algorithm="LMS", ... NumTaps=5, ... ReferenceTap=3, ... StepSize=0.01);
リセットを使用する各パケットの先頭でのイコライザーの学習
各パケットを処理するときに、先頭に追加されたトレーニング シンボルを使用します。各パケットの処理後にイコライザーをリセットします。このリセットにより、イコライザーは事前知識なしにタップを学習するようになります。最初、2 番目、および最後のパケットのイコライザー誤差信号プロットは、各パケットの先頭でシンボル エラーが多くなっていることを示しています。
jj = 1; figure for ii = 1:numPkts b = randi([0 M-1],numDataSymbols,1); dataSym = pskmod(b,M,pi/4); packet = [trainingSymbols;dataSym]; rx = awgn(packet,SNR); [~,err] = lineq(rx,trainingSymbols); reset(lineq) if (ii ==1 || ii == 2 ||ii == numPkts) subplot(3,1,jj) plot(abs(err)) title(['Packet # ',num2str(ii)]) xlabel('Symbols') ylabel('Error Magnitude') axis([0,length(packet),0,1]) grid on; jj = jj+1; end end
リセットを使用しない各パケットの先頭でのイコライザーの学習
先頭に追加されたトレーニング シンボルを使用して各パケットを処理します。各パケットの処理後にイコライザーをリセットしません。各パケットの後にリセットしないことで、イコライザーは前のパケットの学習によるタップ重みを保持します。最初、2 番目、および最後のパケットのイコライザー誤差信号プロットは、最初のパケットに対する初期学習の後に、後続のパケットが各パケットの先頭でシンボル エラーが少なくなることを示しています。
release(lineq) jj = 1; figure for ii = 1:numPkts b = randi([0 M-1],numDataSymbols,1); dataSym = pskmod(b,M,pi/4); packet = [trainingSymbols;dataSym]; channel = 1; rx = awgn(packet*channel,SNR); [~,err] = lineq(rx,trainingSymbols); if (ii ==1 || ii == 2 ||ii == numPkts) subplot(3,1,jj) plot(abs(err)) title(['Packet # ',num2str(ii)]) xlabel('Symbols') ylabel('Error Magnitude') axis([0,length(packet),0,1]) grid on; jj = jj+1; end end
周期的なイコライザーの学習
時変チャネルの影響を受ける信号があるシステムには、チャネル変動に対してロックを維持するために周期的なイコライザーの学習が必要です。1800 個のデータ シンボルごとに 200 個のシンボルの学習を行うシステムを指定します。学習の合間では、イコライザーはタップ重みを更新しません。イコライザーはパケットあたり 200 個のシンボルを処理します。
Rs = 1e6;
fd = 20;
spp = 200; % Symbols per packet
b = randi([0 M-1],numDataSymbols,1);
dataSym = pskmod(b,M,pi/4);
packet = [trainingSymbols; dataSym];
stream = repmat(packet,10,1);
tx = (0:length(stream)-1)'/Rs;
channel = exp(1i*2*pi*fd*tx);
rx = awgn(stream.*channel,SNR);
AdaptAfterTraining
プロパティを false
に設定して、学習フェーズの後にイコライザーのタップ重みの更新を停止します。
release(lineq) lineq.AdaptAfterTraining = false
lineq = comm.LinearEqualizer with properties: Algorithm: 'LMS' NumTaps: 5 StepSize: 0.0100 Constellation: [0.7071 + 0.7071i -0.7071 + 0.7071i -0.7071 - 0.7071i 0.7071 - 0.7071i] ReferenceTap: 3 InputDelay: 0 InputSamplesPerSymbol: 1 TrainingFlagInputPort: false AdaptAfterTraining: false InitialWeightsSource: 'Auto' WeightUpdatePeriod: 1
劣化したデータをイコライズします。チャネルからの角度誤差、イコライザーの誤差信号、および信号コンスタレーションをプロットします。チャネルが変動しても、イコライザー出力からチャネルの影響は除去されません。出力コンスタレーションが同期せずに回転し、ビット エラーが発生します。
[y,err] = lineq(rx,trainingSymbols); figure subplot(2,1,1) plot(tx, unwrap(angle(channel))) xlabel('Time (sec)') ylabel('Channel Angle (rad)') title('Angular Error Over Time') subplot(2,1,2) plot(abs(err)) xlabel('Symbols') ylabel('Error Magnitude') grid on title('Time-Varying Channel Without Retraining')
scatterplot(y)
TrainingInputPort
プロパティを true
に設定し、trainFlag
入力により信号が送られたときにタップを再学習するようにイコライザーを構成します。イコライザーは、trainFlag
が true
の場合にのみ学習を行います。イコライザーは 2000 個のシンボルごとにタップを再学習し、チャネルの変動に対してロックを維持します。チャネルからの角度誤差、イコライザーの誤差信号、および信号コンスタレーションをプロットします。チャネルが変動すると、イコライザー出力からチャネルの影響が除去されます。出力コンスタレーションが同期せずに回転することがなくなり、ビット エラーが減少します。
release(lineq) lineq.TrainingFlagInputPort = true; symbolCnt = 0; numPackets = length(rx)/spp; trainFlag = true; trainingPeriod = 2000; eVec = zeros(size(rx)); yVec = zeros(size(rx)); for p=1:numPackets [yVec((p-1)*spp+1:p*spp,1),eVec((p-1)*spp+1:p*spp,1)] = ... lineq(rx((p-1)*spp+1:p*spp,1),trainingSymbols,trainFlag); symbolCnt = symbolCnt + spp; if symbolCnt >= trainingPeriod trainFlag = true; symbolCnt = 0; else trainFlag = false; end end figure subplot(2,1,1) plot(tx, unwrap(angle(channel))) xlabel('t (sec)') ylabel('Channel Angle (rad)') title('Angular Error Over Time') subplot(2,1,2) plot(abs(eVec)) xlabel('Symbols') ylabel('Error Magnitude') grid on title('Time-Varying Channel With Retraining')
scatterplot(yVec)
送信シンボルと受信サンプルの間に遅延があるシステムをシミュレートします。一般的なシステムには送信側と受信側のフィルターがあり、これにより遅延が発生します。システムを同期させるには、この遅延を考慮しなければなりません。この例では、送信フィルターと受信フィルターを使用せずにシステム遅延が発生しています。線形イコライズは、最小平均二乗 (LMS) アルゴリズムを使用して、QPSK シンボルを復元します。
シミュレーション変数を初期化します。
M = 4; % QPSK
numSymbols = 10000;
numTrainingSymbols = 1000;
mpChan = [1 0.5*exp(1i*pi/6) 0.1*exp(-1i*pi/8)];
systemDelay = dsp.Delay(20);
snr = 24;
QPSK 変調されたシンボルを生成します。送信シンボルにマルチパス チャネルのフィルター処理、システム遅延、および AWGN を適用します。
data = randi([0 M-1],numSymbols,1); tx = pskmod(data,M,pi/4); % OQPSK delayedSym = systemDelay(filter(mpChan,1,tx)); rx = awgn(delayedSym,snr,'measured');
イコライザーおよび EVM の System object を作成します。イコライザー System object は、LMS アルゴリズムを使用する線形イコライザーを指定します。
lineq = comm.LinearEqualizer('Algorithm','LMS', ... 'NumTaps',9,'ReferenceTap',5); evm = comm.EVM('ReferenceSignalSource', ... 'Estimated from reference constellation');
入力遅延を調整しないイコライズ
受信シンボルをイコライズします。
[y1,err1,wts1] = lineq(rx,tx(1:numTrainingSymbols,1));
関数 finddelay
を使用して、受信シンボルと送信シンボルの間の遅延を検出します。
rxDelay = finddelay(tx,rx)
rxDelay = 20
イコライザー情報を表示します。レイテンシ値は、イコライザーによって発生した遅延を示します。合計遅延を、rxDelay
とイコライザーのレイテンシの合計として計算します。
eqInfo = info(lineq)
eqInfo = struct with fields:
Latency: 4
totalDelay = rxDelay + eqInfo.Latency;
イコライザー出力が収束するまで、シンボル エラー レートは高くなります。誤り出力 err1
をプロットして、イコライズされた出力がいつ収束するかを判断します。
plot(abs(err1)) xlabel('Symbols') ylabel('Error Magnitude') title('Equalizer Error Signal')
このプロットでは、1000 個のシンボルの学習期間を超えて過度な誤りが示されています。シンボルを復調してシンボル エラーを計算するときは、収束していない出力と、イコライザー出力と送信シンボルの間のシステム遅延を考慮して、最初の 2000 個のシンボルをスキップします。
dataRec1 = pskdemod(y1(2000+totalDelay:end),M,pi/4); symErrWithDelay = symerr(data(2000:end-totalDelay),dataRec1)
symErrWithDelay = 5999
evmWithDelay = evm(y1)
evmWithDelay = 32.0802
イコライザー System object で受信遅延が考慮されていないため、エラー レートと EVM が高くなります。
イコライザーでの入力遅延の調整
遅延値を使用して InputDelay
プロパティを設定し、受信データをイコライズします。InputDelay
は調整できないプロパティであるため、InputDelay
プロパティを再構成するには lineq
System object を解放しなければなりません。受信シンボルをイコライズします。
release(lineq) lineq.InputDelay = rxDelay
lineq = comm.LinearEqualizer with properties: Algorithm: 'LMS' NumTaps: 9 StepSize: 0.0100 Constellation: [0.7071 + 0.7071i -0.7071 + 0.7071i -0.7071 - 0.7071i 0.7071 - 0.7071i] ReferenceTap: 5 InputDelay: 20 InputSamplesPerSymbol: 1 TrainingFlagInputPort: false AdaptAfterTraining: true InitialWeightsSource: 'Auto' WeightUpdatePeriod: 1
[y2,err2,wts2] = lineq(rx,tx(1:numTrainingSymbols,1));
タップ重みとイコライズされた誤差の大きさをプロットします。ステム プロットは、システム遅延が除去される前後のイコライザーのタップ重みを示します。2 次元ライン プロットは、遅延が除去された信号と比較して、遅延信号のイコライザー収束が遅いことを示しています。
subplot(2,1,1) stem([real(wts1),real(wts2)]) xlabel('Taps') ylabel('Tap Weight Real') legend('rxDelayed','rxDelayRemoved') grid on subplot(2,1,2) stem([imag(wts1),imag(wts2)]) xlabel('Taps') ylabel('Tap Weight Imaginary') legend('rxDelayed','rxDelayRemoved') grid on
figure plot([abs(err1),abs(err2)]) xlabel('Symbols') ylabel('Error Magnitude') legend('rxDelayed','rxDelayRemoved') grid on
イコライズされた信号 rxDelayed
および rxDelayRemoved
の誤り出力をプロットします。遅延が除去された信号では、イコライザーは 1000 個のシンボルの学習期間中に収束します。シンボルを復調してシンボル エラーを計算するときは、収束していない出力と、イコライザー出力と送信シンボルの間のシステム遅延を考慮して、最初の 500 個のシンボルをスキップします。システム遅延を考慮するためにイコライザーを再構成すると、信号のイコライズが改善され、シンボル エラーと EVM が減少します。
eqInfo = info(lineq)
eqInfo = struct with fields:
Latency: 4
totalDelay = rxDelay + eqInfo.Latency; dataRec2 = pskdemod(y2(500+totalDelay:end),M,pi/4); symErrDelayRemoved = symerr(data(500:end-totalDelay),dataRec2)
symErrDelayRemoved = 0
evmDelayRemoved = evm(y2(500+totalDelay:end))
evmDelayRemoved = 9.4364
定包絡線基準アルゴリズム (CMA) と EVM ベースのタップの学習を使用して、線形イコライザーで QPSK シンボルを復元します。CMA などのブラインド イコライザー アルゴリズムを使用する場合は、AdaptWeights
プロパティを使用して学習を開始および停止することによって、イコライザーのタップを学習させます。補助関数を使用してプロットを生成し、位相補正を適用します。
システム変数を初期化します。
rng(123456); M = 4; % QPSK numSymbols = 100; numPackets = 5000; raylChan = comm.RayleighChannel( ... 'PathDelays',[0 1], ... 'AveragePathGains',[0 -12], ... 'MaximumDopplerShift',1e-5); SNR = 50; adaptWeights = true;
イコライザーおよび EVM の System object を作成します。イコライザー System object は、CMA 適応アルゴリズムを使用して線形イコライザーを指定します。補助関数を呼び出して Figure のプロットを初期化します。
lineq = comm.LinearEqualizer( ... 'Algorithm','CMA', ... 'NumTaps',5, ... 'ReferenceTap',3, ... 'StepSize',0.03, ... 'AdaptWeightsSource','Input port')
lineq = comm.LinearEqualizer with properties: Algorithm: 'CMA' NumTaps: 5 StepSize: 0.0300 Constellation: [0.7071 + 0.7071i -0.7071 + 0.7071i -0.7071 - 0.7071i 0.7071 - 0.7071i] ReferenceTap: 3 InputSamplesPerSymbol: 1 AdaptWeightsSource: 'Input port' InitialWeightsSource: 'Auto' WeightUpdatePeriod: 1
info(lineq)
ans = struct with fields:
Latency: 2
evm = comm.EVM('ReferenceSignalSource', ... 'Estimated from reference constellation'); [errPlot,evmPlot,scatSym,adaptState] = ... initFigures(numPackets,lineq);
イコライズ ループ
イコライズ ループを実装するには、以下の手順に従います。
PSK データ パケットを生成します。
レイリー フェージングと AWGN を送信データに適用します。
受信データにイコライズを、イコライザー出力に位相補正を適用します。
EVM を推定し、EVM レベルに基づいて
adaptWeights
フラグをtrue
またはfalse
に切り替えます。Figure のプロットを更新します。
for p=1:numPackets data = randi([0 M-1],numSymbols,1); tx = pskmod(data,M,pi/4); rx = awgn(raylChan(tx),SNR); rxDelay = finddelay(rx,tx); [y,err,wts] = lineq(rx,adaptWeights); y = phaseCorrection(y); evmEst = evm(y); adaptWeights = (evmEst > 20); updateFigures(errPlot,evmPlot,scatSym,adaptState, ... wts,y(end),evmEst,adaptWeights,p,numPackets) end
rxDelay
rxDelay = 0
Figure のプロットは、EVM が変化するにつれて、イコライザーが判定指向の重み適応モードのオンとオフを切り替えていることを示しています。
補助関数
この補助関数は、シミュレーション結果の 4 つのプロットを示す Figure を初期化します。
function [errPlot,evmPlot,scatter,adaptState] = ... initFigures(numPkts,lineq) yVec = nan(numPkts,1); evmVec = nan(numPkts,1); wVec = zeros(lineq.NumTaps,1); adaptVec = nan(numPkts,1); figure subplot(2,2,1) evmPlot = stem(wVec); grid on; axis([1 lineq.NumTaps 0 1.8]) xlabel('Taps'); ylabel('|Weights|'); title('Tap Weight Magnitude') subplot(2,2,2) scatter = plot(yVec, '.'); axis square; axis([-1.2 1.2 -1.2 1.2]); grid on xlabel('In-phase'); ylabel('Quadrature'); title('Scatter Plot'); subplot(2,2,3) adaptState = plot(adaptVec); grid on; axis([0 numPkts -0.2 1.2]) ylabel('Training'); xlabel('Symbols'); title('Adapt Weights Signal') subplot(2,2,4) errPlot = plot(evmVec); grid on; axis([1 numPkts 0 100]) xlabel('Symbols'); ylabel('EVM (%)'); title('EVM') end
この補助関数は Figure を更新します。
function updateFigures(errPlot,evmPlot,scatSym, ... adaptState,w,y,evmEst,adaptWts,p,numFrames) persistent yVec evmVec adaptVec if p == 1 yVec = nan(numFrames,1); evmVec = nan(numFrames,1); adaptVec = nan(numFrames,1); end yVec(p) = y; evmVec(p) = evmEst; adaptVec(p) = adaptWts; errPlot.YData = abs(evmVec); evmPlot.YData = abs(w); scatSym.XData = real(yVec); scatSym.YData = imag(yVec); adaptState.YData = adaptVec; drawnow limitrate end
この補助関数は位相補正を適用します。
function y = phaseCorrection(y) a = angle(y((real(y) > 0) & (imag(y) > 0))); a(a < 0.1) = a(a < 0.1) + pi/2; theta = mean(a) - pi/4; y = y * exp(-1i*theta); end
最小平均二乗 (LMS) アルゴリズムを使用して、線形イコライザーでフェージング環境の QPSK シンボルを復元します。オブジェクト関数 reset
を使用して、独立したパケットをイコライズします。補助関数を使用してプロットを生成します。この例では、シンボルベースの処理とフレームベースの処理も示します。
設定
システム変数を初期化し、イコライザー System object を作成して、プロット図を初期化します。
M = 4; % QPSK numSym = 1000; numTrainingSym = 100; numPackets = 5; numTaps = 9; ttlNumSym = numSym + numTrainingSym; raylChan = comm.RayleighChannel( ... 'PathDelays',[0 1], ... 'AveragePathGains',[0 -9], ... 'MaximumDopplerShift',0, ... 'PathGainsOutputPort',true); SNR = 35; rxVec = zeros(ttlNumSym,numPackets); txVec = zeros(ttlNumSym,numPackets); yVec = zeros(ttlNumSym,1); eVec = zeros(ttlNumSym,1); lineq1 = comm.LinearEqualizer( ... 'Algorithm','LMS', ... 'NumTaps',numTaps, ... 'ReferenceTap',5, ... 'StepSize',0.01, ... 'TrainingFlagInputPort',true); [errPlot,wStem,hStem,scatPlot] = initFigures(ttlNumSym,lineq1, ... raylChan.AveragePathGains);
シンボルベースの処理
シンボルベースの処理では、イコライザーの入力で 1 つのシンボルを指定します。各パケットの処理後にイコライザーの状態とチャネルをリセットします。
for p = 1:numPackets trainingFlag = true; for q=1:ttlNumSym data = randi([0 M-1],1,1); tx = pskmod(data,M,pi/4); [xc,pg] = raylChan(tx); rx = awgn(xc,25); [y,err,wts] = lineq1(rx,tx,trainingFlag);
numTrainingSym
個のトレーニング シンボルを処理した後に学習を無効にします。
if q == numTrainingSym trainingFlag = false; end updateFigures(errPlot,wStem,hStem,scatPlot,err, ... wts,y,pg,q,ttlNumSym); txVec(q,p) = tx; rxVec(q,p) = rx; end
各パケットの処理後に、チャネル System object をリセットしてチャネル タップの新しい実現を取得し、イコライザー System object をリセットして既定のタップ重み集合に戻します。
reset(raylChan)
reset(lineq1)
end
パケットベースの処理
パケットベースの処理では、イコライザーの入力で 1 つのパケットを指定します。各パケットには ttlNumSym
個のシンボルが含まれています。学習期間がパケット長よりも短いため、学習の開始の入力を指定する必要はありません。
yVecPkt = zeros(ttlNumSym,numPackets); errVecPkt = zeros(ttlNumSym,numPackets); wgtVecPkt = zeros(numTaps,numPackets); lineq2 = comm.LinearEqualizer('Algorithm','LMS', ... 'NumTaps',9,'ReferenceTap',6,'StepSize',0.01); for p = 1:numPackets [yVecPkt(:,p),errVecPkt(:,p),wgtVecPkt(:,p)] = ... lineq2(rxVec(:,p),txVec(1:numTrainingSym,p)); for q=1:ttlNumSym updateFigures(errPlot,wStem,hStem,scatPlot, ... errVecPkt(q,p),wgtVecPkt(:,p), ... yVecPkt(q,p),pg,q,ttlNumSym); end
各パケットの処理後に、チャネル System object をリセットしてチャネル タップの新しい実現を取得し、イコライザー System object をリセットして既定のタップ重み集合に戻します。
reset(raylChan)
reset(lineq2)
end
補助関数
この補助関数は Figure を初期化します。
function [errPlot,wStem,hStem,scatPlot] = ... initFigures(ttlNumSym,lineq,pg) yVec = nan(ttlNumSym,1); eVec = nan(ttlNumSym,1); wVec = zeros(lineq.NumTaps,1); figure; subplot(2,2,1); wStem = stem(wVec); axis([1 lineq.NumTaps 0 1.8]); grid on; xlabel('Taps'); ylabel('|Weights|'); title('Tap Weight Magnitude'); subplot(2,2,2); hStem = stem([0 abs(pg) 0]); grid on; xlabel('Taps'); ylabel('|Path Gain|'); title('Channel Path Gain Magnitude'); subplot(2,2,3); errPlot = plot(eVec); axis([1 ttlNumSym 0 1.2]); grid on; xlabel('Symbols'); ylabel('|Error Magnitude|'); title('Error Magnitude'); subplot(2,2,4); scatPlot = plot(yVec,'.'); axis square; axis([-1.2 1.2 -1.2 1.2]); grid on; xlabel('In-phase'); ylabel('Quadrature'); title(sprintf('Scatter Plot')); end
この補助関数は Figure を更新します。
function updateFigures(errPlot,wStem,hStem,scatPlot, ... err,wts,y,pg,p,ttlNumSym) persistent yVec eVec if p == 1 yVec = nan(ttlNumSym,1); eVec = nan(ttlNumSym,1); end yVec(p) = y; eVec(p) = abs(err); errPlot.YData = abs(eVec); wStem.YData = abs(wts); hStem.YData = [0 abs(pg) 0]; scatPlot.XData = real(yVec); scatPlot.YData = imag(yVec); drawnow limitrate end
非適応モードで線形イコライザーを使用します。オブジェクト関数 mmseweights
を使用して最小平均二乗誤差 (MMSE) の解を計算し、線形イコライザーのタップ重み集合にその重みを使用します。
シミュレーション変数を初期化します。
M = 4; % QPSK
numSymbols = 10000;
numTrainingSymbols = 1000;
chtaps = [1 0.5*exp(1i*pi/6) 0.1*exp(-1i*pi/8)];
EbN0 = 20;
QPSK 変調されたシンボルを生成します。シンボルに遅延したマルチパス チャネルのフィルター処理と AWGN 障害を適用します。
data = randi([0 M-1], numSymbols, 1);
tx = pskmod(data, M, pi/4);
rx = awgn(filter(chtaps,1,tx),25,'measured');
CMA アルゴリズムを使用するように構成された線形イコライザー System object を作成し、AdaptWeights
プロパティを false
、InitialWeightsSource
プロパティを Property
に設定します。MMSE 重みを計算します。初期タップ重みを計算された MMSE 重みに設定します。劣化したシンボルをイコライズします。
eq = comm.LinearEqualizer( ... 'Algorithm','CMA', ... 'AdaptWeights',false, ... 'InitialWeightsSource','Property')
eq = comm.LinearEqualizer with properties: Algorithm: 'CMA' NumTaps: 5 StepSize: 0.0100 Constellation: [0.7071 + 0.7071i -0.7071 + 0.7071i -0.7071 - 0.7071i 0.7071 - 0.7071i] InputSamplesPerSymbol: 1 AdaptWeightsSource: 'Property' AdaptWeights: false InitialWeightsSource: 'Property' InitialWeights: [5×1 double] WeightUpdatePeriod: 1
wgts = mmseweights(eq,chtaps,EbN0)
wgts = 5×1 complex
0.0005 - 0.0068i
0.0103 + 0.0117i
0.9694 - 0.0019i
-0.3987 + 0.2186i
0.0389 - 0.1756i
eq.InitialWeights = wgts; [y,err,weights] = eq(rx);
劣化したシンボルとイコライズされたシンボルのコンスタレーションをプロットします。
constell = comm.ConstellationDiagram('NumInputPorts',2);
constell(rx,y);
イコライザーの誤差信号をプロットし、イコライズされたシンボルのエラー ベクトル振幅を計算します。
plot(abs(err)); grid on; xlabel('Symbols'); ylabel('|e|');
errevm = comm.EVM; evm = errevm(tx,y)
evm = 139.0863
イコライザーのタップ重みをプロットします。
subplot(3,1,1); stem(real(weights)); ylabel('real(weights)'); xlabel('Tap'); grid on; axis([1 8 -0.5 1]); line([eq.NumTaps+0.5 eq.NumTaps+0.5],[-0.5 1], ... 'Color','r','LineWidth',1); title('Equalizer Tap Weights'); subplot(3,1,2); stem(imag(weights)); ylabel('imag(weights)'); xlabel('Tap'); grid on; axis([1 8 -0.5 1]); line([eq.NumTaps+0.5 eq.NumTaps+0.5],[-0.5 1], ... 'Color','r','LineWidth',1); subplot(3,1,3); stem(abs(weights)); ylabel('abs(weights)'); xlabel('Tap'); grid on; axis([1 8 -0.5 1]); line([eq.NumTaps+0.5 eq.NumTaps+0.5], ... [-0.5 1],'Color','r','LineWidth',1);
最小平均二乗 (LMS) アルゴリズムを使用した線形イコライズを示して、AWGN チャネル経由で渡した QPSK シンボルを復元します。信号をサンプルごとに処理します。
システム設定
AWGN の影響を受ける QPSK 変調システムをシミュレートします。200 個のトレーニング シンボルと 1800 個のランダム データ シンボルで構成されるパケットを送信します。パケット データを復元するように線形 LMS イコライザーを構成します。
M = 4; numTrainSymbols = 200; numDataSymbols = 1800; SNR = 20; trainingSymbols = ... pskmod(randi([0 M-1],numTrainSymbols,1),M,pi/4); numPkts = 10; lineq = comm.LinearEqualizer( ... 'Algorithm','LMS', ... 'NumTaps',5, ... 'ReferenceTap',3, ... 'StepSize',0.01, ... 'TrainingFlagInputPort',true);
メイン ループ
各パケットを処理するときに、先頭に追加されたトレーニング シンボルを使用します。各パケットの処理後にイコライザーをリセットします。このリセットにより、イコライザーは事前知識なしにタップを学習するようになります。受信信号をサンプルごとにイコライズします。パケットごとに、最初の 200 個のシンボルを学習用に使用します。
subPlotCnt = 1; figure for ii = 1:numPkts b = randi([0 M-1],numDataSymbols,1); dataSym = pskmod(b,M,pi/4); packet = [trainingSymbols;dataSym]; rx = awgn(packet,SNR); y = zeros(numDataSymbols+numTrainSymbols,1); err = zeros(numDataSymbols+numTrainSymbols,1); for jj = 1:numDataSymbols+numTrainSymbols if jj <= numTrainSymbols [y(jj),err(jj)] = ... lineq(rx(jj),trainingSymbols(jj),true); else [y(jj),err(jj)] = lineq(rx(jj),1i,false); end end reset(lineq) if (ii ==1 || ii == 2 ||ii == numPkts) subplot(3,1,subPlotCnt) plot(abs(err)) title(['Packet # ',num2str(ii)]) xlabel('Symbols') ylabel('Error Magnitude') axis([0,length(packet),0,1]) grid on; subPlotCnt = subPlotCnt+1; end end
最小平均二乗 (LMS) アルゴリズムを使用した線形イコライズを示して、AWGN チャネル経由で渡した QPSK シンボルを復元します。複数パスで、最初にトレーニング シンボルを持つパケットを処理します。結果を、単一パスでパケット全体を処理するイコライズと比較します。
システム設定
AWGN の影響を受ける QPSK 変調システムをシミュレートします。200 個のトレーニング シンボルと 1800 個のランダム データ シンボルで構成されるパケットを送信します。パケット データを復元するように線形 LMS イコライザーを構成します。
M = 4; numTrainSymbols = 200; numDataSymbols = 1800; SNR = 20; trainingSymbols = ... pskmod(randi([0 M-1],numTrainSymbols,1),M,pi/4); b = randi([0 M-1],numDataSymbols,1); dataSym = pskmod(b,M,pi/4); packet = [trainingSymbols;dataSym]; rx = awgn(packet,SNR); lineq = comm.LinearEqualizer( ... 'Algorithm','LMS', ... 'NumTaps',5, ... 'ReferenceTap',3, ... 'StepSize',0.01);
1 パスでのパケットの処理
各パケットを処理するときに、先頭に追加されたトレーニング シンボルを使用します。各パケットの処理後にイコライザーをリセットします。このリセットにより、イコライザーは事前知識なしにタップを学習するようになります。受信信号をサンプルごとにイコライズします。パケットごとに、最初の 200 個のシンボルを学習用に使用します。
subPlotCnt = 1; figure [y1,err1] = lineq(rx,trainingSymbols); reset(lineq) plot(abs(err1)) title("Single Pass Processing") xlabel('Symbols') ylabel('Error Magnitude') axis([0,length(packet),0,1]) grid on;
複数パスでのパケットの処理
各パケットを処理するときに、先頭に追加されたトレーニング シンボルを使用します。各パケットの処理後にイコライザーをリセットします。このリセットにより、イコライザーは事前知識なしにタップを学習するようになります。受信信号をサンプルごとにイコライズします。パケットごとに、最初の 200 個のシンボルを学習用に使用します。
lineq = comm.LinearEqualizer( ... 'Algorithm','LMS', ... 'NumTaps',5, ... 'ReferenceTap',3, ... 'StepSize',0.01, ... 'TrainingFlagInputPort',true); frameLen = 100; numFrames = (numDataSymbols+numTrainSymbols) / frameLen; figure y2 = zeros(numDataSymbols+numTrainSymbols,1); err2 = zeros(numDataSymbols+numTrainSymbols,1); idx = 1:frameLen; symbolCnt = 0; for jj = 1:numFrames if symbolCnt < numTrainSymbols [y2(idx),err2(idx)] = ... lineq(rx(idx),trainingSymbols(idx),true); else [y2(idx),err2(idx)] = ... lineq(rx(idx),1i*ones(frameLen,1),false); end idx = idx + frameLen; symbolCnt = symbolCnt + frameLen; end reset(lineq) plot(abs(err2)) title("Multipass Processing") xlabel('Symbols') ylabel('Error Magnitude') axis([0,length(packet),0,1]) grid on;
単一パスと複数パスを使用した場合のイコライズの結果は一致します。
outputsEqual = isequal(y1,y2)
outputsEqual = logical
1
errorsEqual = isequal(err1,err2)
errorsEqual = logical
1
詳細
シンボル間隔イコライザーまたは分数シンボル間隔イコライザーとして動作するようにイコライザーを構成できます。
シンボル間隔レートでイコライザーを動作させるには、シンボルあたりのサンプル数を
1
に指定します。シンボル レート イコライザーでは、タップはシンボル区間の間隔で配置されます。シンボル レート イコライザーはタイミング位相の影響を受けます。分数シンボル間隔レートでイコライザーを動作させるには、シンボルあたりの入力サンプル数を
1
より大きい整数に指定し、そのサンプル レートでオーバーサンプリングされた入力信号を指定します。分数シンボル間隔イコライザーでは、入力シンボル区間の整数分の 1 の間隔でタップが配置されています。分数シンボル間隔イコライザーはタイミング位相の影響を受けません。
アルゴリズム
線形イコライザーは、チャネルの周波数応答に null が存在しない場合、符号間干渉 (ISI) を削除できます。チャネルの周波数応答に null が存在する場合、線形イコライザーはノイズを強調する傾向があります。この場合は、ノイズが強調されないように判定フィードバック イコライザーを使用します。
線形イコライザーは、入力信号からのサンプルを格納するタップ付き遅延線で構成されます。シンボル周期ごとに一度、イコライザーは遅延ラインで値の重み付き総和を出力し、次のシンボル周期のための準備として重みを更新します。
線形イコライザーはシンボル間隔または分数シンボル間隔にすることができます。
シンボル間隔イコライザーの場合、シンボルあたりのサンプル数 K は 1 です。出力サンプル レートは入力サンプル レートと等しくなります。
分数シンボル間隔イコライザーの場合、シンボルあたりのサンプル数 K は 1 より大きい整数です。通常、分数間隔イコライザーの K は 4 です。出力サンプルレートは 1/T、入力サンプルレートは K/T になります。ここで、T はシンボル周期です。タップ重みの更新は、出力レートで起こります。
この図は、重みが L、シンボル周期が T、シンボルあたりのサンプル数が K の線形イコライザーを示しています。K が 1 の場合、結果は分数シンボル間隔線形イコライザーではなくシンボル間隔線形イコライザーです。
シンボル周期ごとに、イコライザーはタップ付き遅延線で K 個の入力サンプルを受信します。イコライザーはその後、遅延線で値の重み付き総和を出力し、次のシンボル周期のための準備として重みを更新します。
詳細については、イコライズを参照してください。
LMS アルゴリズムの場合、前の図の w はすべての重み wi のベクトル、u はすべての入力 ui のベクトルです。現在の重み集合に基づき、LMS アルゴリズムは次の式で新しい重み集合を作成します。
wnew = wcurrent + (StepSize) ue*.
適応アルゴリズムで使用されるステップ サイズは、正のスカラーとして指定します。ステップ サイズを大きくすると、イコライザーの収束時間が短縮されますが、イコライズされた出力信号の安定性は低下します。LMS 適応アルゴリズムを使用する際に許容される最大ステップ サイズを決定するには、オブジェクト関数 maxstep
を使用します。* 演算子は複素共役を表し、誤り計算は e = d - y を表します。
RLS アルゴリズムの場合、前の図の w はすべての重み wi のベクトル、u はすべての入力 ui のベクトルです。現在の入力の集合 u と逆相関行列 P を基に、RLS アルゴリズムは最初にカルマン ゲイン ベクトル K を次のように計算します。
適応アルゴリズムで使用される忘却係数は、範囲 (0, 1] のスカラーとして指定します。忘却係数を小さくすると、イコライザーの収束時間が短縮されますが、イコライズされた出力信号の安定性は低下します。H はエルミート転置を表します。現在の逆相関行列に基づき、新しい逆相関行列は次のようになります。
現在の重み集合に基づき、RLS アルゴリズムは次の式で新しい重み集合を作成します。
wnew = wcurrent+K*e.
* 演算子は複素共役を表し、誤り計算は e = d - y を表します。
CMA 適応アルゴリズムの場合、前の図の w はすべての重み wi のベクトル、u はすべての入力 ui のベクトルです。現在の重み集合に基づき、CMA 適応アルゴリズムは次の式で新しい重み集合を作成します。
wnew = wcurrent + (StepSize) u*e.
適応アルゴリズムで使用されるステップ サイズは、正のスカラーとして指定します。ステップ サイズを大きくすると、イコライザーの収束時間が短縮されますが、イコライズされた出力信号の安定性は低下します。CMA 適応アルゴリズムにより許容される最大ステップ サイズを決定するには、オブジェクト関数 maxstep
を使用します。* 演算子は複素共役を表し、誤り計算は e = y(R - |y|2) です。ここで、R は信号コンスタレーションに関連する定数です。
拡張機能
C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。
バージョン履歴
R2019a で導入
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)