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
#include"typedef.h"
2
/**************************************************************************\
3
@---------------------------------------------------------------------------
4
@---------------------------------------------------------------------------
5
@ FILE: shortest.c
6
@---------------------------------------------------------------------------
7
@---------------------------------------------------------------------------
8
@
9
\**************************************************************************/
10
11
#define EPS 0.001
12
13
static int n, max, *vec, anzahl, con;
14
static int **grn; /* Gram matrix */
15
static int **ba; /* basis transformation matrix */
16
static double **mo, *ge;
17
static matrix_TYP *SV;
18
static int SV_size, SV_ext;
19
20
21
static double scapr(i, j)
22
int i, j;
23
{
24
double r, *moi, *moj;
25
int l;
26
27
r = grn[i][j];
28
moi = mo[i];
29
moj = mo[j];
30
for (l = 0; l <= j-1; ++l)
31
r -= ge[l] * moi[l] * moj[l];
32
if (ge[j] == 0)
33
{
34
printf("Error: found norm 0 vector\n");
35
exit(3);
36
}
37
r = r / ge[j];
38
return r;
39
}
40
41
static double orth(i)
42
int i;
43
{
44
double r, *moi;
45
int l;
46
47
r = grn[i][i];
48
moi = mo[i];
49
for (l = 0; l <= i-1; ++l)
50
r -= ge[l] * moi[l] * moi[l];
51
return r;
52
}
53
54
/*---------------------------------------------------------*\
55
| makes model of the lattice (with same scalarproducts)
56
\*__________________________________________________________*/
57
58
static void modellmachen(a, e)
59
int a, e;
60
{
61
int i, j;
62
63
if (a == 0)
64
{
65
ge[0] = grn[0][0];
66
i = 1;
67
}
68
else
69
i = a;
70
while (i <= e)
71
{
72
for (j = 0; j < i; ++j)
73
mo[i][j] = scapr(i, j);
74
ge[i] = orth(i);
75
++i;
76
}
77
}
78
79
static int iround(r)
80
double r;
81
{
82
int i;
83
84
if (r >= 0)
85
i = (int)(2*r + 1) / 2;
86
else
87
i = -(int)(2*(-r) + 1) / 2;
88
return i;
89
}
90
91
static void red(k, l)
92
int k, l;
93
{
94
double r, *mok, *mol;
95
int i, ir, *bak, *bal, *grnk, *grnl;
96
97
r = mo[k][l];
98
if (2*r > 1.0 || 2*r < -1.0)
99
{
100
ir = iround(r);
101
mok = mo[k];
102
bak = ba[k];
103
grnk = grn[k];
104
mol = mo[l];
105
bal = ba[l];
106
grnl = grn[l];
107
for (i = 0; i < n; ++i)
108
{
109
mok[i] -= ir * mol[i];
110
bak[i] -= ir * bal[i];
111
grnk[i] -= ir * grnl[i];
112
}
113
for (i = 0; i < n; ++i)
114
grn[i][k] -= ir * grn[i][l];
115
}
116
}
117
118
static int interchange(k)
119
int k;
120
{
121
int i, z, *zp;
122
123
zp = ba[k];
124
ba[k] = ba[k-1];
125
ba[k-1] = zp;
126
127
zp = grn[k];
128
grn[k] = grn[k-1];
129
grn[k-1] = zp;
130
131
for (i = 0; i < n; ++i)
132
{
133
z = grn[i][k];
134
grn[i][k] = grn[i][k-1];
135
grn[i][k-1] = z;
136
}
137
if (k > 1)
138
return k-1;
139
else
140
return k;
141
}
142
143
static void reduzieren(k)
144
int k;
145
{
146
int l;
147
148
for (l = k-2; l >= 0; --l)
149
red(k, l);
150
}
151
152
153
/* prints the vector corresponding to vec */
154
/* in the model and its length */
155
156
static void vecschr(m, d)
157
int m;
158
double d;
159
{
160
int i, j, entry;
161
int l;
162
int *v;
163
164
l = iround(d);
165
if(l<max)
166
{
167
max = l;
168
for(i=0;i<SV->rows;i++)
169
free(SV->array.SZ[i]);
170
SV_size = SV_ext;
171
SV->rows = 0;
172
if((SV->array.SZ = (int **)realloc(SV->array.SZ, SV_size *sizeof(int *))) == 0)
173
exit(2);
174
anzahl = 0;
175
}
176
anzahl++;
177
if(SV->rows == SV_size)
178
{
179
SV_size += SV_ext;
180
if((SV->array.SZ = (int **)realloc(SV->array.SZ, SV_size *sizeof(int *))) == 0)
181
exit(2);
182
}
183
if((v = (int *)malloc((n+1) *sizeof(int))) == 0)
184
exit(2);
185
for (i = 0; i < m; ++i)
186
{
187
v[i] = 0;
188
for (j = 0; j < m; ++j)
189
v[i] += vec[j] * ba[j][i];
190
}
191
v[m] = l;
192
SV->array.SZ[SV->rows] = v;
193
SV->rows++;
194
}
195
196
197
/* recursion for finding shortest vectors */
198
199
static void shrt(c, damage)
200
int c;
201
double damage;
202
{
203
double x, gec;
204
int i, j;
205
206
if (c == -1)
207
{
208
for (i = 0; i < n && vec[i] == 0; ++i);
209
if (i == n)
210
con = 1;
211
else
212
{
213
vecschr(n, damage);
214
}
215
}
216
else
217
{
218
x = 0.0;
219
for (j = c+1; j < n; ++j)
220
x += vec[j] * mo[j][c];
221
i = -iround(x);
222
gec = ge[c];
223
if (gec*(x+i)*(x+i) + damage < max + EPS)
224
{
225
while ((gec*(x+i)*(x+i) + damage <= max + EPS) ||
226
(x + i <= 0))
227
++i;
228
--i;
229
while ((gec*(x+i)*(x+i) + damage < max + EPS) &&
230
con == 0)
231
{
232
vec[c] = i;
233
shrt(c-1, gec*(x+i)*(x+i) + damage);
234
--i;
235
}
236
}
237
}
238
}
239
240
241
242
243
/**************************************************************************\
244
@---------------------------------------------------------------------------
245
@ matrix_TYP *shortest(mat, min_norm)
246
@ matrix_TYP *mat;
247
@ int *min_norm;
248
@
249
@ The function callulates the shortest vectors of the integral, symmetric,
250
@ positiv definite matrix 'mat'.
251
@ The minmum
252
@
253
@ m(mat) := min{ v * mat *v^{tr} | v in Z^n and v not 0}
254
@
255
@ is returned in the pointer 'min_norm'. The shortest vectors are the vectors
256
@ with n(x) = min(x).
257
@ They are stored as rows in the returned matrix called 'SV' in the following.
258
@ For 'SV' n+1 columns are allocated. The last column contains the norm n(x).
259
@ Although n+1 columns are allocated, SV->cols = n.
260
@
261
@ Warning: if 'mat' is not positiv definite, the function runs into an
262
@ infinite loop.
263
@---------------------------------------------------------------------------
264
@
265
\**************************************************************************/
266
matrix_TYP *shortest(mat, min_norm)
267
matrix_TYP *mat;
268
int *min_norm;
269
{
270
int i, j, ak, bk;
271
double de, cst = 0.75;
272
char c;
273
matrix_TYP *erg;
274
275
extern matrix_TYP *init_mat();
276
277
anzahl = 0;
278
con = 0;
279
n = mat->rows;
280
SV_ext = n * (n+1)/2;
281
SV = init_mat(1, n+1, "");
282
SV->cols--;
283
SV->rows = 0;
284
free(SV->array.SZ[0]);
285
/* inserted the next line 15/1/97 tilman */
286
free(SV->array.SZ);
287
288
if((SV->array.SZ = (int **)malloc(SV_ext *sizeof(int *))) == 0)
289
exit(2);
290
SV_size = SV_ext;
291
if ((grn = (int**)malloc(n * sizeof(int*))) == 0)
292
exit (2);
293
if ((ba = (int**)malloc(n * sizeof(int*))) == 0)
294
exit (2);
295
if ((mo = (double**)malloc(n * sizeof(double*))) == 0)
296
exit (2);
297
if ((ge = (double*)malloc(n * sizeof(double))) == 0)
298
exit (2);
299
if ((vec = (int*)malloc(n * sizeof(int))) == 0)
300
exit (2);
301
for (i = 0; i < n; ++i)
302
{
303
vec[i] = 0;
304
if ((grn[i] = (int*)malloc(n * sizeof(int))) == 0)
305
exit (2);
306
if ((ba[i] = (int*)malloc(n * sizeof(int))) == 0)
307
exit (2);
308
if ((mo[i] = (double*)malloc(n * sizeof(double))) == 0)
309
exit (2);
310
for (j = 0; j < n; ++j)
311
{
312
ba[i][j] = 0;
313
mo[i][j] = 0.0;
314
}
315
ba[i][i] = 1;
316
mo[i][i] = 1.0;
317
318
/* read the Gram matrix (can be square or lower triangular) */
319
for (j = 0; j <= i; ++j)
320
{
321
grn[i][j] = mat->array.SZ[i][j];
322
grn[j][i] = grn[i][j];
323
}
324
}
325
max = mat->array.SZ[0][0];
326
for(i=1;i<n;i++)
327
{
328
if(mat->array.SZ[i][i] < max)
329
max = mat->array.SZ[i][i];
330
}
331
332
bk = 1;
333
while (bk < n)
334
{
335
ak = bk - 1;
336
modellmachen(ak, bk);
337
red(bk, bk-1);
338
if (ge[bk] < ((cst - mo[bk][bk-1]*mo[bk][bk-1]) * ge[bk-1]))
339
{
340
bk = interchange(bk);
341
modellmachen(bk-1, bk);
342
if (bk > 1)
343
--bk;
344
}
345
else
346
{
347
if (bk > 1)
348
reduzieren(bk);
349
++bk;
350
}
351
}
352
353
shrt(n-1, 0.0); /* recursively calculate the vectors up to length max */
354
355
for(i=0;i<n;i++)
356
{
357
free(grn[i]);
358
free(ba[i]);
359
free(mo[i]);
360
}
361
free(grn); free(ba); free(mo); free(ge); free(vec);
362
363
erg = SV;
364
SV = NULL;
365
*min_norm = max;
366
367
return(erg);
368
}
369
370