Пример #1
0
        /**
         * Create a Vandermonde matrix, which is guaranteed to have the
         * property that any subset of rows that forms a square matrix
         * is invertible.
         *
         * @param rows Number of rows in the result.
         * @param cols Number of columns in the result.
         * @return A Matrix.
         */
        private static Matrix vandermonde(int rows, int cols)
        {
            Matrix result = new Matrix(rows, cols);

            try
            {
                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < cols; c++)
                    {
                        result.set(r, c, Galois.exp((byte)r, c));
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            return(result);
        }
Пример #2
0
        /**
         * Multiplies this matrix (the one on the left) by another
         * matrix (the one on the right).
         */
        public Matrix times(Matrix right)
        {
            if (getColumns() != right.getRows())
            {
                throw new Exception(
                          "Columns on left (" + getColumns() + ") " +
                          "is different than rows on right (" + right.getRows() + ")");
            }
            Matrix result = new Matrix(getRows(), right.getColumns());

            for (int r = 0; r < getRows(); r++)
            {
                for (int c = 0; c < right.getColumns(); c++)
                {
                    byte value = 0;
                    for (int i = 0; i < getColumns(); i++)
                    {
                        value ^= Galois.multiply(get(r, i), right.get(i, c));
                    }
                    result.set(r, c, value);
                }
            }
            return(result);
        }
Пример #3
0
        /**
         * Does the work of matrix inversion.
         *
         * Assumes that this is an r by 2r matrix.
         */
        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] == 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.
                if (data[r][r] == 0)
                {
                    throw new Exception("Matrix is singular");
                }
                // Scale to 1.
                if (data[r][r] != 1)
                {
                    byte scale = Galois.divide(1, data[r][r]);
                    for (int c = 0; c < columns; c++)
                    {
                        data[r][c] = Galois.multiply(data[r][c], scale);
                    }
                }
                // Make everything below the 1 be a 0 by subtracting
                // a multiple of it.  (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] ^= Galois.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] != 0)
                    {
                        byte scale = data[rowAbove][d];
                        for (int c = 0; c < columns; c++)
                        {
                            data[rowAbove][c] ^= Galois.multiply(scale, data[d][c]);
                        }
                    }
                }
            }
        }