/// <inheritdoc/> public new RealMatrix outerProduct(RealVector v) { if (v is ArrayRealVector) { double[] vData = ((ArrayRealVector)v).data; int m = data.Length; int n = vData.Length; RealMatrix outp = MatrixUtils.createRealMatrix(m, n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { outp.setEntry(i, j, data[i] * vData[j]); } } return(outp); } else { int m = data.Length; int n = v.getDimension(); RealMatrix outp = MatrixUtils.createRealMatrix(m, n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { outp.setEntry(i, j, data[i] * v.getEntry(j)); } } return(outp); } }
/// <summary> /// Returns the bi-diagonal matrix B of the transform. /// </summary> /// <returns>the B matrix</returns> public RealMatrix getB() { if (cachedB == null) { int m = householderVectors.Length; int n = householderVectors[0].Length; double[][] ba = new double[m][]; for (int i = 0; i < main.Length; ++i) { ba[i][i] = main[i]; if (m < n) { if (i > 0) { ba[i][i - 1] = secondary[i - 1]; } } else { if (i < main.Length - 1) { ba[i][i + 1] = secondary[i]; } } } cachedB = MatrixUtils.createRealMatrix(ba); } // return the cached matrix return(cachedB); }
/// <inheritdoc/> /// <exception cref="NumberIsTooLargeException"> if <c>m</c> is an /// <c>OpenMapRealMatrix</c>, and the total number of entries of the product /// is larger than <c>Int32.MaxValue</c>.</exception> public new RealMatrix multiply(RealMatrix m) { try { return(multiply((OpenMapRealMatrix)m)); } catch (InvalidCastException) { MatrixUtils.checkMultiplicationCompatible(this, m); int outCols = m.getColumnDimension(); BlockRealMatrix outp = new BlockRealMatrix(rows, outCols); for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.MoveNext();) { double value = iterator.Current.Value; int key = iterator.Current.Key; int i = key / columns; int k = key % columns; for (int j = 0; j < outCols; ++j) { outp.addToEntry(i, j, value * m.getEntry(k, j)); } } return(outp); } }
/// <inheritdoc/> public void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination) { MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); int nCols = selectedColumns.Length; if ((destination.Length < selectedRows.Length) || (destination[0].Length < nCols)) { throw new MatrixDimensionMismatchException(destination.Length, destination[0].Length, selectedRows.Length, selectedColumns.Length); } for (int i = 0; i < selectedRows.Length; i++) { double[] destinationI = destination[i]; if (destinationI.Length < nCols) { throw new MatrixDimensionMismatchException(destination.Length, destinationI.Length, selectedRows.Length, selectedColumns.Length); } for (int j = 0; j < selectedColumns.Length; j++) { destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); } } }
/// <summary> /// Get the inverse of the decomposed matrix. /// </summary> /// <returns>the inverse matrix.</returns> /// <exception cref="SingularMatrixException"> if the decomposed matrix is singular. /// </exception> public RealMatrix getInverse() { if (!isNonSingular()) { throw new SingularMatrixException(); } int m = realEigenvalues.Length; double[][] invData = new double[m][]; for (int i = 0; i < m; ++i) { double[] invI = invData[i]; for (int j = 0; j < m; ++j) { double invIJ = 0; for (int k = 0; k < m; ++k) { double[] vK = eigenvectors[k].getDataRef(); invIJ += vK[i] * vK[j] / realEigenvalues[k]; } invI[j] = invIJ; } } return(MatrixUtils.createRealMatrix(invData)); }
/// <summary> /// Returns the Hessenberg matrix H of the transform. /// </summary> /// <returns>the H matrix</returns> public RealMatrix getH() { if (cachedH == null) { int m = householderVectors.Length; double[][] h = new double[m][]; for (int i = 0; i < m; ++i) { if (i > 0) { // copy the entry of the lower sub-diagonal h[i][i - 1] = householderVectors[i][i - 1]; } // copy upper triangular part of the matrix for (int j = i; j < m; ++j) { h[i][j] = householderVectors[i][j]; } } cachedH = MatrixUtils.createRealMatrix(h); } // return the cached matrix return(cachedH); }
/// <summary> /// Returns the matrix P of the transform. /// <para>P is an orthogonal matrix, i.e. its inverse is also its transpose.</para> /// </summary> /// <returns>the P matrix</returns> public RealMatrix getP() { if (cachedP == null) { cachedP = MatrixUtils.createRealMatrix(matrixP); } return(cachedP); }
/// <summary> /// Returns the diagonal matrix Σ of the decomposition. /// <para>Σ is a diagonal matrix. The singular values are provided in /// non-increasing order, for compatibility with Jama.</para> /// </summary> /// <returns>the Σ matrix</returns> public RealMatrix getS() { if (cachedS == null) { // cache the matrix for subsequent calls cachedS = MatrixUtils.createRealDiagonalMatrix(singularValues); } return(cachedS); }
/// <inheritdoc/> public new void multiplyEntry(int row, int column, double factor) { // we don't care about non-diagonal elements for multiplication if (row == column) { MatrixUtils.checkRowIndex(this, row); data[row] *= factor; } }
/// <summary> /// Returns the quasi-triangular Schur matrix T of the transform. /// </summary> /// <returns>the T matrix</returns> public RealMatrix getT() { if (cachedT == null) { cachedT = MatrixUtils.createRealMatrix(matrixT); } // return the cached matrix return(cachedT); }
/// <inheritdoc/> public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) { MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); RealMatrix subMatrix = createMatrix(selectedRows.Length, selectedColumns.Length); subMatrix.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitorAnonymous1(ref selectedRows, ref selectedColumns, this)); return(subMatrix); }
/// <summary> /// Returns the transpose of the matrix L of the decomposition. /// <para>L^T is an upper-triangular matrix</para> /// </summary> /// <returns>the transpose of the matrix L of the decomposition</returns> public RealMatrix getLT() { if (cachedLT == null) { cachedLT = MatrixUtils.createRealMatrix(lTData); } // return the cached matrix return(cachedLT); }
/// <inheritdoc/> /// <exception cref="NumberIsTooLargeException"> if <c>row != column</c> and increment is /// non-zero.</exception> public new void addToEntry(int row, int column, double increment) { if (row == column) { MatrixUtils.checkRowIndex(this, row); data[row] += increment; } else { ensureZero(increment); } }
/// <inheritdoc/> /// <exception cref="NumberIsTooLargeException"> if <c>row != column</c> and value is /// non-zero.</exception> public override void setEntry(int row, int column, double value) { if (row == column) { MatrixUtils.checkRowIndex(this, row); data[row] = value; } else { ensureZero(value); } }
/// <inheritdoc/> public double[] getColumn(int column) { MatrixUtils.checkColumnIndex(this, column); int nRows = getRowDimension(); double[] outp = new double[nRows]; for (int i = 0; i < nRows; ++i) { outp[i] = getEntry(i, column); } return(outp); }
/// <inheritdoc/> public RealMatrix getRowMatrix(int row) { MatrixUtils.checkRowIndex(this, row); int nCols = getColumnDimension(); RealMatrix outp = createMatrix(1, nCols); for (int i = 0; i < nCols; ++i) { outp.setEntry(0, i, getEntry(row, i)); } return(outp); }
/// <inheritdoc/> public RealMatrix getColumnMatrix(int column) { MatrixUtils.checkColumnIndex(this, column); int nRows = getRowDimension(); RealMatrix outp = createMatrix(nRows, 1); for (int i = 0; i < nRows; ++i) { outp.setEntry(i, 0, getEntry(i, column)); } return(outp); }
/// <inheritdoc/> public override void setEntry(int row, int column, double value) { MatrixUtils.checkRowIndex(this, row); MatrixUtils.checkColumnIndex(this, column); if (value == 0.0) { entries.remove(computeKey(row, column)); } else { entries.put(computeKey(row, column), value); } }
/// <inheritdoc/> public double[] getRow(int row) { MatrixUtils.checkRowIndex(this, row); int nCols = getColumnDimension(); double[] outp = new double[nCols]; for (int i = 0; i < nCols; ++i) { outp[i] = getEntry(row, i); } return(outp); }
/// <inheritdoc/> public new RealVector preMultiply(RealVector v) { double[] vectorData; if (v is ArrayRealVector) { vectorData = ((ArrayRealVector)v).getDataRef(); } else { vectorData = v.toArray(); } return(MatrixUtils.createRealVector(preMultiply(vectorData))); }
/// <summary> /// Returns the result of postmultiplying <c>this</c> by <c>m</c>. /// </summary> /// <param name="m">matrix to postmultiply by</param> /// <returns><c>this * m</c></returns> /// <exception cref="DimensionMismatchException"> if /// <c>columnDimension(this) != rowDimension(m)</c></exception> public DiagonalMatrix multiply(DiagonalMatrix m) { MatrixUtils.checkMultiplicationCompatible(this, m); int dim = getRowDimension(); double[] outData = new double[dim]; for (int i = 0; i < dim; i++) { outData[i] = data[i] * m.data[i]; } return(new DiagonalMatrix(outData, false)); }
/// <summary> /// Returns the matrix V of the transform. /// <para>V is an orthogonal matrix, i.e. its transpose is also its inverse.</para> /// </summary> /// <returns>the V matrix</returns> public RealMatrix getV() { if (cachedV == null) { int m = householderVectors.Length; int n = householderVectors[0].Length; int p = main.Length; int diagOffset = (m >= n) ? 1 : 0; double[] diagonal = (m >= n) ? secondary : main; double[][] va = new double[n][]; // fill up the part of the matrix not affected by Householder transforms for (int k = n - 1; k >= p; --k) { va[k][k] = 1; } // build up first part of the matrix by applying Householder transforms for (int k = p - 1; k >= diagOffset; --k) { double[] hK = householderVectors[k - diagOffset]; va[k][k] = 1; if (hK[k] != 0.0) { for (int j = k; j < n; ++j) { double beta = 0; for (int i = k; i < n; ++i) { beta -= va[i][j] * hK[i]; } beta /= diagonal[k - diagOffset] * hK[k]; for (int i = k; i < n; ++i) { va[i][j] += -beta * hK[i]; } } } } if (diagOffset > 0) { va[0][0] = 1; } cachedV = MatrixUtils.createRealMatrix(va); } // return the cached matrix return(cachedV); }
/// <summary> /// Returns the matrix U of the transform. /// <para>U is an orthogonal matrix, i.e. its transpose is also its inverse.</para> /// </summary> /// <returns>the U matrix</returns> public RealMatrix getU() { if (cachedU == null) { int m = householderVectors.Length; int n = householderVectors[0].Length; int p = main.Length; int diagOffset = (m >= n) ? 0 : 1; double[] diagonal = (m >= n) ? main : secondary; double[][] ua = new double[m][]; // fill up the part of the matrix not affected by Householder transforms for (int k = m - 1; k >= p; --k) { ua[k][k] = 1; } // build up first part of the matrix by applying Householder transforms for (int k = p - 1; k >= diagOffset; --k) { double[] hK = householderVectors[k]; ua[k][k] = 1; if (hK[k - diagOffset] != 0.0) { for (int j = k; j < m; ++j) { double alpha = 0; for (int i = k; i < m; ++i) { alpha -= ua[i][j] * householderVectors[i][k - diagOffset]; } alpha /= diagonal[k - diagOffset] * hK[k - diagOffset]; for (int i = k; i < m; ++i) { ua[i][j] += -alpha * householderVectors[i][k - diagOffset]; } } } } if (diagOffset > 0) { ua[0][0] = 1; } cachedU = MatrixUtils.createRealMatrix(ua); } // return the cached matrix return(cachedU); }
/// <summary> /// Gets the matrix V of the decomposition. /// V is an orthogonal matrix, i.e. its transpose is also its inverse. /// The columns of V are the eigenvectors of the original matrix. /// No assumption is made about the orientation of the system axes formed /// by the columns of V (e.g. in a 3-dimension space, V can form a left- /// or right-handed system). /// </summary> /// <returns>the V matrix.</returns> public RealMatrix getV() { if (cachedV == null) { int m = eigenvectors.Length; cachedV = MatrixUtils.createRealMatrix(m, m); for (int k = 0; k < m; ++k) { cachedV.setColumnVector(k, eigenvectors[k]); } } // return the cached matrix return(cachedV); }
/// <inheritdoc/> public new double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int j = startColumn; j <= endColumn; ++j) { for (int i = startRow; i <= endRow; ++i) { visitor.visit(i, j, data[i][j]); } } return(visitor.end()); }
/// <inheritdoc/> public void setColumn(int column, double[] array) { MatrixUtils.checkColumnIndex(this, column); int nRows = getRowDimension(); if (array.Length != nRows) { throw new MatrixDimensionMismatchException(array.Length, 1, nRows, 1); } for (int i = 0; i < nRows; ++i) { setEntry(i, column, array[i]); } }
/// <inheritdoc/> public void setRow(int row, double[] array) { MatrixUtils.checkRowIndex(this, row); int nCols = getColumnDimension(); if (array.Length != nCols) { throw new MatrixDimensionMismatchException(1, array.Length, 1, nCols); } for (int i = 0; i < nCols; ++i) { setEntry(row, i, array[i]); } }
/// <inheritdoc/> public double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow, int endRow, int startColumn, int endColumn) { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); visitor.start(getRowDimension(), getColumnDimension(), startRow, endRow, startColumn, endColumn); for (int column = startColumn; column <= endColumn; ++column) { for (int row = startRow; row <= endRow; ++row) { visitor.visit(row, column, getEntry(row, column)); } } return(visitor.end()); }
/// <summary> /// Returns the matrix P of the transform. /// <para>P is an orthogonal matrix, i.e. its inverse is also its transpose.</para> /// </summary> /// <returns>the P matrix</returns> public RealMatrix getP() { if (cachedP == null) { int n = householderVectors.Length; int high = n - 1; double[][] pa = new double[n][]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { pa[i][j] = (i == j) ? 1 : 0; } } for (int m = high - 1; m >= 1; m--) { if (householderVectors[m][m - 1] != 0.0) { for (int i = m + 1; i <= high; i++) { ort[i] = householderVectors[i][m - 1]; } for (int j = m; j <= high; j++) { double g = 0.0; for (int i = m; i <= high; i++) { g += ort[i] * pa[i][j]; } // Double division avoids possible underflow g = (g / ort[m]) / householderVectors[m][m - 1]; for (int i = m; i <= high; i++) { pa[i][j] += g * ort[i]; } } } } cachedP = MatrixUtils.createRealMatrix(pa); } return(cachedP); }
/// <summary> /// Compute the sum of <c>this</c> and <c>m</c>. /// </summary> /// <param name="m">Matrix to be added.</param> /// <returns><c>this + m</c>.</returns> /// <exception cref="MatrixDimensionMismatchException"> if <c>m</c> is not the same /// size as <c>this</c>.</exception> public DiagonalMatrix add(DiagonalMatrix m) { // Safety check. MatrixUtils.checkAdditionCompatible(this, m); int dim = getRowDimension(); double[] outData = new double[dim]; for (int i = 0; i < dim; i++) { outData[i] = data[i] + m.data[i]; } return(new DiagonalMatrix(outData, false)); }