/// <summary> /// Performs a principal component analysis of the data. /// </summary> /// <returns>The result of the principal component analysis.</returns> /// <exception cref="InsufficientDataException">The number of data entries (<see cref="Count"/>) is /// less than the number of variables (<see cref="Dimension"/>).</exception> /// <seealso cref="PrincipalComponentAnalysis"/> public PrincipalComponentAnalysis PrincipalComponentAnalysis() { if (Count < Dimension) { throw new InsufficientDataException(); } // construct a (Count X Dimension) matrix of mean-centered data double[] store = MatrixAlgorithms.AllocateStorage(Count, Dimension); int i = 0; for (int c = 0; c < Dimension; c++) { double mu = storage[c].Mean; for (int r = 0; r < Count; r++) { store[i] = storage[c][r] - mu; i++; } } // bidiagonalize it double[] a, b; MatrixAlgorithms.Bidiagonalize(store, Count, Dimension, out a, out b); // form the U and V matrices double[] left = MatrixAlgorithms.AccumulateBidiagonalU(store, Count, Dimension); double[] right = MatrixAlgorithms.AccumulateBidiagonalV(store, Count, Dimension); // find the singular values of the bidiagonal matrix MatrixAlgorithms.ExtractSingularValues(a, b, left, right, Count, Dimension); // sort them MatrixAlgorithms.SortValues(a, left, right, Count, Dimension); PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(left, a, right, Count, Dimension); return(pca); }
public void McElieseGenericFormTest(int n, int k, int d, int t, int fieldPower, MatrixInt message, MatrixInt errorVector, MatrixInt scrambler, int[] permutation, int[] mask) { var galoisField = new GaloisField(2, fieldPower); var generator = new ParityCheckMatrixGeneratorEllyptic(2); var linearCode = new LinearCode(n, k, d, t, galoisField); while (true) { linearCode.ParityCheckMatrix = generator.Generate(linearCode); if (Helper.Weight(linearCode.ParityCheckMatrix) < Math.Ceiling(linearCode.ParityCheckMatrix.RowCount * linearCode.ParityCheckMatrix.ColumnCount * 0.7)) { continue; } try { linearCode.GeneratorMatrix = GeneratorMatrixCalculator.CalculateGeneratorMatrixAlt(linearCode); } catch (LinearCodeException ex) { Console.WriteLine(ex.Message); continue; } if (Helper.Weight(MatrixAlgorithms.DotMultiplication(linearCode.GeneratorMatrix, linearCode.ParityCheckMatrix.Transpose(), galoisField)) == 0) { linearCode.GeneratorMatrix = linearCode.GeneratorMatrix; break; } } var crytptogram = McElieseGenericForm.Encrypt(linearCode, scrambler, permutation, mask, generator, message, errorVector); var decryptedMessage = McElieseGenericForm.Decrypt(linearCode, permutation, mask, scrambler, generator, crytptogram); Assert.True(message == decryptedMessage); }
public static MatrixInt Encrypt(ILinearCode linearCode, MatrixInt scramblerMatrix, IList <int> permutation, IList <int> mask, ParityCheckMatrixGeneratorEllyptic generator, MatrixInt message, MatrixInt errorVector) { var encryptionMatrix = MatrixAlgorithms.DotMultiplication(scramblerMatrix, linearCode.GeneratorMatrix, linearCode.GaloisField); Debug.WriteLine(encryptionMatrix); encryptionMatrix = encryptionMatrix.PermuteColumns(permutation); Debug.WriteLine(encryptionMatrix); for (int col = 0; col < encryptionMatrix.ColumnCount; col++) { for (int row = 0; row < encryptionMatrix.RowCount; row++) { encryptionMatrix[row, col] = linearCode.GaloisField.MultiplyWords(encryptionMatrix[row, col], mask[col]); } } Debug.WriteLine(encryptionMatrix); var encryptedMessage = MatrixAlgorithms.DotMultiplication(message, encryptionMatrix, linearCode.GaloisField); for (int i = 0; i < encryptedMessage.ColumnCount; i++) { encryptedMessage[0, i] = linearCode.GaloisField.AddWords(encryptedMessage[0, i], errorVector[0, i]); } return(encryptedMessage); }
public MatrixInt Encode(MatrixInt message) { return(MatrixAlgorithms.DotMultiplication(message, GeneratorMatrix, GaloisField)); }
private bool IsGeneratorMatrixValid(MatrixInt generatorMatrix, MatrixInt parityCheckMatrix, GaloisField galoisField) { var result = MatrixAlgorithms.DotMultiplication(generatorMatrix, parityCheckMatrix.Transpose(), galoisField); return(Helper.Weight(result) == 0); }
/// <summary> /// Performs a principal component analysis of the multivariate sample. /// </summary> /// <returns>The result of the principal component analysis.</returns> /// <param name="columns">The set of columns to analyze.</param> /// <exception cref="ArgumentNullException"><paramref name="columns"/> or one of its members is <see langword="null"/>.</exception> /// <exception cref="DimensionMismatchException">The columns do not all have the same number of entries.</exception> /// <exception cref="InsufficientDataException">The number of entries is less than the number of columns.</exception> /// <remarks> /// <para>For background on principal component analysis, see the remarks at <see cref="Meta.Numerics.Statistics.PrincipalComponentAnalysis"/>.</para> /// <para>Note that the <paramref name="columns"/> argument is column-oriented, i.e. it is a list of columns, /// not row-oriented, i.e. a list of rows. Either of these would match the method signature, but only /// column-oriented inputs will produce correct results.</para> /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="columns"/>, or one of the columns in it, is <see langword="null"/>.</exception> /// <exception cref="DimensionMismatchException">Not all of the columns in <paramref name="columns"/> have the same length.</exception> /// <exception cref="InsufficientDataException">There are fewer rows than columns.</exception> /// <seealso href="https://en.wikipedia.org/wiki/Principal_component_analysis"/> public static PrincipalComponentAnalysis PrincipalComponentAnalysis(this IReadOnlyList <IReadOnlyList <double> > columns) { if (columns == null) { throw new ArgumentNullException(nameof(columns)); } int dimension = columns.Count; int count = -1; for (int c = 0; c < dimension; c++) { IReadOnlyList <double> column = columns[c]; if (column == null) { throw new ArgumentNullException(nameof(columns)); } if (count < 0) { count = column.Count; } else { if (column.Count != count) { throw new DimensionMismatchException(); } } } if (count < dimension) { throw new InsufficientDataException(); } // construct a (Count X Dimension) matrix of mean-centered data double[] store = MatrixAlgorithms.AllocateStorage(count, dimension); int i = 0; for (int c = 0; c < dimension; c++) { IReadOnlyList <double> column = columns[c]; double mu = column.Mean(); for (int r = 0; r < count; r++) { store[i] = column[r] - mu; i++; } } // bidiagonalize it double[] a, b; MatrixAlgorithms.Bidiagonalize(store, count, dimension, out a, out b); // form the U and V matrices double[] left = MatrixAlgorithms.AccumulateBidiagonalU(store, count, dimension); double[] right = MatrixAlgorithms.AccumulateBidiagonalV(store, count, dimension); // find the singular values of the bidiagonal matrix MatrixAlgorithms.ExtractSingularValues(a, b, left, right, count, dimension); // sort them MatrixAlgorithms.SortValues(a, left, right, count, dimension); PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(left, a, right, count, dimension); return(pca); }
public McElieseEllyptic(int n, int k, int d, int t, GaloisField galoisField, MatrixInt scramblerMatrix = null, IList <int> permutation = null, IList <int> mask = null) { _generator = new ParityCheckMatrixGeneratorEllyptic(2); LinearCode = new LinearCode(n, k, d, t, galoisField); MatrixInt parityCheckMatrix = null; MatrixInt generatorMatrix = null; while (true) { parityCheckMatrix = _generator.Generate(LinearCode); LinearCode.ParityCheckMatrix = parityCheckMatrix; Debug.WriteLine(parityCheckMatrix); var minValueFillPercentage = 0.7; if (Helper.Weight(parityCheckMatrix) < Math.Ceiling(parityCheckMatrix.RowCount * parityCheckMatrix.ColumnCount * minValueFillPercentage)) { continue; } try { generatorMatrix = GeneratorMatrixCalculator.CalculateGeneratorMatrixAlt(LinearCode); Debug.WriteLine(generatorMatrix); } catch (LinearCodeException ex) { Debug.WriteLine(ex.Message); continue; } if (IsGeneratorMatrixValid(parityCheckMatrix, generatorMatrix, galoisField)) { LinearCode.GeneratorMatrix = generatorMatrix; break; } } if (scramblerMatrix is null) { scramblerMatrix = Helper.GenerateScramblerMatrix(LinearCode.K); while (true) { try { MatrixAlgorithms.MatrixInverse(scramblerMatrix, galoisField); break; } catch (SolveMatrixException) { Debug.WriteLine("Reattempting to generate scrambler matrix"); } } } if (permutation is null) { permutation = Helper.GeneratePermutaionList(LinearCode.N); } if (mask is null) { mask = Helper.GenerateMask(LinearCode.N, LinearCode.GaloisField); } var inverseMask = new List <int>(LinearCode.N); for (int i = 0; i < LinearCode.N; i++) { inverseMask.Add(LinearCode.GaloisField.GetMultiplicativeInverse(mask[i])); } PrivateKey = new PrivateKey { GeneratorMatrix = LinearCode.GeneratorMatrix, ScramblerMatrix = scramblerMatrix, InverseScramblerMatrix = MatrixAlgorithms.MatrixInverse(scramblerMatrix, galoisField), Permutation = permutation, InversePermutation = Helper.InversePermutation(permutation), Mask = mask, InverseMask = inverseMask }; var encryptionMatrix = MatrixAlgorithms.DotMultiplication(PrivateKey.ScramblerMatrix, generatorMatrix, LinearCode.GaloisField); Debug.WriteLine(encryptionMatrix); encryptionMatrix = encryptionMatrix.PermuteColumns(PrivateKey.Permutation); Debug.WriteLine(encryptionMatrix); for (int col = 0; col < encryptionMatrix.ColumnCount; col++) { for (int row = 0; row < encryptionMatrix.RowCount; row++) { encryptionMatrix[row, col] = LinearCode.GaloisField.MultiplyWords(encryptionMatrix[row, col], PrivateKey.Mask[col]); } } Debug.WriteLine(encryptionMatrix); PublicKey = new PublicKey { EncryptionMatrix = encryptionMatrix, }; }
public void MatrixAlgorithms_Rotate90_Should_Rotate_By_90() { int[,] matrix = { { 6, 12, 8 }, { 2, 9, 3 }, { 4, 8, 0 } }; var result = MatrixAlgorithms.Rotate90(matrix); }