BPSK+AWGN信道下画出误符号率和误比特率的性能曲线

BPSK+AWGN信道下画出误符号率和误比特率的性能曲线_第1张图片

老师给出产生随机数的.h文件。

/*******************************************************************************

RandNum.h: interface for the CRandNum class.

********************************************************************************/
#include



/*************************************************************************
Designed by Xiao Ma ([email protected]), Sun Yat-sen University.
This program can only be employed for academic research.
*************************************************************************/



#if !defined(AFX_RANDNUM_H__72FEDEAF_A51C_4724_9A53_5F2F5E00CED4__INCLUDED_)
#define AFX_RANDNUM_H__72FEDEAF_A51C_4724_9A53_5F2F5E00CED4__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000



class CRandNum
{
public:
	CRandNum();
	virtual ~CRandNum();

};



/************************************************************************
*************************************************************************
The following generator employs the linear-congruential method,
and specifically uses a choice of multiplier that was proposed
as a standard by Stephen K. Park et al. in "Technical correspondence,"
Communications of the ACM36(1993), number 7, 108-110
*************************************************************************
************************************************************************/

class CLCRandNum
{
public:
	CLCRandNum();
	virtual ~CLCRandNum();

	void SetSeed(int flag);
	void PrintState(FILE *fp);
	double Uniform();
	void Normal(double *nn, int len_nn);

private:
	long int state;

	static const int A;
	static const long M;
	static const int Q;
	static const int R;
};


/************************************************************************
*************************************************************************
The following generator employs the Wichman-Hill algorithm
*************************************************************************
************************************************************************/
class CWHRandNum
{
public:
	CWHRandNum();
	virtual ~CWHRandNum();

	void SetSeed(int flag);
	void PrintState(FILE *fp);
	double Uniform();
	void Normal(double *nn, int len_nn);

private:
	int X, Y, Z;
};


#endif // !defined(AFX_RANDNUM_H__72FEDEAF_A51C_4724_9A53_5F2F5E00CED4__INCLUDED_)









产生随机数的.cpp文件
/********************************************************************************

RandNum.cpp: implementation of the CRandNum class.

********************************************************************************/

/*******************************************************************************
Programmed by Xiao Ma, Sun Yat-sen University.
If you have any suggestions, please contact me at [email protected]
The program can only be employed for academic research.
******************************************************************************/


#include "RandNum.h"
#include
#include
#include
#include
#include
#include

/********************************************************************
Construction/Destruction
*********************************************************************/

CRandNum::CRandNum()
{

}

CRandNum::~CRandNum()
{

}



/**********************************************************************************
***********************************************************************************
The following generator employs the linear-congruential method,
and specifically uses a choice of multiplier that was proposed
as a standard by Stephen K. Park et al. in "Technical correspondence,"
Communications of the ACM36(1993), number 7, 108-110
***********************************************************************************
***********************************************************************************/






/*******************************************************************************
Construction/Destruction
*******************************************************************************/

CLCRandNum::CLCRandNum()
{

}


CLCRandNum::~CLCRandNum()
{

}


/*******************************************************************
定义一些常数
*******************************************************************/
const int CLCRandNum::A = 48271;
const long CLCRandNum::M = 2147483647;
const int CLCRandNum::Q = M / A;
const int CLCRandNum::R = M % A;




/******************************************************************
函数:SetSeed(int flag)
功能:为随机数设置种子
输入参数:flag
flag = -1 -----默认种子
flag = 0  -----随机种子
flag = 1  -----自选种子
******************************************************************/

void CLCRandNum::SetSeed(int flag)
{
	if (flag < 0)
		state = 17;
	else if (flag == 0){
		state = 0;
		while (state == 0){
			srand((unsigned)time(NULL));
			state = rand();
		}
	}
	else {
		fprintf(stdout, "\nEnter the initial state: ");
		fscanf_s(stdin, "%ld", &state, sizeof(long));
	}

	return;
}

/**************************************************************************
函数:PrintState(FILE *fp)
功能:向文件中输出种子值
输入参数:文件指针
**************************************************************************/

void CLCRandNum::PrintState(FILE *fp)
{
	fprintf(fp, "\n***init_state = %ld***\n", state);

	return;
}



/**************************************************************************
函数:Uniform()
功能:产生0-1间均匀分布的随机数
***************************************************************************/

double CLCRandNum::Uniform()
{
	double u;

	int tmpState = A * (state % Q) - R * (state / Q);
	if (tmpState >= 0)
		state = tmpState;
	else
		state = tmpState + M;

	u = state / (double)M;

	return u;
}


/***************************************************************************
函数:Normal(double *nn, int len_nn)
功能:产生长为len_nn的服从均值为0,方差为1的正态分布的随机数
输入参数:
len_nn  ----- 随机数长度
输出参数
*nn     ----- 保存产生的随机数
****************************************************************************/

void CLCRandNum::Normal(double *nn, int len_nn)
{
	double x1, x2, w;
	int t;

	for (t = 0; 2 * t + 1 < len_nn; t++){
		w = 2.0;
		while (w > 1.0){
			x1 = 2.0 * Uniform() - 1.0;
			x2 = 2.0 * Uniform() - 1.0;

			w = x1 * x1 + x2 * x2;
		}

		w = sqrt(-2.0 * log(w) / w);

		nn[2 * t] = x1 * w;
		nn[2 * t + 1] = x2 * w;
	}

	if (len_nn % 2 == 1){
		w = 2.0;
		while (w > 1.0){
			x1 = 2.0 * Uniform() - 1.0;
			x2 = 2.0 * Uniform() - 1.0;

			w = x1 * x1 + x2 * x2;
		}

		w = sqrt(-2.0 * log(w) / w);

		nn[len_nn - 1] = x1 * w;
	}
}




/***************************************************************************
**************************************************************************
The following generator employs the Wichman-Hill algorithm
****************************************************************************
***************************************************************************/



/*******************************************************************************
Construction/Destruction
*******************************************************************************/

CWHRandNum::CWHRandNum()
{

}

CWHRandNum::~CWHRandNum()
{

}


/******************************************************************
函数:SetSeed(int flag)
功能:为随机数设置种子
输入参数:flag
flag = -1 -----默认种子
flag = 0  -----随机种子
flag = 1  -----自选种子
******************************************************************/

void CWHRandNum::SetSeed(int flag)
{
	if (flag < 0){
		X = 13;
		Y = 37;
		Z = 91;
	}
	else if (flag == 0){
		X = 0;
		Y = 0;
		Z = 0;
		while (X == 0 || Y == 0 || Z == 0){
			srand((unsigned)time(NULL));
			X = rand();
			Y = rand();
			Z = rand();
		}
	}
	else {
		fprintf(stdout, "\nEnter the initial state (X Y Z): ");
		fscanf_s(stdin, "%d %d %d", &X, sizeof(int), &Y, sizeof(int), &Z, sizeof(int));
	}

	return;
}


/**************************************************************************
函数:PrintState(FILE *fp)
功能:向文件中输出种子值
输入参数:文件指针
**************************************************************************/

void CWHRandNum::PrintState(FILE *fp)
{
	fprintf(fp, "\n***init_state (X Y Z) = %d %d %d***\n", X, Y, Z);

	return;
}


/**************************************************************************
函数:Uniform()
功能:产生0-1间均匀分布的随机数
***************************************************************************/

double CWHRandNum::Uniform()
{
	double U;

	X = 171 * X % 30269;
	Y = 172 * Y % 30307;
	Z = 170 * Z % 30323;

	U = X / 30269.0 + Y / 30307.0 + Z / 30323.0;
	U = U - int(U);

	return U;
}


/***************************************************************************
函数:Normal(double *nn, int len_nn)
功能:产生长为len_nn的服从均值为0,方差为1的正态分布的随机数
输入参数:
len_nn  ----- 随机数长度
输出参数
nn  ----- 保存产生的随机数
****************************************************************************/

void CWHRandNum::Normal(double *nn, int len_nn)
{
	double x1, x2, w;
	int t;

	for (t = 0; 2 * t + 1 < len_nn; t++){
		w = 2.0;
		while (w > 1.0){
			x1 = 2.0 * Uniform() - 1.0;
			x2 = 2.0 * Uniform() - 1.0;

			w = x1 * x1 + x2 * x2;
		}

		w = sqrt(-2.0 * log(w) / w);

		nn[2 * t] = x1 * w;
		nn[2 * t + 1] = x2 * w;
	}

	if (len_nn % 2 == 1){
		w = 2.0;
		while (w > 1.0){
			x1 = 2.0 * Uniform() - 1.0;
			x2 = 2.0 * Uniform() - 1.0;

			w = x1 * x1 + x2 * x2;
		}

		w = sqrt(-2.0 * log(w) / w);

		nn[len_nn - 1] = x1 * w;
	}
}


 
  


计算误码率和误比特率并输出实验结果。

#include"RandNum.h"

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define L 1000

int source_arr[L];
int encode_arr[L];
double total_arr[L];
int decode_arr[L];


/*int* generator() {
int length = 10000000;
int *my_arr = new int[length + 1];
my_arr[0] = length;
int token;
for (int i = 1; i <= length; i++) {
token = rand() % 3 - 1;   // generate number between -1~1
my_arr[i] = token > 0 ? 1 : -1;
}
return my_arr;
}
double gaussrand() {
static double V1, V2, S;
static int phase = 0;
double X;

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);

X = V1 * sqrt(-2 * log(S) / S);
}
else {
X = V2 * sqrt(-2 * log(S) / S);
}
phase = 1 - phase;

return X;
}
double* add_noise(int delta, int length) {
double *my_arr = new double[length + 1];
for (int i = 1; i <= length; i++) {
my_arr[i] = gaussrand();
}
return my_arr;
}
int* BPSK_func(int* int_arr, double* double_arr) {
int length = int_arr[0];
int *return_arr = new int[length + 1];
return_arr[0] = length;
for (int i = 1; i <= length; i++) {
return_arr[i] = abs(double_arr[i] + int_arr[i] - 1) > abs(double_arr[i] + int_arr[i] + 1) ? -1 : 1;
}
return return_arr;
}
int main()
{
int *origin_arr = generator();
double *noise_arr = add_noise(0, origin_arr[0]);
int *BPSK_arr = BPSK_func(origin_arr, noise_arr);
int length = BPSK_arr[0];
int error_num = 0;
for (int i = 1; i <= length; i++) {
if (BPSK_arr[i] != origin_arr[i]) {
error_num++;
}
}
double error_rate = (double)error_num / (double)length;
cout << error_rate << endl;
int i;
cin >> i;
return 0;
}*/
int* generator(int length) {
	double token;
	CLCRandNum temp;
	for (int i = 0; i < length; i++) {
		token = temp.Uniform();   // generate number between 0~1
		source_arr[i] = token > 0.5 ? 1 : 0;
	}
	return source_arr;
}
int *encode(int *src_arr, int length) {
	for (int i = 0; i < length; i++) {
		encode_arr[i] = (src_arr[i] > 0.5) ? 1 : -1;
	}
	return encode_arr;
}
double *add_noise(int *encode_arr, int length, double delta) {
	CLCRandNum temp;
	temp.Normal(total_arr, length);
	for (int i = 0; i < length; i++) {
		total_arr[i] = delta*total_arr[i] + encode_arr[i];
	}
	return total_arr;
}
int *decode(double *total_arr, int length) {
	for (int i = 0; i < length; i++) {
		decode_arr[i] = total_arr[i] > 0 ? 1 : 0;
	}
	return decode_arr;
}
int error_num(int *source_arr, int *decode_arr, int length) {
	int error_num = 0;
	for (int i = 0; i < length; i++) {
		if (source_arr[i] != decode_arr[i]) {
			error_num++;
		}
	}
	return error_num;
}
double calculate_delta(double E_No) {
	double temp = E_No;
	temp = pow(10, temp / 10);
	temp = sqrt(0.5 / temp);
	return temp;
}


int main() {
	double *E_No = new double[100];
	double *delta = new double[100];
	for (int i = 2; i < 100; i++) {
		double temp_int = i;
		E_No[i] = double(temp_int / 10);
		delta[i] = calculate_delta(E_No[i]);
	}
	fstream DataWriter;
	DataWriter.open("data1.txt", ios::out);
	if (!DataWriter) {
		cout << "Create File Error" << endl;
		exit(0);
	}
	cout << "   Es/No" << "         Bit-Error Probability" << endl;
	for (int i = 2; i < 100; i++) {
		int total_error = 0;
		for (int j = 0; j < 10000; j++) {

			int *source_arr = generator(L);
			int *encode_arr = encode(source_arr, L);
			double *total_arr = add_noise(encode_arr, L, delta[i]);
			int *decode_arr = decode(total_arr, L);
			total_error += error_num(source_arr, decode_arr, L);
		}
		cout.precision(4);
		cout << "X: " << fixed << E_No[i] << ",         " << "Y: " << total_error << "*10^(-9)" << endl;
		DataWriter << E_No[i] << "," << total_error << "\n";
	}
	DataWriter.close();
	system("pause");

}
实验输出结果:
BPSK+AWGN信道下画出误符号率和误比特率的性能曲线_第2张图片





你可能感兴趣的:(纠错码入门)