はじめに
apache commons mathで行列計算をしたかったので覚書
ベクトル編はこちら→ https://qiita.com/AlliumAllium/items/7d0ad9eabaf3c01d6090
行列Aの単項演算
コード
import org.apache.commons.math4.legacy.linear.RealMatrix;
import org.apache.commons.math4.legacy.linear.RealVector;
import org.apache.commons.math4.legacy.linear.EigenDecomposition;
import org.apache.commons.math4.legacy.linear.LUDecomposition;
import org.apache.commons.math4.legacy.linear.MatrixUtils;
import org.apache.commons.math4.legacy.linear.RRQRDecomposition;
public class Test {
public static void main(String[] args) {
RealMatrix matrix = MatrixUtils.createRealMatrix(
new double[][] {
{ 2, 9, 4 },
{ 7, 5, 3 },
{ 6, 1, 8 }
});
System.out.println("matrix:");
System.out.println(matrix);
System.out.println("行数:");
System.out.println(matrix.getRowDimension());
System.out.println("列数:");
System.out.println(matrix.getColumnDimension());
// 転置
RealMatrix transposeMatrix = matrix.transpose();
System.out.println("転置行列:");
System.out.println(transposeMatrix);
// 逆行列
RealMatrix inverseMatrix = MatrixUtils.inverse(matrix);
// RealMatrix inverseMatrix =
// new LUDecomposition(matrix).getSolver().getInverse(); こっちでもいける
System.out.println("逆行列:");
System.out.println(inverseMatrix);
// 行列式
double detrminant = new LUDecomposition(matrix).getDeterminant();
System.out.println("行列式:");
System.out.println(detrminant);
// ランク
int rank = new RRQRDecomposition(matrix).getRank(1e-10);
System.out.println("ランク:");
System.out.println(rank);
// 固有値と固有ベクトル
EigenDecomposition eigenDecomposition = new EigenDecomposition(matrix);
double[] realEigenvalues = eigenDecomposition.getRealEigenvalues();
double[] imagineEigenvalues = eigenDecomposition.getImagEigenvalues();
for (int i = 0; i < realEigenvalues.length; i++) {
RealVector eigenVector = eigenDecomposition.getEigenvector(i); // 複素数の固有値には対応しているが、複素数の固有ベクトルには対応していない点に注意
System.out.println(String.format("固有値%d : %f%+fi", i, realEigenvalues[i], imagineEigenvalues[i]));
System.out.println(String.format("固有ベクトル%d :", i));
System.out.println(eigenVector);
}
}
}
結果
matrix:
Array2DRowRealMatrix{{2.0,9.0,4.0},{7.0,5.0,3.0},{6.0,1.0,8.0}}
行数:
3
列数:
3
転置行列:
Array2DRowRealMatrix{{2.0,7.0,6.0},{9.0,5.0,1.0},{4.0,3.0,8.0}}
逆行列:
BlockRealMatrix{{-0.1027777778,0.1888888889,-0.0194444444},{0.1055555556,0.0222222222,-0.0611111111},{0.0638888889,-0.1444444444,0.1472222222}}
行列式:
-360.0
ランク:
3
固有値0 : -4.898979+0.000000i
固有ベクトル0 :
{-0.8130525296; 0.4714045208; 0.3416480088}
固有値1 : 15.000000+0.000000i
固有ベクトル1 :
{0.5773502692; 0.5773502692; 0.5773502692}
固有値2 : 4.898979+0.000000i
固有ベクトル2 :
{-0.3623724357; -0.5; 0.8623724357}
行列Aとスカラーsの二項演算
コード
import org.apache.commons.math4.legacy.linear.RealMatrix;
import org.apache.commons.math4.legacy.linear.MatrixUtils;
public class Test {
public static void main(String[] args) {
RealMatrix matrixA = MatrixUtils.createRealMatrix(
new double[][] {
{ 2, 9, 4 },
{ 7, 5, 3 },
{ 6, 1, 8 }
});
double s = 3.;
// 全要素にスカラーを足す(和)
System.out.println("和 {a_ij + s}_ij=");
System.out.println(matrixA.scalarAdd(s));
// 積
System.out.println("積 A*s=");
System.out.println(matrixA.scalarMultiply(s));
// 累乗(0以上の整数乗のみ)
System.out.println("累乗 A^s=");
System.out.println(matrixA.power((int) s));
}
}
結果
要素和 {a_ij + s}_ij=
Array2DRowRealMatrix{{5.0,12.0,7.0},{10.0,8.0,6.0},{9.0,4.0,11.0}}
積 A*s=
Array2DRowRealMatrix{{6.0,27.0,12.0},{21.0,15.0,9.0},{18.0,3.0,24.0}}
累乗 A^s=
Array2DRowRealMatrix{{1053.0,1221.0,1101.0},{1173.0,1125.0,1077.0},{1149.0,1029.0,1197.0}}
行列Aとベクトルbの二項演算
コード
import org.apache.commons.math4.legacy.linear.RealMatrix;
import org.apache.commons.math4.legacy.linear.RealVector;
import org.apache.commons.math4.legacy.linear.MatrixUtils;
public class Test {
public static void main(String[] args) {
RealMatrix matrixA = MatrixUtils.createRealMatrix(
new double[][] {
{ 2, 9, 4 },
{ 7, 5, 3 },
{ 6, 1, 8 }
});
RealVector vectorB = MatrixUtils.createRealVector(
new double[] { 1, 0, 2 });
// 積
System.out.println("積 A*b=");
System.out.println(matrixA.operate(vectorB));
}
}
結果
積 A*b=
{10; 13; 22}
行列Aと行列Bの二項演算
コード
import org.apache.commons.math4.legacy.linear.RealMatrix;
import org.apache.commons.math4.legacy.linear.MatrixUtils;
public class Test {
public static void main(String[] args) {
RealMatrix matrixA = MatrixUtils.createRealMatrix(
new double[][] {
{ 2, 9, 4 },
{ 7, 5, 3 },
{ 6, 1, 8 }
});
RealMatrix matrixB = MatrixUtils.createRealMatrix(
new double[][] {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
});
System.out.println("行列A:");
System.out.println(matrixA);
System.out.println("行列B:");
System.out.println(matrixB);
// 和
System.out.println("和 A+B=");
System.out.println(matrixA.add(matrixB));
// 差
System.out.println("差 A-B=");
System.out.println(matrixA.subtract(matrixB));
// 積
System.out.println("積 AB=");
System.out.println(matrixA.multiply(matrixB));
System.out.println("積 BA=");
System.out.println(matrixA.preMultiply(matrixB));
}
}
結果
行列A:
Array2DRowRealMatrix{{2.0,9.0,4.0},{7.0,5.0,3.0},{6.0,1.0,8.0}}
行列B:
Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0},{7.0,8.0,9.0}}
和 A+B=
Array2DRowRealMatrix{{3.0,11.0,7.0},{11.0,10.0,9.0},{13.0,9.0,17.0}}
差 A-B=
Array2DRowRealMatrix{{1.0,7.0,1.0},{3.0,0.0,-3.0},{-1.0,-7.0,-1.0}}
積 AB=
Array2DRowRealMatrix{{66.0,81.0,96.0},{48.0,63.0,78.0},{66.0,81.0,96.0}}
積 BA=
Array2DRowRealMatrix{{34.0,22.0,34.0},{79.0,67.0,79.0},{124.0,112.0,124.0}}