📄 chase.c
字号:
/*
*********************************************************************************
* Copyright (c) National Mobile Communications Research Laboratory.
* All rights reserved.
*
* FILE NAME : BTCdecode.c
* ABSTRUCT:
* This file is the C file for Chase algorithm.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
/*
*********************************************************************************
* INCLUDE FILES
*********************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include "BTCstruct.h"
#include "syndrome_dec.h"
#define LRB 4 //least reliable bits
#define NTP 16 //number of test patterns
/*
*********************************************************************************
* Function Definition
*********************************************************************************
*/
/*
*********************************************************************************
* NAME: Chase1
* PURPOSE: perform the chase algorithm for SPC code.
*
* Input: reliable[]: the reliable value for a line block code.
* code_len : code length.
* zero_len : zero bit length
*
* Output: hard_seq[]: hard decision sequence output.
* soft_out[]: soft value output.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
void Chase1(double reliable[],int code_len,int zero_len,int hard_seq[],double soft_out[])
{
double min = 0;
double submin = 0;
int min_pos = 0;
int index;
int check_flag = 0;
min = fabs(reliable[zero_len]);
for(index=zero_len;index<code_len;index++)
{
if(min>fabs(reliable[index]))
{
min = fabs(reliable[index]);
min_pos = index;
}
//hard decision
if(reliable[index]>0)
hard_seq[index] = 0;
else
hard_seq[index] = 1;
check_flag ^= hard_seq[index];
}
submin = min + 1000.0;
for(index=zero_len;index<code_len;index++)
{
if(index!=min_pos)
{
if(submin>fabs(reliable[index]))
submin = fabs(reliable[index]);
}
}
//compute the soft output
if(check_flag==0)
{
for(index=zero_len;index<code_len;index++)
{
if(index!=min_pos)
{
if(hard_seq[index]==0)
soft_out[index] = min;
else
soft_out[index] = 0 - min;
}
else
{
if(hard_seq[index]==0)
soft_out[index] = submin;
else
soft_out[index] = 0 - submin;
}
}
}
else
{
for(index=zero_len;index<code_len;index++)
{
if(index!=min_pos)
{
if(hard_seq[index]==0)
soft_out[index] = 0 - min;
else
soft_out[index] = min;
}
else
{
if(hard_seq[index]==0)
soft_out[index] = 0 - submin;
else
soft_out[index] = submin;
}
}
}
//correct the error bit
if(check_flag==1)
{
hard_seq[min_pos] ^= 1;
}
}
/*
*********************************************************************************
* NAME: GenCodeSet
* PURPOSE: generate the codeword set.
*
* Input: reliable[]: the reliable value for a line block code.
* code_len : code length.
* hard_in[]: hard decision.
*
* Output: softvalue:
* dis[]: distance of each codeword.
* codeset[]: the codeword set.
* mid_code[]: the center codeword.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
void GenCodeSet(double reliable[],int hard_in[],int code_len,double dis[],
int codeset[],int mid_code[])
{
int *lrp; //least reliable position vector.
int *tp; //test patterns vector.
int *ts; //test sequence vector.
double min = 0.0;
int index;
int i,j;
int tmp = 0;
lrp = (int *)malloc(code_len * sizeof(int));
for(index=0;index<code_len;index++)
{
lrp[index] = index;
}
//find the the least reliable bits.
for(i=0;i<LRB;i++)
{
min = fabs(reliable[lrp[i]]);
j = i;
for(index=i+1;index<code_len-1;index++)
{
if(min>fabs(reliable[lrp[index]]))
{
min = fabs(reliable[lrp[index]]);
j = index;
}
}
tmp = lrp[j];
lrp[j] = lrp[i];
lrp[i] = tmp;
}
//initialize test patterns vector tp
tp = (int *)malloc(code_len * sizeof(int));
memset(tp,0,code_len * sizeof(int));
//initialize test sequence vector ts
ts = (int *)malloc(code_len * sizeof(int));
memset(ts,0,code_len * sizeof(int));
//generate test patterns and decode.
for(i=0;i<NTP;i++)
{
//bit add 1
if (i != 0)
{
for (j=0; j<LRB; j++)
{
if (tp[lrp[j]]==1)
{
tp[lrp[j]] = 0;
}
else
{
tp[lrp[j]] = 1;
break;
}
}
}
//generate test sequence according to the test pattern
for (index=0;index<code_len;index++)
{
ts[index] = hard_in[index] ^ tp[index];
}
//syndrome decode.
syndrome_dec(ts,code_len,(codeset+i*code_len));
}
//find the optimum decision from subset
min = 1E10;
tmp = 0;
index = 0;
for (i=0;i<NTP;i++)
{
dis[i] = 0.0;
for (j=0;j<code_len;j++)
{
if (codeset[index]==0)
{
dis[i] -= reliable[j];
}
else
{
dis[i] += reliable[j];
}
index++;
}
if (min>dis[i])
{
min = dis[i];
tmp = i;
}
}
index = tmp * code_len; //index point to the beginning of the ML codeword
memcpy(mid_code,(codeset+index),code_len * sizeof(int));
free(lrp);
free(tp);
free(ts);
}
/*
*********************************************************************************
* NAME: SearchCode
* PURPOSE: search for the compete code in the subset.
*
* Input: codeset[]: the codeword set.
* code_len : code length.
* dis[]: distance of each codeword.
* seekBit: the reverse bit value in the specific position to seek
* position: the position of the bit to seek in a codeword
*
* Output: seekcode[]: the ML codeword which has the reverse bit in the
* specific position.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
int SearchCode(int codeset[],double dis[],int seek_bit,int pos,int code_len,int seekcode[])
{
int i = 0;
int j = 0;
int mp = -1; //the concurrent codeword start position
int code_head = 0; //the position of the start of the codeword in subset
double min = 0.0; //minimum distance value
min = 1E10;
for(i=0;i<NTP;i++)
{
if (*(codeset+code_head+pos)!= seek_bit) //reverse to di
{
if (min>dis[i])
{
min = dis[i];
mp = code_head;
}
}
//move to the next codeword
code_head += code_len;
}
if (mp == -1) //can not find concurrent codeword
{
return (0);
}
else //find the concurrent codeword and return
{
memcpy(seekcode,(codeset + mp),code_len * sizeof(int));
return (1);
}
}
/*
*********************************************************************************
* NAME: Chase2
* PURPOSE: perform the chase algorithm for EBCH code.
*
* Input: reliable[]: the reliable value for a line block code.
* code_len : code length.
* zero_len : zero bit length
* beta : iteration parameter.
*
* Output: hard_seq[]: hard decision sequence output.
* soft_out[]: soft value output.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
void Chase2(double reliable[],int code_len,int zero_len,double beta,
int hard_seq[],double soft_out[])
{
int index;
int i;
int *hard_in; //hard decision of the reliable[].
int *seekcode;
int *subset; //the codeword subset.
double dis[NTP] = {0}; //distance of each codeword.
hard_in = (int *)malloc(code_len * sizeof(int));
//hard decision
for(index=0;index<code_len;index++)
{
if(reliable[index]>0)
hard_in[index] = 0;
else
hard_in[index] = 1;
}
seekcode = (int *)malloc(code_len * sizeof(int));
subset = (int *)malloc(NTP * code_len * sizeof(int));
//generate the codeword subset.
GenCodeSet(reliable,hard_in,code_len,dis,subset,hard_seq);
//calculate soft information of each bit in the ML codeword
for(i=zero_len;i<code_len;i++)
{
soft_out[i] = 0;
//concurrent codeword can be found
if (SearchCode(subset,dis,hard_seq[i],i,code_len,seekcode)==1)
{
for(index=0;index<code_len;index++)
{
soft_out[i] += (seekcode[index] - hard_seq[index]) * reliable[index];
}
if (hard_seq[i]==1)
{
soft_out[i] = 0 - soft_out[i];
}
soft_out[i] -= reliable[i]; //subtract ri from soft information
}
else //concurrent codeword cannot be found
{
if (hard_seq[i]==0)
{
soft_out[i] = beta;
}
else
{
soft_out[i] = 0 - beta;
}
}
}
free(hard_in);
free(seekcode);
free(subset);
}
/*
*********************************************************************************
* NAME: Chase
* PURPOSE: perform the chase algorithm.
*
* Input: reliable[]: the reliable value for a line block code.
* flag : 0 :row sequence; 1 :column sequence.
* beta : parameter for iteration.
*
* Output: hard_seq[]: hard decision sequence output.
* soft_out[]: soft value output.
*
* AUTHOR: Zhang Tao 2007-02-14
*
*********************************************************************************
*/
void Chase(double reliable[],int flag,double beta,BTCstruct BTC,int hard_seq[],
double soft_out[])
{
int code_type; //determine which line block code is used.
int n;
int k;
int z;
if(flag==0)
{
code_type = BTC.r_type;
n = BTC.nx;
k = BTC.kx;
z = BTC.Ix;
}
else
{
code_type = BTC.c_type;
n = BTC.ny;
k = BTC.ky;
z = BTC.Iy;
}
if(code_type<3)
{
Chase1(reliable,n,z,hard_seq,soft_out);
}
else
{
Chase2(reliable,n,z,beta,hard_seq,soft_out);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -