[clang-tools-extra] [MLIR][Presburger] Implement matrix inverse (PR #67382)
Arjun P via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 13 03:36:35 PDT 2023
================
@@ -390,4 +463,83 @@ MPInt IntMatrix::normalizeRow(unsigned row, unsigned cols) {
MPInt IntMatrix::normalizeRow(unsigned row) {
return normalizeRow(row, getNumColumns());
+}
+
+std::optional<IntMatrix> IntMatrix::integerInverse() {
+ Fraction det = Fraction(determinant(), 1);
+ FracMatrix newMat(getNumRows(), getNumColumns());
+ for (unsigned i = 0; i < getNumRows(); i++)
+ for (unsigned j = 0; j < getNumColumns(); j++)
+ newMat(i, j) = Fraction(at(i, j), 1);
+
+ std::optional<FracMatrix> fracInverse = newMat.inverse();
+
+ if (!fracInverse)
+ return {};
+
+ IntMatrix intInverse(getNumRows(), getNumColumns());
+ for (unsigned i = 0; i < getNumRows(); i++)
+ for (unsigned j = 0; j < getNumColumns(); j++)
+ intInverse(i, j) = ((*fracInverse)(i, j) * det).getAsInteger();
+
+ return intInverse;
+}
+
+FracMatrix FracMatrix::identity(unsigned dimension) {
+ return Matrix::identity(dimension);
+}
+
+std::optional<FracMatrix> FracMatrix::inverse() {
+ // We use Gaussian elimination on the rows of [M | I]
+ // to find the integer inverse. We proceed left-to-right,
+ // top-to-bottom. M is assumed to be a dim x dim matrix.
+
+ unsigned dim = getNumRows();
+
+ // Construct the augmented matrix [M | I]
+ FracMatrix augmented(dim, dim + dim);
+ for (unsigned i = 0; i < dim; i++) {
+ augmented.fillRow(i, 0);
+ for (unsigned j = 0; j < dim; j++)
+ augmented(i, j) = at(i, j);
+ augmented(i, dim + i).num = 1;
+ augmented(i, dim + i).den = 1;
+ }
----------------
Superty wrote:
I think it's cleaner to just maintain a copy of `this` and the inverse as separate matrices. You can just assign to 1 btw. and filling 0 should be by default, check the constructor doc.
https://github.com/llvm/llvm-project/pull/67382
More information about the cfe-commits
mailing list