// LDPC_Simulator.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include "math.h" #include "limits.h" #include "malloc.h" #include "time.h" #define MAX_ITERATION 10 #define FALSE 0 #define TRUE 1 //Simulation channel signal to noise parameters #define DB_MAX 2 #define DB_INC 0.25 #define DB_INIT -2 //Channel message bit parameters #define HIGH 1 //BSC = +1 BKSP = +1 #define MID 0 //BSC = +0.5 BKSP = 0 #define LOW -1 //BSC = +0 BKSP = -1 int MakeGenerator(int **pchk_matrix, int **gen_matrix, int rows, int n, int k); void SwapRows(int **matrix, int rowIdx1, int rowIdx2, int cols); void AddRows(int **matrix, int rowIdx1, int rowIdx2, int cols); int FindRowdata(int **matrix, int data, int rowSt, int rows, int colIdx, int dir); int BitFlipping(int **pchk_matrix, double *codeword, int *decoded, int nrows, int ncols); int SumProduct(int **pchk_matrix, double *codeword, int *decoded, int nrows, int ncols, double ch_dev); int OneStepMajorityLogic(int **pchk_matrix, double *codeword, int *decoded, int nrows, int ncols); void PrintIntMatrix(int **matrix, int nrows, int ncols); void PrintMatrix(double **matrix, int nrows, int ncols); void FileOutput(FILE *fp, char type, double *codeword, int length); void PrintCodeword(double *codeword, int ncols); void PrintIntCodeword(int *codeword, int ncols); void FreeMatrix(double **matrix, int nrows); void FreeIntMatrix(int **matrix, int nrows); double BitErrorRate(int *original, int *current, int length); int SyndromeTest(int **matrix, int *codeword, int nrows, int ncols); void AddWhiteGaussianNoise(int *codeword, double *received, int length, double variance, double mean); void HardDecision(int *hardcode, double *softcode, int ncols); void ZeroMatrix(double **matrix, int nrows, int ncols); void ZeroVector(double *vector, int ncols); void ZeroIntVector(int *vector, int ncols); void ResetMatrix(int **pchk_matrix, double **matrix, int nrows, int ncols); void BSCtoBKSP(int *codeword, int ncols); int XOR(int a, int b); void main(){ //variables int **gen_matrix = NULL; /*Pointer to Generator matrix*/ int **pchk_matrix = NULL; /*Pointer to Parity Check matrix*/ int *codeword = NULL; /*Channel codeword vector*/ int *original = NULL; /*Original codeword vector*/ int *decoded = NULL; /*Final decoded vector*/ double *received = NULL; /*Codeword + noise vector received*/ FILE *fp = NULL; /*Input file pointer*/ int pchk_rows = 0; /*Parity Check matrix row dimension*/ int pchk_cols = 0; /*Parity Check matrix column dimension*/ int n = 0; /*Codeword and Generator matrix column dimension */ int k = 0; /*Message and Generator matrix row dimension*/ double code_rate = 0.0; /*Code rate*/ double bit_error = 0.0; /*Bit Error Rate*/ double variance = 0.0; /*Channel variance*/ double deviation = 0.0; /*Channel standard deviation*/ double dB = 0.0; /*Signal to Noise ratio*/ double mean = 0.0; /*Signal mean*/ int i, j; /*Local counter variables*/ int row_wt = 0; int status = 0; /*Decoder status bit*/ int type_decoder = 0; /*Decoder choice*/ int type_encoder = 0; /*Encoder choice*/ char filename[200]; /*Input filename containing parity check matrix*/ system("cls"); //Simulator Engine printf(" ************* LDPC Simulator ***************\n"); //Get encoder options from user printf("Encoding Options:\n"); printf(" 1. Load Parity Check Matrix from file\n"); printf(" 2. Generate Parity Check Matrix"); while (type_encoder < 1 && type_encoder > 2){ printf("Enter a number between 1-2: "); scanf("%d", &type_encoder); } switch(type_encoder){ case 1: while(fp = fopen("C://Project//ldpc//Debug//pchk_matrix_8_12.txt","r"); printf("Enter filename: "); //Get decoder option from user printf("Available Decoders:\n"); printf(" 1. Sum Product Algorithm\n"); printf(" 2. Bit Flipping Algorithm\n"); printf(" 3. Majority Logic Algorithm\n"); printf("Enter Decoder number: "); scanf("%d", &type_decoder); while (type_decoder < 1 && type_decoder > 3){ printf("Enter a number between 1-3: "); scanf("%d", &type_decoder); } //Load parity check matrix from file //File contents to be: //nrows ncols //H00.......H0ncols // . . //Hnrows0...Hnrowsncols //fp = fopen("C://Project//ldpc//Debug//pchk_matrix_3_7.txt","r"); //fp = fopen("C://Project//ldpc//Debug//pchk_matrix_6_12.txt","r"); fp = fopen("C://Project//ldpc//Debug//pchk_matrix_8_12.txt","r"); //fp = fopen("C://Project//ldpc//Debug//pchk_matrix_816_408.txt","r"); //fp = fopen("C://Project//ldpc//Debug//pchk_matrix_15_15.txt","r"); if (fp == NULL){ printf("Error: Could not open input file ...\n"); exit(0); } //Get matrix dimensions fscanf(fp, "%d %d", &pchk_rows, &pchk_cols); //Calculate code dimensions n = pchk_cols; k = n - pchk_rows; code_rate = (double)k / (double)n; //Allocate Parity Check matrix memory space pchk_matrix = malloc(pchk_rows * sizeof(int *)); if(pchk_matrix == NULL){ printf("Error: failed to allocate memory for pchk_matrix matrix\n"); exit(1); } for(i = 0; i < pchk_rows; i++){ pchk_matrix[i] = malloc(n * sizeof(int *)); if(pchk_matrix[i] == NULL){ printf("Error: failed to allocate memory for pchk_matrix row\n"); exit(1); } } //Populate Parity Check matrix data for(i = 0; i < pchk_rows; i++){ for(j = 0; j < n; j++){ fscanf(fp, "%d", &pchk_matrix[i][j]); } } //Allocate Parity Check matrix memory space gen_matrix = malloc(k * sizeof(int *)); if(gen_matrix == NULL){ printf("Error: failed to allocate memory for gen_matrix matrix\n"); exit(1); } for(i = 0; i < k; i++){ gen_matrix[i] = malloc(n * sizeof(int *)); if(gen_matrix[i] == NULL){ printf("Error: failed to allocate memory for gen_matrix row\n"); exit(1); } } //Initialise the generator matrix ZeroMatrix(gen_matrix, k, n); //Allocate memory for codeword vector codeword = (int *)malloc(sizeof(int) * n); if(codeword == NULL){ printf("Error: failed to allocate memory for codeword vector\n"); exit(1); } //Allocate memory for codeword vector original = (int *)malloc(sizeof(int) * k); if(original == NULL){ printf("Error: failed to allocate memory for codeword vector\n"); exit(1); } //Allocate memory for decoded vector decoded = (int *)malloc(sizeof(int) * n); if(decoded == NULL){ printf("Error: failed to allocate memory for decoded vector\n"); exit(1); } //Allocate memory for received codeword vector received = (double *)malloc(sizeof(double) * n); if(received == NULL){ printf("Error: failed to allocate memory for received vector\n"); exit(1); } //For testing set codeword to zero vector ZeroIntVector(codeword, n); ZeroIntVector(original, k); PrintIntCodeword(codeword, n); //Convert the codeword to bpsk BSCtoBKSP(codeword, n); PrintIntCodeword(codeword, n); PrintIntMatrix(pchk_matrix, pchk_rows, n); /*DELETE AFTER TESTING*/ for(dB = DB_INIT; dB < DB_MAX; dB += DB_INC){ printf("db: %lf\n", dB); //Initialise received vector ZeroVector(received, n); //Calculate variance for current SNR variance = 1.0/(2.0*code_rate*pow(10.0,dB/10.0)); //Calculate standrad deviation deviation = sqrt(variance); //Add White Guassian Noise AddWhiteGaussianNoise(codeword, received, n, variance, mean); printf("Sent: "); PrintIntCodeword(codeword, n); //printf("Received: "); //PrintCodeword(received, n); //Run Decoders switch(type_decoder){ case 1: status = SumProduct(pchk_matrix, received, decoded, pchk_rows, n, deviation); break; case 2: status = BitFlipping(pchk_matrix, received, decoded, pchk_rows, n); break; case 3: status = OneStepMajorityLogic(pchk_matrix, received, decoded, pchk_rows, n); break; default: printf("Error: Unable to resolve decoder type.\n"); } printf("Last: "); PrintIntCodeword(decoded, n); if(status == 1) printf("Decoded\n"); else printf("Unresolved\n"); bit_error = BitErrorRate(original, decoded, n); printf("BER: %lf\n", bit_error); } //Close open file pointers fclose(fp); //Free used memory FreeIntMatrix(pchk_matrix, pchk_rows); free(codeword); free(decoded); free(received); } /* ************* Generator Matrix Production Methods ************/ int MakeGenerator(int **pchk_matrix, int **gen_matrix, int rows, int n, int k){ int **temp_matrix = NULL; //working matrix int state = 0; //Function state variable fail = 0 success = 1 int rowIdx = 0; //Row index of a matrix int i, j; //Local counter variables temp_matrix = malloc(rows * sizeof(int *)); if(temp_matrix == NULL){ printf("Error: failed to allocate memory for temp_matrix matrix\n"); exit(1); } for(i = 0; i < rows; i++){ temp_matrix[i] = malloc(n * sizeof(int *)); if(temp_matrix[i] == NULL){ printf("Error: failed to allocate memory for temp_matrix row\n"); exit(1); } } //Initialise temp matrix to parity check matrix for(i = 0; i < rows; i++){ for(j = 0; j < n; j++){ temp_matrix[i][j] = pchk_matrix[i][j]; } } //Make temp matrix lower triangular for(i = 0; i < rows; i++){ //Ensure curent matrix data starts with a 1 if(temp_matrix[i][i] == 0){ //Find the next row with a 1 in the column and swap rowIdx = FindRowdata(temp_matrix, 1, i+1, rows, i, 1); if(rowIdx < 0){ printf("Error: unable to make generator matrix from parity check matrix\n"); printf("Reason: no row to swap to make H lower triangular\n"); return state ; } else { SwapRows(temp_matrix, i, rowIdx, n); } } //Ensure each row below current row does not start have a 1 for this column for(j = i+1; j < rows; j++){ if(temp_matrix[j][i] == 1){ AddRows(temp_matrix, i, j, n); } } } //Make temp matrix upper triangular for(i = rows-1; i >= 0; i--){ //Ensure each row below current row does not start have a 1 for this column for(j = i-1; j >= 0; j--){ if(temp_matrix[j][i] == 1){ AddRows(temp_matrix, i, j, n); } } } //Take Parity submatrix and transpose into generator matrix for(i = 0; i < rows; i++){ for(j = rows; j < n; j++){ gen_matrix[j-rows][i] = temp_matrix[i][j]; } } //Add Identity matrix to generator matrix for(i = 0; i < k; i++){ gen_matrix[i][i+rows] = 1; } state = 1; return state; } void SwapRows(int **matrix, int rowIdx1, int rowIdx2, int cols){ int temp; int i; for(i = 0; i < cols; i++){ temp = matrix[rowIdx1][i]; matrix[rowIdx1][i] = matrix[rowIdx2][i]; matrix[rowIdx2][i] = temp; } } //Add content of row1 and row2 and put result into row2 void AddRows(int **matrix, int rowIdx1, int rowIdx2, int cols){ int i; //Only 2 canges to make 1+1->0 & 1+0->1 //no changes for 0+0->0 & 0+1->1 for(i = 0; i < cols; i++){ if(matrix[rowIdx1][i] == 1 && matrix[rowIdx2][i] == 1){ matrix[rowIdx2][i] = 0; } else if(matrix[rowIdx1][i] == 1 && matrix[rowIdx2][i] == 0){ matrix[rowIdx2][i] = 1; } } } //Find data in a matrix given a starting position int FindRowdata(int **matrix, int data, int rowSt, int rows, int colIdx, int dir){ int i; int rowIdx = -1; if(dir > 0){ for(i = rowSt; i < rows; i++){ if(matrix[i][colIdx] == data){ rowIdx = i; break; } } } else { for(i = rowSt; i >= 0; i--){ if(matrix[i][colIdx] == data){ rowIdx = i; break; } } } return rowIdx; } /* ***************** Decoding Methods ************************* */ int BitFlipping(int **matrix, double *codeword, int *decoded, int nrows, int ncols){ int *check_fails = NULL; double currentBit = 0.0; double sum = 0.0; int syndrome = 0; int iteration = 1; int maxFailed = 0; int i, j, k; //Create Check Failure vector for(i = 0; i < ncols; i++) check_fails = (int *)malloc(sizeof(int) * ncols); if(check_fails == NULL){ printf("Error: failed to allocate memory for check_fails\n"); exit(1); } //Convert to hard decision quantized form HardDecision(decoded, codeword, ncols); /*Commence decoding iterations*/ do{ //Check if codeword passes syndrome test syndrome = SyndromeTest(matrix, decoded, nrows, ncols); //If sydrome test failed - find and replace incorrect message bits //For each message bit for(j = 0; j < ncols; j++){ //Get the current message bit currentBit = decoded[j]; //Find a link to a check node for(i = 0; i < nrows; i++){ if(matrix[i][j] == 1){ //Find the links to the variable nodes for(k = 0; k < ncols; k++){ if(k != j && matrix[i][k] == 1) //Add the message bits sum = sum + decoded[k]; } //Compare sum to original bit if(currentBit != fmod(sum , 2)){ //Sum is incorrect increment the failure count check_fails[j]++; } sum = 0; } } } //Find the bits with largest failed checksums for(j = 0; j < ncols; j++){ if(check_fails[j] > maxFailed) maxFailed = check_fails[j]; } //Flip the bits having the largest failure rate for(j = 0; j < ncols; j++){ if(check_fails[j] == maxFailed) decoded[j] = (int)fmod((decoded[j] + 1), 2.0); } maxFailed = 0; iteration++; //Reset failure counter for(i = 0; i < ncols; i++){ check_fails[i] = 0; } //Reset maximum failure counter maxFailed = 0; }while (iteration < MAX_ITERATION && syndrome != 1); //Free allocated memory free(check_fails); return syndrome; } int SumProduct(int **matrix, double *codeword, int *decoded, int nrows, int ncols, double ch_dev){ //Variables double **p0 = NULL; /*Pointer to P0ij probabilities*/ double **p1 = NULL; /*Pointer to P1ij probabilities*/ double **deltaP = NULL; /*Pointer to P deltas*/ double **deltaQ = NULL; /*Pointer to Q deltas*/ double **q0 = NULL; /*Pointer to Q0ij probabilities*/ double **q1 = NULL; /*Pointer to Q1ij probabilities*/ double *f0 = NULL; /*Gaussian probability function for 0 bit*/ double *f1 = NULL; /*Gaussian probability function for 1 bit*/ double *soft0 = NULL; /*soft codeword probability for bit 0*/ double *soft1 = NULL; /*soft codeword probability for bit 1*/ int i, j, k; /*local variables*/ int syndrome = 0; /*syndrome test flag*/ int iteration = 1; /*number of iterations*/ int num_data = 0; /*number of data bits*/ double coeff0 = 0.0; /*scaling coefficient for bit 0*/ double coeff1 = 0.0; /*scaling coefficient for bit 1*/ double column_sum = 0.0;/*matrix column data sum*/ /*Create message bit vectors */ soft0 = (double *)malloc(sizeof(double) * ncols); if(soft0 == NULL){ printf("Error: failed to allocate memory for softc\n"); exit(1); } soft1 = (double *)malloc(sizeof(double) * ncols); if(soft1 == NULL){ printf("Error: failed to allocate memory for softc\n"); exit(1); } /*Create Gaussian probability density function vectors*/ f0 = (double *)malloc(sizeof(double) * ncols); if(f0 == NULL){ printf("Error: failed to allocate memory for f0\n"); exit(1); } f1 = (double *)malloc(sizeof(double) * ncols); if(f1 == NULL){ printf("Error: failed to allocate memory for f1\n"); exit(1); } /*Allocate space for algorithm variables*/ /*prior probabilities*/ p0 = (double **)malloc(sizeof(double *) * nrows); if(p0 == NULL){ printf("Error: failed to allocate memory for p0\n"); exit(1); } for(i = 0; i < nrows; i++){ p0[i] = (double *)malloc(sizeof(double) * ncols); if(p0[i] == NULL){ printf("Error: failed to allocate memory for p0\n"); exit(1);} } p1 = (double **)malloc(sizeof(double *) * nrows); if(p1 == NULL){ printf("Error: failed to allocate memory for p1\n"); exit(1); } for(i = 0; i < nrows; i++){ p1[i] = (double *)malloc(sizeof(double) * ncols); if(p1[i] == NULL){ printf("Error: failed to allocate memory for p1\n"); exit(1); } } /*difference equations*/ deltaP = (double **)malloc(sizeof(double *) * nrows); if(deltaP == NULL){ printf("Error: failed to allocate memory for deltaP\n"); exit(1); } for(i = 0; i < nrows; i++){ deltaP[i] = (double *)malloc(sizeof(double) * ncols); if(deltaP[i] == NULL){ printf("Error: failed to allocate memory for deltaP\n"); exit(1); } } deltaQ = (double **)malloc(sizeof(double *) * nrows); if(deltaQ == NULL){ printf("Error: failed to allocate memory for deltaQ\n"); exit(1); } for(i = 0; i < nrows; i++){ deltaQ[i] = (double *)malloc(sizeof(double) * ncols); if(deltaQ[i] == NULL){ printf("Error: failed to allocate memory for deltaQ\n"); exit(1); } } /*conditional probabilities*/ q0 = (double **)malloc(sizeof(double *) * nrows); if(q0 == NULL){ printf("Error: failed to allocate memory for q0\n"); exit(1); } for(i = 0; i < nrows; i++){ q0[i] = (double *)malloc(sizeof(double) * ncols); if(q0[i] == NULL){ printf("Error: failed to allocate memory for q0\n"); exit(1); } } q1 = (double **)malloc(sizeof(double *) * nrows); if(q1 == NULL){ printf("Error: failed to allocate memory for q1\n"); exit(1); } for(i = 0; i < nrows; i++){ q1[i] = (double *)malloc(sizeof(double) * ncols); if(q1[i] == NULL){ printf("Error: failed to allocate memory for q1\n"); exit(1); } } /* Initialise all algorithm matrices to parity check matrix */ ResetMatrix(matrix, p0, nrows, ncols); ResetMatrix(matrix, p1, nrows, ncols); ResetMatrix(matrix, q0, nrows, ncols); ResetMatrix(matrix, q1, nrows, ncols); ResetMatrix(matrix, deltaP, nrows, ncols); ResetMatrix(matrix, deltaQ, nrows, ncols); //Calculate the Guassian density probabilities for(i = 0; i < ncols; i++) f1[i] = 1 /(1+exp((-2*codeword[i])/pow(ch_dev,2))); for(i = 0; i < ncols; i++) f0[i] = 1 - f1[i]; /*calculate the q1ij probabilities*/ for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ if(q1[i][j] != 0) q1[i][j] *= f1[j]; } } //calculate the q0ij probabilities for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ if(q0[i][j] != 0) q0[i][j] *= f0[j]; } } /*Commence decoding iterations*/ do{ //Convert to hard decision quantized form HardDecision(decoded, codeword, ncols); //Check if codeword passes syndrome test syndrome = SyndromeTest(matrix, decoded, nrows, ncols); //Calculate the probability deltas for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ deltaQ[i][j] = q0[i][j] - q1[i][j]; } } for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ if(deltaP[i][j] != 0){ for(k = 0; k < ncols; k++){ if(j != k && deltaP[i][k] != 0){ deltaP[i][j] *= deltaQ[i][k]; } } } } } //Calculate p values for(i = 0; i < nrows; i++){ for(j= 0; j < ncols; j++){ if(p0[i][j] != 0){ p0[i][j] *= (0.5 * (1 + deltaP[i][j])); p1[i][j] *= (0.5 * (1 - deltaP[i][j])); } } } //calculate the coefficients for(i = 0; i < ncols; i++){ for(j = 0; j < nrows; j++){ if(matrix[j][i] != 0){ coeff0 = 1.0; coeff1 = 1.0; for(k = 0; k < nrows; k++){ if(j != k && matrix[k][i] != 0){ coeff0 *= p0[k][i]; coeff1 *= p1[k][i]; } } coeff0 *= f0[i]; coeff1 *= f1[i]; q0[j][i] = coeff0 /(coeff0 + coeff1); q1[j][i] = coeff1 /(coeff0 + coeff1); } } } //Generate new soft codewords for each bit for(i = 0; i < ncols; i++){ soft0[i] = 1; soft1[i] = 1; for(j = 0; j < nrows; j++){ if(p0[j][i] != 0){ soft0[i] *= p0[j][i]; soft1[i] *= p1[j][i]; } } soft0[i] *= f0[i]; soft1[i] *= f1[i]; //Hard code the new codeword if(soft1[i] > soft0[i]) decoded[i] = 1; else decoded[i] = 0; } //Reset matrices ResetMatrix(matrix, deltaP, nrows, ncols); ResetMatrix(matrix, deltaQ, nrows, ncols); ResetMatrix(matrix, p0, nrows, ncols); ResetMatrix(matrix, p1, nrows, ncols); iteration++; } while( iteration <= MAX_ITERATION && syndrome != 1); //Free allocated memory FreeMatrix(p0, nrows); FreeMatrix(p1, nrows); FreeMatrix(deltaP, nrows); FreeMatrix(deltaQ, nrows); FreeMatrix(q0, nrows); FreeMatrix(q1, nrows); free(soft0); free(soft1); return syndrome; } int OneStepMajorityLogic(int **matrix, double *codeword, int *decoded, int nrows, int ncols){ // int iteration = 1; /*Iteration counter*/ //int syndrome = 0; /*Syndrome test status flag*/ //int col_wt = 0; /*Parity check matrix column weight*/ //int err_wt = 0; /*Error column weight*/ //int pass = 0; /*Orthogonal pass flag*/ //int ***Errors = NULL; /*3d Error matrix*/ //int **Used = NULL; /*Tracking matrix*/ //int *Erows = NULL; /*Number of rows in each Error matrix*/ //int i, j, k, l, m, n; /*Local counter variables*/ //printf("**********Entering One Step Majority Logic Decoder***********\n"); /*DELETE AFTER TESTING*/ ////Create Error matrix //Errors = (int ***)malloc(sizeof(int **) * ncols); //if(Errors == NULL){ // printf("Error: failed to allocate memory for Error matrix\n"); // exit(1); //} //for(i = 0; i < ncols; i++){ // Errors[i] = (int **)malloc(sizeof(int *) * nrows); // if(Errors[i] == NULL){ // printf("Error: failed to allocate memory for Error Matrix row\n"); // exit(1); // } // for(j = 0; j < nrows; j++){ // Errors[i][j] = (int *)malloc(sizeof(int) * ncols); // if(Errors[i][j] == NULL){ // printf("Error: failed to allocate memory for Error Matrix column\n"); // exit(1); // } // } //} ////Create tracking matrix //Used = (int **)malloc(sizeof(int *) * nrows); //if(Used == NULL){ // printf("Error: failed to allocate memory for Used matrix\n"); // exit(1); //} // for(i = 0; i < nrows; i++){ // Used[i] = (int *)malloc(sizeof(int) * ncols); // if(Used[i] == NULL){ // printf("Error: failed to allocate memory for Used matrix row\n"); // exit(1);} //} ////Initialise tracking matrix to the parity check matrix //for(i = 0; i < nrows; i++){ // for(j = 0; j < ncols; j++) // Used[i][j] = matrix[i][j]; //} ////Create Error rows vector //Erows = (int *)malloc(sizeof(int) * ncols); //if(Erows == NULL){ // printf("Error: failed to allocate memory for Error rows vector\n"); // exit(1); //} ////Transfer Parity check matrix base vectors to Error matrix //for(i = 0; i < ncols; i++){ // col_wt = 0; // for(j = 0; j < nrows; j++){ // if(matrix[j][i] == 1){ // col_wt++; // for(k = 0; k < ncols; k++){ // Errors[i][col_wt-1][k] = matrix[j][k]; // } // } // } // Erows[i] = col_wt; //} ////Make Error vectors orthogonal //for(i = 0; i < ncols; i++){ //for each bit in the codeword // do{ // for(j = 0; j < Erows[i]; j++){ //for each row in the error matrix // for(k = 0; k < ncols; k++){ //for each bit in the Error matrix row // if( k != i){ //do not check the same as the current codeword bit // if(Errors[i][j][k] == 1){ //check if the bit is a 1 // err_wt++; //keep the total of ones in this Error matrix column // } // if(err_wt > 1){ //if more than one 1 // for(l = 0; l < nrows; l++){ //Find a row in the Used matrix where // if(Used[l][i] == 0 && Used[l][k] == 1){ //the row has not been used and has a 1 in the current column // //Add the Used row to the Error row using binary addition // for(m = 0; m < ncol; m++){ // Errors[i][j][m] = XOR(Errors[i][j][m],Used[l][m]); // } // //Set the Used matrix current codeword bit to a 1 to indicate the row has been used // Used[l][i] = 1; // } // } // } // } // } // err_wt = 0; // } // }while(pass != 1); //} ////Display Error Matrix DELETE AFTER TEST //for(i = 0; i < ncols; i++){ // printf("\n\n%d:\n", i+1); // for(j = 0; j < Erows[i]; j++){ // for(k = 0; k < ncols; k ++){ // printf("%d ", Errors[i][j][k]); // } // printf("\n"); // } //} // //do{ // //iteration++; //}while( iteration <= MAX_ITERATION && syndrome != 1); // //return syndrome; return 0; } /**************** Common Methods ***********************/ //Display the matrix void PrintIntMatrix(int **matrix, int nrows, int ncols){ int i, j; for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ printf("%d ", matrix[i][j]); } printf("\n"); } } //Display a matrix void PrintMatrix(double **matrix, int nrows, int ncols){ int i, j; for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ printf("%2.4f ", matrix[i][j]); } printf("\n"); } printf("\n\n"); } //Output code to file void FileOutput(FILE *fp, char type, double *codeword, int ncols){ int i; fprintf(fp, " %c: ", type); for(i = 0; i < ncols; i++){ fprintf(fp, "%d", (int)codeword[i]); } } //Display the message void PrintCodeword(double *codeword, int length){ int i; for(i = 0; i < length; i++){ printf("%2.4lf ", codeword[i]); } printf("\n"); } void PrintIntCodeword(int *codeword, int length){ int i; for(i = 0; i < length; i++){ printf("%d ", codeword[i]); } printf("\n"); } //Free matrix memory void FreeMatrix(double **matrix, int nrows){ int i; for(i = 0; i < nrows; i++) free(matrix[i]); free(matrix); } void FreeIntMatrix(int **matrix, int nrows){ int i; for(i = 0; i < nrows; i++) free(matrix[i]); free(matrix); } //Calculate the BER for the signal double BitErrorRate(int *original, int *current, int length){ int errors = 0; int i; for(i = 0; i < length; i++){ if(current[i] != original[i]) errors++; } return((double)errors / (double)length); } //Conduct syndrome test for cH = 0 int SyndromeTest(int **matrix, int *codeword, int nrows, int ncols){ int pass = -1; int rowsum = 0; int multi = 0; int i, j; for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++){ multi += (codeword[j] * matrix[i][j]); } rowsum = (multi % 2); if(rowsum > 0) pass = 1; } return pass; } //Add AWGN noise using Box-Muller method to codeword void AddWhiteGaussianNoise(int *codeword, double *received, int length, double variance, double mean){ double s1, s2, rand_n, r, noise; int i; srand((int) time(NULL)); for(i = 0; i < length; i++){ do { rand_n = (rand() / (double)RAND_MAX); s1 = rand_n * 2.0 - 1.0; rand_n = (rand() / (double)RAND_MAX); s2 = rand_n * 2.0 - 1.0; r = s1 * s1 + s2 * s2; } while( r >= 1.0 || r == 0.0); noise = mean + sqrt(variance) *( s1 * sqrt((-2.0 * log(r)) / r)); received[i] = codeword[i] + noise; } } //Convert message bits to either 0 or 1 void HardDecision(int *hardcode, double *softcode, int length){ int i; for(i = 0; i < length; i++){ if (softcode[i] <= MID) hardcode[i] = LOW; else hardcode[i] = HIGH; } } //Zeroise matrix data void ZeroMatrix(double **matrix, int nrows, int ncols){ int i, j; for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++) matrix[i][j] = 0; } } //Zero a double type vector void ZeroVector( double *vector, int ncols){ int i; for(i = 0; i < ncols; i++) vector[i] = 0.0; } //Zero an int vector void ZeroIntVector( int *vector, int ncols){ int i; for(i = 0; i < ncols; i++) vector[i] = 0; } void ResetMatrix(int **pchk_matrix, double **matrix, int nrows, int ncols){ int i, j; for(i = 0; i < nrows; i++){ for(j = 0; j < ncols; j++) matrix[i][j] = (double)pchk_matrix[i][j]; } } void BSCtoBKSP(int *codeword, int ncols){ int i; for(i = 0; i < ncols; i++){ if(codeword[i] < 0.5) codeword[i] = -1; else codeword[i] = 1; } } void BKSPtoBSC(int *codeword, int ncols){ int i; for(i = 0; i < ncols; i++){ if(codeword[i] < 0) codeword[i] = 0; else codeword[i] = 1; } } int XOR(int a, int b){ return (a == b) ? 0 : 1; }