简体   繁体   English

如何使用 Java 中的 Apache Commons Math 库找到矩阵的逆矩阵?

[英]How to find the inverse of a matrix using Apache Commons Math library in Java?

I'm trying to find the inverse of a matrix using the Apache Commons Math Library.我正在尝试使用 Apache Commons Math Library 找到矩阵的逆。

Below is my attempt at doing just that:以下是我这样做的尝试:

BigReal[][] leftMatrixData = new BigReal[][] {
    { new BigReal(1), new BigReal(0), new BigReal(0), new BigReal(0) },
    { new BigReal(1), new BigReal(0), new BigReal(1), new BigReal(0) },
    { new BigReal(1), new BigReal(1), new BigReal(0), new BigReal(0) },
    { new BigReal(1), new BigReal(1), new BigReal(1), new BigReal(1) },
};

FieldMatrix<BigReal> leftMatrix = MatrixUtils.createFieldMatrix(leftMatrixData);
FieldMatrix<BigReal> leftMatrixInverse = new FieldLUDecomposition<>(leftMatrix)
    .getSolver()
    .getInverse();

When I run this, I get the following error:当我运行它时,我收到以下错误:

org.apache.commons.math3.exception.MathArithmeticException: zero not allowed here

    at org.apache.commons.math3.util.BigReal.divide(BigReal.java:255)
    at org.apache.commons.math3.util.BigReal.divide(BigReal.java:39)
    at org.apache.commons.math3.linear.FieldLUDecomposition.<init>(FieldLUDecomposition.java:160)

When I go to line 160 of FieldLUDecomposition.java per the above error message, I see that the library thinks this matrix is Singular ie it thinks it has no inverse:当我根据上述错误消息转到FieldLUDecomposition.java第 160 FieldLUDecomposition.java ,我看到库认为这个矩阵是奇异矩阵,即它认为它没有逆矩阵:

public T getDeterminant() {
    if (this.singular) { <---- this is line 160
        return (FieldElement)this.field.getZero();
    } else {
        int m = this.pivot.length;
        T determinant = this.even ? (FieldElement)this.field.getOne() : (FieldElement)((FieldElement)this.field.getZero()).subtract(this.field.getOne());

However, doing a quick check on WolframAlpha shows that this matrix has a non-zero determinant and indeed has an inverse:但是,对 WolframAlpha 进行快速检查表明该矩阵具有非零行列式并且确实具有逆:

在此处输入图片说明

So the question is - what am I doing wrong and how do I find the inverse of my matrix?所以问题是 - 我做错了什么,我如何找到矩阵的逆? Am I using the wrong solver?我是否使用了错误的求解器?

Below is based on apache common math 3.6.1下面是基于apache common math 3.6.1

A ticket is raised concerning this issue, I submitted a patch to fix the problem and the fix version will be 4.0 (not yet released as of 2021-07-19)是关于这个问题的提出,我提交了一个补丁来解决这个问题和修复版本将是4.0(尚未发布截至2021年7月19日)

The reason of issue is equals method in BigReal问题的原因是BigReal equals方法

    @Override
    public boolean equals(Object other) {
        if (this == other){
            return true;
        }

        if (other instanceof BigReal){
            return d.equals(((BigReal) other).d);
        }
        return false;
    }

where d is BigDecimal , the backing value of BigReal .其中 d 是BigDecimalBigReal的支持值。 This cause equals comparison return undesired result when two BigReal has d with same value but different scale , and cause error when initializing FieldLUDecomposition .这会导致当两个BigReal具有相同值但不同比例的d时等于比较返回不想要的结果,并在初始化FieldLUDecomposition时导致错误。 For BigDecimal we should check对于BigDecimal我们应该检查

    return d.compareTo((BigReal) other) == 0;

instead.反而。

Solution:解决方案:

  1. Check if workaround section (Copy BigReal as local class and change equals ) helps.检查解决方法部分(将BigReal复制为本地类并更改equals )是否有帮助。
  2. Wait for version 4.0 release.等待 4.0 版本发布。
  3. If double value matrix is acceptable, Use RealMatrix instead, and MatrixUtils provide handy inverse method如果可以接受双值矩阵,请改用RealMatrixMatrixUtils提供方便的inverse方法
import org.apache.commons.math3.linear.MatrixUtils;
import org.apache.commons.math3.linear.RealMatrix;

public class CalculateInverse {
    public static void main(String[] args) {
        double[][] matrixData = new double[][]{
                {1, 0, 0, 0},
                {1, 0, 1, 0},
                {1, 1, 0, 0},
                {1, 1, 1, 1}
        };
        RealMatrix matrix = MatrixUtils.createRealMatrix(matrixData);
        RealMatrix inverse = MatrixUtils.inverse(matrix);
        System.out.println(inverse);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM