public void Test() { var matrixField = new MatrixField(new int[, ] { { 0, 0, 1 }, { 1, 1, 1 }, { 1, 2, 3 } }); var inverseRuben = matrixField.InverseRuben(); var inverse = matrixField.Inverse; Assert.Equal(inverse, inverseRuben); }
public static List <Block <byte> > RecoverData(List <Block <byte> > dataBlocks, List <Block <byte> > recoveryBlocks, int parityBlockCount) { var combinedData = dataBlocks.Concat(recoveryBlocks).ToList(); var combinedDataWithoutMissingData = combinedData.Where(t => t.Data != null).ToList(); int dataLengthInsideBlock = combinedData.First(t => t.Data != null).Data.Length; var parMatrix = ParityAlgorithm.CreateParityMatrix(dataBlocks, parityBlockCount); //var parMatrixOnly = ParityAlgorithm.CreateParityOnlyMatrix(dataBlocks, parityBlockCount); var missingDataElements = new List <int>(); var missingRows = new List <Field[]>(); var nonMissingRows = new List <Field[]>(); for (int i = 0; i < combinedData.Count; i++) { var dataBlock = combinedData[i]; if (dataBlock.Data == null) { missingDataElements.Add(i); missingRows.Add(parMatrix.Array[i]); } else { nonMissingRows.Add(parMatrix.Array[i]); } } if (missingDataElements.Count > parityBlockCount) { throw new InvalidOperationException("Can't recover this data as too much blocks are damaged"); } //var subspace = new MatrixField(new int[,] { // { 0, 0, 1, 0, 0 }, // { 0, 0, 0, 1, 0 }, // }); //If there's more repair data then we need, from all the blocks, just take the amount of data blocks var rowsNeeded = nonMissingRows.Take(dataBlocks.Count).ToArray(); var subspace = new MatrixField(rowsNeeded); Console.WriteLine($"Subspace:\n\r{subspace}"); var inverse = subspace.InverseRuben(); var inverse2 = subspace.Inverse; Console.WriteLine($"Inverse:\n\r{inverse}"); if (inverse2 != inverse) { Console.WriteLine("NU"); } foreach (var dataBlock in dataBlocks) { if (dataBlock.Data == null) { dataBlock.Data = new byte[dataLengthInsideBlock]; } } for (int i = 0; i < dataLengthInsideBlock; i++) { var data = new List <Field>(); //If there's more repair data then we need, from all the blocks, just take the amount of data blocks foreach (var dataBlock in combinedDataWithoutMissingData.Take(dataBlocks.Count)) { data.Add(new Field(dataBlock.Data[i])); } var toArray = data.ToArray(); var vector = new CoolVectorField(toArray); var res = inverse * vector; //Console.WriteLine($"Recovered data:\n\r{res}"); for (int y = 0; y < res.Length; y++) { dataBlocks[y].Data[i] = res.Data[y].Value; } } return(dataBlocks); }