22 const int n =
B.cols();
27 B.col(k).swap(
B.col(k - 1));
31 H1(k - 1) = H(k) + std::pow(M(k, k - 1), 2) * H(k - 1);
33 M1(k, k - 1) *= H(k - 1) / H1(k - 1);
34 H1(k) = H(k - 1) - std::pow(M1(k, k - 1), 2) * H1(k - 1);
36 for (
int i = k + 1; i < n; ++i)
38 M1(i, k - 1) = M(i, k - 1) * M1(k, k - 1) + M(i, k) * H(k) / H1(k - 1);
39 M1(i, k) = M(i, k - 1) - M(i, k) * M(k, k - 1);
42 for (
int j = 0; j <= k - 2; ++j)
44 M1(k - 1, j) = M(k, j);
45 M1(k, j) = M(k - 1, j);
68 const double &delta) : B(B0),
69 U(
Eigen::Matrix<long long int,
Eigen::Dynamic,
Eigen::Dynamic>::Identity(B0.cols(), B0.cols()))
71 assert(delta >= 0.5 && delta <= 1.0 &&
"delta must be in [0.5 1]");
73 const int n = B0.cols();
74 const int dim = B0.rows();
80 assert(dim <= B0.rows() &&
"B.rows() must be >= B.cols()");
85 orthonormalBasis= B0.householderQr().householderQ();
86 orthonormalBasis= orthonormalBasis.block(0,0,dim,n).eval();
89 B0InNewCoords= orthonormalBasis.transpose()*B0;
91 Eigen::MatrixXd reducedB0InNewCoords=
RLLL(B0InNewCoords,delta).
reducedBasis();
93 B = orthonormalBasis*reducedB0InNewCoords;
97 std::vector<int> indices(n);
98 Eigen::Matrix<long long int, Eigen::Dynamic, Eigen::Dynamic> preU(n,n);
99 for(
int i=0; i<n; ++i)
101 for (
int i=0;i<2;++i) {
109 U = Eigen::Matrix<long long int, Eigen::Dynamic, Eigen::Dynamic>::Identity(n, n);
110 for (
int i = 0; i < n; ++i) {
111 B.col(i) = B0.col(indices[i]) / scale;
112 preU.col(i) =
U.col(indices[i]);
117 for (
int j = 0; j < n; ++j) {
118 H(j) =
B.col(j).squaredNorm();
125 for (
int j = 0; j < n; ++j) {
126 for (
int i = j + 1; i < n; ++i) {
130 for (
int k = 0; k <= j - 1; ++k)
134 temp += M(j, k) * M(i, k) * H(k);
136 M(i, j) = (
B.col(i).dot(
B.col(j)) - temp) / H(j);
137 H(i) -= std::pow(M(i, j), 2) * H(j);
148 if (fabs(M(k, k - 1)) > 0.5) {
152 if (H(k) < (delta - std::pow(M(k, k - 1), 2)) * H(k - 1)) {
154 U.col(k).swap(
U.col(k - 1));
155 k = std::max(1, k - 1);
158 for (
int j = k - 2; j >= 0; --j) {
159 if (fabs(M(k, j)) > 0.5) {
168 err = (B0.lu().solve(scale *
B) -
U.cast<
double>()).norm() /
U.cast<
double>().norm();
169 absDetU = fabs(
U.cast<
double>().determinant());
170 if (err < FLT_EPSILON && fabs(absDetU - 1.0) < FLT_EPSILON) {
174 }
while (std::next_permutation(indices.begin(), indices.end()));
177 if (err > FLT_EPSILON) {
178 std::cout <<
"RLLL relative error= " << std::setprecision(15) << std::scientific << err <<
" > "
179 << FLT_EPSILON << std::endl;
180 throw std::runtime_error(
"Relative error too large. RLLL failed.\n");
183 if (fabs(absDetU - 1.0) > FLT_EPSILON) {
184 std::cout <<
"|det(U)|= " << std::setprecision(15) << std::scientific << absDetU << std::endl;
185 throw std::runtime_error(
"U is not unimodular. RLLL failed.\n");