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

563642 views
1
#include "typedef.h"
2
#include "matrix.h"
3
#include "symm.h"
4
#include "bravais.h"
5
#include "voronoi.h"
6
#include "longtools.h"
7
#include "tools.h"
8
#include "getput.h"
9
10
11
/*********************************************************************\
12
@
13
@---------------------------------------------------------------------
14
@ FILE: first_perfect.c
15
@---------------------------------------------------------------------
16
@
17
\*********************************************************************/
18
19
/*********************************************************************\
20
@
21
@ matrix_TYP *first_perfect(A, G, Ftr, trbifo, min)
22
@ matrix_TYP *A, **Ftr, *trbifo;
23
@ bravais_TYP *G;
24
@ int *min;
25
@
26
@ 'first_perfect' calculates a G-perfect Form.
27
@ The arguments of 'first_perfect' are
28
@ A: a G-invariant, positive definite Form
29
@ G: the group for which a perfect form will be calculated
30
@ Ftr: a Z-basis for the integral forms in the formspace of G^{tr}
31
@ trbifo: The matrix of the bilinear form
32
@ F(G)xF(G^{tr})--> R: (A,B)---> trace(AB)
33
@ with respect to the Z-bases given by G->form and Ftr
34
@ min: The pointer min returns the minimum of the calculated
35
@ perfect form.
36
@---------------------------------------------------------------------
37
@
38
\*********************************************************************/
39
matrix_TYP *first_perfect(A, G, Ftr, trbifo, min)
40
matrix_TYP *A, **Ftr, *trbifo;
41
bravais_TYP *G;
42
int *min;
43
{
44
int i,j,k, n, lc, rc, g;
45
matrix_TYP **V, *Vmat, *P, *M, *W, *W1, *M1;
46
int Vanz;
47
int rang;
48
int Pmin;
49
50
51
n = G->form_no;
52
P = copy_mat(A);
53
/*****************************************************************\
54
| Check whether P is G-perfect or not
55
\*****************************************************************/
56
V = voronoi_vertices(P, G, &Vanz, &Pmin, &i);
57
Vmat = init_mat(Vanz, G->form_no, "");
58
for(i=0;i<Vanz;i++)
59
{
60
form_to_vec(Vmat->array.SZ[i], V[i], Ftr, n, &k);
61
free_mat(V[i]);
62
}
63
free(V);
64
rang = long_row_basis(Vmat,FALSE);
65
if(rang == n)
66
{
67
free_mat(Vmat);
68
Vmat = NULL;
69
/* inserted 11/2/97 tilman */
70
Vmat = shortest(P,min);
71
free_mat(Vmat);
72
73
return(P);
74
}
75
W = init_mat(n, n, "");
76
M = init_mat(A->rows, A->cols, "");
77
while(rang != n)
78
{
79
/* printf("The Voronoi domain of the following form has dimension %d\n", rang);
80
put_mat(P, NULL, "next approximation", 2); */
81
/****************************************************************\
82
| Search for a form M perpendicular to the Voronoi-vertices
83
| (with respect to trbifo)
84
| if M is positive semidefinite take -M
85
\****************************************************************/
86
for(i=0;i<rang;i++)
87
for(j=0;j<n;j++)
88
{
89
W->array.SZ[i][j] = 0;
90
for(k=0;k<n;k++)
91
W->array.SZ[i][j] += Vmat->array.SZ[i][k] * trbifo->array.SZ[j][k];
92
}
93
free_mat(Vmat);
94
Vmat = NULL;
95
W1 = long_kernel_mat(W);
96
for(i=0;i<A->rows;i++)
97
for(j=0;j<=i;j++)
98
{
99
M->array.SZ[i][j] = 0;
100
for(k=0;k<n;k++)
101
M->array.SZ[i][j] += W1->array.SZ[k][W1->cols-1] * G->form[k]->array.SZ[i][j];
102
M->array.SZ[j][i] = M->array.SZ[i][j];
103
}
104
free_mat(W1);
105
k = definite_test(M);
106
if(k >= 0)
107
{
108
for(i=0;i<M->rows;i++)
109
for(j=0;j<M->cols;j++)
110
M->array.SZ[i][j] = -M->array.SZ[i][j];
111
}
112
/*****************************************************************\
113
| calculate next form with more shortest vectors
114
| and divide the matrix by the gcd of the entries
115
\*****************************************************************/
116
M1 = voronoi_neighbour(P, M, Pmin, &lc, &rc);
117
free_mat(P);
118
P = M1;
119
M1 = NULL;
120
Pmin = Pmin * lc;
121
g = Pmin;
122
for(i=0;i<P->rows && g != 1; i++)
123
for(j=0;j<=i && g != 1;j++)
124
{
125
if(P->array.SZ[i][j] != 0)
126
{ k = GGT(g, P->array.SZ[i][j]); g = k;}
127
}
128
if(g != 1 && g!= -1)
129
{
130
Pmin /= g;
131
for(i=0;i<P->cols;i++)
132
for(j=0;j<=i;j++)
133
{
134
P->array.SZ[i][j] /= g;
135
P->array.SZ[j][i] = P->array.SZ[i][j];
136
}
137
}
138
139
/*****************************************************************\
140
| if rang < n-1, check whether P is G-perfect or not
141
| if rang = n-1, the new Form must be perfect
142
\*****************************************************************/
143
if(rang < n-1)
144
{
145
V = voronoi_vertices(P, G, &Vanz, &k, &i);
146
if(k != Pmin)
147
{
148
put_mat(P,NULL,"P",2);
149
printf("Minimum of P %d, Pmin %d\n",k,Pmin);
150
printf("Fehler in first_perfect, Minimum falsch\n");
151
exit(3);
152
}
153
Vmat = init_mat(Vanz, G->form_no, "");
154
for(i=0;i<Vanz;i++)
155
{
156
form_to_vec(Vmat->array.SZ[i], V[i], Ftr, n, &k);
157
free_mat(V[i]);
158
}
159
free(V);
160
rang = long_row_basis(Vmat,FALSE);
161
}
162
else{
163
rang = n;
164
}
165
}
166
free_mat(W);
167
free_mat(M);
168
*min = Pmin;
169
170
if (Vmat != NULL){
171
free_mat(Vmat);
172
}
173
174
return(P);
175
}
176
177