Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <time.h>
- #include <math.h>
- #include <stdio.h>
- #include <malloc.h>
- #include <vector>
- #include <cstdlib>
- #include <string>
- #include <iostream>
- #include <fstream>
- #define PI 3.141592654
- using namespace std;
- //Deklaracje stałych
- const int n = 14;
- const int k = 5; // + 2 bity do zerowania rejestrow
- //Deklaracje zmiennych
- int min_E_b_N_t = 10;
- int max_E_b_N_t = 11;
- int krok = 1;
- long double BER = 0.0;
- int numer_blokow = 10;
- //Deklaracje wektorow
- typedef int bit;
- typedef vector<bit> bitVector;
- typedef vector<float> floatVector;
- vector<bitVector> wygenerowany_ciag;
- vector<bitVector> zakodowany_ciag;
- vector<bitVector> ciag_po_dekod_Vit;
- //Deklaracje funkcji
- vector<bitVector> wygenerujCiag();
- vector<bitVector> zakodujCiag(vector<bitVector> ciag_wygenerowany);
- vector<bitVector> Detekcja(vector<floatVector>& wejscie);
- vector<bitVector> zdekodujCiag(vector<bitVector>& ciag_odebrany);
- int okreslRozniceMiedzyCiagami(bit x1, bit x2, bit t1, bit t2);
- long double obliczanieBER(vector<bitVector>& ciag_zakodowany, vector<bitVector>& ciag_detekcji);
- float gauss(float mean, float sigma);
- void kanal(float es_n0, long dl_kan, int* wej, float* wyj);
- ofstream plik_zakodowane;
- ofstream plik_wygenerowane;
- ofstream plik_odebrane;
- ofstream plik_zdekodowane;
- //
- //main
- int main() {
- vector<floatVector> ciag_po_kanale;
- vector<float> wyjscie_kanalu(n);
- vector<bitVector> po_detekcji;
- plik_odebrane.open("odebrane.txt");
- cout << "Podaj liczbe transmitowanych blokow danych: " ;
- cin >> numer_blokow;
- cout << endl << "Podaj minimalna wartosc E_b/N_0 : ";
- cin >> min_E_b_N_t ;
- cout << endl << "Podaj maksymalna wartosc E_b/N_0 : ";
- cin >> max_E_b_N_t ;
- cout << endl << "Podaj krok zmian wartosci E_b/N_0 : ";
- cin >> krok;
- cout << endl;
- wygenerowany_ciag = wygenerujCiag();
- zakodowany_ciag = zakodujCiag(wygenerowany_ciag);
- for(int eb_n0 = min_E_b_N_t; eb_n0 <= max_E_b_N_t; eb_n0 = eb_n0 + krok){
- plik_odebrane << "Ciagi na wyjsciu kanalu dla Eb/N0 = " << eb_n0 << endl;
- for (int i = 0; i < numer_blokow; i++) {
- kanal(eb_n0, n, zakodowany_ciag[i].data(), wyjscie_kanalu.data());
- ciag_po_kanale.push_back(wyjscie_kanalu);
- for(int k=0; k < wyjscie_kanalu.size(); ++k){
- plik_odebrane << wyjscie_kanalu[k] << " ";
- }
- plik_odebrane << endl;
- }
- plik_odebrane << endl;
- po_detekcji = Detekcja(ciag_po_kanale);
- //ciag_po_dekod_Vit = zdekodujCiag(po_detekcji);
- //BER = obliczanieBER(wygenerowany_ciag, ciag_po_dekod_Vit);
- ciag_po_kanale.clear();
- }
- plik_odebrane.close();
- system("pause");
- return 0;
- }
- // generowanie bitow wejsciowych
- vector<bitVector> wygenerujCiag() {
- vector<bit> wektor;
- vector<bitVector> wygenerowany;
- plik_wygenerowane.open("wygenerowane.txt");
- srand(time(NULL));
- for (int i = 0; i < numer_blokow; i++) {
- for (int j = 0; j < k; j++) {
- wektor.push_back(rand() % 2);
- }
- for (int j =0; j < 2; j++){
- wektor.push_back(0); // bity zerujące rejestr przesuwny
- }
- wygenerowany.push_back(wektor);
- for(int k=0; k < wektor.size(); ++k){
- plik_wygenerowane << wektor[k];
- }
- plik_wygenerowane << endl;
- wektor.clear();
- }
- plik_wygenerowane.close();
- return wygenerowany;
- }
- //koder
- vector<bitVector> zakodujCiag(vector<bitVector> ciag_wygenerowany) {
- vector<bit> wektor;
- vector<bit> wyjscie_kodera;
- vector<bitVector> zakodowany_ciag;
- char stan = 'A'; //stany przedstawiane literami -> stan A : 00, stan B : 10, stan C : 01, stan D : 11
- plik_zakodowane.open("zakodowane.txt");
- for (int i = 0; i < numer_blokow; i++) {
- wektor = ciag_wygenerowany[i];
- for (int j = 0; j <(k+2); j++) {
- switch(stan){
- case 'A':
- if(wektor[j] == 0){
- wyjscie_kodera.push_back(0); wyjscie_kodera.push_back(0);
- stan = 'A';
- }
- else if(wektor[j] == 1){
- wyjscie_kodera.push_back(1); wyjscie_kodera.push_back(1);
- stan = 'B';
- }
- break;
- case 'B':
- if(wektor[j] == 0){
- wyjscie_kodera.push_back(1); wyjscie_kodera.push_back(0);
- stan = 'C';
- }
- else if(wektor[j] == 1){
- wyjscie_kodera.push_back(0); wyjscie_kodera.push_back(1);
- stan = 'D';
- }
- break;
- case 'C':
- if(wektor[j] == 0){
- wyjscie_kodera.push_back(1); wyjscie_kodera.push_back(1);
- stan = 'A';
- }
- else if(wektor[j] == 1){
- wyjscie_kodera.push_back(0); wyjscie_kodera.push_back(0);
- stan = 'B';
- }
- break;
- case 'D':
- if(wektor[j] == 0){
- wyjscie_kodera.push_back(0); wyjscie_kodera.push_back(1);
- stan = 'C';
- }
- else if(wektor[j] == 1){
- wyjscie_kodera.push_back(1); wyjscie_kodera.push_back(0);
- stan = 'D';
- }
- break;
- }
- }
- zakodowany_ciag.push_back(wyjscie_kodera);
- for(int k=0; k < wyjscie_kodera.size(); ++k){
- plik_zakodowane << wyjscie_kodera[k];
- }
- plik_zakodowane << endl;
- wyjscie_kodera.clear();
- }
- plik_zakodowane.close();
- return zakodowany_ciag;
- }
- //Detekcja bitów dla dekodowania twardodecyzyjnego
- vector<bitVector> Detekcja(vector<floatVector>& wejscie) {
- vector<bit> wyjscie;
- vector<bitVector> ciag_po_detekcji;
- for (int i = 0; i < numer_blokow; i++) {
- for (int j = 0; j < n; j++) {
- if (wejscie[i][j] < 0) {
- wyjscie.push_back(0);
- }
- else {
- wyjscie.push_back(1);
- }
- }
- ciag_po_detekcji.push_back(wyjscie);
- wyjscie.clear();
- }
- return ciag_po_detekcji;
- }
- //Dekoder twardodecyzyjny Viterbiego
- vector<bitVector> zdekodujCiag(vector<bitVector>& ciag_odebrany) {
- vector<bitVector> zdekodowany_ciag;
- vector<bit> wyjscie_dekodera;
- plik_zdekodowane.open("zdekodowane.txt");
- int najlepsza_trasa_stan_A[7][2];
- int odl_Hamm_A = 0;
- int najlepsza_trasa_stan_B[7][2];
- int odl_Hamm_B = 0;
- int najlepsza_trasa_stan_C[7][2];
- int odl_Hamm_C = 0;
- int najlepsza_trasa_stan_D[7][2];
- int odl_Hamm_D = 0;
- //string najlepsza_trasa = "";
- for (int i = 0; i < numer_blokow; i++) {
- for (int j = 0; j < n/2; j++) {
- if(j == 0){ //zaczynamy od stanu A (00)
- odl_Hamm_A = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 0);
- najlepsza_trasa_stan_A[j][0] = odl_Hamm_A;
- najlepsza_trasa_stan_B[j][0] = odl_Hamm_A;
- najlepsza_trasa_stan_C[j][0] = odl_Hamm_A;
- najlepsza_trasa_stan_D[j][0] = odl_Hamm_A;
- odl_Hamm_B = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 1);
- najlepsza_trasa_stan_A[j][1] = odl_Hamm_B;
- najlepsza_trasa_stan_B[j][1] = odl_Hamm_B;
- najlepsza_trasa_stan_C[j][1] = odl_Hamm_B;
- najlepsza_trasa_stan_D[j][1] = odl_Hamm_B;
- }
- else if(j == 1){ //znajdujemy się tylko w stanie A i stanie B
- //po dwa rozwidlenia ze stanu A i B
- odl_Hamm_A = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 0);
- najlepsza_trasa_stan_A[j][0] = najlepsza_trasa_stan_A[j-1][0] + odl_Hamm_A;
- najlepsza_trasa_stan_A[j][1] = najlepsza_trasa_stan_A[j-1][1] + odl_Hamm_A;
- odl_Hamm_B = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 1);
- najlepsza_trasa_stan_B[j][0] = najlepsza_trasa_stan_A[j-1][0] + odl_Hamm_B;
- najlepsza_trasa_stan_B[j][1] = najlepsza_trasa_stan_A[j-1][1] + odl_Hamm_B;
- odl_Hamm_C = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 0);
- najlepsza_trasa_stan_C[j][0] = najlepsza_trasa_stan_B[j-1][0] + odl_Hamm_C;
- najlepsza_trasa_stan_C[j][1] = najlepsza_trasa_stan_B[j-1][1] + odl_Hamm_C;
- odl_Hamm_D = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 1);
- najlepsza_trasa_stan_D[j][0] = najlepsza_trasa_stan_B[j-1][0] + odl_Hamm_D;
- najlepsza_trasa_stan_D[j][1] = najlepsza_trasa_stan_B[j-1][1] + odl_Hamm_D;
- }
- else{
- //po dwie możliwości rozwidleń z każdego stanu
- //stan A:
- odl_Hamm_A = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 0);
- najlepsza_trasa_stan_A[j][0] = najlepsza_trasa_stan_A[j-1][0] + odl_Hamm_A;
- odl_Hamm_A = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 1);
- najlepsza_trasa_stan_A[j][1] = najlepsza_trasa_stan_C[j-1][0] + odl_Hamm_A;
- //stan B:
- odl_Hamm_B = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 1);
- najlepsza_trasa_stan_B[j][0] = najlepsza_trasa_stan_A[j-1][0] + odl_Hamm_B;
- odl_Hamm_B = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 0);
- najlepsza_trasa_stan_B[j][1] = najlepsza_trasa_stan_C[j-1][1] + odl_Hamm_B;
- //stan C:
- odl_Hamm_C = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 0);
- najlepsza_trasa_stan_C[j][0] = najlepsza_trasa_stan_B[j-1][0] + odl_Hamm_C;
- odl_Hamm_C = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 1);
- najlepsza_trasa_stan_C[j][1] = najlepsza_trasa_stan_D[j-1][0] + odl_Hamm_C;
- //stan D:
- odl_Hamm_D = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 0, 1);
- najlepsza_trasa_stan_D[j][0] = najlepsza_trasa_stan_B[j-1][1] + odl_Hamm_D;
- odl_Hamm_D = okreslRozniceMiedzyCiagami(ciag_odebrany[i][2*j], ciag_odebrany[i][2*j+1], 1, 0);
- najlepsza_trasa_stan_D[j][1] = najlepsza_trasa_stan_D[j-1][1] + odl_Hamm_D;
- }
- //Obliczenie minimum, jeśli nie zakończyliśmy dekodowania ciągu w stanie A, to znaczy, że ciąg został błędnie zdekodowany
- // tu obliczenie minimum
- //...
- int trasa_końcowa[7];
- char stan = 'A';
- int licznik = 1;
- if((najlepsza_trasa_stan_A[6][0] - najlepsza_trasa_stan_C[6][0]) > 0){ //koniec na stanie A (00)
- trasa_końcowa[6] = 0;
- stan = 'C';
- }else{
- trasa_końcowa[6] = 0;
- stan = 'A';
- }
- while (licznik < 5){
- switch(stan){
- case 'A':
- if((najlepsza_trasa_stan_A[6 - licznik][0] - najlepsza_trasa_stan_C[6 - licznik][0]) > 0){
- trasa_końcowa[6 - licznik] = 0;
- stan = 'C';
- }
- else{
- trasa_końcowa[6 - licznik] = 0;
- stan = 'A';
- }
- break;
- case 'B':
- if((najlepsza_trasa_stan_A[6 - licznik][1] - najlepsza_trasa_stan_C[6 - licznik][1]) > 0){
- trasa_końcowa[6 - licznik] = 1;
- stan = 'C';
- }
- else{
- trasa_końcowa[6 - licznik] = 1;
- stan = 'A';
- }
- break;
- case 'C':
- if((najlepsza_trasa_stan_B[6 - licznik][0] - najlepsza_trasa_stan_D[6 - licznik][0]) > 0){
- trasa_końcowa[6 - licznik] = 0;
- stan = 'D';
- }
- else{
- trasa_końcowa[6 - licznik] = 0;
- stan = 'B';
- }
- break;
- case 'D':
- if((najlepsza_trasa_stan_B[6 - licznik][1] - najlepsza_trasa_stan_D[6 - licznik][1]) > 0){
- trasa_końcowa[6 - licznik] = 1;
- stan = 'D';
- }
- else{
- trasa_końcowa[6 - licznik] = 1;
- stan = 'B';
- }
- break;
- licznik ++;
- }
- }
- switch(stan){
- case 'A':
- trasa_końcowa[1] = 0;
- stan = 'A';
- break;
- case 'B':
- trasa_końcowa[1] = 1;
- stan = 'A';
- break;
- case 'C':
- trasa_końcowa[1] = 0;
- stan = 'B';
- break;
- case 'D':
- trasa_końcowa[1] = 1;
- stan = 'B';
- break;
- }
- if(stan == 'A'){
- trasa_końcowa[1] = 0;
- }
- else{
- trasa_końcowa[1] = 1;
- }
- for (int j = 0; j < (k+2); j++) {
- wyjscie_dekodera.push_back(trasa_końcowa[j]);
- }
- }
- for(int k=0; k < wyjscie_dekodera.size(); ++k){
- plik_zdekodowane << wyjscie_dekodera[k];
- }
- plik_zdekodowane << endl;
- zdekodowany_ciag.push_back(wyjscie_dekodera);
- wyjscie_dekodera.clear();
- }
- plik_zdekodowane.close();
- return zdekodowany_ciag;
- }
- int okreslRozniceMiedzyCiagami(bit x1, bit x2, bit t1, bit t2) {
- int roznica = 0;
- if(x1 != t1){roznica += 1;}
- if(x2 != t1){roznica += 1;}
- return roznica;
- }
- //************************************************************************
- // Function kanal changes binary values into bipolar ones (-1/+1) and adds noise
- // *wej - Input vector of binary values (0/1)
- // *wyj - Output vector of real numbers
- // es_n0 - Es/N0
- // dl_kan - the number of input bits
- void kanal(float es_n0, long dl_kan, int *wej, float *wyj)
- {
- float mean=0;
- float es=1;
- float sygnal;
- float sigma;
- float s_n;
- long y;
- s_n=(float) pow(10, (es_n0/10));
- sigma=(float) sqrt (es/(2*s_n));
- for (y=0; y<dl_kan; y++)
- {
- sygnal = 2 * *(wej+y)-1; // change the binary value (0/1) into symbol (-1/+1)
- *(wyj+y)=sygnal+gauss(mean,sigma); // noise addition
- }
- }
- //**********************************************************************
- float gauss(float mean, float sigma)
- {
- double x;
- double z;
- z=(double)rand()/RAND_MAX;
- if (z==1.0) z=0.9999999;
- x=sigma*sqrt(2.0*log(1.0/(1.0-z)));
- z=(double)rand()/RAND_MAX;
- if (z==1.0) z=0.9999999;
- return((float)(mean+x*cos(2*PI*z)));
- }
- //*******************************************************************
- long double obliczanieBER(vector<bitVector>& ciag_zakodowany, vector<bitVector>& ciag_detekcji){
- float bledy = 0.0;
- long double ber = 0.0;
- for (int i = 0; i < numer_blokow; i++) {
- for (int j = 0; j < k; j++) {
- if(ciag_zakodowany[i][j] != ciag_detekcji[i][j]){
- bledy++;
- }
- }
- }
- ber = bledy/(numer_blokow*n);
- cout << endl << "KONIEC! BER wynosi: " << ber << endl;
- return ber;
- }
Add Comment
Please, Sign In to add comment