/// <inheritdoc/>
        public FieldMatrix <T> multiply(FieldMatrix <T> m)
        {
            // safety check
            checkMultiplicationCompatible(m);

            int             nRows = getRowDimension();
            int             nCols = m.getColumnDimension();
            int             nSum  = getColumnDimension();
            FieldMatrix <T> outp  = createMatrix(nRows, nCols);

            for (int row = 0; row < nRows; ++row)
            {
                for (int col = 0; col < nCols; ++col)
                {
                    T sum = field.getZero();
                    for (int i = 0; i < nSum; ++i)
                    {
                        sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col)));
                    }
                    outp.setEntry(row, col, sum);
                }
            }

            return(outp);
        }
        /// <summary>
        /// Returns true iff <c>object</c> is a
        /// <c>FieldMatrix</c> instance with the same dimensions as this
        /// and all corresponding matrix entries are equal.
        /// </summary>
        /// <param name="obj">the object to test equality against.</param>
        /// <returns>true if object equals this</returns>
        public override Boolean Equals(Object obj)
        {
            if (obj == this)
            {
                return(true);
            }
            if (obj is FieldMatrix <T> )
            {
                return(false);
            }
            FieldMatrix <T> m     = (FieldMatrix <T>)obj;
            int             nRows = getRowDimension();
            int             nCols = getColumnDimension();

            if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows)
            {
                return(false);
            }
            for (int row = 0; row < nRows; ++row)
            {
                for (int col = 0; col < nCols; ++col)
                {
                    if (!getEntry(row, col).Equals(m.getEntry(row, col)))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        /// <inheritdoc/>
        public void setColumnMatrix(int column, FieldMatrix <T> matrix)
        {
            checkColumnIndex(column);
            int nRows = getRowDimension();

            if ((matrix.getRowDimension() != nRows) ||
                (matrix.getColumnDimension() != 1))
            {
                throw new MatrixDimensionMismatchException(matrix.getRowDimension(),
                                                           matrix.getColumnDimension(),
                                                           nRows, 1);
            }
            for (int i = 0; i < nRows; ++i)
            {
                setEntry(i, column, matrix.getEntry(i, 0));
            }
        }
        /// <inheritdoc/>
        public void setRowMatrix(int row, FieldMatrix <T> matrix)
        {
            checkRowIndex(row);
            int nCols = getColumnDimension();

            if ((matrix.getRowDimension() != 1) ||
                (matrix.getColumnDimension() != nCols))
            {
                throw new MatrixDimensionMismatchException(matrix.getRowDimension(),
                                                           matrix.getColumnDimension(),
                                                           1, nCols);
            }
            for (int i = 0; i < nCols; ++i)
            {
                setEntry(row, i, matrix.getEntry(0, i));
            }
        }
        /// <inheritdoc/>
        public FieldMatrix <T> subtract(FieldMatrix <T> m)
        {
            // safety check
            checkSubtractionCompatible(m);

            int             rowCount    = getRowDimension();
            int             columnCount = getColumnDimension();
            FieldMatrix <T> outp        = createMatrix(rowCount, columnCount);

            for (int row = 0; row < rowCount; ++row)
            {
                for (int col = 0; col < columnCount; ++col)
                {
                    outp.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col)));
                }
            }

            return(outp);
        }
            /// <inheritdoc/>
            public FieldMatrix <U> solve(FieldMatrix <U> b)
            {
                int m = pivot.Length;

                if (b.getRowDimension() != m)
                {
                    throw new DimensionMismatchException(b.getRowDimension(), m);
                }
                if (singular)
                {
                    throw new SingularMatrixException();
                }

                int nColB = b.getColumnDimension();

                // Apply permutations to b
                U[][] bp = MathArrays.buildArray(field, m, nColB);
                for (int row = 0; row < m; row++)
                {
                    U[] bpRow = bp[row];
                    int pRow  = pivot[row];
                    for (int col = 0; col < nColB; col++)
                    {
                        bpRow[col] = b.getEntry(pRow, col);
                    }
                }

                // Solve LY = b
                for (int col = 0; col < m; col++)
                {
                    U[] bpCol = bp[col];
                    for (int i = col + 1; i < m; i++)
                    {
                        U[] bpI    = bp[i];
                        U   luICol = lu[i][col];
                        for (int j = 0; j < nColB; j++)
                        {
                            bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
                        }
                    }
                }

                // Solve UX = Y
                for (int col = m - 1; col >= 0; col--)
                {
                    U[] bpCol  = bp[col];
                    U   luDiag = lu[col][col];
                    for (int j = 0; j < nColB; j++)
                    {
                        bpCol[j] = bpCol[j].divide(luDiag);
                    }
                    for (int i = 0; i < col; i++)
                    {
                        U[] bpI    = bp[i];
                        U   luICol = lu[i][col];
                        for (int j = 0; j < nColB; j++)
                        {
                            bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
                        }
                    }
                }

                return(new Array2DRowFieldMatrix <U>(field, bp, false));
            }