For those who seeks matrix inversion (not fast), see https://github.com/rchen8/Algorithms/blob/master/Matrix.java.
import java.util.Arrays;
public class Matrix {
private static double determinant(double[][] matrix) {
if (matrix.length != matrix[0].length)
throw new IllegalStateException("invalid dimensions");
if (matrix.length == 2)
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
double det = 0;
for (int i = 0; i < matrix[0].length; i++)
det += Math.pow(-1, i) * matrix[0][i]
* determinant(submatrix(matrix, 0, i));
return det;
}
private static double[][] inverse(double[][] matrix) {
double[][] inverse = new double[matrix.length][matrix.length];
// minors and cofactors
for (int i = 0; i < matrix.length; i++)
for (int j = 0; j < matrix[i].length; j++)
inverse[i][j] = Math.pow(-1, i + j)
* determinant(submatrix(matrix, i, j));
// adjugate and determinant
double det = 1.0 / determinant(matrix);
for (int i = 0; i < inverse.length; i++) {
for (int j = 0; j <= i; j++) {
double temp = inverse[i][j];
inverse[i][j] = inverse[j][i] * det;
inverse[j][i] = temp * det;
}
}
return inverse;
}
private static double[][] submatrix(double[][] matrix, int row, int column) {
double[][] submatrix = new double[matrix.length - 1][matrix.length - 1];
for (int i = 0; i < matrix.length; i++)
for (int j = 0; i != row && j < matrix[i].length; j++)
if (j != column)
submatrix[i < row ? i : i - 1][j < column ? j : j - 1] = matrix[i][j];
return submatrix;
}
private static double[][] multiply(double[][] a, double[][] b) {
if (a[0].length != b.length)
throw new IllegalStateException("invalid dimensions");
double[][] matrix = new double[a.length][b[0].length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b[0].length; j++) {
double sum = 0;
for (int k = 0; k < a[i].length; k++)
sum += a[i][k] * b[k][j];
matrix[i][j] = sum;
}
}
return matrix;
}
private static double[][] rref(double[][] matrix) {
double[][] rref = new double[matrix.length][];
for (int i = 0; i < matrix.length; i++)
rref[i] = Arrays.copyOf(matrix[i], matrix[i].length);
int r = 0;
for (int c = 0; c < rref[0].length && r < rref.length; c++) {
int j = r;
for (int i = r + 1; i < rref.length; i++)
if (Math.abs(rref[i][c]) > Math.abs(rref[j][c]))
j = i;
if (Math.abs(rref[j][c]) < 0.00001)
continue;
double[] temp = rref[j];
rref[j] = rref[r];
rref[r] = temp;
double s = 1.0 / rref[r][c];
for (j = 0; j < rref[0].length; j++)
rref[r][j] *= s;
for (int i = 0; i < rref.length; i++) {
if (i != r) {
double t = rref[i][c];
for (j = 0; j < rref[0].length; j++)
rref[i][j] -= t * rref[r][j];
}
}
r++;
}
return rref;
}
private static double[][] transpose(double[][] matrix) {
double[][] transpose = new double[matrix[0].length][matrix.length];
for (int i = 0; i < matrix.length; i++)
for (int j = 0; j < matrix[i].length; j++)
transpose[j][i] = matrix[i][j];
return transpose;
}
public static void main(String[] args) {
// example 1 - solving a system of equations
double[][] a = { { 1, 1, 1 }, { 0, 2, 5 }, { 2, 5, -1 } };
double[][] b = { { 6 }, { -4 }, { 27 } };
double[][] matrix = multiply(inverse(a), b);
for (double[] i : matrix)
System.out.println(Arrays.toString(i));
System.out.println();
// example 2 - example 1 using reduced row echelon form
a = new double[][]{ { 1, 1, 1, 6 }, { 0, 2, 5, -4 }, { 2, 5, -1, 27 } };
matrix = rref(a);
for (double[] i : matrix)
System.out.println(Arrays.toString(i));
System.out.println();
// example 3 - solving a normal equation for linear regression
double[][] x = { { 2104, 5, 1, 45 }, { 1416, 3, 2, 40 },
{ 1534, 3, 2, 30 }, { 852, 2, 1, 36 } };
double[][] y = { { 460 }, { 232 }, { 315 }, { 178 } };
matrix = multiply(
multiply(inverse(multiply(transpose(x), x)), transpose(x)), y);
for (double[] i : matrix)
System.out.println(Arrays.toString(i));
}
}
Here you will get java program to find inverse of a matrix of order 2×2 and 3×3.
We can find inverse of a matrix in following way.
- First find the determinant of matrix.
- Calculate adjoint of matrix.
- Finally divide adjoint of matrix by determinant.
Image Source
Below I have shared program to find inverse of 2×2 and 3×3 matrix.
2×2 Matrix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import java.util.Scanner; public class JavaMatrixInverse { public static void main(String args[]) { int i, j; float det, temp; float mat[][] = new float[2][2]; Scanner sc = new Scanner(System.in); System.out.println(«Enter elements of matrix row wise:»); for(i = 0; i < 2; ++i) for(j = 0; j < 2; ++j) mat[i][j] = sc.nextFloat(); det = (mat[0][0] * mat[1][1]) — (mat[0][1] * mat[1][0]); System.out.println(«ndeterminant = « + det); temp = mat[0][0]; mat[0][0] = mat[1][1]; mat[1][1] = temp; mat[0][1] = — mat[0][1]; mat[1][0] = — mat[1][0]; System.out.println(«nInverse of matrix is:»); for(i = 0; i < 2; ++i) { for(j = 0; j < 2; ++j) System.out.print((mat[i][j]/det) + » «); System.out.print(«n»); } } } |
Output
Enter elements of matrix row wise:
4 7
2 6
determinant = 10.0
Inverse of matrix is:
0.6 -0.7
-0.2 0.4
3×3 Matrix
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.util.Scanner; public class JavaMatrixInverse { public static void main(String args[]) { int i, j; float det = 0; float mat[][] = new float[3][3]; Scanner sc = new Scanner(System.in); System.out.println(«Enter elements of matrix row wise:»); for(i = 0; i < 3; ++i) for(j = 0; j < 3; ++j) mat[i][j] = sc.nextFloat(); for(i = 0; i < 3; i++) det = det + (mat[0][i] * (mat[1][(i+1)%3] * mat[2][(i+2)%3] — mat[1][(i+2)%3] * mat[2][(i+1)%3])); System.out.println(«ndeterminant = « + det); System.out.println(«nInverse of matrix is:»); for(i = 0; i < 3; ++i) { for(j = 0; j < 3; ++j) System.out.print((((mat[(j+1)%3][(i+1)%3] * mat[(j+2)%3][(i+2)%3]) — (mat[(j+1)%3][(i+2)%3] * mat[(j+2)%3][(i+1)%3]))/ det) + » «); System.out.print(«n»); } } } |
Output
Enter elements of matrix row wise:
1 2 3
0 1 4
5 6 0
determinant = 1.0
Inverse of matrix is:
-24.0 18.0 5.0
20.0 -15.0 -4.0
-5.0 4.0 1.0
Comment below if you have any queries related to above program to find inverse of matrix in java.
Добрый день, народ.
Столкнулся я с вечной проблемой под названием Обратная матрица. Убил час на нахождения кода на любом языке, но нормального и точного ответа я нашел.
Пообщавшись со знакомым «дотнетчиком» он пользовался таким кодом(я его кончено перевел в Java)
Java | ||
|
И все бы прекрасно работало, но столкнулся я с такой матрицей:
1.0 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
1.0 18.0 0.0 0.0 20.0 0.0 22.0 0.0 0.0 0.0 0.0 0.0
4.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 1.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 79.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 77.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 79.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 79.0 0.0 0.0 0.0 1.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 77.0 0.0 0.0 0.0 0.0 1.0
Обработал и получил NaN по всем елементам
Подумал: «Может матрица не переводиться?», но нет онлаин калькуляторы ответ дают четкий.
Народ, поделитесь кодом, кто решал такую задачу, пожалуйста. Приму код на любом современном языке!))) Заранее спасибо!
Добавлено через 19 часов 16 минут
В общем нашел я этот алгоритм. Все работает прекрасно. Кто сюда дойдет ловите
Java | ||
|
I found function for calculate inverse matrix with jama java matrix class
public Matrix inverse()
Matrix inverse or pseudoinverse
Returns:
inverse(A) if A is square, pseudoinverse otherwise.
But i don’t know how is this working or how to forward nxn matrix, so can someone explain me how it works with some simple example.
I found this function here http://math.nist.gov/javanumerics/jama/doc/Jama/Matrix.html#inverse()
Thank you
- java
asked Jun 26, 2015 at 17:00
zeuszeus
891 silver badge7 bronze badges
3
-
Do you know the math behind it?
Jun 26, 2015 at 17:02
-
You can construct a Matrix object, and then call inverse() on it, which will return the inverse of the Matrix (if it is square) as a new Matrix object.
Jun 26, 2015 at 17:03
Load 7 more related questions
Show fewer related questions
Permalink
Cannot retrieve contributors at this time
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Use Gaussian elimination on an augmented matrix to find the inverse of a matrix. | |
* | |
* <p>Time Complexity: O(n^3) | |
*/ | |
package com.williamfiset.algorithms.linearalgebra; | |
class MatrixInverse { | |
// Define a small value of epsilon to compare double values | |
static final double EPS = 0.00000001; | |
// Invert the specified matrix. Assumes invertibility. Time Complexity: O(r²c) | |
static double[][] inverse(double[][] matrix) { | |
if (matrix.length != matrix[0].length) return null; | |
int n = matrix.length; | |
double[][] augmented = new double[n][n * 2]; | |
for (int i = 0; i < n; i++) { | |
for (int j = 0; j < n; j++) augmented[i][j] = matrix[i][j]; | |
augmented[i][i + n] = 1; | |
} | |
solve(augmented); | |
double[][] inv = new double[n][n]; | |
for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) inv[i][j] = augmented[i][j + n]; | |
return inv; | |
} | |
// Solves a system of linear equations as an augmented matrix | |
// with the rightmost column containing the constants. The answers | |
// will be stored on the rightmost column after the algorithm is done. | |
// NOTE: make sure your matrix is consistent and does not have multiple | |
// solutions before you solve the system if you want a unique valid answer. | |
// Time Complexity: O(r²c) | |
static void solve(double[][] augmentedMatrix) { | |
int nRows = augmentedMatrix.length, nCols = augmentedMatrix[0].length, lead = 0; | |
for (int r = 0; r < nRows; r++) { | |
if (lead >= nCols) break; | |
int i = r; | |
while (Math.abs(augmentedMatrix[i][lead]) < EPS) { | |
if (++i == nRows) { | |
i = r; | |
if (++lead == nCols) return; | |
} | |
} | |
double[] temp = augmentedMatrix[r]; | |
augmentedMatrix[r] = augmentedMatrix[i]; | |
augmentedMatrix[i] = temp; | |
double lv = augmentedMatrix[r][lead]; | |
for (int j = 0; j < nCols; j++) augmentedMatrix[r][j] /= lv; | |
for (i = 0; i < nRows; i++) { | |
if (i != r) { | |
lv = augmentedMatrix[i][lead]; | |
for (int j = 0; j < nCols; j++) augmentedMatrix[i][j] -= lv * augmentedMatrix[r][j]; | |
} | |
} | |
lead++; | |
} | |
} | |
// Checks if the matrix is inconsistent | |
static boolean isInconsistent(double[][] arr) { | |
int nCols = arr[0].length; | |
outer: | |
for (int y = 0; y < arr.length; y++) { | |
if (Math.abs(arr[y][nCols — 1]) > EPS) { | |
for (int x = 0; x < nCols — 1; x++) if (Math.abs(arr[y][x]) > EPS) continue outer; | |
return true; | |
} | |
} | |
return false; | |
} | |
// Make sure your matrix is consistent as well | |
static boolean hasMultipleSolutions(double[][] arr) { | |
int nCols = arr[0].length, nEmptyRows = 0; | |
outer: | |
for (int y = 0; y < arr.length; y++) { | |
for (int x = 0; x < nCols; x++) if (Math.abs(arr[y][x]) > EPS) continue outer; | |
nEmptyRows++; | |
} | |
return nCols — 1 > arr.length — nEmptyRows; | |
} | |
public static void main(String[] args) { | |
// Check this matrix is invertable | |
double[][] matrix = { | |
{2, —4, 0}, | |
{0, 6, 0}, | |
{2, 2, —2} | |
}; | |
double[][] inv = inverse(matrix); | |
for (double[] row : inv) System.out.println(java.util.Arrays.toString(row)); | |
} | |
} |