/// <summary> /// Check if a matrix is subtraction compatible with the instance. /// </summary> /// <param name="m">Matrix to check.</param> /// <exception cref="MatrixDimensionMismatchExceptio">n if the matrix is not /// subtraction-compatible with instance.</exception> protected void checkSubtractionCompatible(FieldMatrix <T> m) { if ((getRowDimension() != m.getRowDimension()) || (getColumnDimension() != m.getColumnDimension())) { throw new MatrixDimensionMismatchException(m.getRowDimension(), m.getColumnDimension(), getRowDimension(), getColumnDimension()); } }
/// <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)); } }
/// <summary> /// Calculates the LU-decomposition of the given matrix. /// </summary> /// <param name="matrix">The matrix to decompose.</param> /// <exception cref="NonSquareMatrixException"> if matrix is not square</exception> public FieldLUDecomposition(FieldMatrix <T> matrix) { if (!matrix.isSquare()) { throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); } int m = matrix.getColumnDimension(); field = matrix.getField(); lu = matrix.getData(); pivot = new int[m]; cachedL = null; cachedU = null; cachedP = null; // Initialize permutation array and parity for (int row = 0; row < m; row++) { pivot[row] = row; } even = true; singular = false; // Loop over columns for (int col = 0; col < m; col++) { T sum = field.getZero(); // upper for (int row = 0; row < col; row++) { T[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < row; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; } // lower int nonZero = col; // permutation row for (int row = col; row < m; row++) { T[] luRow = lu[row]; sum = luRow[col]; for (int i = 0; i < col; i++) { sum = sum.subtract(luRow[i].multiply(lu[i][col])); } luRow[col] = sum; if (lu[nonZero][col].Equals(field.getZero())) { // try to select a better permutation choice ++nonZero; } } // Singularity check if (nonZero >= m) { singular = true; return; } // Pivot if necessary if (nonZero != col) { T tmp = field.getZero(); for (int i = 0; i < m; i++) { tmp = lu[nonZero][i]; lu[nonZero][i] = lu[col][i]; lu[col][i] = tmp; } int temp = pivot[nonZero]; pivot[nonZero] = pivot[col]; pivot[col] = temp; even = !even; } // Divide the lower elements by the "winning" diagonal elt. T luDiag = lu[col][col]; for (int row = col + 1; row < m; row++) { T[] luRow = lu[row]; luRow[col] = luRow[col].divide(luDiag); } } }
/// <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)); }