天天看點

信道均衡-LMS自适應均衡算法matlab實作

1.主程式

clear;clc;echo off;close all;
N=10000;                 %指定信号序列長度
info=random_binary(N);   %産生雙極性不歸零基帶信号序列
SNR_in_dB=8:1:18;        %AWGN信道信噪比
for j=1:length(SNR_in_dB)
    [y,len]=channel(info,SNR_in_dB(j));  %通過既有碼間幹擾又有高斯白噪聲信道
    numoferr=0;                          %初始誤碼統計數
    for i=len+1:N+len,                   %從第len個碼元開始為真實信号碼元
        if (y(i)<0),                     %判決譯碼
            decis=-1;
        else
            decis=1;
        end;
        if(decis~=info(i-len)),          %判斷是否誤碼,統計誤碼碼元個數
            numoferr=numoferr+1;
        end;
    end;
    Pe(j)=numoferr/N;                    %未經均衡器均衡,得到的誤碼率
end;
semilogy(SNR_in_dB,Pe,'red*-');          %未經均衡器,誤碼率結果圖
    hold on;                             %semilogy表示y坐标軸是對數坐标系
delta_1=0.11;     %指定自适應均衡器的步長
delta_2=0.09;     %指定自适應均衡器的步長

for j=1:length(SNR_in_dB)
    y=channel(info,SNR_in_dB(j));        %通過信道
    z=lms_equalizer(y,info,delta_1);     %通過自适應均衡器,并設定步長為0.11
    numoferr=0;
    for i=1:N,
        if (z(i)<0),
            decis=-1;
        else
            decis=1;
        end;
        if (decis~=info(i)),
            numoferr=numoferr+1;
        end;
    end;
    Pe(j)=numoferr/N;                   %經自适應均衡器均衡後,得到的誤碼率
end;
semilogy(SNR_in_dB,Pe,'blacko-');       %自适應均衡器均衡之後,誤碼率結果圖
    hold on;
xlabel('SNR in dB');
ylabel('Pe');
title('ISI信道自适應均衡系統仿真');
legend('未經均衡器均衡','經自适應均衡器均衡,步長detla=0.11');
eyediagram(y(500:1000),10);             %均衡前眼圖
eyediagram(z(500:1000),10);             %均衡後眼圖,步長0.11;
           

2.主程式中用到的函數實作

  • random_binary
function [ info ] = random_binary( N )
%UNTITLED2 此處顯示有關此函數的摘要
%   此處顯示詳細說明
if nargin == 0,      %nargin表示所引用的函數的輸入參數的個數
    N=10000;         %如果沒有輸入參數,則指定資訊序列為10000個碼元
end;
for i=1:N,
    temp=rand;
    if(temp<0.5)
        info(i)=-1;  %1/2的機率
    else
        info(i)=1;
    end
end;
end
           
  • channel
function [ y,len ] = channel( x,snr_in_dB )
%模拟既有碼間幹擾又有高斯白噪聲的信道
SNR=exp(snr_in_dB*log(10)/10);   %信噪比真值轉換
sigma=1/sqrt(2*SNR);             %高斯白噪聲的标準差
%指定信道的ISI參數,可以看出此信道品質還是比較差的
actual_isi=[0.05 -0.063 0.088 -0.126 -0.25 0.9047 0.25 0 0.126 0.038 0.088];
len_actual_isi=(length(actual_isi)-1)/2;
len=len_actual_isi;
y=conv(actual_isi,x);             %信号通過信道,相當于信号序列與信道模型序列作卷積
%需要指出,此時碼元序列長度變為N+L=N+2len+1,譯碼時我們從第len個碼元開始到N+len個結束
for i=1:2:size(y,2), 
    [noise(i) noise(i+1)]=gngauss(sigma); %産生噪聲
end;
y=y+noise;                                %疊加噪聲
%也可直接用y = awgn(y,SNR)
end
           
  • gngauss
function [ gsrv1,gsrv2 ] = gngauss( m,sgma )
%産生高斯白噪聲
if nargin ==0,       %如果沒有輸入實參,則均方為0,标準差為1
    m=0; sgma=1;
elseif nargin ==1,   %如果輸入實參為1個參數,則标準差為輸入實參,均值為0
    sgma=m; m=0;
end
u=rand;
z=sgma*(sqrt(2*log(1/(1-u))));
u=rand;
gsrv1=m+z*cos(2*pi*u);
gsrv2=m+z*sin(2*pi*u);
end
           
  • lms_equalizer
function [ z ] = lms_equalizer( y,info,delta )
%LMS算法自适應濾波器實作
estimated_c=[0 0 0 0 0 1 0 0 0 0 0]; %初始抽頭系數(長度應該是和channel中信道階數相同=11)
K=5;                                 %K=(length(estimated_c)-1)/2
for k=1:size(y,2)-2*K,               %channel中傳回參數len的長度也是5,或許K的選擇便是基于len,需要K=len
     y_k=y(k:k+2*K);                 %擷取碼元,一次11個
     z_k=estimated_c*y_k';           %各抽頭系數與碼元相乘後求和
     e_k=info(k)-z_k;                %誤差估計
     estimated_c=estimated_c+delta*e_k*y_k;%計算校正抽頭系數
     z(k)=z_k;                       %均衡後輸出的碼元序列
end;
%誤差e=d-y,(y指經過信道後的輸出信号)這裡期望信号d使用的是輸入信号info
%比較誤碼率都是隻比較info的長度N
%size(y,2)傳回y的列數=N+L-1(L=2len+1),則size(y,2)-2*K=N+L-(2K+1)=N+2(len-K)
%這裡将會有個弊端:如果len>K,則k=1:N+2(len-K)會超過info的長度N.
end
           

個人覺得這個裡面最不好選擇的便是期望信号d(t),這段程式中選用的是輸入信号info,但按實際情況來說輸入信号info應該是未知的,按照信道均衡原理可直接選用判決器的實際輸出代替。

繼續閱讀