Matrix exponential, power and log use eigenvalues for symmetric matrix.
@@ -604,14 +604,33 @@ public class LinearAlgebra {
return new Array2DRowRealMatrix(matrix).multiply(new Array2DRowRealMatrix(vector)).getColumn(0);
}
+ /**
+ * Matrix power. Tries to calculate a matrix A such that M^{exponent} = A.
+ *
+ * @param matrix The matrix M of which we like to have the power.
+ * @param exponent The exponent.
+ * @return The exponent-th power of M
+ */
public static double[][] matrixPow(double[][] matrix, double exponent) {
return matrixExp(matrixLog(new Array2DRowRealMatrix(matrix)).scalarMultiply(exponent)).getData();
}
+ /**
+ * Matrix exponential. Tries to calculate the matrix A such that exp(M) = A.
+ *
+ * @param matrix The matrix M
+ * @return exp(M)
+ */
public static double[][] matrixExp(double[][] matrix) {
return matrixExp(new Array2DRowRealMatrix(matrix)).getData();
}
+ /**
+ * Matrix logarithm. Tries to calculate the matrix A such that log(M) = A.
+ *
+ * @param matrix The matrix M
+ * @return log(M)
+ */
public static double[][] matrixLog(double[][] matrix) {
return matrixLog(new Array2DRowRealMatrix(matrix)).getData();
}
@@ -621,6 +640,14 @@ public class LinearAlgebra {
*/
private static RealMatrix matrixExp(RealMatrix matrix) {
+ if(MatrixUtils.isSymmetric(matrix, 1E-10)) {
+ // Symmetric matrix: try to use eigenvalue decomposition.
+ EigenDecomposition eigenDecomposition = new EigenDecomposition(matrix);
+ RealMatrix diag = eigenDecomposition.getD();
+ for(int i=0; i<diag.getRowDimension(); i++) diag.setEntry(i, i, Math.exp(diag.getEntry(i, i)));
+ return eigenDecomposition.getV().multiply(eigenDecomposition.getD()).multiply(eigenDecomposition.getVT());
+ }
+ else {
RealMatrix exp = MatrixUtils.createRealIdentityMatrix(matrix.getRowDimension());;
double factor = 1.0;
for(int k=1; k<15; k++) {
@@ -629,8 +656,17 @@ public class LinearAlgebra {
}
return exp;
}
+ }
private static RealMatrix matrixLog(RealMatrix matrix) {
+ if(MatrixUtils.isSymmetric(matrix, 1E-10)) {
+ // Symmetric matrix: try to use eigenvalue decomposition.
+ EigenDecomposition eigenDecomposition = new EigenDecomposition(matrix);
+ RealMatrix diag = eigenDecomposition.getD();
+ for(int i=0; i<diag.getRowDimension(); i++) diag.setEntry(i, i, Math.log(diag.getEntry(i, i)));
+ return eigenDecomposition.getV().multiply(eigenDecomposition.getD()).multiply(eigenDecomposition.getVT());
+ }
+ else {
RealMatrix m = matrix.subtract(MatrixUtils.createRealIdentityMatrix(matrix.getRowDimension()));
RealMatrix log = m.copy();
for(int k=2; k<15; k++) {
@@ -639,3 +675,4 @@ public class LinearAlgebra {
return log;
}
}
+}
