Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563604 views
1
/***** This file contains routines for lattice reduction and the
2
calculation of shortest vectors *****/
3
#include "typedef.h"
4
5
/*********************************************************************\
6
| changes v according to the transformation matrix T, i.e. v := T*v
7
\*********************************************************************/
8
static void change(v, nv, T, n)
9
int **v, nv, **T, n;
10
{
11
int i, j, k, **w, *wi, *Ti, *vi, *vj, fac;
12
13
if ((w = (int**)malloc(nv * sizeof(int*))) == 0)
14
exit (2);
15
for (i = 0; i < nv; ++i)
16
{
17
if ((w[i] = (int*)malloc(n * sizeof(int))) == 0)
18
exit (2);
19
wi = w[i];
20
for (j = 0; j < n; ++j)
21
wi[j] = 0;
22
}
23
for (i = 0; i < nv; ++i)
24
{
25
wi = w[i];
26
Ti = T[i];
27
for (j = 0; j < nv; ++j)
28
{
29
if ((fac = Ti[j]) != 0)
30
{
31
vj = v[j];
32
for (k = 0; k < n; ++k)
33
wi[k] += fac * vj[k];
34
}
35
}
36
}
37
for (i = 0; i < nv; ++i)
38
{
39
vi = v[i];
40
wi = w[i];
41
for (j = 0; j < n; ++j)
42
vi[j] = wi[j];
43
free(wi);
44
}
45
free(w);
46
}
47
48
/**********************************************************************\
49
| LLL-reduction of the positive semidefinite
50
| Gram-matrix F with transformation matrix T
51
\**********************************************************************/
52
static int lll(F, T, dim)
53
int **F, **T, dim;
54
{
55
int **gram, i, j, m, l, rank, *ptmp, tmp;
56
double **mu, *B;
57
58
/* the weights */
59
if ((B = (double*)malloc(dim * sizeof(double))) == 0)
60
exit (2);
61
/* the model matrix */
62
if ((mu = (double**)malloc(dim * sizeof(double*))) == 0)
63
exit (2);
64
/* F is copied on gram and remains unchanged */
65
if ((gram = (int**)malloc(dim * sizeof(int*))) == 0)
66
exit (2);
67
for (i = 0; i < dim; ++i)
68
{
69
if ((mu[i] = (double*)malloc(dim * sizeof(double))) == 0)
70
exit (2);
71
if ((gram[i] = (int*)malloc(dim * sizeof(int))) == 0)
72
exit (2);
73
for (j = 0; j < dim; ++j)
74
{
75
T[i][j] = 0;
76
mu[i][j] = 0.0;
77
gram[i][j] = F[i][j];
78
}
79
T[i][i] = 1;
80
mu[i][i] = 1.0;
81
}
82
/* the first basis-vector should not have norm 0 */
83
for (i = 0; i < dim && gram[i][i] == 0; ++i);
84
if (i == dim)
85
return(0);
86
else if (i > 0)
87
{
88
ptmp = gram[i];
89
gram[i] = gram[0];
90
gram[0] = ptmp;
91
for (j = 0; j < dim; ++j)
92
{
93
tmp = gram[j][i];
94
gram[j][i] = gram[j][0];
95
gram[j][0] = tmp;
96
}
97
T[0][0] = 0;
98
T[0][i] = 1;
99
T[i][i] = 0;
100
T[i][0] = 1;
101
}
102
rank = dim;
103
initialize(0, mu, B, gram);
104
if (dim > 1)
105
initialize(1, mu, B, gram);
106
/* recursively go through the matrix */
107
m = 1;
108
l = 0;
109
while (m < rank)
110
m = red(&m, &l, gram, T, mu, B, dim, &rank);
111
free(B);
112
for (i = 0; i < dim; ++i)
113
{
114
free(mu[i]);
115
free(gram[i]);
116
}
117
free(mu);
118
free(gram);
119
return(rank);
120
}
121
122
/**********************************************************************\
123
| initialization of the model
124
\**********************************************************************/
125
static void initialize(i, mu, B, gram)
126
int i, **gram;
127
double **mu, *B;
128
{
129
int j, k;
130
double muh, *mui, *muj;
131
132
B[i] = (double)gram[i][i];
133
mui = mu[i];
134
for (j = 0; j < i; ++j)
135
{
136
muh = (double)gram[i][j];
137
muj = mu[j];
138
for (k = 0; k < j; ++k)
139
muh -= B[k] * mui[k] * muj[k];
140
muh /= B[j];
141
B[i] -= B[j] * muh * muh;
142
mui[j] = muh;
143
}
144
}
145
146
/**********************************************************************\
147
| pair-reduction with vectors m and l,
148
| changes Gram-matrix, transformation matrix and model appropriately
149
\**********************************************************************/
150
static int red(m, l, gram, T, mu, B, dim, rank)
151
int *m, *l, **gram, **T, dim, *rank;
152
double **mu, *B;
153
{
154
double r;
155
int j, ir, *ptmp, jump, *Tm, *Tl, *gramm, *graml;
156
157
jump = 0;
158
r = mu[*m][*l];
159
if (r > 0.5 || r < -0.5)
160
{
161
ir = iround(r);
162
Tm = T[*m];
163
Tl = T[*l];
164
gramm = gram[*m];
165
graml = gram[*l];
166
for (j = 0; j < dim; ++j)
167
{
168
Tm[j] -= ir * Tl[j];
169
gramm[j] -= ir * graml[j];
170
}
171
for (j = 0; j < dim; ++j)
172
gram[j][*m] -= ir * gram[j][*l];
173
initialize(*m, mu, B, gram);
174
}
175
gramm = gram[*m];
176
for (j = 0; j < *rank && gramm[j] == 0; ++j);
177
if (j == *rank)
178
{
179
ptmp = T[*m];
180
T[*m] = T[*rank-1];
181
T[*rank-1] = ptmp;
182
for (j = 0; j < dim; ++j)
183
{
184
gram[*m][j] = gram[*rank-1][j];
185
gram[*rank-1][j] = 0;
186
}
187
for (j = 0; j < dim; ++j)
188
{
189
gram[j][*m] = gram[j][*rank-1];
190
gram[j][*rank-1] = 0;
191
}
192
*rank -= 1;
193
if (*m < *rank)
194
{
195
initialize(*m, mu, B, gram);
196
*l = *m-1;
197
jump = 1;
198
}
199
else
200
jump = 1;
201
}
202
if (*l == *m-1 && jump == 0)
203
check(B, m, l, gram, T, mu, dim, rank);
204
else if (jump == 0)
205
decrease(m, l, gram, mu, B, rank);
206
return(*m);
207
}
208
209
/**********************************************************************\
210
| check the LLL-condition
211
\**********************************************************************/
212
static void check(B, m, l, gram, T, mu, dim, rank)
213
int *m, *l, **gram, **T, dim, *rank;
214
double *B, **mu;
215
{
216
if (B[*m] < (LLL_CONST - mu[*m][*m-1]*mu[*m][*m-1]) * B[*m-1])
217
interchange(m, l, gram, T, mu, B, dim);
218
else
219
{
220
*l = *m-1;
221
decrease(m, l, gram, mu, B, rank);
222
}
223
}
224
225
/**********************************************************************\
226
| go back in the recursion and change the model
227
\**********************************************************************/
228
static void decrease(m, l, gram, mu, B, rank)
229
int *m, *l, **gram, *rank;
230
double **mu, *B;
231
{
232
*l -= 1;
233
if (*l < 0)
234
{
235
*m += 1;
236
if (*m < *rank)
237
{
238
*l = *m-1;
239
initialize(*m, mu, B, gram);
240
}
241
}
242
}
243
244
/**********************************************************************\
245
| interchange the vectors nr. m and m-1
246
| and change the model appropriately
247
\**********************************************************************/
248
static void interchange(m, l, gram, T, mu, B, dim)
249
int *m, *l, **gram, **T, dim;
250
double **mu, *B;
251
{
252
int i, tmp, *ptmp;
253
/* these variables weren't used at all, delete 02/12/97
254
double Mu, b; */
255
256
ptmp = T[*m];
257
T[*m] = T[*m-1];
258
T[*m-1] = ptmp;
259
ptmp = gram[*m];
260
gram[*m] = gram[*m-1];
261
gram[*m-1] = ptmp;
262
for (i = 0; i < dim; ++i)
263
{
264
tmp = gram[i][*m];
265
gram[i][*m] = gram[i][*m-1];
266
gram[i][*m-1] = tmp;
267
}
268
initialize(*m-1, mu, B, gram);
269
if (*m > 1)
270
{
271
*m -= 1;
272
*l = *m-1;
273
}
274
else
275
{
276
initialize(*m, mu, B, gram);
277
*l = *m-1;
278
}
279
}
280
281
/**********************************************************************\
282
| rounds x to an integer
283
\**********************************************************************/
284
static int iround(x)
285
double x;
286
{
287
if (x >= 0)
288
return((int)(2.0*x + 1.0) / 2);
289
else
290
return(-((int)(-2.0*x + 1.0) / 2));
291
}
292
293