QPSKの誤り率を出力

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Letheee

QPSKの誤り率を出力

#1

投稿記事 by Letheee » 3年前

初めてこちらを利用させていただきます、よろしくお願いします。

下のBPSKの誤り率を出力するプログラムを改変してOPSKの誤り率を出力したいのですが、プログラムの組み方がよくわかりません。

コード:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#define Nnum 16			// 素波数
#define pi 3.141592653589793238462643383279

double drand48(); /* 一様乱数 */
double rcos0, rsin0; /* 正規乱数 */
double Ichannel, Qchannel; /* I-channelとQ-channel */
double phai[16]; // 素波の初期位相



void main()
{

	void normal();
	void fading();
	void Init();
	double ebn0; /* Eb/N0 真値 */
	double ebn0d; /* Eb/N0 dB値 */
	int Istrans, Qstrans; /* 送信信号 */
	double Amp; /* 送信電力 */
	double fdt; /* 正規化最大ドップラー周波数 */
	double Isrec, Qsrec; /* 受信信号 */
	double Idet, Qdet; /* 復調信号 */
	int Idec, Qdec; /* 復号結果 */
	double sumt; /* 総送信ビット数 */
	double sume; /* 総誤りビット数 */
	double rave;
	int error; /* 送信ビットと復号ビットの積 */
	int ebit; /* 判定結果 */
	double r0;
	double pr;
	long i0, i1, i2;
	long itime1;
	long itime2;

	FILE *stream;



	fopen_s(&stream, "test.txt", "w");
	fprintf_s(stream, "Eb/No ber \n");

	itime1 = 1000;
	itime2 = 1000;
	fdt = 0.01;

	for (i0 = 0; i0 <= 10; i0 = i0 + 1) {
		ebn0d = (double)i0;
		ebn0 = pow(10.0, ebn0d / 10.0);
		Amp = sqrt(2 * ebn0);
		sumt = 0.0;
		sume = 0.0;
		rave = 0.0;

		for (i1 = 0; i1 < itime1; i1++) {
			Init();
			for (i2 = 0; i2 < itime2; i2++) {
				r0 = drand48();
				if (r0 > 0.5) Istrans = 1;
				else Istrans = -1;
				Qstrans = 0;
				normal(0.0, 1.0);
				fading(fdt, i2);
				r0 = (Ichannel*Ichannel) + (Qchannel*Qchannel);
				rave = rave + r0;

							Ichannel=Qchannel=1/sqrt(2.0);

				Isrec = Amp * Ichannel*(double)Istrans - Amp * Qchannel*(double)Qstrans + rcos0;
				Qsrec = Amp * Qchannel*(double)Istrans + Amp * Ichannel*(double)Qstrans + rsin0;

				Idet = Isrec * Ichannel + Qsrec * Qchannel;
				Qdet = -Isrec * Qchannel + Qsrec * Ichannel;

				if (Idet > 0) Idec = 1;
				else Idec = -1;
				error = Idec * Istrans;
				if (error > 0) ebit = 0;
				else ebit = 1;
				sumt = sumt + 1.0;
				sume = sume + (double)ebit;
			}

		}
		pr = sume / sumt;
		rave = rave / sumt;

		fprintf_s(stream, "%d %f %f %f %f \n", i0, pr, sumt, sume, rave);
	}


	fclose(stream);
}

/*  normal distribution */
void normal(av, st)
double av, st;
{
	double r1, r2, z1, z2;
	r1 = drand48();
	r2 = drand48();
	z1 = sqrt(-2.0*log(r1));
	z2 = cos(2.0*pi*r2);
	rcos0 = st * z1*z2 + av;
	z2 = sin(2.0*pi*r2);
	rsin0 = st * z1*z2 + av;
	/*	printf("%f %f %f \n",r1,r2,rcos0); */
}

// fading
void fading(fdt, time)
double fdt;
long time;
{
	int i;
	double r0, r1, cos1, sin1;

	Ichannel = 0.0;
	Qchannel = 0.0;
	for (i = 0; i < Nnum; i++) {
		r0 = cos(2 * pi*(double)i / (double)Nnum);
		r1 = 2.0*pi*r0*fdt*(double)time;
		cos1 = cos(r1 + phai[i]);
		sin1 = sin(r1 + phai[i]);
		Ichannel = Ichannel + cos1;
		Qchannel = Qchannel + sin1;
	}
	Ichannel = Ichannel / sqrt(Nnum);
	Qchannel = Qchannel / sqrt(Nnum);
}

// 素波の初期位相の初期化
void Init()
{
	double r;
	int i;
	for (i = 0; i < Nnum; i++) {
		r = drand48();
		phai[i] = 2 * pi*r;
	}
}

/* random number generator [0,1] */
double drand48()
{
	double x0, x1, x2;
	x0 = (double)rand();
	x1 = (double)rand();
	x2 = 32768.0*x0 + x1;
	x2 = x2 / (32768.0*32767.0 + 32767.0);
	return(x2);
}
改変する必要のある箇所は送信ビットを発生させる

コード:

				r0 = drand48();
				if (r0 > 0.5) Istrans = 1;
				else Istrans = -1;
				Qstrans = 0;
と信号の判定を行う

コード:

				if (Idet > 0) Idec = 1;
				else Idec = -1;
				error = Idec * Istrans;
				if (error > 0) ebit = 0;
				else ebit = 1;
の部分なのですが、QPSKの場合はどう組めばいいかわからないため教えていただきたいです。
差し支えなければ考え方も教えていただけると幸いです。
よろしくお願いします。

[os] Windows10
Visualstudio2019
.c

Meta3

Re: QPSKの誤り率を出力

#2

投稿記事 by Meta3 » 3年前

https://ja.wikipedia.org/wiki/%E4%BD%8D ... 9%E8%AA%BF

コード:

/*  normal distribution */
void normal(av, st)
double av, st;
{
これは相当古いC の書法でかかれていますね
ググレば沢山の情報があるので解決への問い合わせ先も見つかるでしょう
専門的過ぎてここには不向きと思います。

返信

“C言語何でも質問掲示板” へ戻る