Exemple #1
0
        public void MultiplicationInGaliosFieldShouldWorkCorrect(byte firstOperand, byte secondOperand, uint irreduciblePolynomial, byte expectedResult)
        {
            //arrange
            var gfUnderTest = new GaloisField(irreduciblePolynomial);
            //act
            var actualResult = gfUnderTest.Multiply(firstOperand, secondOperand);

            //assert
            Assert.Equal(expectedResult, actualResult);
        }
Exemple #2
0
        /// <summary>
        /// Multiplies this matrix (the one on the left) by another matrix (the one on the right).
        /// </summary>
        public Matrix Multiply(Matrix right)
        {
            Throw.If(this.Columns != right.Rows, $"Columns on left ({this.Columns}) is different than rows on right ({right.Rows})");

            Matrix result = new Matrix(this.Rows, right.Columns);

            for (int r = 0; r < this.Rows; r++)
            {
                for (int c = 0; c < right.Columns; c++)
                {
                    byte value = 0;
                    for (int i = 0; i < this.Columns; i++)
                    {
                        value ^= GaloisField.Multiply(Get(r, i), right.Get(i, c));
                    }
                    result.Set(r, c, value);
                }
            }

            return(result);
        }
Exemple #3
0
        /// <summary>
        /// Does the work of matrix inversion. Assumes that this is an r by 2r matrix.
        /// </summary>
        private void GaussianElimination()
        {
            // Clear out the part below the main diagonal and scale the main diagonal to be 1.
            for (int r = 0; r < Rows; r++)
            {
                // If the element on the diagonal is 0, find a row below
                // that has a non-zero and swap them.
                if (_data[r, r] == (byte)0)
                {
                    for (int rowBelow = r + 1; rowBelow < Rows; rowBelow++)
                    {
                        if (_data[rowBelow, r] != 0)
                        {
                            SwapRows(r, rowBelow);
                            break;
                        }
                    }
                }

                // If we couldn't find one, the matrix is singular.
                Throw.If(_data[r, r] == 0, "Matrix is singular");

                // Scale to 1.
                if (_data[r, r] != 1)
                {
                    byte scale = GaloisField.Divide(1, _data[r, r]);
                    for (int c = 0; c < Columns; c++)
                    {
                        _data[r, c] = GaloisField.Multiply(_data[r, c], scale);
                    }
                }

                // Make everything below the 1 be a 0 by subtracting a multiple of it.
                // Note: subtraction and addition are both exclusive or in the Galois field.
                for (int rowBelow = r + 1; rowBelow < Rows; rowBelow++)
                {
                    if (_data[rowBelow, r] != 0)
                    {
                        byte scale = _data[rowBelow, r];
                        for (int c = 0; c < Columns; c++)
                        {
                            _data[rowBelow, c] ^= GaloisField.Multiply(scale, _data[r, c]);
                        }
                    }
                }
            }

            // Now clear the part above the main diagonal.
            for (int d = 0; d < Rows; d++)
            {
                for (int rowAbove = 0; rowAbove < d; rowAbove++)
                {
                    if (_data[rowAbove, d] != (byte)0)
                    {
                        byte scale = _data[rowAbove, d];
                        for (int c = 0; c < Columns; c++)
                        {
                            _data[rowAbove, c] ^= GaloisField.Multiply(scale, _data[d, c]);
                        }
                    }
                }
            }
        }