Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
Lattices_NEW/RLLL.cpp
Go to the documentation of this file.
1/* This file is part of model.
2 *
3 * MoDELib is distributed without any warranty under the MIT License.
4 */
5
6
7#ifndef model_RLLL_cpp_
8#define model_RLLL_cpp_
9
10#include <RLLL.h>
11
12namespace model
13{
14
15
16 /**********************************************************************/
17 void RLLL::update(VectorType &H,
18 MatrixType &M,
19 const int &k)
20 {
21 const int n = B.cols();
22
23 // B1=B;
24 // B1(:,k-1)=B(:,k);
25 // B1(:,k)=B(:,k-1);
26 B.col(k).swap(B.col(k - 1));
27
28 MatrixType H1 = H;
29 MatrixType M1 = M;
30 H1(k - 1) = H(k) + std::pow(M(k, k - 1), 2) * H(k - 1);
31 // M1(k,k-1)=M(k,k-1)*H(k-1)/H1(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);
34 // for i=k+1:n
35 for (int i = k + 1; i < n; ++i)
36 {
37 M1(i, k - 1) = M(i, k - 1) * M1(k, k - 1) + M(i, k) * H(k) / H1(k - 1);
38 M1(i, k) = M(i, k - 1) - M(i, k) * M(k, k - 1);
39 }
40 // for j=1:k-2
41 for (int j = 0; j <= k - 2; ++j)
42 {
43 M1(k - 1, j) = M(k, j);
44 M1(k, j) = M(k - 1, j);
45 }
46 H = H1;
47 M = M1;
48 }
49
50 /**********************************************************************/
51 void RLLL::size_reduce(MatrixType &M,
52 const int &k,
53 const int &j)
54 {
55
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) // j is already 0-based, so use <=
60 {
61 M(k, l) -= c * M(j, l);
62 }
63 }
64
65 /**********************************************************************/
66 RLLL::RLLL(const MatrixType &B0,
67 const double &delta) : /* init */ B(B0),
68 /* init */ U(Eigen::Matrix<long int, Eigen::Dynamic, Eigen::Dynamic>::Identity(B0.cols(), B0.cols()))
69 {
70 assert(delta >= 0.5 && delta <= 1.0 && "delta must be in [0.5 1]");
71
72 const int n = B0.cols();
73 assert(n <= B0.rows() && "B.rows() must be >= B.cols()");
74
75 // //std::cout<<"here 0"<<std::endl;
76 VectorType H(VectorType::Zero(n));
77 for (int j = 0; j < n; ++j)
78 {
79 H(j) = B.col(j).squaredNorm();
80 }
81
82 //std::cout<<H.transpose()<<std::endl;
83
84 //std::cout<<"here 1"<<std::endl;
85 MatrixType M(MatrixType::Identity(n, n));
86 for (int j = 0; j < n; ++j)
87 {
88 for (int i = j + 1; i < n; ++i)
89 {
90 double temp = 0.0;
91 //std::cout<<i<<" "<<j<<std::endl;
92
93 for (int k = 0; k <= j - 1; ++k) // j is already 0-based, so use <=
94 {
95 //std::cout<<i<<" "<<j<<" "<<k<<std::endl;
96
97 temp += M(j, k) * M(i, k) * H(k);
98 }
99 M(i, j) = (B.col(i).dot(B.col(j)) - temp) / H(j);
100 H(i) -= std::pow(M(i, j), 2) * H(j);
101 }
102 }
103
104 //std::cout<<std::setprecision(15)<<std::scientific<<M<<std::endl;
105 //std::cout<<std::setprecision(15)<<std::scientific<<H<<std::endl;
106
107 // MatrixType M(MatrixType::Identity(n,n));
108 int k = 1;
109 while (k < n)
110 {
111 if (fabs(M(k, k - 1)) > 0.5)
112 {
113 size_reduce(M, k, k - 1);
114 }
115
116 if (H(k) < (delta - std::pow(M(k, k - 1), 2)) * H(k - 1))
117 {
118 update(H, M, k);
119 U.col(k).swap(U.col(k - 1));
120 k = std::max(1, k - 1);
121 }
122 else
123 {
124 // for j=k-2:-1:1
125 for (int j = k - 2; j >= 0; --j)
126 {
127 if (fabs(M(k, j)) > 0.5)
128 {
129 size_reduce(M, k, j);
130 }
131 }
132 k = k + 1;
133 }
134 }
135
136 const double err = (B0.lu().solve(B) - U.cast<double>()).norm() / U.cast<double>().norm();
137 if (err > FLT_EPSILON)
138 {
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.");
141 }
142
143 const double absDetU(fabs(U.cast<double>().determinant()));
144 if (fabs(absDetU - 1.0) > FLT_EPSILON)
145 {
146 std::cout << "|det(U)|= " << std::setprecision(15) << std::scientific << absDetU << std::endl;
147 assert(false && "U is not unimodular. RLLL failed.");
148 }
149 }
150
151 /**********************************************************************/
152 const typename RLLL::MatrixType& RLLL::reducedBasis() const
153 {
154 return B;
155 }
156
157 /**********************************************************************/
158 const Eigen::Matrix<long int, Eigen::Dynamic, Eigen::Dynamic>& RLLL::unimodularMatrix() const
159 {
160 return U;
161 }
162
163} // end namespace
164#endif
Eigen::Matrix3d M
RLLL(const MatrixType &B0, const double &delta)
initial point of the source segment B
c
Definition int_R.m:15
int j
int k
int i
vertex temp