16 if (mpz_sgn(a) < 0)
return false;
17 if (mpz_sgn(b) < 0)
return false;
18 if (mpz_cmp(a, b) > 0)
return false;
21 mpz_mul_2exp(c, a, 2);
22 int cmp = mpz_cmp(b, c);
24 if (cmp >= 0)
return false;
35 ERROR(
"LLL only defined for matrices over ZZ");
44 ERROR(
"LLL threshold should be in the range (1/4, 1]");
83 bool Lnotzero = lambda->
get_entry(k - 1, k, L);
98 mpz_mul(a, a, alphaBottom.
get_mpz());
101 mpz_mul(b, alphaTop.
get_mpz(), b);
102 int cmp = mpz_cmp(a, b);
117 if (!lambda->
get_entry(ell, k, mkl))
return;
124 mpz_mul_2exp(c, a, 1);
127 mpz_mul_2exp(d, b, 1);
136 if (Achange) Achange->
column_op(k, q, ell);
150 mpz_t a, b, B, C1, C2, D, D1, lam;
164 mpz_init_set(D1, rD1.
get_mpz());
168 mpz_init_set(lam, rlam.
get_mpz());
191 mpz_mul(b, lam, lam);
193 mpz_fdiv_q(B, a, D1);
200 for (i = k + 1; i <= kmax; i++)
203 bool s_notzero = lambda->
get_entry(k - 1, i,
s);
204 bool t_notzero = lambda->
get_entry(k, i, t);
206 mpz_mul(a, D,
s.get_mpz());
215 mpz_fdiv_q(C1, a, D1);
225 mpz_fdiv_q(C2, a, D);
256 std::pair<bool, long> res =
globalZZ->coerceToLongInteger(a);
258 k =
static_cast<int>(res.second);
265 std::pair<bool, long> res =
globalZZ->coerceToLongInteger(a);
267 kmax =
static_cast<int>(res.second);
273 LLLstate->
get_entry(0, n + 3, alphaBottom);
282 if (nsteps % 20 == 0) o <<
newline;
293 if (nsteps % 20 == 0) o <<
newline;
298 for (
int j = 0; j <= k; j++)
302 for (
int i = 0; i <= j - 1; i++)
327 ERROR(
"LLL vectors not independent");
332 REDI(k, k - 1, A, Achange, LLLstate);
333 if (
Lovasz(LLLstate, k, alphaTop, alphaBottom))
335 SWAPI(k, kmax, A, Achange, LLLstate);
341 for (
int ell = k - 2; ell >= 0; ell--)
342 REDI(k, ell, A, Achange, LLLstate);
362 int ret =
doLLL(A, Achange, LLLstate);
Lenstra-Lenstra-Lovász integer lattice basis reduction, in place on a MutableMatrix.
static void SWAPI(int k, int kmax, MutableMatrix *A, MutableMatrix *Achange, MutableMatrix *lambda)
static bool LLL(MutableMatrix *M, MutableMatrix *U, gmp_QQ threshold)
static int doLLL(MutableMatrix *A, MutableMatrix *Achange, MutableMatrix *LLLstate, int nsteps=-1)
static bool checkThreshold(ring_elem num, ring_elem den)
static bool Lovasz(MutableMatrix *lambda, int k, ring_elem alphaTop, ring_elem alphaBottom)
static bool initializeLLL(const MutableMatrix *A, gmp_QQ threshold, MutableMatrix *&LLLstate)
static void REDI(int k, int ell, MutableMatrix *A, MutableMatrix *Achange, MutableMatrix *lambda)
virtual bool dot_product(size_t i, size_t j, ring_elem &result) const =0
virtual size_t n_cols() const =0
virtual bool interchange_columns(size_t i, size_t j)=0
virtual bool get_entry(size_t r, size_t c, ring_elem &result) const =0
static MutableMatrix * zero_matrix(const Ring *R, size_t nrows, size_t ncols, bool dense)
virtual bool is_dense() const =0
virtual bool column_op(size_t i, ring_elem r, size_t j)=0
virtual const Ring * get_ring() const =0
virtual bool set_entry(size_t r, size_t c, const ring_elem a)=0
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
Matrix — the engine's immutable homomorphism F -> G between free modules.
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
mpz_srcptr get_mpz() const