因爲在快變信道下,矩陣H進行帶狀處理後,狀態數可以減少。所以可以用減少狀態數的MAP算法來實現均衡器的軟輸出。而MAP算法可以根據BCJR算法來實現。
BCJR算法最初是應用於卷積碼的譯碼軟輸出,因此先學習在卷積碼的情況下BCJR算法的實現。
void CViterbi::Malloc()
{
int t,s,i,j,edge_cnt;
int temp,temp_out;
int state_temp,sub_state;
m_num_trellis=5;
m_num_input_bits=1; //輸入比特數 1
m_num_output_bits=2; //輸出比特數 2
m_num_reg=2; //寄存器數 2
m_num_input=1<<m_num_input_bits; //輸入比特狀態0,1
m_num_output=1<<m_num_output_bits;
m_num_state=1<<m_num_reg; //trellis圖狀態數
m_edge_no=m_num_input*m_num_state; //邊標號
m_in_lable=new int [m_edge_no]; //輸入標籤{0 ,1, 0 ,1, 0,1,0,1}
m_left_vertex=new int [m_edge_no]; //左邊狀態 {00,00,01,01,10,10,11,11}
m_right_vertex=new int [m_edge_no]; //右邊狀態 {00,10,00,10,01,11,01,11}
m_out_lable=new int [m_edge_no]; //輸出標籤{00,11,11,00,10,01,01,10}
m_G=new int [m_num_output_bits]; //生成多項式
m_G[0]=7; //g0=1 1 1
m_G[1]=5; //g1=1 0 1
m_input_bit=new int [m_num_input]; //輸入比特[0,1]
m_input_bit[0]=0;
m_input_bit[1]=1;
m_output_bit=new int *[m_num_output];
for(i=0;i<m_num_output;i++)
m_output_bit[i]=new int [m_num_output_bits];
m_output_bit[0][0]=0; m_output_bit[0][1]=0;
m_output_bit[1][0]=0; m_output_bit[1][1]=1;
m_output_bit[2][0]=1; m_output_bit[2][1]=0;
m_output_bit[3][0]=1; m_output_bit[3][1]=1;
m_delta=new double *[m_num_output];
m_gama=new double *[m_edge_no];
for(i=0;i<m_num_output;i++)
m_delta[i]=new double[m_num_trellis];
for(i=0;i<m_edge_no;i++)
m_gama[i]=new double [m_num_trellis];
m_difference=new double**[m_num_state];
for(s=0;s<m_num_state;s++){
m_difference[s]=new double *[m_num_trellis+1];
for(t=0;t<=m_num_trellis;t++)
m_difference[s][t]=new double[m_num_input];
}
m_edge_to_state=new int*[m_num_state];
for(s=0;s<m_num_state;s++)
m_edge_to_state[s]=new int [m_num_input];
//trellis的構建
state_temp=0; //臨時狀態
sub_state=0;
temp=0;
edge_cnt=0;
for(s=0;s<m_num_state;s++)
{
sub_state=s;
for(i=0;i<m_num_input;i++){
m_left_vertex[edge_cnt]=sub_state; //當前狀態
m_in_lable[edge_cnt]=i; //當前輸入
m_out_lable[edge_cnt] = 0;
m_right_vertex[edge_cnt] = 0; //初始化都是0
state_temp=(m_input_bit[i]<<m_num_reg)+sub_state;
temp_out=0;
for(j=0;j<m_num_output_bits;j++){ //第1,2個輸出
temp=BitDotProd(state_temp,m_G[j],m_num_reg+1);
temp_out=( temp_out<<1)+temp; //輸出碼字比特
}
m_out_lable[edge_cnt]=(m_out_lable[edge_cnt])^temp_out; //輸出碼字
m_right_vertex[edge_cnt]=(m_right_vertex[edge_cnt]<<m_num_reg)+ state_temp>>1; //新狀態 m_right_vertex[edge_cnt]初始時都是零
edge_cnt++;
}
}
for(s=0;s<m_num_state;s++){
edge_cnt=0;
for(i=0;i<m_edge_no;i++){
if(m_right_vertex[i]==s){
m_edge_to_state[s][edge_cnt]=i; //到達s狀態存儲的邊號
edge_cnt++;
}
}
}
m_backtrace=new int **[m_num_state];
for(s=0;s<m_num_state;s++){
m_backtrace[s]=new int *[m_num_trellis];
for(t=0;t<m_num_trellis;t++){
m_backtrace[s][t]=new int [m_num_input];
}
}
}
//編碼
void CViterbi::Encode(int *uu,int *cc)
{
int i,t,input,output,state;
state=0;
for(t=0;t<m_num_trellis;t++){
input=uu[t]; //輸入
for(i=0;i<m_edge_no;i++){
if(m_left_vertex[i]==state&& m_in_lable[i]==input)
output= m_out_lable[i];
state=m_right_vertex[i];
break;
}
for(i=0;i<m_num_output_bits;i++)
uu[t*m_num_output_bits+i]=m_output_bit[output][i];
}
m_end_s = state; //把最後的狀態當做已知的結束狀態
}
“`