[
https://issues.apache.org/jira/browse/MATH-1617?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ng Tsz Sum updated MATH-1617:
-
Description:
>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 leftMatrix =
MatrixUtils.createFieldMatrix(leftMatrixData);
FieldMatrix 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.(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}} and {{FixBIgReal#hashcode }}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;
}
...
@Override
public int hashCode() {
return Double.hashCode(d.doubleValue());
}
{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 leftMatrix =
MatrixUtils.createFieldMatrix(leftMatrixData);
FieldMatrix leftMatrixInverse = new
FieldLUDecomposition<>(leftMatrix)
.getSolver()
.getInverse();
}
}
{code}
was:
>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 leftMatrix =
MatrixUtils.createFieldMatrix(leftMatrixData);
FieldMatrix leftMatrixInverse = new
FieldLUDecomposition<>(leftMatrix)
.getSolver()
.getInverse();
//