next | previous | forward | backward | up | top | index | toc | Macaulay2 website
LLLBases :: LLL(...,Strategy=>...)

LLL(...,Strategy=>...) -- choose among different algorithms



There are several variants of the LLL reduction algorithm implemented. There are three all integer versions: NTL, CohenEngine, and CohenTopLevel. The NTL version (NTL is an excellent package written by Victor shoup) is generally the best, however, the top level version is written in the Macaulay2 language, and so is easily modifiable and can be used to understand the algorithm better. There are also a number of approximate LLL variants implemented in NTL. These use real numbers instead of exact integer arithmetic, and so are often much faster, but only provide approximate answers (i.e. the result might not be an LLL basis, only close to one). Much of the information here about NTL's algorithms comes directly from the NTL documentation (translated to be relevant here).

Here is the complete list of possible strategies:

The first three are similar all-integer algorithms, basically the one which appears in H. Cohen's book. The rest of the algorithms are approximate variants, provided by Victor Shoup's NTL package. For these, there are three choices to be made: (1) the reduction condition, (2) the choice of orthogonalization strategy, and (3) the choice of precision.

Reduction condition

Orthogonalization Strategy


Generally speaking, the choice RealFP will be the fastest, but may be prone to roundoff errors and/or overflow.

Putting it all together

This subsection comes directly from Victor Shoup's LLL documentation

I think it is safe to say that nobody really understands how the LLL algorithm works. The theoretical analyses are a long way from describing what "really" happens in practice. Choosing the best variant for a certain application ultimately is a matter of trial and error.

The first thing to try is Strategy => RealFP. It is the fastest of the routines, and is adequate for many applications.

If there are precision problems, you will most likely get a warning message, something like "warning--relaxing reduction". If there are overflow problems, you should get an error message saying that the numbers are too big.

If either of these happens, the next thing to try is Strategy=>{Givens,RealFP}, which uses the somewhat slower, but more stable, Givens rotations. This approach also has the nice property that the numbers remain smaller, so there is less chance of an overflow.

If you are still having precision problems try Strategy=>RealQP or Strategy=>{Givens,RealQP}, which use quadratic precision.

If you are still having overflow problems, try Strategy=>RealXD or Strategy=>{Givens,RealXD}

I haven't yet come across a case where one *really* needs the extra precision available in the RealRR variants.

All of the above discussion applies to the BKZ variants as well. In addition, if you have a matrix with really big entries, you might try using Strategy=>{Givens,RealFP} or Strategy=>RealXD first to reduce the sizes of the numbers, before running one of the BKZ variants.

Also, one shouldn't rule out using the "all integer" LLL routines. For some highly structured matrices, this is not necessarily much worse than some of the floating point versions, and can under certain circumstances even be better.

i1 : m1 = map(ZZ^50, ZZ^50, (j,i) -> (i+1)^8 * (j+1)^4 + i + j + 2);

              50        50
o1 : Matrix ZZ   <--- ZZ
i2 : m = syz m1;

              50        47
o2 : Matrix ZZ   <--- ZZ
i3 : time LLL m;
     -- used 0.0162097 seconds

              50        47
o3 : Matrix ZZ   <--- ZZ
i4 : time LLL(m, Strategy=>CohenEngine);
     -- used 0.0779385 seconds

              50        47
o4 : Matrix ZZ   <--- ZZ
i5 : time LLL(m, Strategy=>CohenTopLevel);
     -- used 0.173686 seconds

              50        47
o5 : Matrix ZZ   <--- ZZ
i6 : time LLL(m, Strategy=>{Givens,RealFP});
     -- used 0.0239203 seconds

              50        47
o6 : Matrix ZZ   <--- ZZ
i7 : time LLL(m, Strategy=>{Givens,RealQP});
     -- used 0.0969379 seconds

              50        47
o7 : Matrix ZZ   <--- ZZ
i8 : time LLL(m, Strategy=>{Givens,RealXD});
     -- used 0.112375 seconds

              50        47
o8 : Matrix ZZ   <--- ZZ
i9 : time LLL(m, Strategy=>{Givens,RealRR});
     -- used 0.606216 seconds

              50        47
o9 : Matrix ZZ   <--- ZZ
i10 : time LLL(m, Strategy=>{BKZ,Givens,RealQP});
     -- used 0.223222 seconds

               50        47
o10 : Matrix ZZ   <--- ZZ

Further information


For most of the options, the columns do not need to be linearly independent. The strategies CohenEngine and CohenTopLevel currently require the columns to be linearly independent.

See also

Functions with optional argument named Strategy :