You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
295 lines
8.3 KiB
295 lines
8.3 KiB
package xyz.fycz.myreader.ai;
|
|
|
|
/**
|
|
* @author fengyue
|
|
* @date 2021/4/7 16:10
|
|
*/
|
|
public class MatrixUtil {
|
|
//矩阵加法 C=A+B
|
|
public static double[][] add(double[][] m1, double[][] m2) {
|
|
if (m1 == null || m2 == null ||
|
|
m1.length != m2.length ||
|
|
m1[0].length != m2[0].length) {
|
|
return null;
|
|
}
|
|
|
|
double[][] m = new double[m1.length][m1[0].length];
|
|
|
|
for (int i = 0; i < m.length; ++i) {
|
|
for (int j = 0; j < m[i].length; ++j) {
|
|
m[i][j] = m1[i][j] + m2[i][j];
|
|
}
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
public static double[][] add(double[][] m, double a) {
|
|
if (m == null) {
|
|
return null;
|
|
}
|
|
|
|
double[][] retM = new double[m.length][m[0].length];
|
|
|
|
for (int i = 0; i < retM.length; ++i) {
|
|
for (int j = 0; j < retM[i].length; ++j) {
|
|
retM[i][j] = m[i][j] + a;
|
|
}
|
|
}
|
|
|
|
return retM;
|
|
}
|
|
|
|
public static double[][] sub(double[][] m1, double[][] m2) {
|
|
if (m1 == null || m2 == null ||
|
|
m1.length != m2.length ||
|
|
m1[0].length != m2[0].length) {
|
|
return null;
|
|
}
|
|
|
|
double[][] m = new double[m1.length][m1[0].length];
|
|
|
|
for (int i = 0; i < m.length; ++i) {
|
|
for (int j = 0; j < m[i].length; ++j) {
|
|
m[i][j] = m1[i][j] - m2[i][j];
|
|
}
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
//矩阵转置
|
|
public static double[][] transpose(double[][] m) {
|
|
if (m == null) return null;
|
|
double[][] mt = new double[m[0].length][m.length];
|
|
for (int i = 0; i < m.length; ++i) {
|
|
for (int j = 0; j < m[i].length; ++j) {
|
|
mt[j][i] = m[i][j];
|
|
}
|
|
}
|
|
return mt;
|
|
}
|
|
|
|
//矩阵相乘 C=A*B
|
|
public static double[][] dot(double[][] m1, double[][] m2) {
|
|
if (m1 == null || m2 == null || m1[0].length != m2.length)
|
|
return null;
|
|
|
|
double[][] m = new double[m1.length][m2[0].length];
|
|
for (int i = 0; i < m1.length; ++i) {
|
|
for (int j = 0; j < m2[0].length; ++j) {
|
|
for (int k = 0; k < m1[i].length; ++k) {
|
|
m[i][j] += m1[i][k] * m2[k][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
//数乘矩阵
|
|
public static double[][] dot(double[][] m, double k) {
|
|
if (m == null) return null;
|
|
double[][] retM = new double[m.length][m[0].length];
|
|
for (int i = 0; i < m.length; i++) {
|
|
for (int j = 0; j < m[0].length; j++) {
|
|
retM[i][j] = m[i][j] * k;
|
|
}
|
|
}
|
|
return retM;
|
|
}
|
|
|
|
//同型矩阵除法
|
|
public static double[][] divide(double[][] m1, double[][] m2) {
|
|
if (m1 == null || m2 == null ||
|
|
m1.length != m2.length ||
|
|
m1[0].length != m2[0].length) {
|
|
return null;
|
|
}
|
|
double[][] retM = new double[m1.length][m1[0].length];
|
|
for (int i = 0; i < retM.length; ++i) {
|
|
for (int j = 0; j < retM[i].length; ++j) {
|
|
retM[i][j] = m1[i][j] / m2[i][j];
|
|
}
|
|
}
|
|
return retM;
|
|
}
|
|
|
|
//矩阵除数
|
|
public static double[][] divide(double[][] m, double k) {
|
|
if (m == null) return null;
|
|
double[][] retM = new double[m.length][m[0].length];
|
|
for (int i = 0; i < m.length; i++) {
|
|
for (int j = 0; j < m[0].length; j++) {
|
|
retM[i][j] = m[i][j] / k;
|
|
}
|
|
}
|
|
return retM;
|
|
}
|
|
|
|
//求矩阵行列式(需为方阵)
|
|
public static double det(double[][] m) {
|
|
if (m == null || m.length != m[0].length)
|
|
return 0;
|
|
|
|
if (m.length == 1)
|
|
return m[0][0];
|
|
else if (m.length == 2)
|
|
return det2(m);
|
|
else if (m.length == 3)
|
|
return det3(m);
|
|
else {
|
|
int re = 0;
|
|
for (int i = 0; i < m.length; ++i) {
|
|
re += (((i + 1) % 2) * 2 - 1) * det(companion(m, i, 0)) * m[i][0];
|
|
}
|
|
return re;
|
|
}
|
|
}
|
|
|
|
//求二阶行列式
|
|
public static double det2(double[][] m) {
|
|
if (m == null || m.length != 2 || m[0].length != 2)
|
|
return 0;
|
|
|
|
return m[0][0] * m[1][1] - m[1][0] * m[0][1];
|
|
}
|
|
|
|
//求三阶行列式
|
|
public static double det3(double[][] m) {
|
|
if (m == null || m.length != 3 || m[0].length != 3)
|
|
return 0;
|
|
|
|
double re = 0;
|
|
for (int i = 0; i < 3; ++i) {
|
|
int temp1 = 1;
|
|
for (int j = 0, k = i; j < 3; ++j, ++k) {
|
|
temp1 *= m[j][k % 3];
|
|
}
|
|
re += temp1;
|
|
temp1 = 1;
|
|
for (int j = 0, k = i; j < 3; ++j, --k) {
|
|
if (k < 0) k += 3;
|
|
temp1 *= m[j][k];
|
|
}
|
|
re -= temp1;
|
|
}
|
|
|
|
return re;
|
|
}
|
|
|
|
//求矩阵的逆(需方阵)
|
|
public static double[][] inv(double[][] m) {
|
|
if (m == null || m.length != m[0].length)
|
|
return null;
|
|
|
|
double A = det(m);
|
|
double[][] mi = new double[m.length][m[0].length];
|
|
for (int i = 0; i < m.length; ++i) {
|
|
for (int j = 0; j < m[i].length; ++j) {
|
|
double[][] temp = companion(m, i, j);
|
|
mi[j][i] = (((i + j + 1) % 2) * 2 - 1) * det(temp) / A;
|
|
}
|
|
}
|
|
|
|
return mi;
|
|
}
|
|
|
|
//求方阵代数余子式
|
|
public static double[][] companion(double[][] m, int x, int y) {
|
|
if (m == null || m.length <= x || m[0].length <= y ||
|
|
m.length == 1 || m[0].length == 1)
|
|
return null;
|
|
|
|
double[][] cm = new double[m.length - 1][m[0].length - 1];
|
|
|
|
int dx = 0;
|
|
for (int i = 0; i < m.length; ++i) {
|
|
if (i != x) {
|
|
int dy = 0;
|
|
for (int j = 0; j < m[i].length; ++j) {
|
|
if (j != y) {
|
|
cm[dx][dy++] = m[i][j];
|
|
}
|
|
}
|
|
++dx;
|
|
}
|
|
}
|
|
return cm;
|
|
}
|
|
|
|
//生成全为0的矩阵
|
|
public static double[][] zeros(int rows, int cols){
|
|
return new double[rows][cols];
|
|
}
|
|
|
|
//生成全为1的矩阵
|
|
public static double[][] ones(int rows, int cols){
|
|
return add(zeros(rows, cols), 1);
|
|
}
|
|
|
|
public static double sum(double[][] matrix){
|
|
double sum = 0;
|
|
for (double[] doubles : matrix) {
|
|
for (double aDouble : doubles) {
|
|
sum += aDouble;
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
public static double[][] pow(double[][] matrix, int exponent){
|
|
if (matrix == null) return null;
|
|
double[][] retM = new double[matrix.length][matrix[0].length];
|
|
for (int i = 0; i < matrix.length; i++) {
|
|
for (int j = 0; j < matrix[i].length; j++) {
|
|
retM[i][j] = Math.pow(matrix[i][j], exponent);
|
|
}
|
|
}
|
|
return retM;
|
|
}
|
|
|
|
public static double[][] sqrt(double[][] matrix){
|
|
if (matrix == null) return null;
|
|
double[][] retM = new double[matrix.length][matrix[0].length];
|
|
for (int i = 0; i < matrix.length; i++) {
|
|
for (int j = 0; j < matrix[i].length; j++) {
|
|
retM[i][j] = Math.sqrt(matrix[i][j]);
|
|
}
|
|
}
|
|
return matrix;
|
|
}
|
|
|
|
public static double[][] to2dMatrix(double[] vector, boolean isCol){
|
|
if (vector == null) return null;
|
|
double[][] retM;
|
|
if (isCol) {
|
|
retM = new double[vector.length][1];
|
|
}else {
|
|
retM = new double[1][vector.length];
|
|
}
|
|
for (int i = 0; i < vector.length; i++) {
|
|
if (isCol) {
|
|
retM[i][0] = vector[i];
|
|
}else {
|
|
retM[0][i] = vector[i];
|
|
}
|
|
}
|
|
return retM;
|
|
}
|
|
|
|
public static double[] toVector(double[][] matrix){
|
|
double[] retV = null;
|
|
if (matrix.length == 1){
|
|
retV = new double[matrix[0].length];
|
|
double[] doubles = matrix[0];
|
|
System.arraycopy(doubles, 0, retV, 0, doubles.length);
|
|
}else if (matrix[0].length == 1){
|
|
retV = new double[matrix.length];
|
|
for (int i = 0; i < matrix.length; i++) {
|
|
retV[i] = matrix[i][0];
|
|
}
|
|
}
|
|
return retV;
|
|
}
|
|
}
|
|
|