Ng Tsz Sum created MATH-1617: -------------------------------- Summary: FieldLUDecomposition with BigReal throw divide by zero error Key: MATH-1617 URL: https://issues.apache.org/jira/browse/MATH-1617 Project: Commons Math Issue Type: Bug Affects Versions: 3.6.1 Reporter: Ng Tsz Sum
>From >[https://stackoverflow.com/questions/68427448/how-to-find-the-inverse-of-a-matrix-using-apache-commons-math-library-in-java/68427869?noredirect=1#comment120932354_68427869] h3. Reproducible example {code:java} import org.apache.commons.math3.linear.FieldLUDecomposition; import org.apache.commons.math3.linear.FieldMatrix; import org.apache.commons.math3.linear.MatrixUtils; import org.apache.commons.math3.util.BigReal; public class REPREX { public static void main(String[] args) { 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(); // Exception in thread "main" 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) // at stackoverflow.math.matrix.REPREX.main(REPREX.java:18) } } {code} h3. Possible reason: In {{FieldLUDecomposition}} line 130-133 {code:java} if (lu[nonZero][col].equals(field.getZero())) { // try to select a better permutation choice ++nonZero; } {code} Which produce incorrect result when {{lu[nonZeror][col]}} the BigDecimal val has different scale to {{field.getZero()}} scale. as the {{BigReal#equals}} is comparing using {{BigDecimal#equals}} h3. Workaround I tried to copy class {{BigReal}} and {{BigRealField}} to {{FixBigReal}} and {{FixBigRealField}} and replace all {{BigReal}} to {{FixBigReal}} inside. Then override {{FixBIgReal#equals}} as {code:java} @Override public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof FixBigReal) { return d.compareTo(((FixBigReal) other).d) == 0; } return false; } {code} Then the below program will not throw error {code:java} import org.apache.commons.math3.linear.FieldLUDecomposition; import org.apache.commons.math3.linear.FieldMatrix; import org.apache.commons.math3.linear.MatrixUtils; import org.apache.commons.math3.util.BigReal; public class MVE { public static void main(String[] args) { FixBigReal[][] leftMatrixData = new FixBigReal[][]{ {new FixBigReal(1), new FixBigReal(0), new FixBigReal(0), new FixBigReal(0)}, {new FixBigReal(1), new FixBigReal(0), new FixBigReal(1), new FixBigReal(0)}, {new FixBigReal(1), new FixBigReal(1), new FixBigReal(0), new FixBigReal(0)}, {new FixBigReal(1), new FixBigReal(1), new FixBigReal(1), new FixBigReal(1)}, }; FieldMatrix<FixBigReal> leftMatrix = MatrixUtils.createFieldMatrix(leftMatrixData); FieldMatrix<FixBigReal> leftMatrixInverse = new FieldLUDecomposition<>(leftMatrix) .getSolver() .getInverse(); } } {code} -- This message was sent by Atlassian Jira (v8.3.4#803005)