private static async Task <int[, ]> GetGallagerParityMatrix(int rows, int columns) { int blocksCount = _wc; int[,] firstSetOfRows = new int[rows / blocksCount, columns]; for (int i = 0; i < firstSetOfRows.GetLength(0); i++) { for (int j = i * _wr; j < (i + 1) * _wr; j++) { firstSetOfRows[i, j] = 1; } } Console.WriteLine("firstSetOfRows"); MatrixOperation.ShowMatrix(firstSetOfRows); TaskFactory <SetInfo> taskFactory = new TaskFactory <SetInfo>(); Task <SetInfo>[] tasks = new Task <SetInfo> [blocksCount]; tasks[0] = taskFactory.StartNew(() => { return(new SetInfo(firstSetOfRows, 0)); }); for (int i = 1; i < blocksCount; i++) { int counter = i; tasks[i] = taskFactory.StartNew(() => CreateSet(firstSetOfRows, counter)); } SetInfo parityMatrixinfo = await taskFactory.ContinueWhenAll(tasks, completedTasks => { int[,] parityCheckMatrix = new int[rows, columns]; foreach (var task in completedTasks) { SetInfo set = task.Result; int matrixCounter = 0; for (int i = set.Matrix.GetLength(0) * set.Number; i < set.Matrix.GetLength(0) * (set.Number + 1); i++) { for (int j = 0; j < set.Matrix.GetLength(1); j++) { parityCheckMatrix[i, j] = set.Matrix[matrixCounter, j]; } matrixCounter++; } } return(new SetInfo(parityCheckMatrix, 0)); }); return(parityMatrixinfo.Matrix); }
static void Main() { Facade facade = new Facade(); int[,] matrix = new int[28, 28]; Random rand = new Random(0); for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { matrix[i, j] = rand.Next(100) < 50 ? 0 : 1; } } try { int[,] encodedMatrix = facade.Encode(matrix, 0).Result; Console.WriteLine("Закодированная"); MatrixOperation.ShowMatrix(encodedMatrix); facade.CreateMistakes(encodedMatrix); Console.WriteLine("Зашумленная"); MatrixOperation.ShowMatrix(encodedMatrix); int[,] decodedMatrix = facade.Decode(encodedMatrix).Result; Console.WriteLine("Декодированная"); MatrixOperation.ShowMatrix(decodedMatrix); Console.WriteLine("Исходная"); MatrixOperation.ShowMatrix(matrix); for (int i = 0; i < decodedMatrix.GetLength(0); i++) { for (int j = 0; j < decodedMatrix.GetLength(1); j++) { if (decodedMatrix[i, j] != matrix[i, j]) { Console.WriteLine("Различия в {0} строке {1} столбце", i, j); } } } } catch (Exception ex) { } System.Threading.Thread.Sleep(3600 * 1000); }
public async Task <int[, ]> Encode(int[,] matrix, int rank) { if (_parityMatrix == null) { _parityMatrix = await ParityMatrixCreator.Create(matrix.GetLength(0), matrix.GetLength(1), 8, 4, _rank); } Console.WriteLine("Проверочная"); MatrixOperation.ShowMatrix(_parityMatrix); return(await new EncoderCPU().Encode(matrix, _parityMatrix, ParityMatrixCreator.Gap)); }
private int[,] RemoveLinearDependence(int[,] matrix, ref int gap) { int[,] tempMatrix = (int[, ])matrix.Clone(); List <int> linearDependentRows = new List <int>(); for (int i = 0; i < tempMatrix.GetLength(0); i++) { int count = 0; for (int j = 0; j < tempMatrix.GetLength(1); j++) { count += tempMatrix[i, j]; } if (count == 0 || count == tempMatrix.GetLength(1)) { linearDependentRows.Add(i); } } linearDependentRows.Reverse(); foreach (var row in linearDependentRows) { if (row == tempMatrix.GetLength(0)) { continue; } MatrixOperation.PermuteRow(tempMatrix, row, tempMatrix.GetLength(0) - 1); } int[,] result = new int[tempMatrix.GetLength(0) - linearDependentRows.Count, tempMatrix.GetLength(1)]; for (int i = 0; i < result.GetLength(0); i++) { for (int j = 0; j < tempMatrix.GetLength(1); j++) { result[i, j] = tempMatrix[i, j]; } } gap -= linearDependentRows.Count; return(result); }
private int[] EncodeMessage(int[,] parityMatrix, int[] message, int gap, int oldGap) { int[,] p1 = null; int[,] messageArray = new int[1, message.Length]; for (int i = 0; i < message.Length; i++) { messageArray[0, i] = message[i]; } if (gap != 0) { int startRow = parityMatrix.GetLength(0) - gap; int[,] DMatrix = new int[gap, gap]; int[,] CMatrix = new int[gap, parityMatrix.GetLength(1) - DMatrix.GetLength(1) - parityMatrix.GetLength(0) + gap]; for (int i = startRow; i < parityMatrix.GetLength(0); i++) { for (int j = 0; j < parityMatrix.GetLength(1) - parityMatrix.GetLength(0) + gap; j++) { if (j < CMatrix.GetLength(1)) { CMatrix[i % startRow, j] = parityMatrix[i, j]; } else { DMatrix[i % startRow, j % CMatrix.GetLength(1)] = parityMatrix[i, j]; } } } int[,] DCMatrix = MatrixOperation.LogicMultiplicateMatrixes(MatrixOperation.LogicGetInverseMatrix(DMatrix), CMatrix); p1 = MatrixOperation.Transponse(MatrixOperation.LogicMultiplicateMatrixes(DCMatrix, MatrixOperation.Transponse(messageArray))); } else { p1 = new int[1, oldGap]; } int[,] BMatrix = new int[parityMatrix.GetLength(0) - gap, oldGap]; int[,] TMatrix = new int[parityMatrix.GetLength(0) - gap, parityMatrix.GetLength(0) - gap]; int[,] AMatrix = new int[BMatrix.GetLength(0), parityMatrix.GetLength(1) - BMatrix.GetLength(1) - TMatrix.GetLength(1)]; for (int i = 0; i < AMatrix.GetLength(0); i++) { for (int j = 0; j < parityMatrix.GetLength(1); j++) { if (j < AMatrix.GetLength(1)) { AMatrix[i, j] = parityMatrix[i, j]; } else if (j < AMatrix.GetLength(1) + BMatrix.GetLength(1)) { BMatrix[i, j % AMatrix.GetLength(1)] = parityMatrix[i, j]; } else { TMatrix[i, j % (AMatrix.GetLength(1) + BMatrix.GetLength(1))] = parityMatrix[i, j]; } } } int[,] AuMatrix = MatrixOperation.LogicMultiplicateMatrixes(AMatrix, MatrixOperation.Transponse(messageArray)); int[,] addedMatrixes = null; int[,] Bp1Matrix = MatrixOperation.LogicMultiplicateMatrixes(BMatrix, MatrixOperation.Transponse(p1)); addedMatrixes = MatrixOperation.LogicAddUpMatrixes(AuMatrix, Bp1Matrix); int[,] p2 = MatrixOperation.Transponse(MatrixOperation.LogicMultiplicateMatrixes(MatrixOperation.LogicGetInverseMatrix(TMatrix), addedMatrixes)); int[] codeword = new int[message.Length + p1.GetLength(1) + p2.GetLength(1)]; for (int i = 0; i < codeword.Length; i++) { if (i < message.Length) { codeword[i] = message[i]; } else if (i < message.Length + p1.GetLength(1)) { codeword[i] = p1[0, i % message.Length]; } else { codeword[i] = p2[0, i % (message.Length + p1.GetLength(1))]; } } return(codeword); }
private static int[,] GetGaussMatrix(int[,] parityMatrix, int gap) { int[,] resultMatrix = new int[parityMatrix.GetLength(0), parityMatrix.GetLength(0)]; int[,] EMatrix = new int[gap, parityMatrix.GetLength(0) - gap]; int[,] TMatrix = new int[parityMatrix.GetLength(0) - gap, parityMatrix.GetLength(0) - gap]; int matrixRow = 0; for (int row = 0; row < parityMatrix.GetLength(0); row++) { int matrixColumn = 0; for (int column = parityMatrix.GetLength(1) - TMatrix.GetLength(1); column < parityMatrix.GetLength(1); column++) { if (row < parityMatrix.GetLength(0) - gap) { TMatrix[row, matrixColumn] = parityMatrix[row, column]; } else { EMatrix[matrixRow, matrixColumn] = parityMatrix[row, column]; } matrixColumn++; } if (row >= parityMatrix.GetLength(0) - gap) { matrixRow++; } } int[,] ETMatrix = MatrixOperation.LogicMultiplicateMatrixes(EMatrix, MatrixOperation.LogicGetInverseMatrix(TMatrix)); matrixRow = 0; for (int row = 0; row < resultMatrix.GetLength(0); row++) { for (int column = 0; column < resultMatrix.GetLength(1); column++) { if (row < (resultMatrix.GetLength(0) - gap)) { if (row == column) { resultMatrix[row, column] = 1; } } else { if (column < resultMatrix.GetLength(0) - gap) { resultMatrix[row, column] = ETMatrix[matrixRow, column]; } else { if (row == column) { resultMatrix[row, column] = 1; } } } } if (row >= (resultMatrix.GetLength(0) - gap)) { matrixRow++; } } return(resultMatrix); }
private static int[,] GetEncodeMatrix(int[,] parityMatrix, out int gap) { int[,] parityMatrixCopy = (int[, ])parityMatrix.Clone(); int permutations = 0; for (int i = 0; i < parityMatrixCopy.GetLength(0) - permutations; i++) { if (parityMatrixCopy[i, parityMatrixCopy.GetLength(1) - 1] == 1) { MatrixOperation.PermuteRow(parityMatrixCopy, i, parityMatrixCopy.GetLength(0) - 1); permutations++; i = 0; } } gap = permutations - 1; // номер столбца, с которым мы работаем int p = parityMatrixCopy.GetLength(1) - 2; int j = 2; for (; ;) { int diagonalRow = parityMatrixCopy.GetLength(0) - (gap + j); if (diagonalRow < 0) { break; } int columnWithMinOnes = 0; int minOnesInColumn = Int32.MaxValue; for (int column = 0; column <= p; column++) { int onesInColumn = 0; for (int row = 0; row <= diagonalRow; row++) { if (parityMatrixCopy[row, column] == 1) { onesInColumn++; } } if (onesInColumn < minOnesInColumn && onesInColumn > 0) { minOnesInColumn = onesInColumn; columnWithMinOnes = column; } } MatrixOperation.PermuteColumn(parityMatrixCopy, columnWithMinOnes, p); int rowWithOne = 0; for (int row = 0; row <= diagonalRow; row++) { if (parityMatrixCopy[row, p] == 1) { rowWithOne = row; break; } } MatrixOperation.PermuteRow(parityMatrixCopy, rowWithOne, diagonalRow); if (minOnesInColumn > 1) { for (int i = 0; i < minOnesInColumn - 1; i++) { rowWithOne = 0; for (int row = 0; row < diagonalRow; row++) { if (parityMatrixCopy[row, p] == 1) { rowWithOne = row; break; } } MatrixOperation.PermuteRow(parityMatrixCopy, rowWithOne, parityMatrixCopy.GetLength(0) - 1); gap++; diagonalRow--; } } j++; p--; } int[,] gaussMatrix = GetGaussMatrix(parityMatrixCopy, gap); parityMatrixCopy = MatrixOperation.LogicMultiplicateMatrixes(gaussMatrix, parityMatrixCopy); Console.WriteLine("Проверочная"); MatrixOperation.ShowMatrix(parityMatrixCopy); return(parityMatrixCopy); }
private bool DecodeMessage(int[] codeword, int[,] parityMatrix, float rank, out int[] originalMessage) { int[] finalCodeWord = new int[codeword.Length]; bool isSindromConfirmed = false; int[,] parityMatrixTransposed = MatrixOperation.Transponse(parityMatrix); int[] syndrome = MatrixOperation.LogicMultiplicateVectorMatrix(codeword, parityMatrixTransposed); for (int i = 0; i < syndrome.Length; i++) { if (syndrome[i] == 1) { isSindromConfirmed = true; break; } } Console.WriteLine("Синдром = " + isSindromConfirmed); if (!isSindromConfirmed) { originalMessage = new int[(int)(codeword.Length * rank)]; for (int i = 0; i < originalMessage.Length; i++) { originalMessage[i] = codeword[i]; } return(isSindromConfirmed); } int[] F = MatrixOperation.MultiplicateVectorMatrix(syndrome, parityMatrix); int threshold = 0; int[] codewordCopy = (int[])codeword.Clone(); for (int i = 0; i < F.Length; i++) { if (threshold < F[i]) { threshold = F[i]; } } Console.WriteLine("Порог " + threshold); for (int i = 0; i < F.Length; i++) { if (F[i] >= threshold) { Console.WriteLine("Исправление в {0} элементе", i); codewordCopy[i] = (codewordCopy[i] + 1) % 2; break; } } originalMessage = codewordCopy; Console.WriteLine("Новое кодовое слово"); for (int i = 0; i < codewordCopy.Length; i++) { Console.Write(codeword[i] + " "); } Console.WriteLine(); return(isSindromConfirmed); }