[Mlir-commits] [mlir] [MLIR][Presburger] Add LLL basis reduction (PR #75565)

Arjun P llvmlistbot at llvm.org
Sat Dec 16 05:31:49 PST 2023


================
@@ -576,4 +576,73 @@ FracMatrix FracMatrix::gramSchmidt() const {
     }
   }
   return orth;
-}
\ No newline at end of file
+}
+
+// Convert the matrix, interpreted (row-wise) as a basis
+// to an LLL-reduced basis.
+//
+// This is an implementation of the algorithm described in
+// "Factoring polynomials with rational coefficients" by
+// A. K. Lenstra, H. W. Lenstra Jr., L. Lovasz.
+//
+// Let {b_1,  ..., b_n}  be the current basis and
+//     {b_1*, ..., b_n*} be the Gram-Schmidt orthogonalised
+//                          basis (unnormalized).
+// Define the Gram-Schmidt coefficients μ_ij as
+// (b_i • b_j*) / (b_j* • b_j*), where (•) represents the inner product.
+//
+// We iterate starting from the second row to the last row.
+//
+// For the kth row, we first check μ_kj for all rows j < k.
+// If it is more than 1/2, we subtract b_j (scaled by μ_kj)
+// from b_k.
+//
+// Now, we update k.
+// If b_k and b_{k-1} satisfy the Lovasz condition, we are done
+// and we increment k.
+// Otherwise, we swap b_k and b_{k-1} and decrement k.
+//
+// We repeat this until k = n and return.
+void FracMatrix::LLL(Fraction delta) {
+  MPInt nearest;
+  Fraction mu;
+
+  // `gsOrth` holds the Gram-Schmidt orthogonalisation
+  // of the matrix at all times. It is recomputed every
+  // time the matrix is modified during the algorithm.
+  // This is naive and can be optimised.
+  FracMatrix gsOrth = gramSchmidt();
+
+  // We start from the second row.
+  unsigned k = 1;
+
+  while (k < getNumRows()) {
+    for (unsigned j = k - 1; j < k; j--) {
+      // Compute the Gram-Schmidt coefficient μ_jk.
+      mu = dotProduct(getRow(k), gsOrth.getRow(j)) /
+           dotProduct(gsOrth.getRow(j), gsOrth.getRow(j));
+      if (abs(mu) > Fraction(1, 2)) {
+        nearest = floor(mu + Fraction(1, 2));
+        // Subtract b_j scaled by μ_jk from b_k.
+        addToRow(k, getRow(j), -Fraction(nearest, 1));
+        gsOrth = gramSchmidt(); // recomputation
+      }
+    }
+    mu = dotProduct(getRow(k), gsOrth.getRow(k - 1)) /
+         dotProduct(gsOrth.getRow(k - 1), gsOrth.getRow(k - 1));
+    // Check the Lovasz condition for b_k and b_{k-1}.
+    if (dotProduct(gsOrth.getRow(k), gsOrth.getRow(k)) >
+        (delta - mu * mu) *
+            dotProduct(gsOrth.getRow(k - 1), gsOrth.getRow(k - 1)))
+      // If it is satisfied, proceed to the next k.
+      k += 1;
+    else {
+      // If it is unsatisfied, decrement k (without
----------------
Superty wrote:

"not satisfied"

https://github.com/llvm/llvm-project/pull/75565


More information about the Mlir-commits mailing list