17 const int n =
B.cols();
22 B.col(k).swap(
B.col(k - 1));
26 H1(k - 1) = H(k) + std::pow(M(k, k - 1), 2) * H(k - 1);
28 M1(k, k - 1) *= H(k - 1) / H1(k - 1);
29 H1(k) = H(k - 1) - std::pow(M1(k, k - 1), 2) * H1(k - 1);
31 for (
int i = k + 1; i < n; ++i) {
32 M1(i, k - 1) = M(i, k - 1) * M1(k, k - 1) + M(i, k) * H(k) / H1(k - 1);
33 M1(i, k) = M(i, k - 1) - M(i, k) * M(k, k - 1);
36 for (
int j = 0; j <= k - 2; ++j) {
37 M1(k - 1, j) = M(k, j);
38 M1(k, j) = M(k - 1, j);
61 const double &delta) : B(B0),
62 U(
Eigen::Matrix<long long int,
Eigen::Dynamic,
Eigen::Dynamic>::Identity(B0.cols(), B0.cols()))
64 assert(delta >= 0.5 && delta <= 1.0 &&
"delta must be in [0.5 1]");
66 const int n = B0.cols();
67 const int dim = B0.rows();
73 assert(dim <= B0.rows() &&
"B.rows() must be >= B.cols()");
78 orthonormalBasis= B0.householderQr().householderQ();
79 orthonormalBasis= orthonormalBasis.block(0,0,dim,n).eval();
82 B0InNewCoords= orthonormalBasis.transpose()*B0;
84 Eigen::MatrixXd reducedB0InNewCoords=
RLLL(B0InNewCoords,delta).
reducedBasis();
86 B = orthonormalBasis*reducedB0InNewCoords;
90 std::vector<int> indices(n);
91 Eigen::Matrix<long long int, Eigen::Dynamic, Eigen::Dynamic> preU(n,n);
92 for(
int i=0; i<n; ++i)
94 for (
int i=0;i<2;++i) {
102 U = Eigen::Matrix<long long int, Eigen::Dynamic, Eigen::Dynamic>::Identity(n, n);
103 for (
int i = 0; i < n; ++i) {
104 B.col(i) = B0.col(indices[i]) / scale;
105 preU.col(i) =
U.col(indices[i]);
110 for (
int j = 0; j < n; ++j) {
111 H(j) =
B.col(j).squaredNorm();
118 for (
int j = 0; j < n; ++j) {
119 for (
int i = j + 1; i < n; ++i) {
123 for (
int k = 0; k <= j - 1; ++k)
127 temp += M(j, k) * M(i, k) * H(k);
129 M(i, j) = (
B.col(i).dot(
B.col(j)) - temp) / H(j);
130 H(i) -= std::pow(M(i, j), 2) * H(j);
141 if (fabs(M(k, k - 1)) > 0.5) {
145 if (H(k) < (delta - std::pow(M(k, k - 1), 2)) * H(k - 1)) {
147 U.col(k).swap(
U.col(k - 1));
148 k = std::max(1, k - 1);
151 for (
int j = k - 2; j >= 0; --j) {
152 if (fabs(M(k, j)) > 0.5) {
161 err = (B0.lu().solve(scale *
B) -
U.cast<
double>()).norm() /
U.cast<
double>().norm();
162 absDetU = fabs(
U.cast<
double>().determinant());
163 if (err < FLT_EPSILON && fabs(absDetU - 1.0) < FLT_EPSILON) {
167 }
while (std::next_permutation(indices.begin(), indices.end()));
170 if (err > FLT_EPSILON) {
171 std::cout <<
"RLLL relative error= " << std::setprecision(15) << std::scientific << err <<
" > "
172 << FLT_EPSILON << std::endl;
173 throw std::runtime_error(
"Relative error too large. RLLL failed.\n");
176 if (fabs(absDetU - 1.0) > FLT_EPSILON) {
177 std::cout <<
"|det(U)|= " << std::setprecision(15) << std::scientific << absDetU << std::endl;
178 throw std::runtime_error(
"U is not unimodular. RLLL failed.\n");