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應該是未知的,按照信道均衡原理可直接選用判決器的實際輸出代替。