All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
LatticeReduction.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include "Exception.h"
23 #include "LatticeReduction.h"
24 
25 namespace PLMD{
26 
27 const double epsilon=1e-28;
28 
30  for(int i=0;i<3;i++) for(int j=i+1;j<3;j++) if(modulo2(v[i])>modulo2(v[j])){
31  Vector x=v[i]; v[i]=v[j]; v[j]=x;
32  }
33  for(int i=0;i<2;i++) plumed_assert(modulo2(v[i])<=modulo2(v[i+1]));
34 }
35 
37  double ma=modulo2(a);
38  double mb=modulo2(b);
39  while(true){
40  if(mb>ma){
41  Vector t(a); a=b; b=t;
42  double mt(ma); ma=mb; mb=mt;
43  }
44  a-=b*floor(dotProduct(a,b)/modulo2(b)+0.5);
45  ma=modulo2(a);
46  if(mb<=ma+epsilon) break;
47  }
48 
49  Vector t(a); a=b; b=t;
50 }
51 
53  Vector v[3];
54  v[0]=a; v[1]=b; v[2]=c;
55  int iter=0;
56  int ok=0;
57  while(ok<3){
58  int i,j;
59  if(iter%3==0){
60  i=0; j=1;
61  } else if(iter%3==1){
62  i=0; j=2;
63  } else {
64  i=1; j=2;
65  }
66  if(isReduced(v[i],v[j])) ok++;
67  else {
68  reduce(v[i],v[j]);
69  ok=1;
70  }
71  iter++;
72  }
73  a=v[0]; b=v[1]; c=v[2];
74 }
75 
77  const int cut=5;
78  for(int i=-cut;i<=cut;i++){
79  if(modulo2(b+i*a)<modulo2(b)) return false;
80  }
81  return modulo2(a)<=modulo2(b) && 2.0*dotProduct(a,b)<=modulo2(a);
82 }
83 
85  Vector a=t.getRow(0);
86  Vector b=t.getRow(1);
87  Vector c=t.getRow(2);
88  reduce2(a,b,c);
89  t.setRow(0,a);
90  t.setRow(1,b);
91  t.setRow(2,c);
92 }
93 
95  reduceFast(t);
96 }
97 
99  Vector v[3];
100  v[0]=t.getRow(0);
101  v[1]=t.getRow(1);
102  v[2]=t.getRow(2);
103  while(true){
104  sort(v);
105  reduce(v[0],v[1]);
106  double b11=modulo2(v[0]);
107  double b22=modulo2(v[1]);
108  double b12=dotProduct(v[0],v[1]);
109  double b13=dotProduct(v[0],v[2]);
110  double b23=dotProduct(v[1],v[2]);
111  double z=b11*b22-b12*b12;
112  double y2=-(b11*b23-b12*b13)/z;
113  double y1=-(b22*b13-b12*b23)/z;
114  int x1min=floor(y1);
115  int x1max=x1min+1;
116  int x2min=floor(y2);
117  int x2max=x2min+1;
118  bool first=true;
119  double mbest,mtrial;
120  Vector trial,best;
121  for(int x1=x1min;x1<=x1max;x1++)
122  for(int x2=x2min;x2<=x2max;x2++){
123  trial=v[2]+x2*v[1]+x1*v[0];
124  mtrial=modulo2(trial);
125  if(first || mtrial<mbest){
126  mbest=mtrial;
127  best=trial;
128  first=false;
129  }
130  }
131  if(modulo2(best)+epsilon>=modulo2(v[2])) break;
132  v[2]=best;
133  }
134  sort(v);
135  t.setRow(0,v[0]);
136  t.setRow(1,v[1]);
137  t.setRow(2,v[2]);
138 }
139 
140 
142  Vector v[3];
143  v[0]=t.getRow(0);
144  v[1]=t.getRow(1);
145  v[2]=t.getRow(2);
146  reduce2(v[0],v[1],v[2]);
147  double e01=dotProduct(v[0],v[1]);
148  double e02=dotProduct(v[0],v[2]);
149  double e12=dotProduct(v[1],v[2]);
150  if(e01*e02*e12<0){
151  int eps01=0; if(e01>0.0) eps01=1; else if(e01<0.0) eps01=-1;
152  int eps02=0; if(e02>0.0) eps02=1; else if(e02<0.0) eps02=-1;
153  Vector n=v[0]-eps01*v[1]-eps02*v[2];
154  int i=0; double mx=modulo2(v[i]);
155  for(int j=1;j<3;j++){
156  double f=modulo2(v[j]);
157  if(f>mx){
158  i=j;
159  mx=f;
160  }
161  }
162  if(modulo2(n)<mx) v[i]=n;
163  }
164  sort(v);
165  t.setRow(0,v[0]);
166  t.setRow(1,v[1]);
167  t.setRow(2,v[2]);
168 }
169 
170 bool LatticeReduction::isReduced2(const Vector&a,const Vector&b,const Vector &c){
171  return isReduced(a,b) && isReduced(a,b) && isReduced(b,c);
172 }
173 
175  Vector v[3];
176  double m[3];
177  v[0]=t.getRow(0);
178  v[1]=t.getRow(1);
179  v[2]=t.getRow(2);
180  for(int i=0;i<3;i++) m[i]=modulo2(v[i]);
181  if(!((m[0]<=m[1]) && m[1]<=m[2])) return false;
182  const int cut=5;
183  for(int i=-cut;i<=cut;i++){
184  double mm=modulo2(v[1]+i*v[0]);
185  if(mm<m[1]) return false;
186  for(int j=-cut;j<=cut;j++){
187  double mx=modulo2(v[2]+i*v[1]+j*v[0]);
188  if(mx<m[2])return false;
189  }
190  }
191  return true;
192 }
193 
194 }
static void sort(Vector v[3])
Sort three vectors by modulo.
const double epsilon
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
static bool isReduced(const Vector &a, const Vector &b)
Check if two vectors are reduced.
static void reduceFast(Tensor &t)
Reduce a basis in place using the fast algorithm (Algorithm 3 in the paper)
static bool isReduced2(const Vector &a, const Vector &b, const Vector &c)
Check if three vectors are reduced-2.
void const char const char int * n
Definition: Matrix.h:42
T dotProduct(const std::vector< T > &A, const std::vector< T > &B)
Calculate the dot product between two vectors.
Definition: Matrix.h:54
double modulo2(const VectorGeneric< n > &v)
Definition: Vector.h:330
static void reduce2(Vector &a, Vector &b, Vector &c)
Obtain three reduce-2 vectors (Algorithm 1 in the paper), equivalent to reduce2(Tensor&t) ...
void const char const char int double int double double int int double int * m
Definition: Matrix.h:42
static void reduce(Vector &a, Vector &b)
Gaussian reduction.
TensorGeneric & setRow(unsigned i, const VectorGeneric< m > &r)
set i-th row
Definition: Tensor.h:254
void const char const char int double * a
Definition: Matrix.h:42
static void reduceSlow(Tensor &t)
Reduce a basis in place using the slow algorithm (Algorithm 2 in the paper)
VectorGeneric< m > getRow(unsigned i) const
get i-th row
Definition: Tensor.h:267