📄 chase2decoding.txt
字号:
/* 程序实现了[7,4,3]汉明码硬判决译码器及CHS2算法
* 程序取4*1,000,000个仿真点时可取得很好的效果,程序大概需运行3min
* 程序运行结果将产生三个txt文件:
* uncode.txt: 无编码的性能;
* hard_dec.txt: [7,4,3]汉明码/硬判决的性能;
* chase2.txt: [7,4,3]汉明码/CHS2的性能。
* 编译环境:Visual C++ 6.0
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#define N 100000 //N*4个点的仿真;
/* 校验矩阵 */
const int H[3][7]={ {1, 1, 1, 0, 1, 0, 0},
{1, 1, 0, 1, 0, 1, 0},
{1, 0, 1, 1, 0, 0, 1} };
/* 生成矩阵 */
const int G[4][7]={ {1, 0, 0, 0, 1, 1, 1},
{0, 1, 0, 0, 1, 1, 0},
{0, 0, 1, 0, 1, 0, 1},
{0, 0, 0, 1, 0, 1, 1} };
/* 产生二进制随机离散信号 */
void produce_binary_seq(int *b)
{
int i;
for(i = 0; i < 4; i++)
b[i] = rand() % 2;
return ;
}
/* 产生长度为7的高斯随机序列g[] */
void produce_gauss_seq(double *g)
{
int i;
for(i = 0; i < 7; i++)
{
static double V1, V2, S;
static int phase = 0;
if ( phase == 0 ) //迭代法产生高斯随机数;
{
do {
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
} while(S >= 1 || S == 0);
g[i] = V1 * sqrt(-2 * log(S) / S);
}
else
g[i] = V2 * sqrt(-2 * log(S) / S);
phase = 1 - phase;
}
return ;
}
/* [7,4,3]编码,a[4]为编码前的信号,e[7]为编码后的信号 */
void encoding_binary_seq(int *a, int *e)
{
int i;
for(i = 0; i < 7; i++)
{
e[i] = a[0]*G[0][i] + a[1]*G[1][i] + a[2]*G[2][i] + a[3]*G[3][i];
e[i] %= 2;
}
return ;
}
/* 硬判决过程,r[7]为判决前的模拟信号,d[7]为判决结果 */
void hard_decision(double *r, int *d)
{
int i;
for(i = 0; i < 7; i++)
{
if( r[i] < 0 ) d[i] = 0;
else d[i] = 1;
}
return ;
}
/* 译码纠错,r[7]为译码纠错前的信号,d[7]为译码纠错后的信号 */
void decode(int *r, int *d)
{
int i, j;
int S[3];
//000: 无错 001:r[6]错 010:r[5]错 011:r[3]错
//100:r[4]错 101:r[2]错 110:r[1]错 111:r[0]错
int error_pos[8]={-1, 6, 5, 3, 4, 2, 1, 0};
int sss;
for(i = 0; i < 3; i++) //乘校验矩阵H;
{
S[i] = 0;
for(j = 0; j < 7; j++)
S[i] += (r[j] * H[i][j]);
S[i] %= 2;
}
for(i = 0; i < 7; i++)
d[i] = r[i];
//通过查表修正误码;
sss = S[0]*4 + S[1]*2 + S[2];
if( sss != 0 )
d[ error_pos[sss] ]=1-d[ error_pos[sss] ];
return ;
}
/* CHS2算法,A为信号幅度,r[7]为译码前模拟信号,d[7]为译码纠错后的二进制信号 */
void soft_decision(double A, double *r, int *d)
{
int i;
int Rs[7]; //量化序列;
int min_cred = -1; //最小可信度的比较;
int min_cred_pos; //最小可信度码的位置;
for(i = 0; i < 7; i++) //量化过程;
{
if(r[i] < A*(-1))
{
Rs[i] = 0;
continue;
}
if(r[i] >= A)
{
Rs[i] = 7;
continue;
}
Rs[i] = (int)(4*r[i]/A+4);
if((Rs[i]-0)*(7-Rs[i]) > min_cred) //找出最小可信度码的位置;
{
min_cred = (Rs[i]-0)*(7-Rs[i]);
min_cred_pos = i;
}
}
int Rh[7]; //存放硬判决的结果;
hard_decision(r,Rh);
int T0[7], T1[7]; //试探序列,共有pow(2, (d-1)/2)=2个试探序列;
int R0[7], R1[7]; //试探图样,即试探序列与硬判决结果的模2和;
for(i = 0; i < 7; i++)
{
T0[i] = 0;
if(i == min_cred_pos) T1[i] = 1;
else T1[i] = 0;
R0[i] = (Rh[i]+T0[i]) % 2;
R1[i] = (Rh[i]+T1[i]) % 2;
}
int decode_T0[7], decode_T1[7]; //对试探图样的译码纠错的结果;
decode(R0, decode_T0);
decode(R1, decode_T1);
int ds0 = 0, ds1 = 0; //软距离;
for(i = 0; i < 7; i++)
{
ds0 += abs(decode_T0[i]*7-Rs[i]);
ds1 += abs(decode_T1[i]*7-Rs[i]);
}
//选用软距离最小的作为结果;
if(ds0 < ds1)
for(i = 0; i < 7; i++) d[i] = decode_T0[i];
else
for(i = 0; i < 7; i++) d[i] = decode_T1[i];
return ;
}
int main()
{
time_t t;
srand((unsigned)time(&t));
int loop, i,j;
int binary_seq[4]; //二进制随机离散信号;
int encode_seq[7]; //编码后的二进制信号;
double gauss_seq[7]; //高斯白噪声;
double receive_uncode_seq[4]; //无编码下接收到的模拟信号;
int uncode_seq[4]; //无编码下,直接硬判决得到的二进制信号;
double receive_code_seq[7]; //有编码下接收到的模拟信号;
int hard_decision_seq[7]; //硬判决结果;
int hard_decode_seq[7]; //硬判决译码纠错后的二进制信号;
int soft_decode_seq[7]; //软判决译码纠错后的二进制信号;
double EbNo; //信噪比;
double A_uncode; //无编码下需要的信号幅度;
double A_code; //有编码下需要的信号幅度;
int uncode_count; //无编码下的误码个数;
int hard_count; //硬判决误码个数;
int soft_count; //软判决误码个数;
double uncode_Pe; //无编码下的误码率;
double hard_Pe; //硬判决误码率;
double soft_Pe; //软判决误码率;
double uncode_point[100][2]; //无编码画图的点;
double hard_point[100][2]; //硬判决画图的点;
double soft_point[100][2]; //软判决画图的点;
printf("\n Eb/No\t\tPe/uncode\t\tPe/hard_dec\t\tPe/chase2\n");
printf("-----------------------------------------------------------------------------\n");
for(loop = 0; loop <= 20; loop++)
{
EbNo = loop*0.5;
A_code = sqrt( pow(10, EbNo/10)*8/7 );
A_uncode = sqrt( pow(10, EbNo/10)*2 );
uncode_count = 0;
hard_count = 0;
soft_count = 0;
for(i = 0; i < N; i++)
{
// 在相同的二进制信号和相同的高斯白噪声下,
// 比较无编码、硬判决、CHS2三者的性能
produce_binary_seq(binary_seq); //产生二进制信号;
produce_gauss_seq(gauss_seq); //产生高斯随机序列;
/* 无编码情况下,计算误码率 */
//(0,1)信号变成(-A_uncode,A_uncode)信号,并叠加上高斯白噪声;
for(j = 0; j < 4; j++)
{
if(binary_seq[j] == 0)
receive_uncode_seq[j] = A_uncode*(binary_seq[j] - 1) + gauss_seq[j];
else
receive_uncode_seq[j] = A_uncode*(binary_seq[j]) + gauss_seq[j];
}
for(j = 0; j < 4; j++) //对4位无编码信号的硬判决;
{
if(receive_uncode_seq[j] < 0) uncode_seq[j] = 0;
else uncode_seq[j] = 1;
}
for(j = 0; j < 4; j++) //统计误码个数;
if(binary_seq[j] != uncode_seq[j]) uncode_count++;
/* 采用[7,4,3]编码后的误码率,包括硬判决和软判决CHS2译码 */
encoding_binary_seq(binary_seq, encode_seq); //编码;
//(0,1)信号变成(-A_code,A_code)信号,并叠加上高斯白噪声;
for(j = 0; j < 7; j++)
{
if(encode_seq[j] == 0)
receive_code_seq[j] = A_code*(encode_seq[j] - 1) + gauss_seq[j];
else
receive_code_seq[j] = A_code*(encode_seq[j]) + gauss_seq[j];
}
//硬判决译码纠错;
hard_decision(receive_code_seq, hard_decision_seq);
decode(hard_decision_seq, hard_decode_seq);
for(j = 0; j < 4; j++)
if(binary_seq[j] != hard_decode_seq[j]) hard_count++;
//软判决译码纠错;
soft_decision(A_code, receive_code_seq, soft_decode_seq);
for(j = 0; j < 4; j++)
if(binary_seq[j] != soft_decode_seq[j]) soft_count++;
}
/* 计算并储存误码率 */
uncode_Pe = (double)uncode_count/(4*N);
uncode_point[loop][0] = EbNo;
uncode_point[loop][1] = uncode_Pe;
hard_Pe = (double)hard_count/(4*N);
hard_point[loop][0] = EbNo;
hard_point[loop][1] = hard_Pe;
soft_Pe = (double)soft_count/(4*N);
soft_point[loop][0] = EbNo;
soft_point[loop][1] = soft_Pe;
printf(" %4.1lf\t\t%.9lf\t\t%.9lf\t\t%.9lf\n", EbNo, uncode_Pe, hard_Pe, soft_Pe);
}
//保存至文本;
freopen("uncode.txt", "w", stdout);
for(i = 0; i <= 20; i++)
printf("%.1lf %.9lf\n", uncode_point[i][0], uncode_point[i][1]);
fclose(stdout);
freopen("hard_dec.txt", "w", stdout);
for(i = 0; i <= 20; i++)
printf("%.1lf %.9lf\n", hard_point[i][0], hard_point[i][1]);
fclose(stdout);
freopen("chase2.txt", "w", stdout);
for(i = 0; i <= 20; i++)
printf("%.1lf %.9lf\n", soft_point[i][0], soft_point[i][1]);
fclose(stdout);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -