apache commons mathで行列演算(行列編)

# はじめに
apache commons mathで行列計算をしたかったので覚書
ベクトル編はこちら→　https://qiita.com/AlliumAllium/items/7d0ad9eabaf3c01d6090

# 行列Aの単項演算
## コード
```Java
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);
        }
    }
}
```

## 結果

``` java
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の二項演算
## コード
```Java
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));

    }
}
```

## 結果

``` java
要素和 {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の二項演算
## コード
```Java
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));

    }
}


```

## 結果

``` java
積 A*b=
{10; 13; 22}
```
# 行列Aと行列Bの二項演算
## コード
```Java
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));
    }
}

```

## 結果

``` java
行列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}}
```