Как найти обратную матрицу java

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.

Java Program to Find Inverse of a Matrix

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
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
36
37
private float[][] backInBlack(float[][] matr,int length) {
        float[][] backMatr = new float[length] [length];
        for (int i=0; i<length; i++)
            for (int j = 0; j < length; j++)
            {
                if (i == j)
                    backMatr[i][j] = 1;
                else
                    backMatr[i][j] = 0;
            }
 
        double p = 0, q = 0, s =0;
        for (int i = 0; i < length; i++)
        {
            p = matr[i] [i];
            for (int j = i + 1; j < length; j++)
            {
                q = matr[j] [i];
                for (int k = 0; k < length; k++)
                {
                    matr[j] [k] = (float) (matr[i] [k] * q - matr[j] [k] * p);
                    backMatr[j] [k] = (float) (backMatr[i][k] * q - backMatr[j][k] * p);
                }
            }
        }
        for (int i = 0; i < length; i++)
        {
            for (int j = length - 1; j >= 0; j--)
            {
                s = 0;
                for (int k = length - 1; k > j; k--)
                    s += matr[j][ k] * backMatr[k][i];
                backMatr[j][i] = (float) ((backMatr[j][i] - s) / matr[j][j]);
            }
        }
        return backMatr;
    }

И все бы прекрасно работало, но столкнулся я с такой матрицей:

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
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void inversion(float [][]A, int N)
    {
        double temp;
 
        float [][] E = new float [N][N];
 
 
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
            {
                E[i][j] = 0f;
 
                if (i == j)
                    E[i][j] = 1f;
            }
 
        for (int k = 0; k < N; k++)
        {
            temp = A[k][k];
 
            for (int j = 0; j < N; j++)
            {
                A[k][j] /= temp;
                E[k][j] /= temp;
            }
 
            for (int i = k + 1; i < N; i++)
            {
                temp = A[i][k];
 
                for (int j = 0; j < N; j++)
                {
                    A[i][j] -= A[k][j] * temp;
                    E[i][j] -= E[k][j] * temp;
                }
            }
        }
 
        for (int k = N - 1; k > 0; k--)
        {
            for (int i = k - 1; i >= 0; i--)
            {
                temp = A[i][k];
 
                for (int j = 0; j < N; j++)
                {
                    A[i][j] -= A[k][j] * temp;
                    E[i][j] -= E[k][j] * temp;
                }
            }
        }
 
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                A[i][j] = E[i][j];
 
    }

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

zeus's user avatar

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

Show hidden 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][nCols1]) > EPS) {
for (int x = 0; x < nCols1; 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 nCols1 > arr.lengthnEmptyRows;
}
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));
}
}

Понравилась статья? Поделить с друзьями:
  • Как исправить старую селедку
  • Как быстро найти 300000 рублей
  • Как найти капитана корабля
  • Как найти классификацию веществ
  • Как найти человека где воевал в вов