public static void setSubMatrix( RowD1Matrix64F src , RowD1Matrix64F dst , int srcRow , int srcCol , int dstRow , int dstCol , int numSubRows, int numSubCols ) { for( int i = 0; i < numSubRows; i++ ) { for( int j = 0; j < numSubCols; j++ ) { double val = src.get(i+srcRow,j+srcCol); dst.set(i+dstRow,j+dstCol,val); } } } }
/** * Returns the linear index of the maximal element of the abs() * matrix. If there are more than one elements with this value, * the first one is returned. */ public static int absArgmax(RowD1Matrix64F matrix) { int numElements = matrix.getNumElements(); if (numElements == 0) { return -1; } double v = Double.NEGATIVE_INFINITY; int a = -1; for (int i = 0; i < numElements; i++) { double abs = Math.abs(matrix.get(i)); if (!Double.isNaN(abs) && abs > v) { v = abs; a = i; } } return a; } }
private static void preMultAddBlock_vector(double d, D1Matrix64F a, RowD1Matrix64F b, RowD1Matrix64F c, int startRow, int startCol) { for (int row = 0; row < Math.min(a.numRows, b.numRows); row++) { for (int col = 0; col < b.numCols; col++) { c.unsafe_set(startRow + row, startCol + col, c.unsafe_get(startRow + row, startCol + col) + d * a.data[row] * b.unsafe_get(row, col)); } } }
public static void scaleInputDiag(final RowD1Matrix64F matrix, final RowD1Matrix64F diag) { for (int i = 0; i < matrix.numRows; i++) { matrix.unsafe_set(i, i, matrix.unsafe_get(i, i) + 1 / diag.get(i)); } }
/** * @see org.ejml.ops.CommonOps#multAddTransAB(double, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAddTransAB( double alpha , RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numRows != b.numCols ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numCols != c.numRows || b.numRows != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } int cIndex = 0; for( int i = 0; i < a.numCols; i++ ) { int indexB = 0; for( int j = 0; j < b.numRows; j++ ) { int indexA = i; int end = indexB + b.numCols; double total = 0; for( ;indexB<end; ) { total += a.get(indexA) * b.get(indexB++); indexA += a.numCols; } c.plus( cIndex++ , alpha*total ); } } }
/** * @see org.ejml.ops.CommonOps#multAdd( org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAdd_aux( RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numCols != b.numRows ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numRows != c.numRows || b.numCols != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ b.numRows ]; for( int j = 0; j < b.numCols; j++ ) { // create a copy of the column in B to avoid cache issues for( int k = 0; k < b.numRows; k++ ) { aux[k] = b.unsafe_get(k,j); } int indexA = 0; for( int i = 0; i < a.numRows; i++ ) { double total = 0; for( int k = 0; k < b.numRows; ) { total += a.get(indexA++)*aux[k++]; } c.plus( i*c.numCols+j , total ); } } }
/** * @see org.ejml.ops.CommonOps#mult(double, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void mult_aux( double alpha , RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numCols != b.numRows ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numRows != c.numRows || b.numCols != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ b.numRows ]; for( int j = 0; j < b.numCols; j++ ) { // create a copy of the column in B to avoid cache issues for( int k = 0; k < b.numRows; k++ ) { aux[k] = b.unsafe_get(k,j); } int indexA = 0; for( int i = 0; i < a.numRows; i++ ) { double total = 0; for( int k = 0; k < b.numRows; ) { total += a.get(indexA++)*aux[k++]; } c.set( i*c.numCols+j , alpha*total ); } } }
/** * Finds the inverse of a diagonal matrix * @param matrixToInvertAndPack matrix to compute inverse of */ public static void invertDiagonalMatrix(RowD1Matrix64F matrixToInvertAndPack) { if (matrixToInvertAndPack.numRows != matrixToInvertAndPack.numCols) { throw new MatrixDimensionException( "Diagonal matrix to invert is not square. Number of rows in matrix: " + matrixToInvertAndPack.getNumRows() + ", number of" + " cols in matrix: " + matrixToInvertAndPack.getNumCols() + "."); } int size = matrixToInvertAndPack.getNumRows(); for (int index = 0; index < size; index++) matrixToInvertAndPack.unsafe_set(index, index, 1.0 / matrixToInvertAndPack.unsafe_get(index, index)); }
/** * <p> * This computes the trace of the matrix:<br> * <br> * trace = ∑<sub>i=1:n</sub> { a<sub>ii</sub> }<br> * where n = min(numRows,numCols) * </p> * * @param a A square matrix. Not modified. */ public static double trace( RowD1Matrix64F a ) { int N = Math.min(a.numRows, a.numCols); double sum = 0; int index = 0; for( int i = 0; i < N; i++ ) { sum += a.get(index); index += 1 + a.numCols; } return sum; }
/** * @see org.ejml.ops.CommonOps#multAddTransAB( org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAddTransAB_aux( RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numRows != b.numCols ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numCols != c.numRows || b.numRows != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ a.numRows ]; int indexC = 0; for( int i = 0; i < a.numCols; i++ ) { for( int k = 0; k < b.numCols; k++ ) { aux[k] = a.unsafe_get(k,i); } for( int j = 0; j < b.numRows; j++ ) { double total = 0; for( int k = 0; k < b.numCols; k++ ) { total += aux[k] * b.unsafe_get(j,k); } c.plus( indexC++ , total ); } } }
/** * @see org.ejml.ops.CommonOps#multTransAB( org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multTransAB_aux( RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numRows != b.numCols ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numCols != c.numRows || b.numRows != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ a.numRows ]; int indexC = 0; for( int i = 0; i < a.numCols; i++ ) { for( int k = 0; k < b.numCols; k++ ) { aux[k] = a.unsafe_get(k,i); } for( int j = 0; j < b.numRows; j++ ) { double total = 0; for( int k = 0; k < b.numCols; k++ ) { total += aux[k] * b.unsafe_get(j,k); } c.set( indexC++ , total ); } } }
/** * Sets all the diagonal elements equal to one and everything else equal to zero. * If this is a square matrix then it will be an identity matrix. * * @param mat A square matrix. */ public static void setDiagonal( RowD1Matrix64F mat , double diagonalValue) { int width = mat.numRows < mat.numCols ? mat.numRows : mat.numCols; Arrays.fill(mat.data, 0, mat.getNumElements(), 0); int index = 0; for( int i = 0; i < width; i++ , index += mat.numCols + 1) { mat.data[index] = diagonalValue; } }
/** * Computes the product of the diagonal elements. For a diagonal or triangular * matrix this is the determinant. * * @param T A matrix. * @return product of the diagonal elements. */ public static double diagProd( RowD1Matrix64F T ) { double prod = 1.0; int N = Math.min(T.numRows,T.numCols); for( int i = 0; i < N; i++ ) { prod *= T.unsafe_get(i,i); } return prod; }
/** * C=diagxmat(vec,B) C=diag(vec) * B */ public static DenseMatrix64F diagxmat(final RowD1Matrix64F diag, final RowD1Matrix64F B) { //if (!MatrixFeatures.isVector(diag)) //logger.info("diagXMat: sizes A,B: diag is NOT vector."); DenseMatrix64F result = B.copy(); for (int i = 0; i < result.numRows; i++) { for (int j = 0; j < result.numCols; j++) { result.unsafe_set(i, j, result.unsafe_get(i, j) * diag.get(i)); } } return result; } // END diagxmat
/** * @see org.ejml.ops.CommonOps#multAddTransB(double, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAddTransB( double alpha , RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numCols != b.numCols ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numRows != c.numRows || b.numRows != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } int cIndex = 0; int aIndexStart = 0; for( int xA = 0; xA < a.numRows; xA++ ) { int end = aIndexStart + b.numCols; int indexB = 0; for( int xB = 0; xB < b.numRows; xB++ ) { int indexA = aIndexStart; double total = 0; while( indexA<end ) { total += a.get(indexA++) * b.get(indexB++); } c.plus( cIndex++ , alpha*total ); } aIndexStart += a.numCols; } }
/** * @see org.ejml.ops.CommonOps#multAdd( org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAdd_aux( RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numCols != b.numRows ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numRows != c.numRows || b.numCols != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ b.numRows ]; for( int j = 0; j < b.numCols; j++ ) { // create a copy of the column in B to avoid cache issues for( int k = 0; k < b.numRows; k++ ) { aux[k] = b.unsafe_get(k,j); } int indexA = 0; for( int i = 0; i < a.numRows; i++ ) { double total = 0; for( int k = 0; k < b.numRows; ) { total += a.get(indexA++)*aux[k++]; } c.plus( i*c.numCols+j , total ); } } }
/** * @see org.ejml.ops.CommonOps#mult( org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void mult_aux( RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numCols != b.numRows ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numRows != c.numRows || b.numCols != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ b.numRows ]; for( int j = 0; j < b.numCols; j++ ) { // create a copy of the column in B to avoid cache issues for( int k = 0; k < b.numRows; k++ ) { aux[k] = b.unsafe_get(k,j); } int indexA = 0; for( int i = 0; i < a.numRows; i++ ) { double total = 0; for( int k = 0; k < b.numRows; ) { total += a.get(indexA++)*aux[k++]; } c.set( i*c.numCols+j , total ); } } }
/** * Finds the inverse of a diagonal matrix * @param matrixToInvert matrix to compute inverse of * @param invertedMatrixToPack matrix to store inverse */ public static void invertDiagonalMatrix(RowD1Matrix64F matrixToInvert, RowD1Matrix64F invertedMatrixToPack) { if (matrixToInvert.numRows != matrixToInvert.numCols) { throw new MatrixDimensionException( "Diagonal matrix to invert is not square. Number of rows in matrix: " + matrixToInvert.getNumRows() + ", number of" + " cols in matrix: " + matrixToInvert.getNumCols() + "."); } if (invertedMatrixToPack.numRows != matrixToInvert.numRows && invertedMatrixToPack.numCols != matrixToInvert.numCols) { throw new MatrixDimensionException( "Matrix destination is the wrong size. Number of rows in matrix: " + matrixToInvert.getNumRows() + ", number of" + " cols in matrix: " + matrixToInvert.getNumCols() + "."); } if (matrixToInvert == invertedMatrixToPack) { throw new IllegalArgumentException("Matrices should not be the same. Use {@link DiagonalMatrixTools.invertDiagonalMatrix(RowD1Matrix64F)} instead."); } int size = matrixToInvert.getNumRows(); Arrays.fill(invertedMatrixToPack.data, 0, invertedMatrixToPack.getNumElements(), 0.0); for (int index = 0; index < size; index++) invertedMatrixToPack.unsafe_set(index, index, 1.0 / matrixToInvert.unsafe_get(index, index)); }
/** * <p> * This computes the trace of the matrix:<br> * <br> * trace = ∑<sub>i=1:n</sub> { a<sub>ii</sub> }<br> * where n = min(numRows,numCols) * </p> * * @param a A square matrix. Not modified. */ public static double trace( RowD1Matrix64F a ) { int N = Math.min(a.numRows,a.numCols); double sum = 0; int index = 0; for( int i = 0; i < N; i++ ) { sum += a.get(index); index += 1 + a.numCols; } return sum; }
/** * @see org.ejml.ops.CommonOps#multAddTransAB(double, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F, org.ejml.data.RowD1Matrix64F) */ public static void multAddTransAB_aux( double alpha , RowD1Matrix64F a , RowD1Matrix64F b , RowD1Matrix64F c , double []aux ) { if( a == c || b == c ) throw new IllegalArgumentException("Neither 'a' or 'b' can be the same matrix as 'c'"); else if( a.numRows != b.numCols ) { throw new MatrixDimensionException("The 'a' and 'b' matrices do not have compatible dimensions"); } else if( a.numCols != c.numRows || b.numRows != c.numCols ) { throw new MatrixDimensionException("The results matrix does not have the desired dimensions"); } if( aux == null ) aux = new double[ a.numRows ]; int indexC = 0; for( int i = 0; i < a.numCols; i++ ) { for( int k = 0; k < b.numCols; k++ ) { aux[k] = a.unsafe_get(k,i); } for( int j = 0; j < b.numRows; j++ ) { double total = 0; for( int k = 0; k < b.numCols; k++ ) { total += aux[k] * b.unsafe_get(j,k); } c.plus( indexC++ , alpha*total ); } } }