?? 卷積碼編程.txt
字號:
卷積碼
卷積碼的編碼器輸入相同的符號時,輸出可能不同,因為卷積碼的編碼不僅與當前的輸入有關,而且與以前的輸入有關。下面介紹一下卷積編碼的編碼器描述方式。
卷積碼的多項式描述,描述了卷積碼編碼器中移位寄存器與模2加法器的連接關系。如圖描述了一個輸入、兩個輸出和兩個移位寄存器的前饋卷積碼編碼器。
卷積碼編碼器的多項式描述包含3個組成部分,分別為:
(1) 約束長度。
(2) 生成多項式。
(3) 反饋連接多項式。
1. 約束長度
編碼器的約束長度形成一個向量,這個向量的長度為編碼器的輸入個數,向量的元素表示存儲在每個移位寄存器中的比特數,包括前輸入比特。如上圖比特數為3。
2. 生成多項式
如果編碼器在K個輸入,N個輸出,那么這個碼的生成矩陣就是一個k×n的矩陣。在第i行,第j列的元素,表示第i個輸入如何影響第j個輸出的。對于一個系統反饋編碼器的系統位,它生成矩陣的項與反饋連接矢量的相應元素匹配。
3. 反饋連接多項式
如果描述一個帶反饋的編碼器,用戶需要一個反饋連接多項式向量。這個向量的長度為編碼器的輸入個數。向量的元素用八進制形式表示每個輸入的反饋連接。
如果編碼器具有反饋結構,而且是系統的,那么生成多項式和反饋連接多項式相應的系統位參數一定是相同值。下圖是一個帶反饋的卷積碼編碼器框圖:
卷積碼是一種有記憶的編碼,在任意給定的時間單元處,編碼器的n個輸出不僅與此時間單元的k個輸入有關,而且也與前m個輸入有關。卷積碼通常表示為:(n,k,m)
本次仿真采用(2,1,2)卷積碼。
性能參數如下:
生成矩陣G: 1 0 1
1 1 1
編碼個數: n=2
信息碼個數: k=1
約束長度: N=m+1=3
卷積碼的碼率: =1/2
MATLAB源程序
%線性時不變系統的卷積運算仿真
function [y,ny]=conv_m(x,nx,h,nh)
%modified convolution function
%[y,ny]=conv_m(x,nx,h,nh)
nyb=nx(1)+nh(1); %輸出序列的開始位置
nye=nx(length(x))+nh(length(h)); %輸出序列的結束位置
ny=[nyb:nye];y=conv(x,h); %卷積運算
%我們可以通過兩種方法來計算系統的輸出y(n),并比較兩種輸
%出是否相等來驗證上述線性時不變特性。
%用MATLAB實現:
n=[1:19];
hn=ones(1,19);
hn=hn.*(power(0.8,n)); %生成序列
[xn1,n1]=2*impseq(0,0,20);
[xn2,n2]=sigshift(xn1,n1,20);
[xn3,n3]=sigshift(xn1,n1,40);
xn2=2*xn2;
xn3=4*xn3;
[xn,nx]=sigadd(xn1,n1,xn2,n2);
[xn,nx]=sigadd(xn,41,xn2,n2); %生成序列x(n)
[yn1,ny1]=conv_m(hn,n,xn,n4); %同卷積方法求輸出y(n)
stem(ny1,yn1);
[hn1,nh1]=sigshift(hn,n,20); %以下用LTI性質求y(n)
hn1=2*hn1;
[hn2,nh2]=sigshift(hn,n,40);
hn2=4*hn2;
[yn2,ny2]=sigadd(hn,n,hn1,nh1);
[yn2,ny2]=sigadd(yn2,ny2,hn2,nh2);
stem(ny2,yn2);
可以用以下語句來驗證兩種方法的等價:
all(ny1==ny2)
ans=1
all(yn1==yn2)
ans=1
主要是對卷積特性的研究。
運行結果所下圖所示:
function output=convenc(G,k0,input)
%output=convenc(G,k0,input) 卷積碼編碼函數
%G 生成矩陣
%k0 輸入碼長
%input 輸入信源序列
%output 輸出卷積編碼序列
%+ 0..0
if rem(length(input),k0)0
input=[input,zeros(size(1:k0-rem(length(input),k0)))];
end
n=length(input)/k0;
%G size
if rem(size(G,2),k0)~=0
error('Error,g is not of the right size.')
end
%li L,n0
li=size(g,2)/k0;
n0=size(g,1);
%+ 0..0
u=[zeros(size(1:(li-1)*k0)),input,zeros(size(1:(li-1)*k0))];
%uu lie i*T,i=1,2...
u1=u(li*k0:-1:1);
for i=1:n+li-2
u1=[u1,u((i+li)*k0:-1:i*k0+1)];
end
uu=reshape(u1,li*k0,n+li-1);
%output reshape
output=reshape(rem(g*uu,2),1,n0*(n+li-1));
%output=convenc(g,k0,input)卷積碼編碼函數
%卷積碼的維特比譯碼函數
function [decoder_output,survivor_state,cumulated_metric]=viterbi(G,k,channel_output)
%VITERBI 卷積碼的維特比解碼器
%[decoder_ouput,survivor_state,cumulated_metric]=viterbi(G,k,channel_output)
% G是一個n*Lk矩陣,該矩陣的每一行確
% 定了從移位記錯器到第n個輸出間的連接,
% 是碼速率。
% survivor_state是表示通過網絡的最佳路徑的矩陣。
% 量度在另一個函數metric(x,y)中給出,而且可根據
% 硬判決和軟判決來指定。
% 該算法最小化了量度而不是最大化似然
n=size(G,1); %取出矩陣G的一維大小,即得出輸出端口
% 檢查大小
if rem(size(G,2),k)~=0 %當G列數不是k的整數倍時
error('Size of G and k do not agree') %發出出錯信息
end
if rem(size(channel_output,2),n)~=0 %當輸出量元素個數不是輸出端口的整數倍時
error('Channel output not of the right size') %發出出錯信息
end
L=size(G,2)/k; %得出移位數,即寄存器的個數
% 由于L-1個寄存器的狀態即可表示出輸出狀態,
% 所以總的狀態數number_of_states可由前L-1個
% 寄存器的狀態組合來確定
number_of_states=2^((L-1)*k);
% 產生狀態轉移矩陣、輸出矩陣和輸入矩陣
for j=0:number_of_states-1 %j表示當前寄存器組的狀態因為狀態是從零
%開始的,所以循環從0到number_of_states-1
for l=0:2^k-1 %l為從k個輸入端的信號組成的狀態,總的狀
%態數為2^k,所以循環從0到2^k-11
% nxt_stat完成從當前的狀態和輸入的矢量得出下寄存器組的一個狀態
[next_state,memory_contents]=nxt_stat(j,l,L,k);
% input數組值是用于記錄當前狀態到下一個狀態所要的輸入信號矢量
% input數組的維數: 一維坐標x=j+1指當前狀態的值
% 二維坐標y=next_state+1指下一個狀態的值
% 由于Matlab中數組的下標是從1開始的,而狀態值
% 是從0開始的,所以以上坐標值為:狀態值+1
input(j+1,next_state+1)=l;
% branch_output用于記錄在狀態j下輸入l時的輸出
branch_output=rem(memory_contents*G',2);
% nextstate數組記錄了當前狀態j下輸入l時的下一個狀態
nextstate(j+1,l+1)=next_state;
% output數組記錄了當前狀態j下輸入l時的輸出(十進制)
output(j+1,l+1)=bin2deci(branch_output);
end
end
% state_metric數組用于記錄譯碼過程在每狀態時的漢明距離
% state_metric大小為number_of_states2,(:,1)當前
% 狀態位置的漢明距離,為確定值,而(:,2)為當前狀態加輸入
% 得到的下一個狀態漢明距離,為臨時值
state_metric=zeros(number_of_states,2);
% depth_of_trellis用于記錄網格圖的深度
depth_of_trellis=length(channel_output)/n;
% 輸出矩陣,每一列為一個輸出狀態
channel_output_matrix=reshape(channel_output,n,depth_of_trellis);
% survivor_state描述譯碼過程中在網格圖中的路徑
survivor_state=zeros(number_of_states,depth_of_trellis+1);
%開始無尾信道輸出的解碼
for i=1:depth_of_trellis-L+1 %i指示網格圖的深度
% flag矩陣用于記錄網格圖中的某一列是否被訪問過
flag=zeros(1,number_of_states);
if i=L
step=2^((L-i)*k); %在網格圖的開始處,并不是所有的狀態都取
else %用step來說明這個變化
step=1; %狀態數從1→2→4→...→number_of_states
end
for j=0:step:number_of_states-1 %j表示寄存器的當前狀態
for l=0:2^k-1 %l為當前的輸入
branch_metric=0; %用于記錄碼間距離
% 將當前狀態下輸入狀態l時的輸出output轉為n位二進制,以便
% 計算碼間距離(說明:數組坐標大小變化同上)。
binary_output=deci2bin(output(j+1,l+1),n);
% 計算實際的輸出碼同網格圖中此格某種輸出的碼間距離
for ll=1:n
branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll));
end
% 選擇碼間距離較小的那條路徑
% 選擇方法:
% 當下一個狀態沒有被訪問時就直接賦值,否則,用比它小的將其覆蓋
if((state_metric(nextstate(j+1,l+1)+1,2)state_metric(j+1,1)...
+branch_metric)|flag(nextstate(j+1,l+1)+1)==0)
% 下一個狀態的漢明距離(臨時值)=當前狀態的漢明距離(確定值)+ 碼間距離
state_metric(nextstate(j+1,l+1)+1,2)=state_metric(j+1,1)+branch_metric;
% survivor_state數組的一維坐標為下一個狀態值,二維坐標為此狀態
% 在網格圖中的列位置,記錄的數值為當前狀態,這樣就可以從網格圖中
% 某位置的某個狀態得出其對應上一個列位置的狀態,從而能很方便的完
% 成譯碼過程。
survivor_state(nextstate(j+1,l+1)+1,i+1)=j;
flag(nextstate(j+1,l+1)+1)=1; %指示該狀態已被訪問過
end
end
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -