This repository contains a golang implementation of the PSLQ Algorithm as described in the original 1992 PSLQ paper, with modifications geared to cryptanalysis. PSLQ is an algorithm that can find a small but not-all-zero integer-only solution m1,m2,...,mn of the equation
x1m1+x2m2+...+xnmn=0
where the xi are real numbers.
The purpose of this repository is to demonstrate the usefulness of PSLQ in cryptanalysis, for example against a type of cryptography based on something called LWE.
"LWE" stands for Learning with Errors, and the "LWE problem" refers to a problem that a cryptanalyst must solve in order to break the class of crypto-systems bearing the same name. The LWE problem can be reduced to solving Am = 0 where
- A is a pxn public matrix with entries from ℤq.
- m is a short n-long vector with integer entries.
Right-multiplying A by b^ = [1, b, b2, ..., bp-1] transforms A into a 1xn matrix, appropriate for input to PSLQ. Solutions of <b^A, m> = 0 are likely solutions of Am = 0 for sufficiently large b.
There are lots of issues to work out, including the fact that the entries of A are elements of ℤq, not ℤ. There are also answers to these issues, some better than others. For example, extending A with a certain p x p matrix containing 0s and non-zero integers of the form bkq, gets around the ℤq, vs. ℤ issue. Anyway, the cryptanalyst only needs to win now and then to succeed.
Rather than run down all the details of the transformation of the LWE problem into a PSLQ problem, the point here is to raise the possibility that PSLQ is a powerful, if under-appreciated, tool for cryptanalysis. To be a credible tool, PSLQ should be able to solve <x,m> = 0 with the smallest possible m when x has hundreds of large integer entries. This repository begins to tackle this problem.
Without some changes, PSLQ is not a useful tool for cryptanalysis. PSLQ was originally designed to handle real (or complex or quaternion), non-integer input. Given integer input, PSLQ as defined in the original 1992 paper quickly finds a bad (high-norm) solution, m, and terminates.
Read on to see in detail how this problem can be fixed. For now, let it suffice to say that the modification of PSLQ proposed here delays the termination of the algorithm until the solution is optimal.
PSLQ, as originally defined, is both a framework and a strategy. The framework consists of a matrix equation and a set of allowed operations on this equation that change its components until a solution of <x,m> = 0 is found. The strategy specifies what operations to perform, and when to perform them.
The framework cannot change; the strategy can. In fact, the strategy has been modified in the literature, most notably in this paper, where one of the authors of the original 1992 paper proposes a strategy that can take advantage of parallel processing. The reason the framework cannot change is that its set of allowed operations is what guarantees some invariants needed to solve <x,m> = 0.
The adjective, "classic", in both this README and in the code, refers to the original strategy suggested in the 1992 paper. The classic strategy is geared towards proving bounds on the performance of PSLQ, so it can be considered a polynomial time algorithm that finds solutions within a certain factor of the optimal solution.
In this repository, the classic strategy is modified greatly. The purpose of the modifications is to delay termination and optimize the solution.
The PSLQ algorithm performs iterations that maintain a matrix equation,
xBAHxQ = 0 (equation 1)
while updating the factors B, A and Q.
Here,
- x is the sequence of real numbers for which we are trying to find a relation. In the context of matrix equations like equation 1, consider x to be a 1 x n matrix of real numbers
- B and A are n x n matrices with integer entries and determinant 1 or -1. They are identity matrices at initialization. After each iteration, B = A-1.
- Hx is an n x n-1 matrix with real entries, non-zero diagonal entries, and zeroes above the diagonal
- Q is a rotation matrix that keeps 0s above the diagonal of AHxQ
PSLQ stores AHxQ, which we will call H (as opposed to Hx) in this section. In later sections, when the value of H at a particular iteration k matters more than it does here, the notation Hk will be used. Substituting H for AHxQ in equation 1,
xBH = 0 (equation 2)
Both x and Hx remain fixed at their initial values, whereas B, A and H are updated while PSLQ runs. Q itself is not stored directly, but is implicitly stored by storing H. H, like Hx, is non-zero on the diagonal and zero above the diagonal.
Because H is zero above the diagonal, the last column of H -- column n-1 -- is mostly 0. It contains non-zero values in at most its last two entries. It would be a shame if something happened to one of those entries, like Hn-1,n-1 becoming 0. That would leave just one non-zero entry in column n-1, namely Hn,n-1. Then the fact that (xBH)n-1 = 0 (along with the other entries of xBH) would mean that (xB)n = 0.
Of course this wouldn't really be a shame. According to equation 2, Hn-1,n-1 = 0 and Hn,n-1 ≠ 0 would mean that the last entry of xB -- the coefficient of Hn,n-1 in equation 2 -- has to be 0. In other words,
<x,last column B> = 0
This means that -- once Hn-1,n-1 is forced to be zero -- setting m to the last column of B makes m a solution with integer entries of <x,m> = 0.
So the idea of PSLQ is to force a 0 into the last diagonal element of H while maintaining 0s above the diagonal of H and the validity of equation 2. When that happens, PSLQ reaps a solution of <x,m> = 0 from column n of B!
The way B, A and H are modified is through row operations on A, and their inverses as column operations on B. These row operations put non-zero values above the diagonal of H, which the last factor in equation 1, Q, zeroes out with a rotation. Zeroing out entries of H above the diagonal is called "corner removal", because it removes the non-zero upper-right corner entry from a 2x2 sub-matrix of H. It is essential that Q be a rotation so the diagonal entries of H track the norms of potential solutions of <x,m> = 0.
The row operations on A are designed not only to force a zero into Hn-1,n-1, but to nudge the large diagonal entries of H towards the right, for reasons explained later. These goals have random effects on the entries of H below the diagonal. Left unchecked, these effects would cause the sub-diagonal of H to grow without bound. To offset this, the original 1992 PSLQ paper specifies the use of what it calls Hermite reduction, which aggressively minimizes the entries below the diagonal of H.
Up to the mention of Hermite reduction, everything in the description above can be considered the framework of PSLQ. Hermite reduction, in lieu of other kinds of reduction of H below the diagonal, can be considered part of the strategy for putting a zero in Hn-1,n-1 to force a solution of <x,m> = 0 into a column of B.
As noted earlier, there are many reasonable strategies. The primary example is the classic strategy from the original 1992 paper: Swap rows according to a criterion governed by a parameter, γ. When j < n-1 and γj |Hj,j| ≥ γi |Hi,i| for all i, it is rows j and j+1 that are swapped. If no j satisfies this criterion, rows n-1 and n are swapped. After swapping, update Q to remove the corner just created (unless swapping rows n-1 and n), and perform Hermite reduction.
The classic strategy is good if there is just one independent solution of <x,m> = 0, but not good if there are many. In cryptanalytic use cases, there are many independent solutions of <x,m> = 0, so this README develops alternative strategies to find good solutions among the many.
The diagonal of H is crucial. It is the key to "accuracy", which is the term used here for the Euclidean length ("norm") of the solution m of <x,m> = 0 that PSLQ calculates. The smaller the norm, the more accurate the output.
As shown in the section "A Sharper Lower Bound on the Smallest Solution While PSLQ is Running" below, the larger the diagonal elements, the smaller the norm of the relation m that PSLQ finds (details are deferred to that section).
Of greatest importance is the last diagonal element, Hn-1,n-1. Lemma 10 in a 1999 paper analyzing PSLQ states that the norm of the solution is the value of 1/|Hn-1,n-1| at the iteration of PSLQ before Hn-1,n-1 becomes 0. So it would improve accuracy to keep |Hn-1,n-1| as large as possible while PSLQ is running.
Lemma 10 is crucial to the strategies employed in this repository, so we need to delve into some of the details of its proof. This section is a guide to that proof, not a full proof. It fills in some details, and fleshes out the assumptions behind the lemma. That way, we can be assured that adding row operations to the toolkit used in classical PSLQ does not violate the assumptions.
Lemma 10 relies on the assumptions listed below, which are not broken by any row operation with determinant 1 or -1 ("unit determinant"), or any rotation to remove zeroes above the diagonal of H. These assumptions refer to
- A matrix Px, defined in the statement of lemma 2 in the same paper
- m, the solution the PSLQ algorithm is about to output, when rows n-1 and n are swapped.
- A, the matrix with integer entries and unit determinant that is the product of all previous row operations.
- B=A-1, following the notation used here, though in the proof of lemma 10 "A-1" is the notation for what we call B throughout this README.
The assumptions are:
- APx = TDQtHxt is a decomposition of APx into into the product of a lower trapezoidal matrix T with diagonal 1s, an invertible diagonal matrix D with the same diagonal as H, and an n−1×n matrix QtHxt with orthonormal rows. This, by the way, is copied from the proof of theorem 1, not lemma 10. The proof of lemma 10 implicitly refers back to that proof.
- At the point where a zero appears in Hn,n-1, the (n−1)-st column of B is m.
Based on the second assumption,
Amt =<B-1, column n-1 of B> = en−1, the (n−1)-st standard basis vector.
The second of the two "=" signs is true for any B-1 and B. The left and right quantities are equated in the proof of lemma 10 without connecting this equality to the second assumption. So Amt=en-1 can appear to be a separate assumption but it's not.
The first assumption depends only on the initial setup of PSLQ and the fact that A has integer entries and unit determinant. So no row operation with unit determinant falsifies the first assumption.
The second assumption relies only on the fact that Hn,n-1 = 0, leaving Hn-1,n-1 as the lone non-zero entry in column n-1 of H. Equation 1, xBAHxQ = 0, tells us that in particular, if you just focus on the last coordinate of xBAHxQ, that coordinate is zero. From this and Hn-1,n-1 being the only non-zero entry in column n-1, we get:
0 = (xBAHxQ)n-1 = (xBH)n-1 = (xB)n-1 (Hn-1,n-1) ⇒ (xB)n-1 = 0
The rightmost equality above just says that column n-1 of B is a solution we can call "m" of <x,m> = 0.
Each iteration of PSLQ performs a pair of row operations on H -- one to tame the diagonal of H, another to reduce the entries below the diagonal. In this section, "row operation" refers to the former, designed to tame the diagonal of H. Any row operation with determinant 1 or -1 is acceptable. But the original 1992 PSLQ paper and the 1999 analysis of PSLQ consider only swaps of adjacent rows.
The reason for re-implementing PSLQ here, rather than using an existing implementation, is to replace the classic strategy in the original 1992 PSLQ paper with
- Row operations other than swaps of adjacent rows
- Swaps of adjacent rows chosen with criteria other than the ones specified in the original 1992 PSLQ paper
- Delaying termination until best possible solution becomes available.
Using these three extensions to "improve" the diagonal of H trades provable performance for empirically verified accuracy. Proofs of both accuracy and speed are presented in the original 1992 PSLQ paper and in the 1999 paper analyzing PSLQ. But the accuracy bounds these proofs promise are poor, as Table 1
below shows in its results for the classic strategy, which the 1992 (and 1999) papers propose.
Because the accuracy guarantees in the 1992 and 1999 PSLQ papers do not meet the needs of cryptographic use cases, the extensions in this repository sacrifice them, along with speed guarantees, in exchange for empirically demonstrated, albeit not mathematically proven, improvements in accuracy. Empirical results in Table 1
show that the improved accuracy comes at the cost of speed. It would not be surprising if the speed remains polynomial, but with an increase of 1 in the degree of the polynomial.
Table 1
contains a column called strategy
. As noted earlier, a "strategy" is a set of rules for choosing row operations to imrpove the diagonal of H. The strategies compared in Table 1
are:
Classic
: Swap rows to improve the diagonal of H as recommended in the original PSLQ paper, until a zero-valued entry is swapped into the last diagonal element of H; terminate when that happens.IDASIF
: "Improve diagonal after solution is found". Use theClassic
strategy until a zero is about to be swapped into the last diagonal entry of H. Then instead of swapping in that zero and terminating, use row operations to improve the last three columns of the table below, until there are no row operations left to perform that improve the diagonal.IDASIF
is an early version of the as-yet untested "Swap, Reduce, Solve" strategy. See the section below, "The Swap, Reduce, Solve Strategy", for details about this strategy.
It is understood that, just based on the description above, IDASIF
is not a well-defined strategy. To learn the details, search improveDiagonalWhenAboutToTerminate
in strategy/strategyv1.go
.
Entries in Table 1
were copied from the output of the test, TestGetRImprovingDiagonal
. In that test, the input to PSLQ is an n-long challenge vector (x, in the notation above) with a known small solution m0, i.e. <x,m0> = 0. Each entry of x is chosen from the uniform distribution on [-maxX/2
,maxX/2
], where maxX
is chosen so that the chance of at least one random vector of norm |m0| or less being perpendicular to x is deemed to be about 0.001. The effort that went into this probability calculation is minimal compared to an exact calculation (it's not an easy calculation). But maxX
is in the ballpark of having the desired property.
The metric |largest diagonal element / last|
refers to the diagonal just before PSLQ terminates. | output of PSLQ |
is the norm of the solution PSLQ computes, and | m0 | is the norm of the causal vector PSLQ should ideally find. Note that two rows with the same | m0 | are likely to have the same input and causal relation, especially for large n.
Table 1 - Test results comparing Classic and IDASIF strategies
n | strategy | number of iterations | |largest diagonal element / last| | |output of PSLQ| | | m0 | |
10 | Classic | 82 | 1.000000 | 4.358899 | 4.358899 |
10 | IDASIF | 79 | 1.000000 | 4.358899 | 4.358899 |
10 | Classic | 68 | 5.258257 | 14.491377 | 4.358899 |
10 | IDASIF | 88 | 1.000000 | 4.358899 | 4.358899 |
10 | Classic | 75 | 2.251075 | 4.358899 | 4.358899 |
10 | Classic | 77 | 2.863976 | 4.358899 | 4.358899 |
10 | Classic | 80 | 13.373215 | 21.954498 | 4.358899 |
10 | Classic | 84 | 12.027440 | 39.306488 | 4.358899 |
10 | Classic | 95 | 1.321454 | 4.358899 | 4.358899 |
10 | IDASIF | 102 | 1.000000 | 4.358899 | 4.358899 |
10 | IDASIF | 89 | 1.000000 | 4.358899 | 4.358899 |
10 | IDASIF | 90 | 1.000000 | 4.358899 | 4.358899 |
10 | IDASIF | 92 | 1.000000 | 4.358899 | 4.358899 |
10 | IDASIF | 95 | 1.000000 | 4.358899 | 4.358899 |
10 | Classic | 60 | 3.074540 | 4.358899 | 4.358899 |
10 | IDASIF | 83 | 1.000000 | 4.358899 | 4.358899 |
40 | Classic | 473 | 1296.976910 | 1297.015035 | 8.485281 |
40 | IDASIF | 3267 | 4.117404 | 13.038405 | 8.485281 |
45 | Classic | 570 | 1142.274989 | 1142.279300 | 9.273618 |
45 | IDASIF | 4321 | 2.816535 | 9.273618 | 9.273618 |
50 | Classic | 640 | 1242.966991 | 1242.967015 | 9.848858 |
50 | IDASIF | 5432 | 5.197691 | 15.491933 | 9.848858 |
55 | Classic | 752 | 3962.335786 | 3962.347284 | 10.198039 |
55 | IDASIF | 6626 | 7.424804 | 17.916473 | 10.198039 |
55 | Classic | 760 | 2688.422980 | 2688.425190 | 10.198039 |
55 | Classic | 783 | 1051.430636 | 1051.434734 | 10.198039 |
55 | IDASIF | 6921 | 6.736039 | 17.233688 | 10.198039 |
55 | IDASIF | 6921 | 6.969158 | 17.972201 | 10.198039 |
55 | Classic | 757 | 3503.093034 | 3503.093062 | 10.198039 |
55 | IDASIF | 6875 | 7.055695 | 16.431677 | 10.198039 |
55 | Classic | 745 | 1626.754306 | 1626.761814 | 10.198039 |
55 | IDASIF | 6971 | 5.948555 | 16.248077 | 10.198039 |
70 | Classic | 1000 | 2845.110951 | 2845.160101 | 11.313708 |
70 | IDASIF | 10814 | 12.968656 | 22.693611 | 11.313708 |
80 | Classic | 1255 | 22622.052275 | 22622.076784 | 11.958261 |
80 | IDASIF | 13058 | 22.895246 | 29.580399 | 11.958261 |
90 | Classic | 1502 | 21569.471628 | 21571.072783 | 12.767145 |
90 | IDASIF | 15567 | 30.156552 | 30.397368 | 12.767145 |
100 | Classic | 1705 | 32151.600720 | 32151.610628 | 13.453624 |
100 | IDASIF | 17841 | 46.556258 | 46.786750 | 13.453624 |
100 | Classic | 1662 | 61586.231676 | 61586.231976 | 13.453624 |
100 | IDASIF | 17805 | 37.646748 | 37.920970 | 13.453624 |
100 | Classic | 1735 | 44705.980105 | 44706.686144 | 13.453624 |
100 | IDASIF | 19397 | 35.389694 | 35.651087 | 13.453624 |
100 | Classic | 1733 | 45292.389840 | 45292.405809 | 13.453624 |
100 | IDASIF | 20381 | 40.390584 | 42.142615 | 13.453624 |
An advanced version of "IDASIF" from the table above can be implemented using this repository. This strategy, called "Swap, Reduce, Solve" (SRS), has two phases. Phase 1 refers to the time before the maximum number of possible solutions of <x,m>=0 is found; and phase 2 refines those solutions.
A summary of phases 1 and 2 is:
- Phase 1: H contains non-zero elements in its last row, row n. Under the right conditions, row combinations of non-zero elements of row n and diagonal can be used to reduce the absolute values of diagonal elements of H.
- Phase 2: H no longer contains non-zero elements in row n. For any column with zero in row n (which is all columns in phase 2), the smallest index, i, of a non-zero entry, is the index of a column in B with a solution of <x,m>=0.
In both phases, the priority is to "swap" values of diagonal elements to make them increase towards the bottom right. In phase 1, when no further swaps can be made on adjacent rows that improve the diagonal of H, diagonal elements are reduced using a row operation involving the diagonal element and the last row of H. In phase 2, the equivalent situation terminates the entire algorithm.
In phase 1 only, when there are no swaps to perform, the SRS strategy (reluctantly) reduces a diagonal element with a row operation involving row n. Thus the second priority is to "reduce", and sometimes reducing creates a solution in B. Hence the name, "Swap, Reduce, Solve". As noted earlier, phase 2 has no reductions, so the only option is to swap or terminate. Still, "Swap, Reduce, Solve" is an accurate overall description.
For now, we will focus on the first phase of SRS. Sub-section headings below indicate which phase the section refers to.
Once the right-most column is fully reduced, putting a zero in Hn,n-1, the same procedure that did that for column n-1 works for column n-2, then n-3, etc. This procedure only works in columns to the right of which row n is zero. Though the zeroes do appear in row n eventually, they only appear when it improves the diagonal of H.
The reason that reducing (the absolute value of) diagonal elements of H makes progress is that it isolates Hn-1,n-1 as an increasingly large diagonal element, compared to the others, which are being reduced. Remember, a corollary of lemma 10 in the 1999 paper analyzing PSLQ is that the solution is optimal when Hn-1,n-1 is the largest diagonal element.
The technique for reducing |Hn-p,n-p| involves a continued fraction approximation of Hn-p,n-p / Hn,n-p for p=2,3,.... It replaces Hn-p,n-p and Hn,n-p with errors from successive iterations of this approximation. For example, if Hn-p,n-p=.5 and Hn,n-p=.3, a row operation would replace Hn-p,n-p by .5-.3=.2; and a second one would replace Hn,n-p with .3-.2=.1, etc. If these row operations terminate with a zero in Hn-p,n-p, a row swap puts that zero in Hn,n-p and keeps Hn-p,n-p non-zero.
If and when |Hn-p,n-p| is small compared to its neighbor to the left, |Hn-p,n-p-1|, the reduction can stop, because what makes a swap of rows n-p-1 and n-p reduce the upper-left diagonal element, |Hn-p-1,n-p-1|, is a small enough Euclidean length of the vector, (Hn-p,n-p-1, Hn-p,n-p). When to stop reducing is a parameter of the strategy that governs the choice of row operations. Later, we will specify the details of the "Swap, Reduce, Solve" strategy, which say to reduce down to near the precision of the numbers in H. But that is just one strategy, and others may be recommended that stop reducing well above the numerical precision.
If Hn,n-p starts off at zero, no reduction can occur in column n-p, but reduction can be attempted in column n-p-1. This is because the condition that makes the reductions of Hn-2,n-2, Hn-3,n-3 ... possible is that there are only zeroes to the right of these entries and their counterparts in row n of the same column. These zeroes enable arbitrary integer row operations involving rows n-p and n for p=2,3,... until for some p, a zero cannot be made to appear in Hn,n-p. For that p, |Hn-p,n-p| is reduced but no reduction of the same kind is possible in columns to the left of column p.
Once a zero appears in Hn,n-1, it makes reduction work for Hn-2,n-2 and Hn,n-2. The zero in (xB)n-1 assures that row operations can put a zero in Hn,n-2 while reducing Hn-2,n-2, provided x contains only integers (more on this below). There is no guarantee that reducing Hn-3,n-3 can put a zero in Hn,n-3, but if it can, that zero makes reduction possible in column n-4, etc.
Let's pause here to note what happens to H in large dimensions, like 50 and above. In spite of the best efforts to move large diagonal elements towards the bottom right using adjacent-row swaps, the largest diagonal elements end up in the upper left. Even small numbers in the sub-diagonal, one below the main diagonal -- typically a hundredth to a tenth the size of the main diagonal elements -- prevent swaps of larger diagonal elements from left to right. Diagonal improvement via standard row swaps comes to a halt.
All this changes, once small numbers appear in the diagonal close to the right-hand side of H. Row swaps are unstuck, as they can readily move these small diagonal elements to the upper left. After that is done, new large diagonal elements appear in Hn-2,n-2, Hn-3,n-3 ... and the cycle of diagonal reduction and standard row-swaps repeats.
When a zero appears in Hn,n-1, every entry of column n-1 of H is zero except Hn-1,n-1. This means that, since xBH=0, (xBH)n-1=0, and therefore (xB)n-1=0 -- making column n-1 of B an integer-valued solution of <x,m>=0. All this has been stated above in the section "How PSLQ Works".
But the same that goes for column n-1 of H goes for the other columns. Once a zero appears in Hn,n-p, there is
- An integer matrix D with determinant 1 or -1 and inverse E, and
- A non-integer matrix N with small entries off the diagonal
for which DHN has zeroes in column n-p, except (DHN)n-p,n-p≠0.
On the final step of PSLQ, A is replaced by DA, H by DHN and B by BE. The fact that (xB)n-p=0 means that column n-p of B is a solution of <x,m> = 0. After these replacements, in every column n-p with Hn,n-p=0, column n-p of B is a solution of <x,m> = 0.
It is expected, but not proven here, that when PSLQ terminates this way, an analog of lemma 10 from the 1997 analysis of PSLQ extends to |Hn-p,n-p|: the solution obtained by putting a zero in Hn,n-p has norm 1/|Hn-p,n-p|; but in this case, that norm is distorted to the extent that N is not a rotation. If so, it is important that D be a full Hermite reduction of H as described in the original 1992 PSLQ paper, making the interior of H below the diagonal small so that N can have small elements off its diagonal. That way, the actual norm of column n-p of B is as close as possible to 1/|Hn-p,n-p|.
It is now possible to give the details of phase 1. These use "gentle Hermite reduction". The code in this repository supports three kinds of gentle Hermite reduction, along with full Hermite reduction as in the classic PSLQ algorithm: See GetInt64D
for details. Only the first kind of gentle reduction listed below is under active consideration at the moment, for reasons indicated below.
- Reduce the first n-1 rows of H, but not the last row. In the code, this is indicated by the constant,
ReductionAllButLastRow
. - Do not reduce any rows of H, except in the sub-diagonal, and when doing so is necessary to keep the interior of H from blowing up in absolute value. In the code, this is indicated by the constant,
ReductionGentle
. There are signs from experimentation that this kind of reduction requires the use of BigNumbers when computing the Hermite reduction matrix, D. Currently, D is computed as anint64
matrix. - Do not reduce any rows of H, except in the sub-diagonal, period. This is indicated by the constant,
ReductionSubDiagonal
. In the first experiment on live data using this mode, the PSLQ algorithm entered an infinite loop with no changes to H.
During phase 1, the SRS strategy runs in three modes, Swap, Reduce and Solve. Upon exiting Solve mode, a termination check is performed, but Termination Check is not considered a mode, because termination happens just once and it would mess up the name of this strategy. In the description below, "zero" refers to 0 up to the precision of the numbers in H. The modes and transitions between them are as follows.
- Swap: Swap rows (or perform a general integer-valued, unit-determinant row operation) when doing so improves the diagonal of H. Improving the diagonal is defined as starting with |Hj,j| > |Hj+1,j+1| for some j with 1 ≤ j < n-1, performing a row operation and corner removal, and thereby reducing |Hj,j|. The row operation to perform on each iteration is the one that reduces |Hj,j,| by the greatest factor over all choices of j and all operations on rows j and j+1. At the end of each iteration in Swap mode, perform gentle Hermite reduction on the modified rows.
- Reduce: At some point, no swap or other row operation involving adjacent rows among rows 1 through n-1 is left that improves the diagonal of H. Let n-p be the number of the rightmost column for which Hn,n-p is not zero. Reduce Hn-p,n-p against Hp,n-p with continued fraction approximations, until one of the pair reaches a pre-determined, non-zero threshold and Swap mode can reduce |Hn-p-1,n-p-1|; or one of the pair reaches zero. If zero = Hn-p,n-p, or zero < |Hn,n-p| < |Hn-p,n-p|, swap rows n-p and n to keep the diagonal non-zero while minimizing it. Perform gentle Hermite reduction on rows n-p and n.
- Solve: If Hn-p,n-p or Hp,n-p reaches zero in the Reduce stage, a solution of <x,m> = 0 has become available, as described in the section, "A Zero in Row n Generates a Solution". First, perform the Termination Check based on this new solution. Failing that, if the new value of Hn-p,n-p has enabled a row operation to reduce |Hn-p-1,n-p-1|, use that fact to return to the Swap mode. Otherwise, proceed to Reduce mode using Hn-p-1,n-p-1 and Hn,n-p-1.
- Termination Check: If the maximum diagonal element is in a column j for which Hn,j is zero, or if all of row n is zero, terminate the PSLQ algorithm and use the procedure described in the section, "A Zero in Row n Generates a Solution" to generate the available solutions.
Note that after Solve mode puts a zero in row n, Swap mode may overwrite it with corner removal. This happens if, in column n-p with a zero in row n, the diagonal element Hn-p,n-p is small enough that Swap mode performs a row operation on rows n-p-1 and n-p, then removes the corner in Hn-p-1,n-p. In the course of that corner removal, the zero in Hn,n-p is replaced by a non-zero.
The reason to delay the Reduce mode until no row operations are available to Swap mode is that when Reduce mode leads to Solve mode, zeroing out Hn,n-p, the initial value of |Hn-p,n-p| should be as large as possible. Starting with a large |Hn-p,n-p| gives the greatest chance of ending with a large |Hn-p,n-p|. Running in Swap mode increases the diagonal elements in columns like n-p with solutions, as they are on the right side of H where Swap mode is putting large diagonal elements.
The reason to stop reducing Hn-p,n-p against Hn,n-p when one of the pair reaches a pre-determined minimum is to avoid underflow, while introducing small elements into the diagonal of H so the "solved" columns are large by comparison.
Waiting for the maximum diagonal element to appear in a solution column (i.e. one with a zero in row n) seems to offer the best chance of solving the shortest vector problem. But it is not a guarantee of solving it, because only column n-1 contains a diagonal element with the undistorted reciprocal of a solution norm.
As promised, here is an explanation of why both Hn-2,n-2 and Hn-3,n-3 can be reduced given integer-valued input x and a non-zero Hn,n-2 and Hn,n-3. As mentioned above, this is because a zero appears in Hn,n-2 when reducing |Hn-2,n-2|. The key to why that zero appears is that
0 = <((xB)n-2, (xB)n-1, (xB)n), (Hn-2,n-2, Hn-1,n-2, Hn,n-2)>
=<((xB)n-2, 0, (xB)n), (Hn-2,n-2, Hn-1,n-2, Hn,n-2)>
=<((xB)n-2, (xB)n), (Hn-2,n-2, Hn,n-2):
is an integer relation between Hn-2,n-2 and Hn,n-2. This guarantees that Hn-2,n-2 / Hn,n-2 is rational. The row operations that mirror the continued fraction approximation of this ratio put an error of zero in Hn,n-2 (or Hn-2,n-2) on the last of finitely many steps. If the zero appears in Hn-2,n-2, you would just swap rows n-2 and n to put the zero in Hn,n-2.
Since we are contemplating the placement of very small entries in the diagonal of H, it may take several rounds of row swaps, corner removals and reduction of sub-diagonal elements in the same 2x2 sub-matrix before this sub-matrix has its best ordering of diagonal elements. Consider, for example, the 2x2 sub-matrix Mk =
1 | 0 |
.5 | .2 |
After swapping rows and zeroing the corner, Mk+1 =
.5385... | 0 |
.9284... | .3713... |
A new round of row reduction, swap and corner removal finally yields the best form M can take in isolation from the rest of H: Mk+2 =
.4 | 0 |
.2 | .5 |
But there is a way to collapse the two rounds of swap, reduction and corner removal into one "general" (non-swap) row operation: RMkQ =
1 | -2 | 1 | 0 | 0 | 1 | = | .4 | 0 | ||
1 | -1 | .5 | .2 | -1 | 0 | .2 | .5 |
To save operations when putting small elements in the diagonal, it could be worth the while to look for general row operations -- even though it does cost a bit to check for them. The reason small diagonal elements create the need for more than one round of row swaps will become apparent below.
Suppose a small ε1 has just been placed in Hj+1,j+1. The introduction of ε1 changes the balance of the diagonal elements in the 2x2 sub-matrix, Mk, containing t=Hj,j, u=Hj+1,j and ε1=Hj+1,j+1. Using continued fraction reduction, find relatively prime, non-zero integers a and b such that at+bu=ε0 is small. Let R be the 2x2 matrix with rows [a, b] and [-w, v] with minimum |v| and determinant 1. R improves the diagonal of Mk: RMk=
a | b | t | 0 | = | ε0 | b ε1 | |
-w | v | u | ε1 | uv-tw | v ε1 |
After zeroing out the upper right corner, the diagonal elements of Mk+1 have absolute values
|Hj,j| ← |ε2| := sqrt(ε02 + b2 ε12) and
|Hj+1,j+1| ← |ε3| := |t ε1 / ε2| (since |det(Mk+1)| = |det(Mk)| =|t ε1|)
Let's compare ε2 to what |Hj,j| gets after a row swap and corner removal, which yeilds:
|Hj,j| ← ε4 := sqrt(u2 + ε12)
|Hj+1,j+1| ← ε5 := |t ε1 / ε4|
The row operation, R, performs better than a swap if it reduces |Hj,j| more, i.e.
|ε2| < |ε4| ⇔ sqrt(ε02 + b2 ε12) < sqrt(u2 + ε12)
⇔ ε02 + b2 ε12 < u2 + ε12
⇔ (b2 - 1) ε12 < u2 - ε02
From this we can conclude that
-
The general row operation, R, performs best when b and ε0 are small. This is possible when -a/b is a good approximation of t/u with a small denominator -- the kind you get from continued fractions.
-
b is not a unit, because that would be incompatible with the fact that after Hermite reduction, or reduction of just the sub-diagonal of H, |u| ≤ |t|/2. If you set b to a unit, you get a contradiction as follows. Since R is not a row swap, a and b are not zero. Therefore,
b2 = 1 ⇒ |a| ≥ |b| = 1
⇒ |ε0| ≥ min(|at+u|, |at-u|) ≥ min(|t+u|, |t-u|) ≥ |t|/2 (since |u| ≤ |t|/2)
⇒ u2 - ε02 ≤ u2 - t2/4 (since |ε0| ≥ |t|/2)
⇒ (b2-1) ε12 < u2 - ε02 ≤ u2 - t2/4 (since R is better than a row swap)
⇒ 0 < u2 - ε02 ≤ u2 - t2/4 (since b2 = 1)
⇒ t2/4 < u2 (using the two ends of the inequality on the previous line)
⇒ |u| > |t|/2,
which contradicts the premise that |u| ≤ |t|/2
- Since |b| ≥ 2 as just shown,
(b2 - 1) ε12 < u2 ⇒ 3 ε12 < u2,
so only row swaps make sense unless |ε1| < |u| / sqrt(3).
- Since |b| ≥ 2 and the condition (b2 - 1) ε12 < u2 - ε02 is what makes R better than a row swap, the range of values of b to consider as the upper-right entry of R satisfies
4 ≤ b2 ≤ 1 + (u2 - ε02) / ε12 ≤ 1 + u2 / ε12
⇒ 2 ≤ |b| ≤ sqrt(1 + u2 / ε12),
which gives a stopping condition for the reduction of t and u.
The last bullet puts us in a position to circle back to a claim above. The claim was that introducing small elements into the diagonal of H creates the need for multiple rounds of swaps, corner removal and reduction, unless general row operations are used. It is believed that each such round corresponds to one round of continued fraction approximation of t and u. Though this is not proven here, the last bullet shows that when |ε1| is small (compared to |u|), an R with a large upper-right entry b still has the potential to out-perform a row swap. Large entries comparable in absolute value to sqrt(1 + u2 / ε12) only appear in R after multiple rounds of continued fraction approximation.
To take advantage of the foregoing analysis, a strategy, like SRS, that places very small elements in the diagonal of H should save time using general row operations. After placing ε1 in Hj+1,j+1, the strategy would reduce t=Hj,j against u=Hj+1,j, storing the reduced entry in Hj,j and the version of R that puts it there at each stage. If the smallest absolute value of the stored Hj,j entries is smaller than sqrt(u2 + ε12), the strategy would use the corresponding R instead of a row swap in the next PSLQ iteration.
Phase 2 is, thankfully, much easier to explain than phase 1. As noted earlier, phase 2 begins when all columns of H represent solutions of <x,m>=0, and no swapping of adjacent diagonal elements can improve the diagonal of H. In phase 2, any two rows j0 < j1 < n for which the Euclidean length L1 of (Hj1,j0, Hj1,j0+1, ... Hj1,j1) is less than L0 = |Hj0,j0| can be swapped. After performing this swap and rotating to remove the non-zero elements to the right of Hj0,j0, |Hj0,j0| = L1 < L0 = |Hj1,j1|. This improves the diagonal of H because
- Before swapping: |Hj1,j1| ≤ L1 < L0 = Hj0,j0. Diagonal elements Hj0,j0 and Hj1,j1 are out of order.
- After swapping: |Hj1,j1| = L0 > L1 = Hj0,j0. Diagonal elements Hj0,j0 and Hj1,j1 are now in order.
In phase 2, each possible pair, (j0, j1), is ranked by how large L0/L1 is -- the larger the better. The pair with the largest L0/L1 is swapped. If no pair has L0/L1 > 1, phase 2 and the entire algorithm terminates.
Phase 2 works surprisingly well, albeit slowly. The reason it works well is the same reason it works slowly: There is no shortage of non-adjacent row swaps to perform, even though each requires not just one sub-diagonal element to be accounted for when computing L1, but j1 - j0 of them. The abundance of possible non-adjacent row swaps makes for slow, steady progress. The time it would take to terminate phase 2 may still be polynomial, as phase 1 probably is, but the polynomial would have a degree one higher than that of phase 1 because it operates on arbitrary pairs of rows, not single rows and their immediate successors.
Since the inputs for high-dimension problems are exquisitely precise, so too are the elements of H during phase 1. This enables the algorithm to recognize when a solution is found by the fact that an entry in the last row of H is essentially zero.
After phase 1, however, there is no longer a need to recognize solutions. The solutions, which already lie in the columns of B, are just being combined by integer column operations (whose inverses are row operations in H). H is no more than a rough guide, relatively speaking, for which rows to swap.
Because H no longer needs to be kept with high precision, the bignumber
package used in phase 1 is no longer needed. H can be kept in float64
or even float32
throughout phase 2. However, the repository does not yet take advantage of this insight.
Initial experiments with SRS have shown that it finds solutions in higher degrees than "IDASIF". The building blocks of phase 1 can be found in the BottomRightOfH
and RowOpGenerator
in the code. Phase 2 uses HPairStatistics
. Details on the performance of SRS, and actual code for SRS, can be obtained under a separate, individually negotiated, license.
To run PSLQ using this repository as a library, you can emulate the way the tests in pslqops/run_test.go
and strategy/strategy_test.go
use pslqops.OneIteration
. See below the overview of the pslqops
and strategy
packages, and the bignumber
and bigmatrix
packages they depend on.
The bignumber
package enables computation of sums, differences, products, quotients and square roots of numbers with arbitrary precision. The precision must be set at most once (it has a default of 1000 bits) using the function, bignumber.Init
. bignumber
also implements operations between bignumber
and int64
instances, so PSLQ can run a bit faster before it switches over to using bignumber
for almost all operations, deep into most runs.
bignumber
is similar to the native golang big.Float
, except that
- Overall minimum precision is set for all instances of
bignumber
, whereas the precision ofbig.Float
is per instance. - There is hereby an explicit guarantee that
bignumber
instances initialized withint64
instances, and any combinations of these, are integer-valued with no round-off error. The underlyingbig.Int
incorporated intobignumber
makes this self-evident by reading the code. Though this is most likely true ofbig.Float
, it is not guaranteed as far as we know.
Though bignumber
has a few constructors, the one the pslqops
package uses to take input is the one that parses base 10 (decimal) string input into a bignumber
.
The bigmatrix
package enables multiplication, addition and subtraction of matrices with entries that are bignumber
instances. It also implements operations between bignumber
instances and int64
instances, so PSLQ can run a bit faster before it switches over to using bignumber
for almost all operations, deep into most runs.
Though bigmatrix
has a few constructors, the one the pslqops
package uses to take input is the one that parses arrays of base 10 (decimal) string inputs into a bigmatrix
.
The pslqops
package contains all the building blocks of PSLQ, except for non-standard strategies for choosing row operations (see the strategy
package for those).
This package includes
New
for constructing apslqops.State
, which keeps track of the matricesx
,B
,A
andH
.New
takes an array of strings representing the input to PSLQ in decimal form.pslqops.State.OneIteration
, the top-level function that performs one iteration of PSLQ.
OneIteration
takes as an argument a function, getR
, that examines H and returns R
, a row operation that performs a row operation on H. In the classic PSLQ from the original 1992 PSLQ paper, R is a swap of adjacent rows j and j+1 for which a certain quantity is maximized (see pslqops.GetRClassic
or the original 1992 PSLQ paper). Other rules for choosing R
are implemented in the strategy
package. One of these strategies is what Table 1
shows results for in rows labeled IDASIF
.
A point of confusion could be that getR
does not return anything called "R". It returns a RowOperation
type saying what rows to operate on and what matrix, or permutation, to apply. That's OK, it's still an R
matrix -- in the sense that the original 1992 PSLQ paper uses that notation -- in the form that OneIteration
accepts.
PSLQ maintains invariants like equation 2, xBH = 0, which you can verify with GetObservedRoundOffError
. Another invariant verifier is CheckInvariants
, which verifies that B = A-1 and that the upper right of H contains zeroes, up to round-off error.
The strategy
package is where all the fun ideas for improving the empirical performance of PSLQ are defined. These are the functions passed to pslqopa.OneIteration
as parameter getR
. This package is in flux as new ideas are tried. In order to avoid making Table 1
out of date, only the IDASIF
strategy (constant improveDiagonalWhenAboutToTerminate
in strategyv1.go
) will necessarily be retained as-is.
All the mathematical variable names in the original PSLQ paper are incorporated into the golang variable and/or function names in the source code. The main examples are
- the matrices A, B, D, E, G, H and R have variable and/or function names to match.
- the vectors s and x have variable and/or function names to match
Though there are exceptions, the rule of thumb is, if a variable is mentioned in the paper, it is used under the same name in the code; but not vice-versa.
The original PSLQ paper and 1999 paper analyzing PSLQ cover a variety of properties of the H matrix. But it was left to later research to discover a key fact about the diagonal of H: The reciprocal of the largest diagonal element in H is a bound on the size of any solution.
This section fills in gaps like this in the two papers, using other references and original results.
Here we present one geometric view of PSLQ. There is at least one other geometric view, not covered in detail here: PSLQ finds an integer matrix with determinant 1 whose columns approximate the solution plane,
S = {m : <x,m> = 0}
So what is presented in detail here is not the geometric view of PSLQ, but it is one very appealing interpretation.
PSLQ computes a matrix, Ak, at every iteration k. This "A" is the same A as in the PSLQ paper, in the invariants above and in the section below, "A Sharper Lower Bound on the Smallest Solution While PSLQ is Running" -- the "Sharper Bound" section for short. Here as in that section, the subscript k is useful to track A through different iterations k=1,2,3,... of PSLQ.
Successive Ak get closer and closer to a change of basis, followed by a rotation and rounding, when applied to S. To see why, let
- (Hx)p be column p of Hx for p=1,...,n-1
- m = ∑p yp (Hx)p be an arbitrary element of S
Then Akm = Hk(QkHxtm) (equation 9 from the "Sharper Bound" section)
The change of basis comes from the product Hxtm in the right-hand side of equation 9. In the context of Akm, m is expressed in terms of the basis (e1, ..., en). But Hxtm gives m in terms of the basis ((Hx)1, ..., (Hx)n-1). In other words,
(Hxtm)i = yi (equation 3)
The reason for this is that
HxtHx = In-1,
as noted in section 3 of the 1992 PSLQ paper. The following calculation uses this identity to prove equation 3:
(Hxtm)i = (Hxt (∑p yp (Hx)p)i
= (∑p yp Hxt (Hx)p)i
= yi
In equation 9, once Hxt applies a change of basis to m, the result is rotated by Qk, then dilated with error by Hk. The fact that Qk is a rotation matrix is explained in the "Sharper Bound" section. The dilation comes from the diagonal elements of Hk, and the error comes from the off-diagonal elements -- including all of row n (so there are really just n-1 meaningful entries in Akm).
Some error is necessary because the left-hand side of equation 9 is an integer matrix. This means that the error in the off-diagonal elements of Hk can be considered to be a rounding error. But this rounding error decreases with each iteration of the PSLQ algorithm, because Hk tends towards a diagonal matrix as k increases.
In summary, Akm is m written as a combination of the columns of Hx, rotated and dilated with rounding error.
There is a sharper bound than 1/|H| (from the original 1992 PSLQ paper) on the size of a solution while the algorithm is still running (i.e., when Hk has no 0s in its diagonal -- a fact used below). This bound,
1/max(|H1,1|, |H2,2|, ..., |Hn-1,n-1|) ≤ |m| for any solution m of <x, m> = 0,
is found, among other places, on pages 97-99 of linear Algebra in Situ, CAAM 335, Fall 2016 by Steven J. Cox. This is a textbook that covers many topics, including QR decomposition. QR decomposition is the same as LQ decomposition, used in PSLQ, except every matrix is transposed. Because the overall topic is QR decomposition in this work, every matrix in the PSLQ algorithm is transposed there; and many are renamed. In what follows, the argument in "Linear Algebra in Situ" is repeated here, but in the LQ context, using similar names to those in the original PSLQ paper and in the source code of this repository.
The notation used below follows the original PSLQ paper, except many matrices are indexed by an iteration number denoted k. Initial matrices are:
- x, the input to PSLQ. It is a unit vector of real numbers, none of which is 0.
- Hx is the initial value of the n x n-1 matrix H.
- P = HxHxt
Below is notation for a specific iteration k of the PSLQ algorithm as presented in the original PSLQ paper. k starts at 1 (as opposed to 0). If k = 1, Hk-1 = Hx.
- Step 1
- Hk is the n x n-1 matrix H after iteration k.
- Dk is the n x n integer matrix used to update Hk-1 in step 1 of iteration k.
- Step 2
- j is the integer selected in step 2 of iteration k.
- Step 3
- Rk is the n x n permutation matrix such that RkM swaps rows j and j+1 of M. The PSLQ paper names this Rj, after the starting index j of the row swap. In what follows we need to track R over multiple iterations, so the k subscript is necessary.
- Gk is the n-1 x n-1 orhtogonal matrix that the PSLQ paper calls Gj. The same comment about subscript j vs. k applies to G that applied to R.
Using this notation, iteration k can be interpreted as:
- H <- DkHk-1. H is an intermediate value, not quite Hk yet.
- Choose j so Rk and Gk are defined.
- Hk <- RkHGk = RkDkHk-1Gk
After iteration k,
Hk = RkDkHk-1Gk
= RkDkRk-1Dk-1Hk-2Gk-1Gk
= ...
= RkDkRk-1Dk-1...R1D1 Hx G1...Gk-1Gk (equation 4)
Let Ak and Qk-1 be what lie to the left and right of Hx, respectively, in equation 4:
- Ak = RkDkRk-1Dk-1...R1D1
- Qk = (G1...Gk-1Gk)-1
Ak is the same "A" as in the original PSLQ paper.
Computation of the bound mentioned at the beginning of this section,
1/max(|H1,1|, |H2,2|, ..., |Hn-1,n-1|) ≤ |m| for any solution m of <x, m> = 0 (equation 5),
begins with the LQ decomposition of AkHx:
Hk = AkHxQ-1
AkHx = HkQ (equation 6)
Equation 6 is an LQ decomposition of non-singular AkHx, because
- Ak is an n x n integer matrix with determinant 1, like all of the Ri and Di in the original PSLQ paper.
- Qk is orthonormal, like all of the Gi in the original PSLQ paper.
As noted earlier, the PSLQ paper defines a matrix P = HxHxt. P fixes any m for which <x,m> = 0. In other words,
xm = 0 ⇒ Pm = m (equation 7)
From equation 7 comes the following proposition: If (Akm)p,1 = 0 for p < i, then
(Akm)i,1 = (Hk)i,i (QkHxtm)i,1 (equation 8)
Substituting from equation 7 in the first line and equation 6 in the fourth line,
Akm = AkPm
= Ak(HxHxt)m
= (AkHx)(Hxtm)
= (HkQ)(Hxtm)
= Hk(QkHxtm) (equation 9)
Using equation 9, we will now calculate (Akm)i,1, starting with i = 1, until (Akm)i,1 ≠ 0. The index p in the summations below ranges from 1 to i, after which (Hk)i,p = 0.
If i = 1, then using equation 9 in the second line below,
(Akm)i,1 = (Akm)1,1
= ∑p (Hk)1,p (QkHxtm)p,1
= (Hk)1,1 (QkHxtm)1,1 (equation 10)
If (Akm)1,1 = 0, we continue with i = 2.
0 = (Akm)1,1 = (Hk)1,1 (QkHxtm)1,1
Since Hk has no 0s on its diagonal,
(QkHxtm)1,1 = 0 (equation 11)
(Akm)i,1 = (Akm)2,1
= ∑p (Hk)2,p (QkHxtm)p,1
= ((Hk)2,1)(0) + (Hk)2,2 (QkHxtm)2,1
= (Hk)2,2 (QkHxtm)2,1 (equation 12)
If (Akm)1,1 = (Akm)2,1 = 0, we continue with i = 3.
0 = (Akm)2,1 = (Hk)2,2 (QkHxtm)2,1
From equation 11 and since Hk has no 0s on its diagonal,
(QkHxtm)1,1 = (QkHxtm)2,1 = 0 (equation 13)
(Akm)i,1 = (Akm)3,1
= ∑p (Hk)3,p (QkHxtm)p,1
= ((Hk)3,1)(0) + ((Hk)3,2)(0) + (Hk)3,3 (QkHxtm)3,1
= (Hk)3,3 (QkHxtm)3,1
This reasoning continues until the first i for which (Akm)i,1 ≠ 0. The formula for (Akm)i,1 is
(Akm)i,1 = (Hk)i,i (QkHxtm)i,1 (proving equation 8)
Recall that the bound to prove is
1/max(H1,1, H2,2, ..., Hn-1,n-1) ≤ |m| for any solution m of <x, m> = 0 (repeating equation 5)
Let
- i be the smallest index for which (Akm)i,1 ≠ 0
- (QkHxt)i denote row i of QkHxt
Note that
- Ak and m are non-zero integer matrices and Ak is non-singular, which makes the first line work in the calculation below
- Equation 8 from the section, "A Formula for (Akm)i,1", permits the replacement of (Akm)i,1 in the second line below.
- Qk is a product of the inverses of matrices Gk, defined in equations 10 through 15 of the original PSLQ paper. These equations define Gk as a rotation matrix. This makes Qk a rotation matrix, which is one of two facts used in the fourth line below to conclude that the norm of a row in QkHxt is 1.
- HxtHx = In-1, which is the second fact needed to conclude that the norm of a row in QkHxt is 1.
1 ≤ |(Akm)i,1|
= |(Hk)i,i (QkHxtm)i,1|
≤ |(Hk)i,i| |(QkHxt)i| |m|
= |(Hk)i,i| |m|
≤ max(H1,1, H2,2, ..., Hn-1,n-1) |m| (proving equation 5)
This section explains the ideas behind the alternative row operations for improving the diagonal of H. As seen in the previous section, "A Sharper Lower Bound on the Smallest Solution While PSLQ is Running", reducing the maximum diagonal element of Hk sharpens the bound on the smallest solution m to the integer relation problem, <x,m> = 0. This raises the question, when would a given row swap reduce the maximum diagonal element of Hk and thereby reduce this lower bound?
Following the notation in a 1999 paper analyzing PSLQ, by the same authors as the original PSLQ paper, the two rows and columns involved in both the row swap and corner steps of an iteration of PSLQ are
α | 0 |
β | λ |
The 1999 paper also defines δ = sqrt(β2 + λ2).
The 1999 paper analyzing PSLQ derives the formula
δ | 0 |
α β / δ | -α λ / δ |
for the result of the row swap and cornering. Up to absolute value, Λ1 is obtained by left-multiplying Λ0 by
|δ / α| | 0 |
0 | |α / δ| |
The row swap and corner steps can be considered to reduce the maximum diagonal element if
max(|δ|, |α λ / δ|) < max(|α|, |λ|) (equation 14)
The row swap and corner steps reduce the maximum diagonal element if and only if
|α| > |δ| > |λ| (equation 15)
To prove this, first assume equation 14 and argue for equation 13. Equation 14 precludes the possibility that |α| < |λ|, since
|α| < |λ| ⇒ |λ| = max(|α|, |λ|) > max(|δ|, |α λ / δ|) ≥ |δ| = sqrt(β2 + λ2) ≥ |λ|, a contradiction.
Therefore, |α| ≥ |λ|. Using equation 14,
|α| = max(|α|, |λ|) > max(|δ|, |α λ / δ|)
⇔ |α| > |δ| and |α| > |αλ / δ|
⇔ |α| > |δ| and 1 > |λ / δ|
⇔ |α| > |δ| and |δ| > |λ| (a restatement of equation 15)
For the reverse direction, assume equation 15. Then since |α| > |δ|,
|α λ / δ| > |δ λ / δ| = |λ|
Therefore,
max(|δ|, |α λ / δ|) ≥ max(|δ|, |λ|)
= max(sqrt(β2 + λ2), |λ|)
= sqrt(β2 + λ2)
= |δ| (equation 16)
Equation 16 selects which of max(|δ|, |α λ / δ|) is the maximum, namely
max(|δ|, |α λ / δ|) = |α λ / δ| (equation 17)
Using equation 17 and the fact from the premise, equation 15, that |λ| < |δ|,
max(|δ|, |α λ / δ|) = |α λ / δ| < |α| ≤ max(|α|, |λ|) (equation 18)
Equation 18 proves equation 14.