17 void RLLL::update(VectorType &H,
21 const int n = B.cols();
26 B.col(
k).swap(B.col(
k - 1));
30 H1(
k - 1) = H(
k) + std::pow(
M(
k,
k - 1), 2) * H(
k - 1);
32 M1(
k,
k - 1) *= H(
k - 1) / H1(
k - 1);
33 H1(
k) = H(
k - 1) - std::pow(M1(
k,
k - 1), 2) * H1(
k - 1);
35 for (
int i =
k + 1;
i <
n; ++
i)
37 M1(
i,
k - 1) =
M(
i,
k - 1) * M1(
k,
k - 1) +
M(
i,
k) * H(
k) / H1(
k - 1);
41 for (
int j = 0;
j <=
k - 2; ++
j)
43 M1(
k - 1,
j) =
M(
k,
j);
44 M1(
k,
j) =
M(
k - 1,
j);
51 void RLLL::size_reduce(MatrixType &
M,
56 const long int c = std::round(
M(
k,
j));
57 B.col(
k) -=
c * B.col(
j);
58 U.col(
k) -=
c * U.col(
j);
59 for (
int l = 0;
l <=
j; ++
l)
61 M(
k, l) -=
c *
M(
j, l);
67 const double &delta) :
B(B0),
68 U(Eigen::Matrix<long int, Eigen::Dynamic, Eigen::Dynamic>::Identity(B0.cols(), B0.cols()))
70 assert(delta >= 0.5 && delta <= 1.0 &&
"delta must be in [0.5 1]");
72 const int n = B0.cols();
73 assert(n <= B0.rows() &&
"B.rows() must be >= B.cols()");
76 VectorType H(VectorType::Zero(n));
77 for (
int j = 0;
j <
n; ++
j)
79 H(
j) =
B.col(
j).squaredNorm();
85 MatrixType
M(MatrixType::Identity(n, n));
86 for (
int j = 0;
j <
n; ++
j)
88 for (
int i =
j + 1;
i <
n; ++
i)
93 for (
int k = 0;
k <=
j - 1; ++
k)
100 H(
i) -= std::pow(
M(
i,
j), 2) * H(
j);
111 if (fabs(
M(
k,
k - 1)) > 0.5)
113 size_reduce(
M,
k,
k - 1);
116 if (H(
k) < (delta - std::pow(
M(
k,
k - 1), 2)) * H(
k - 1))
119 U.col(
k).swap(U.col(
k - 1));
120 k = std::max(1,
k - 1);
125 for (
int j =
k - 2;
j >= 0; --
j)
127 if (fabs(
M(
k,
j)) > 0.5)
129 size_reduce(
M,
k,
j);
136 const double err = (B0.lu().solve(
B) - U.cast<
double>()).norm() / U.cast<
double>().norm();
137 if (err > FLT_EPSILON)
139 std::cout <<
"RLLL relative error= " << std::setprecision(15) << std::scientific << err <<
" > " << FLT_EPSILON << std::endl;
140 assert(
false &&
"Relative error too large. RLLL failed.");
143 const double absDetU(fabs(U.cast<
double>().determinant()));
144 if (fabs(absDetU - 1.0) > FLT_EPSILON)
146 std::cout <<
"|det(U)|= " << std::setprecision(15) << std::scientific << absDetU << std::endl;
147 assert(
false &&
"U is not unimodular. RLLL failed.");
152 const typename RLLL::MatrixType& RLLL::reducedBasis()
const
158 const Eigen::Matrix<long int, Eigen::Dynamic, Eigen::Dynamic>& RLLL::unimodularMatrix()
const
RLLL(const MatrixType &B0, const double &delta)
initial point of the source segment B