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

563665 views
1
/***** This file includes some routines for
2
the preprocessing of the algorithm *****/
3
#include"typedef.h"
4
5
/************************************************************************\
6
| removes those vectors from V.v, which
7
| have other norm combinations than the base-vectors
8
\************************************************************************/
9
static void checkvecs(V, F, norm)
10
veclist *V, norm;
11
invar F;
12
{
13
int i, j, k, dim, *normvec, *Vvi;
14
15
dim = F.dim;
16
if ((normvec = (int*)malloc(norm.dim * sizeof(int))) == 0)
17
exit (2);
18
j = 0;
19
for (i = 1; i <= V->n; ++i)
20
{
21
Vvi = V->v[i];
22
for (k = 0; k < F.n; ++k)
23
{
24
Vvi[dim+k] = scp(Vvi, F.A[k], Vvi, dim);
25
normvec[k] = Vvi[dim+k];
26
}
27
if (abs(numberof(normvec, norm)) > dim)
28
/* the vector V->V[i] has a different norm combination from those in the list
29
norm.v and is therefore deleted */
30
{
31
free(Vvi);
32
++j;
33
}
34
else
35
V->v[i-j] = Vvi;
36
}
37
V->n -= j;
38
free(normvec);
39
}
40
41
/************************************************************************\
42
| checks, whether g fixes the invariant forms
43
\************************************************************************/
44
static int checkgen(g, F)
45
int **g;
46
invar F;
47
{
48
int i, j, k, fix, **FAk;
49
50
fix = 1;
51
for (k = 0; k < F.n && fix == 1; ++k)
52
{
53
FAk = F.A[k];
54
for (i = 0; i < F.dim && fix == 1; ++i)
55
{
56
for (j = 0; j <= i && fix == 1; ++j)
57
{
58
if (scp(g[i], FAk, g[j], F.dim) != FAk[i][j])
59
fix = 0;
60
}
61
}
62
}
63
return(fix);
64
}
65
66
/************************************************************************\
67
| a permutation per := fp.per for the order of the basis-vectors is chosen
68
| such that in every step the number of possible continuations is minimal,
69
| for j from per[i] to per[dim-1] the value f[i][j] in the fingerprint f is
70
| the number of vectors, which have the same scalar product with the
71
| basis-vectors per[0]...per[i-1] as the basis-vector j and the same length as
72
| this vector with respect to all invariant forms
73
\************************************************************************/
74
static void fingerprint(fp, F, V)
75
fpstruct *fp;
76
invar F;
77
veclist V;
78
{
79
int i, j, k, dim, min, tmp, **f, *Vvj;
80
81
dim = F.dim;
82
if ((f = (int**)malloc(dim * sizeof(int*))) == 0)
83
exit (2);
84
for (i = 0; i < dim; ++i)
85
{
86
if ((f[i] = (int*)malloc(dim * sizeof(int))) == 0)
87
exit (2);
88
for (j = 0; j < dim; ++j)
89
f[i][j] = 0;
90
}
91
for (i = 0; i < dim; ++i)
92
fp->per[i] = i;
93
/* the first row of the fingerprint has as entry nr. i the number of
94
vectors, which have the same length as the i-th basis-vector with
95
respect to every invariant form */
96
for (j = 1; j <= V.n; ++j)
97
{
98
Vvj = V.v[j];
99
for (i = 0; i < dim; ++i)
100
{
101
for (k = 0; k < F.n && Vvj[dim+k] == F.A[k][i][i]; ++k);
102
if (k == F.n)
103
f[0][i] += 2;
104
}
105
}
106
for (i = 0; i < dim-1; ++i)
107
{
108
/* a minimal entry != 0 in the i-th row is chosen */
109
min = i;
110
for (j = i+1; j < dim; ++j)
111
{
112
if (f[i][fp->per[j]] < f[i][fp->per[min]])
113
min = j;
114
}
115
tmp = fp->per[i];
116
fp->per[i] = fp->per[min];
117
fp->per[min] = tmp;
118
/* the column below the minimal entry is set to 0 */
119
for (j = i+1; j < dim; ++j)
120
f[j][fp->per[i]] = 0;
121
/* compute the row i+1 of the fingerprint */
122
for (j = i+1; j < dim; ++j)
123
f[i+1][fp->per[j]] = possible(F, V, fp->per, i, fp->per[j]);
124
}
125
/* only the diagonal of f will be needed later */
126
for (i = 0; i < dim; ++i)
127
{
128
fp->diag[i] = f[i][fp->per[i]];
129
free(f[i]);
130
}
131
free(f);
132
}
133
134
/************************************************************************\
135
| returns the number of vectors,
136
| which have the same scalar products with the
137
| basis-vectors nr. per[0]...per[I] as the
138
| basis-vector nr. J and the same length
139
| as this vector with respect to all invariant forms
140
\************************************************************************/
141
static int possible(F, V, per, I, J)
142
invar F;
143
veclist V;
144
int *per, I, J;
145
{
146
int i, j, k, dim, count, *Vvj;
147
148
dim = F.dim;
149
count = 0;
150
for (j = 1; j <= V.n; ++j)
151
{
152
Vvj = V.v[j];
153
i = I+1;
154
/* check the length of the vector */
155
for (k = 0; k < F.n && i > I && Vvj[dim+k] == F.A[k][J][J]; ++k)
156
/* check the scalar products with the basis-vectors */
157
for (i = 0; i <= I && F.v[k][j][per[i]] == F.A[k][per[i]][J]; ++i);
158
if (k == F.n && i > I)
159
++count;
160
/* the same for the negative vector */
161
i = I+1;
162
for (k = 0; k < F.n && i > I && Vvj[dim+k] == F.A[k][J][J]; ++k)
163
for (i = 0; i <= I && F.v[k][j][per[i]] == -F.A[k][per[i]][J]; ++i);
164
if (k == F.n && i > I)
165
++count;
166
}
167
return(count);
168
}
169
170
/************************************************************************\
171
| calculates the scalar products of the vector w with the base
172
| vectors v[b[I]] down to v[b[I-dep+1]] with respect to
173
| all invariant forms and puts them on scpvec
174
\************************************************************************/
175
static void scpvector(scpvec, w, b, I, dep, F)
176
invar F;
177
int *scpvec, *w, *b, I, dep;
178
{
179
int i, j, dim, bi;
180
181
dim = F.dim;
182
for (i = I; i >= 0 && i > I-dep; --i)
183
{
184
if ((bi = b[i]) > 0)
185
{
186
for (j = 0; j < F.n; ++j)
187
scpvec[j*dep + I-i] = sscp(w, F.v[j][bi], dim);
188
}
189
else
190
{
191
for (j = 0; j < F.n; ++j)
192
scpvec[j*dep + I-i] = -sscp(w, F.v[j][-bi], dim);
193
}
194
}
195
}
196
197
/************************************************************************\
198
| computes the list of scalar product
199
| combinations of the vectors in V.v with
200
| the basis-vectors in b
201
\************************************************************************/
202
static void scpvecs(list, vec, I, b, dep, V, F)
203
veclist *list, V;
204
invar F;
205
int ***vec, I, *b, dep;
206
{
207
int i, j, dim, len, *scpvec, nr, sign, *tmp;
208
int *Vvj, *vecnr, *listvn, *vecn, **listv;
209
210
dim = F.dim;
211
len = F.n * dep;
212
/* scpvec is the vector for the scalar product combination */
213
if ((scpvec = (int*)malloc(len * sizeof(int))) == 0)
214
exit (2);
215
/* the first vector in the list is the 0-vector and is not counted */
216
if ((list->v = (int**)malloc(1 * sizeof(int*))) == 0)
217
exit (2);
218
list->dim = len;
219
list->len = len;
220
if ((list->v[0] = (int*)malloc(len * sizeof(int))) == 0)
221
exit (1);
222
for (i = 0; i < len; ++i)
223
list->v[0][i] = 0;
224
list->n = 0;
225
if ((*vec = (int**)malloc(1 * sizeof(int*))) == 0)
226
exit (2);
227
if (((*vec)[0] = (int*)malloc(dim * sizeof(int))) == 0)
228
exit (2);
229
for (i = 0; i < dim; ++i)
230
(*vec)[0][i] = 0;
231
for (j = 1; j <= V.n; ++j)
232
{
233
Vvj = V.v[j];
234
for (i = 0; i < len; ++i)
235
scpvec[i] = 0;
236
scpvector(scpvec, Vvj, b, I, dep, F);
237
for (i = 0; i < len && scpvec[i] == 0; ++i);
238
if (i == len)
239
/* if scpvec is the 0-vector, nr is set to 0, since numberof never returns 0 */
240
nr = 0;
241
else
242
{
243
nr = numberof(scpvec, *list);
244
sign = nr > 0 ? 1 : -1;
245
nr = abs(nr);
246
}
247
/* scpvec is already in list */
248
if (nr <= list->n && nr > 0)
249
{
250
vecnr = (*vec)[nr];
251
for (i = 0; i < dim; ++i)
252
vecnr[i] += sign * Vvj[i];
253
}
254
/* scpvec is a new scalar product combination */
255
else if (nr >= list->n+1)
256
{
257
++list->n;
258
if ((list->v = (int**)realloc(list->v, (list->n+1) * sizeof(int*))) == 0)
259
exit (2);
260
if ((list->v[list->n] = (int*)malloc(len * sizeof(int))) == 0)
261
exit (2);
262
/* numberof changes the sign of scpvec if the first nonzero entry is < 0,
263
hence this is correct */
264
listvn = list->v[list->n];
265
for (i = 0; i < len; ++i)
266
listvn[i] = scpvec[i];
267
if ((*vec = (int**)realloc(*vec, (list->n+1) * sizeof(int*))) == 0)
268
exit (2);
269
if (((*vec)[list->n] = (int*)malloc(dim * sizeof(int))) == 0)
270
exit (2);
271
vecn = (*vec)[list->n];
272
for (i = 0; i < dim; ++i)
273
vecn[i] = sign * Vvj[i];
274
/* shuffle the new vector to the correct position, this should be quick enough,
275
since the length of the list should not exceed some hundreds */
276
listv = list->v;
277
for (i = list->n; i > nr+1-list->n; --i)
278
{
279
tmp = listv[i];
280
listv[i] = listv[i-1];
281
listv[i-1] = tmp;
282
tmp = (*vec)[i];
283
(*vec)[i] = (*vec)[i-1];
284
(*vec)[i-1] = tmp;
285
}
286
}
287
}
288
free(scpvec);
289
}
290
291
/************************************************************************\
292
| computes a basis b for the lattice generated by the vectors in v,
293
| puts a transformation matrix on T, i.e. b = T*v,
294
| uses LLL-reduction with respect to F
295
\************************************************************************/
296
static void base(com, b, v, F, dim)
297
scpcomb *com;
298
int ***b, **v, **F, dim;
299
{
300
int i, j, k, nv, rank, max, **Fv, **f, **tr, *perm, *norm, tmp;
301
int *vi, *Fvi, *comtr, *fj;
302
303
nv = com->list.n + 1;
304
max = 1;
305
/* get the maximal entry in the vector sums */
306
for (i = 0; i < nv; ++i)
307
{
308
for (j = 0; j < dim; ++j)
309
{
310
if (abs(v[i][j]) > max)
311
max = abs(v[i][j]);
312
}
313
}
314
/* Fv is the list of products of F with the vectors in v, scalar products
315
with respect to F can be calculated as standard scalar products of
316
vectors in v with vectors in Fv */
317
if ((Fv = (int**)malloc(nv * sizeof(int*))) == 0)
318
exit (2);
319
/* the product of the maximal entry in the vector sums with the maximal entry
320
in the product of the Gram-matrices with the vector sums should not exceed
321
MAXNORM to avoid overflow */
322
max = MAXNORM / max;
323
for (i = 0; i < nv; ++i)
324
{
325
if ((Fv[i] = (int*)malloc(dim * sizeof(int))) == 0)
326
exit (2);
327
Fvi = Fv[i];
328
for (j = 0; j < dim; ++j)
329
{
330
Fvi[j] = sscp(F[j], v[i], dim);
331
if (abs(Fvi[j]) > max)
332
/* an entry in F.v[i] is too large */
333
{
334
fprintf(stderr, "Error: Found entry %d in vector sum.\nTo avoid overflow, the entries should not exceed %d.\nTry without option -D or use -D with higher value.\n", Fvi[j], max);
335
exit (3);
336
}
337
}
338
}
339
/* b is the basis for the lattice */
340
if ((*b = (int**)malloc(1 * sizeof(int*))) == 0)
341
exit (2);
342
if (((*b)[0] = (int*)malloc(dim * sizeof(int))) == 0)
343
exit (2);
344
/* com->trans is the transformation matrix */
345
if ((com->trans = (int**)malloc(1 * sizeof(int*))) == 0)
346
exit (2);
347
if ((com->trans[0] = (int*)malloc(nv * sizeof(int))) == 0)
348
exit (2);
349
/* f is the Gram-matrix for the basis b with respect to the form F */
350
if ((f = (int**)malloc(1 * sizeof(int*))) == 0)
351
exit (2);
352
if ((f[0] = (int*)malloc(1 * sizeof(int))) == 0)
353
exit (2);
354
/* tr is the transformation matrix for the LLL-reduced lattice */
355
if ((tr = (int**)malloc(1 * sizeof(int*))) == 0)
356
exit (2);
357
if ((tr[0] = (int*)malloc(1 * sizeof(int))) == 0)
358
exit (2);
359
/* perm is the new order in which the vectors in v are added to the lattice
360
generated by the preceding vectors */
361
if ((perm = (int*)malloc(nv * sizeof(int))) == 0)
362
exit (2);
363
if ((norm = (int*)malloc(nv * sizeof(int))) == 0)
364
exit (2);
365
/* bubble sort with respect to the norm of the vectors in v with respect to the
366
Gram-matrix F, which is assumed to be positive definite,
367
this should stabilize the LLL-reduction,
368
the bubble sort should be sufficient since the number of vectors here is
369
assumed to be rather small (at most some hundreds) */
370
for (i = 0; i < nv; ++i)
371
{
372
norm[i] = sscp(v[i], Fv[i], dim);
373
if (norm[i] > MAXNORM)
374
{
375
exit (3);
376
}
377
perm[i] = i;
378
}
379
i = 0;
380
while (i < nv-1)
381
{
382
if (norm[perm[i]] > norm[perm[i+1]])
383
{
384
tmp = perm[i];
385
perm[i] = perm[i+1];
386
perm[i+1] = tmp;
387
if (i > 0)
388
--i;
389
}
390
else
391
++i;
392
}
393
free(norm);
394
/* jump over possible 0-vectors */
395
i = 0;
396
for (j = 0; j < dim && v[perm[i]][j] == 0; ++j);
397
while (j == dim && i < nv)
398
{
399
++i;
400
if (i < nv)
401
for (j = 0; j < dim && v[perm[i]][j] == 0; ++j);
402
}
403
rank = 0;
404
while (i < nv)
405
{
406
/* v[perm[i]] is the candidate to enlarge the lattice generated by the
407
base vectors in b */
408
vi = v[perm[i]];
409
Fvi = Fv[perm[i]];
410
for (j = 0; j < rank; ++j)
411
{
412
f[j][rank] = sscp((*b)[j], Fvi, dim);
413
f[rank][j] = f[j][rank];
414
}
415
f[rank][rank] = sscp(vi, Fvi, dim);
416
if (lll(f, tr, rank+1) > rank)
417
/* the rank of the lattice generated by v[perm[i]] and the vectors in b is
418
rank+1, i.e. one higher than without v[perm[i]] */
419
{
420
++rank;
421
for (j = 0; j < dim; ++j)
422
(*b)[rank-1][j] = vi[j];
423
comtr = com->trans[rank-1];
424
for (j = 0; j < nv; ++j)
425
comtr[j] = 0;
426
comtr[perm[i]] = 1;
427
/* transform basis and transformation matrix */
428
change(*b, rank, tr, dim);
429
change(com->trans, rank, tr, nv);
430
if ((*b = (int**)realloc(*b, (rank+1) * sizeof(int*))) == 0)
431
exit (2);
432
if (((*b)[rank] = (int*)malloc(dim * sizeof(int))) == 0)
433
exit (2);
434
if ((com->trans = (int**)realloc(com->trans, (rank+1) * sizeof(int*))) == 0)
435
exit (2);
436
if ((com->trans[rank] = (int*)malloc(nv * sizeof(int))) == 0)
437
exit (2);
438
if ((f = (int**)realloc(f, (rank+1) * sizeof(int*))) == 0)
439
exit (2);
440
for (j = 0; j < rank; ++j)
441
{
442
if ((f[j] = (int*)realloc(f[j], (rank+1) * sizeof(int))) == 0)
443
exit (2);
444
}
445
if ((f[rank] = (int*)malloc((rank+1) * sizeof(int))) == 0)
446
exit (2);
447
for (j = 0; j < rank; ++j)
448
{
449
fj = f[j];
450
for (k = 0; k <= j; ++k)
451
{
452
fj[k] = scp((*b)[j], F, (*b)[k], dim);
453
f[k][j] = fj[k];
454
}
455
}
456
if ((tr = (int**)realloc(tr, (rank+1) * sizeof(int*))) == 0)
457
exit (2);
458
for (j = 0; j < rank; ++j)
459
{
460
if ((tr[j] = (int*)realloc(tr[j], (rank+1) * sizeof(int))) == 0)
461
exit (2);
462
}
463
if ((tr[rank] = (int*)malloc((rank+1) * sizeof(int))) == 0)
464
exit (2);
465
}
466
else if (abs(tr[rank][rank]) > 1)
467
/* v[perm[i]] enlarges the lattice generated by the vectors in b by a finite
468
index |tr[rank][rank]| */
469
{
470
for (j = 0; j < dim; ++j)
471
(*b)[rank][j] = vi[j];
472
comtr = com->trans[rank];
473
for (j = 0; j < nv; ++j)
474
comtr[j] = 0;
475
comtr[perm[i]] = 1;
476
/* transform basis and transformation matrix */
477
change(*b, rank+1, tr, dim);
478
change(com->trans, rank+1, tr, nv);
479
for (j = 0; j < rank; ++j)
480
{
481
fj = f[j];
482
for (k = 0; k <= j; ++k)
483
{
484
fj[k] = scp((*b)[j], F, (*b)[k], dim);
485
f[k][j] = fj[k];
486
}
487
}
488
}
489
++i;
490
}
491
com->rank = rank;
492
for (i = 0; i < nv; ++i)
493
free(Fv[i]);
494
free(Fv);
495
for (i = 0; i <= rank; ++i)
496
{
497
free(f[i]);
498
free(tr[i]);
499
}
500
free(f);
501
free(tr);
502
free(perm);
503
}
504
505
/************************************************************************\
506
| expresses the vectors in v in the basis b,
507
| puts the transformation matrix on com->coef, i.e. v = com->coef * b,
508
| uses LLL-reduction with respect to F to obtain the coefficients
509
\************************************************************************/
510
static void coef(com, b, v, F, dim)
511
scpcomb *com;
512
int **b, **v, **F, dim;
513
{
514
int i, j, **Fb, nb, **Fv, nv, **f, **tr, sign;
515
int *fi, *fnb, *trnb, *Fvi, *comci;
516
517
if ((com->coef = (int**)malloc((com->list.n+1) * sizeof(int*))) == 0)
518
exit (2);
519
for (i = 0; i <= com->list.n; ++i)
520
{
521
if ((com->coef[i] = (int*)malloc(com->rank * sizeof(int))) == 0)
522
exit (2);
523
}
524
nb = com->rank;
525
nv = com->list.n + 1;
526
/* Fv is the list of products of F with the vectors in v, scalar products
527
with respect to F can be calculated as standard scalar products of
528
vectors in v with vectors in Fv */
529
if ((Fv = (int**)malloc(nv * sizeof(int*))) == 0)
530
exit (2);
531
for (i = 0; i < nv; ++i)
532
{
533
if ((Fv[i] = (int*)malloc(dim * sizeof(int))) == 0)
534
exit (2);
535
for (j = 0; j < dim; ++j)
536
Fv[i][j] = sscp(F[j], v[i], dim);
537
}
538
/* Fb is the list of products of F with the vectors in b */
539
if ((Fb = (int**)malloc(nb * sizeof(int*))) == 0)
540
exit (2);
541
for (i = 0; i < nb; ++i)
542
{
543
if ((Fb[i] = (int*)malloc(dim * sizeof(int))) == 0)
544
exit (2);
545
for (j = 0; j < dim; ++j)
546
Fb[i][j] = sscp(F[j], b[i], dim);
547
}
548
if ((f = (int**)malloc((nb+1) * sizeof(int*))) == 0)
549
exit (2);
550
for (i = 0; i <= nb; ++i)
551
{
552
if ((f[i] = (int*)malloc((nb+1) * sizeof(int))) == 0)
553
exit (2);
554
}
555
for (i = 0; i < nb; ++i)
556
{
557
fi = f[i];
558
for (j = 0; j <= i; ++j)
559
{
560
fi[j] = sscp(b[i], Fb[j], dim);
561
f[j][i] = fi[j];
562
}
563
}
564
if ((tr = (int**)malloc((nb+1) * sizeof(int*))) == 0)
565
exit (2);
566
for (i = 0; i <= nb; ++i)
567
{
568
if ((tr[i] = (int*)malloc((nb+1) * sizeof(int))) == 0)
569
exit (2);
570
}
571
fnb = f[nb];
572
trnb = tr[nb];
573
for (i = 0; i < nv; ++i)
574
{
575
Fvi = Fv[i];
576
for (j = 0; j < nb; ++j)
577
{
578
f[j][nb] = sscp(b[j], Fvi, dim);
579
fnb[j] = f[j][nb];
580
}
581
fnb[nb] = sscp(v[i], Fvi, dim);
582
/* if the vector v[i] is in the lattice generated by the base b, the rank of the
583
Gram-matrix f must be nb and the last row of the transformation matrix tr
584
expresses the 0-vector, in particular |tr[nb][nb]| must be <=1, since
585
otherwise the vector v[i] would enlarge the lattice be an index
586
|tr[nb][nb]| */
587
if (lll(f, tr, nb+1) > nb || abs(trnb[nb]) > 1)
588
{
589
fprintf(stderr, "Error: vector lies not in lattice\n");
590
exit (3);
591
}
592
else
593
{
594
comci = com->coef[i];
595
sign = trnb[nb];
596
for (j = 0; j < nb; ++j)
597
comci[j] = -sign * trnb[j];
598
}
599
}
600
for (i = 0; i < nv; ++i)
601
free(Fv[i]);
602
free(Fv);
603
for (i = 0; i < nb; ++i)
604
free(Fb[i]);
605
free(Fb);
606
for (i = 0; i <= nb; ++i)
607
{
608
free(f[i]);
609
free(tr[i]);
610
}
611
free(f);
612
free(tr);
613
}
614
615
/************************************************************************\
616
| com->F[i] is the Gram-matrix of the basis b with respect to F.A[i]
617
\************************************************************************/
618
static void scpforms(com, b, F)
619
scpcomb *com;
620
invar F;
621
int **b;
622
{
623
int i, j, k, dim, **Fbi, nb, **FAi, *comFij;
624
625
dim = F.dim;
626
nb = com->rank;
627
if ((com->F = (int***)malloc(F.n * sizeof(int**))) == 0)
628
exit (2);
629
/* Fbi is the list of products of F.A[i] with the vectors in b */
630
if ((Fbi = (int**)malloc(nb * sizeof(int*))) == 0)
631
exit (2);
632
for (j = 0; j < nb; ++j)
633
{
634
if ((Fbi[j] = (int*)malloc(dim * sizeof(int))) == 0)
635
exit (2);
636
}
637
for (i = 0; i < F.n; ++i)
638
{
639
if ((com->F[i] = (int**)malloc(nb * sizeof(int*))) == 0)
640
exit (2);
641
FAi = F.A[i];
642
for (j = 0; j < nb; ++j)
643
{
644
for (k = 0; k < dim; ++k)
645
Fbi[j][k] = sscp(FAi[k], b[j], dim);
646
}
647
for (j = 0; j < nb; ++j)
648
{
649
if ((com->F[i][j] = (int*)malloc(nb * sizeof(int))) == 0)
650
exit (2);
651
comFij = com->F[i][j];
652
for (k = 0; k < nb; ++k)
653
comFij[k] = sscp(b[j], Fbi[k], dim);
654
}
655
}
656
for (j = 0; j < nb; ++j)
657
free(Fbi[j]);
658
free(Fbi);
659
}
660
661