在做实验、编写算法时我们经常需要涉及到矩阵的相关计算,包括加、减、乘、除、转置、求逆等等等等。在查阅相关资料后,我了解到一个名为 Efficient Java Matrix Library(EJML,高效矩阵运算包)的第三方库,并将其运用到了我的一个机器学习实验代码中(为什么不用python,我也不知道)。现在对我所用到的类和方法来做一个简单的总结。
二、Efficient Java Matrix Library(EJML)Efficient Java Matrix Library(EJML)称为高效矩阵运算包,你可以在下面这个链接中获取到它的介绍,源代码,API文档、使用方法等等。
EJML直通车:Efficient Java Matrix Library (ejml.org)http://ejml.org/wiki/index.php?title=Main_Page
以下是相关介绍,感兴趣的同学可以自己看看:
关于如何下载和配置第三库,可以看如下博客:
IDEA中利用maven自动下载第三方Jar包_m0_45965703的博客-CSDN博客https://blog.csdn.net/m0_45965703/article/details/120754072?spm=1001.2014.3001.5501
三、SimpleMatrix类的使用SimpleMatrix类(大概就称之为简单矩阵吧)包含了基本上所有的基础矩阵运算(加、减、乘、除、转置、求逆等),以下是对其中部分构造方法与成员方法的介绍:
1、创建矩阵
1.1 创建一个空行矩阵
//创建一个2x4的空矩阵matrix(全部为0)
// SimpleMatrix(int numRows, int numCols)
// 行数 列数
SimpleMatrix matrix0 = new SimpleMatrix(2,4);
1.2 通过数组创建矩阵2、矩阵的常用运算//通过二维数组创建矩阵 //可以理解成将数组变成相同结构的矩阵 //1、以double型的二维数组构造相同结构的矩阵 // SimpleMatrix(double[][] data) double[][] arrayDouble2 = new double[2][4]; SimpleMatrix matrixDouble2 = new SimpleMatrix(arrayDouble2); System.out.println("matrixDouble2:n"+matrixDouble2); //2、以float型的二维数组构造相同结构的矩阵 // SimpleMatrix(float[][] data) double[][] arrayFloat2 = new double[2][4]; SimpleMatrix matrixFloat2 = new SimpleMatrix(arrayFloat2); System.out.println("matrixFloat2:n"+matrixFloat2);//通过一维数组创建矩阵 //可以理解成将一维数组的数据按照每一行(每一列)的顺序填入给定大小的矩阵 double[] arrayDouble1 = {1,2,3,4,5,7,8,9};//double也行 //1.按照每一行填入数据 SimpleMatrix matrixDoubleRow = new SimpleMatrix(4,2,true,arrayDouble1); System.out.println("matrixDoubleRow:n"+matrixDoubleRow); //2.按照每一列填入数据 SimpleMatrix matrixDoubleCol = new SimpleMatrix(4,2,false,arrayDouble1); System.out.println("matrixDoubleCol:n"+matrixDoubleCol);注意:通过一维数组创建矩阵时,一维数组的数据个数必须大于等于行列数需要数据个数。
先创建4x4的矩阵A和4x4的矩阵B,将矩阵A的所有元素都设置为1,将B的所有元素设置为2。
// void fill(double val) 将矩阵的所有元素都用val填充
// 如 matrix.fill(0.1) 表示将matrix的所有元素都设为0.1
SimpleMatrix matrixA = new SimpleMatrix(4,4); //创建4x4的矩阵A
SimpleMatrix matrixB = new SimpleMatrix(4,4); //创建4x4的矩阵B
matrixA.fill(1); //将A的所有元素设为1
matrixB.fill(2); //将B的所有元素设为2
System.out.println(matrixA);
System.out.println(matrixB);
2.1 矩阵加(减)法
matrixC.fill(1);
matrixC = matrixA.plus(0.6); //A的所有元素乘以0.6
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.plus(0.2,matrixB); // A + 0.2*B
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.plus(matrixB); // A + B
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.minus(6); // A的所有元素减6
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.minus(matrixB); // A - B
System.out.println(matrixC);
2.2 矩阵乘法
matrixC = matrixA.mult(matrixB); // C = A * B
System.out.println(matrixC);
matrixC = matrixA.negative(); // C = -A
System.out.println(matrixC);
matrixC = matrixA.scale(9.99); // C = A*9.99
System.out.println(matrixC);
2.3 矩阵的除法
// 除法
// T divide(double val) C = A/val 将矩阵A的所有元素都除以val
matrixC = matrixA.divide(50); //C = A的所有元素都除以50所得的矩阵
System.out.println(matrixC);
2.3 矩阵的转置
int val = 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrixC.set(i, j, val);
val++;
}
} //设置矩阵的值
System.out.println(matrixC);
SimpleMatrix matrixC_transpose = matrixC.transpose(); //矩阵的转置
System.out.println(matrixC_transpose);
输出结果如图:
2.4 矩阵的逆阵
SimpleMatrix matrixD = new SimpleMatrix(4, 4);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j) {
matrixD.set(i, j, i + 1);
} else {
matrixD.set(i, j, 0);
}
}
}
System.out.println("矩阵D:n"+matrixD);
SimpleMatrix D_invert = matrixD.invert();
System.out.println("矩阵D的逆阵:n"+D_invert);
SimpleMatrix D_pseudoInverse = matrixD.pseudoInverse();
System.out.println("矩阵D的广义逆阵:n"+D_pseudoInverse);
输出结果如图:
3、 其他3.1 创建N阶单位矩阵
//创建n阶单位矩阵 identity matrix
int n =7;
SimpleMatrix tempMatrix = new SimpleMatrix(n,1); //创建nx1的列向量
tempMatrix.fill(1); //所有元素置为1
SimpleMatrix I = tempMatrix.diag();
//A.diag()方法,如果A是矩阵,则返回一个由该矩阵的对角线上的值组成的列向量
// 如果A是列向量,则将其扩展为一个矩阵,矩阵的对角线的值就是该列向量
System.out.println(I);
3.2 其他操作(一)
SimpleMatrix matrix = new SimpleMatrix(8,8);
matrix.fill(4); //将矩阵元素都设置为4
matrix.zero(); //将矩阵元素都设置为0
matrix.set(1,4,3); //将第一行第四列元素设置为3
matrix.set(0,8); //将第零个元素设置为8
matrix.rows(1,2); //获取矩阵的部分行,第一个数表示开始的那一行,第二个数表示结束那一行加一(这里表示获取第一行)
matrix.cols(2,8); //获取矩阵的部分列,第一个数表示开始的那一列,第二个数表示结束那一列加一(这里表示获取第2,3,4,5,6,7行)
matrix.get(2,3); //获取第二行第三个数
matrix.get(2); //获取第二个元素
matrix.copy(); //复制一个矩阵
matrix.createLike(); //创建一个与matrix相同行列数且元素相同的矩阵
matrix.numRows(); //获取矩阵的行数
matrix.numCols(); //获取矩阵的列数
matrix.getNumElements(); //获取矩阵的元素个数(行数乘以列数)
matrix.elementMaxAbs(); //获取矩阵中所有元素绝对值的最大值
matrix.elementMinAbs(); //获取矩阵中所有元素绝对值的最小值
matrix.elementSum(); //计算矩阵中所有元素的和
matrix.normF(); //计算矩阵的二范数(所有元素平方和开根号,可以理解成向量的模)
matrix.determinant(); //计算矩阵行列数值
3.3 其他操作(二)(“乘”、“除”、“乘方”等等)
matrixC = matrixA.elementDiv(matrixB); // 对应相除 C(i,j) = A(i,j) / B(i,j)
matrixC = matrixA.elementMult(matrixB); // 对应相乘 C(i,j) = A(i,j) * B(i,j)
matrixC = matrixA.elementExp(); // C(i,j) = e 的 A(i,j)次方
matrixC = matrixA.elementLog(); // C(i,j) = ln(C(i,j))
matrixC = matrixA.elementPower(2); // C(i,j) = A(i,j)^2 (对应元素的n次方)
matrixC = matrixA.elementPower(matrixB); // C(i,j) = A(i,j)^(B(i,j)) (对应元素的对应次方)
4、 API
以下是EJML提供的API文档,链接如下:
Simplebase (ejml.org)http://ejml.org/javadoc/org/ejml/simple/Simplebase.htmlSimpleMatrix (ejml.org)http://ejml.org/javadoc/org/ejml/simple/SimpleMatrix.html(SimpleMatrix继承了Simplebase,所以很多方法声明在Simplebase中)
5、测试代码感谢阅读!!!
import org.ejml.simple.SimpleMatrix;
public class test {
public static void main(String[] args) {
//-------------------------------------------------------------------
//创建一个2x4的矩阵matrix(全部为0)
// SimpleMatrix(int numRows, int numCols)
// 行数 列数
SimpleMatrix matrix0 = new SimpleMatrix(2, 4);
//-------------------------------------------------------------------
//通过二维数组创建矩阵
//可以理解成将数组变成相同结构的矩阵
//1、以double型的二维数组构造相同结构的矩阵
// SimpleMatrix(double[][] data)
double[][] arrayDouble2 = new double[2][4];
SimpleMatrix matrixDouble2 = new SimpleMatrix(arrayDouble2);
System.out.println("matrixDouble2:n" + matrixDouble2);
//2、以float型的二维数组构造相同结构的矩阵
// SimpleMatrix(float[][] data)
double[][] arrayFloat2 = new double[2][4];
SimpleMatrix matrixFloat2 = new SimpleMatrix(arrayFloat2);
System.out.println("matrixFloat2:n" + matrixFloat2);
//---------------------------------------------------------------------
//通过一维数组创建行列数
//可以理解成将一维数组的数据按照每一行(每一列)的顺序填入给定大小的矩阵
double[] arrayDouble1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};//double也行
//1.按照每一行填入数据
SimpleMatrix matrixDoubleRow = new SimpleMatrix(4, 2, true, arrayDouble1);
System.out.println("matrixDoubleRow:n" + matrixDoubleRow);
//2.按照每一列填入数据
SimpleMatrix matrixDoubleCol = new SimpleMatrix(4, 2, false, arrayDouble1);
System.out.println("matrixDoubleCol:n" + matrixDoubleCol);
//-------------------------------------------------------------------
SimpleMatrix matrixA = new SimpleMatrix(4, 4); //创建4x4的矩阵A
SimpleMatrix matrixB = new SimpleMatrix(4, 4); //创建4x4的矩阵B
SimpleMatrix matrixC = new SimpleMatrix(4, 4); //创建5x5的矩阵C
matrixA.fill(1); //将A的所有元素设为1
matrixB.fill(2); //将B的所有元素设为2
System.out.println(matrixA);
System.out.println(matrixB);
matrixC.fill(1);
matrixC = matrixA.plus(0.6); //A的所有元素乘以0.6
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.plus(0.2,matrixB); // A + 0.2*B
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.plus(matrixB); // A + B
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.minus(6); // A的所有元素减6
System.out.println(matrixC);
matrixC.fill(1);
matrixC = matrixA.minus(matrixB); // A - B
System.out.println(matrixC);
matrixC = matrixA.mult(matrixB); // C = A * B
System.out.println(matrixC);
matrixC = matrixA.negative(); // C = -A
System.out.println(matrixC);
matrixC = matrixA.scale(9.99); // C = A*9.99
System.out.println(matrixC);
matrixC = matrixA.divide(50); //C = A的所有元素都除以50所得的矩阵
System.out.println(matrixC);
int val = 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrixC.set(i, j, val);
val++;
}
}
System.out.println(matrixC);
SimpleMatrix matrixC_transpose = matrixC.transpose();
System.out.println(matrixC_transpose);
SimpleMatrix matrixD = new SimpleMatrix(4, 4);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j) {
matrixD.set(i, j, i + 1);
} else {
matrixD.set(i, j, 0);
}
}
}
System.out.println("矩阵D:n"+matrixD);
SimpleMatrix D_invert = matrixD.invert();
System.out.println("矩阵D的逆阵:n"+D_invert);
SimpleMatrix D_pseudoInverse = matrixD.pseudoInverse();
System.out.println("矩阵D的广义逆阵:n"+D_pseudoInverse);
//---------------------------------------------------------------------
//创建n阶单位矩阵 identity matrix
int n =7;
SimpleMatrix tempMatrix = new SimpleMatrix(n,1); //创建nx1的列向量
tempMatrix.fill(1); //所有元素置为1
SimpleMatrix I = tempMatrix.diag();
//A.diag()方法,如果A是矩阵,则返回一个由该矩阵的对角线上的值组成的列向量
// 如果A是列向量,则将其扩展为一个矩阵,矩阵的对角线的值就是该列向量
System.out.println(I);
//---------------------------------------------------------------------
SimpleMatrix matrix = new SimpleMatrix(8,8);
matrix.fill(4); //将矩阵元素都设置为4
matrix.zero(); //将矩阵元素都设置为0
matrix.set(1,4,3); //将第一行第四列元素设置为3
matrix.set(0,8); //将第零个元素设置为8
matrix.rows(1,2); //获取矩阵的部分行,第一个数表示开始的那一行,第二个数表示结束那一行加一(这里表示获取第一行)
matrix.cols(2,8); //获取矩阵的部分列,第一个数表示开始的那一列,第二个数表示结束那一列加一(这里表示获取第2,3,4,5,6,7行)
matrix.get(2,3); //获取第二行第三个数
matrix.get(2); //获取第二个元素
matrix.copy(); //复制一个矩阵
matrix.createLike(); //创建一个与matrix相同行列数且元素相同的矩阵
matrix.numRows(); //获取矩阵的行数
matrix.numCols(); //获取矩阵的列数
matrix.getNumElements(); //获取矩阵的元素个数(行数乘以列数)
matrix.elementMaxAbs(); //获取矩阵中所有元素绝对值的最大值
matrix.elementMinAbs(); //获取矩阵中所有元素绝对值的最小值
matrix.elementSum(); //计算矩阵中所有元素的和
matrix.normF(); //计算矩阵的二范数(所有元素平方和开根号,可以理解成向量的模)
matrix.determinant(); //计算矩阵行列数值
//---------------------------------------------------------------------
matrixC = matrixA.elementDiv(matrixB); // 对应相除 C(i,j) = A(i,j) / B(i,j)
matrixC = matrixA.elementMult(matrixB); // 对应相乘 C(i,j) = A(i,j) * B(i,j)
matrixC = matrixA.elementExp(); // C(i,j) = e 的 A(i,j)次方
matrixC = matrixA.elementLog(); // C(i,j) = ln(C(i,j))
matrixC = matrixA.elementPower(2); // C(i,j) = A(i,j)^2 (对应元素的n次方)
matrixC = matrixA.elementPower(matrixB); // C(i,j) = A(i,j)^(B(i,j)) (对应元素的对应次方)
}
}



