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 <base.h>
3
#include <bravais.h>
4
#include <matrix.h>
5
#include <presentation.h>
6
#include <tsubgroups.h>
7
8
#define DATABASE_NAME TOPDIR "/tables/qcatalog/data"
9
10
11
12
13
/* -------------------------------------------------------------------- */
14
/* transform the i-th row of a matrix to a list of integers */
15
/* -------------------------------------------------------------------- */
16
static int *row_to_list(matrix_TYP *mat,
17
int i)
18
{
19
int *list, n;
20
21
list = (int *)calloc(mat->cols, sizeof(int));
22
for (n = 0; n < mat->cols; n++)
23
list[n] = mat->array.SZ[i][n];
24
25
return(list);
26
}
27
28
/* ---------------------------------------------------------------------- */
29
/* Setze R und P (nur falls aflag = TRUE), in die Zeilen von mat ein. */
30
/* ---------------------------------------------------------------------- */
31
/* Rinv = R^{-1} */
32
/* Pinv = P^{-1} */
33
/* mat: Matrix mit Worten aus GAP */
34
/* (letzte Zeile: Laenge der Bahn unter Raumgr. und Pkt.gr.ordnung) */
35
/* ---------------------------------------------------------------------- */
36
TSubgroup_TYP *ite_gruppe(bravais_TYP *R,
37
bravais_TYP *P,
38
bravais_TYP *Rinv,
39
bravais_TYP *Pinv,
40
matrix_TYP *mat,
41
boolean aflag)
42
{
43
bravais_TYP *sg, *psg = NULL;
44
45
int j, *word;
46
47
TSubgroup_TYP *S;
48
49
50
sg = init_bravais(R->dim);
51
sg->gen_no = mat->rows - 1;
52
sg->gen = (matrix_TYP **)calloc(sg->gen_no, sizeof(matrix_TYP *));
53
if (aflag){
54
psg = init_bravais(P->dim);
55
psg->gen_no = mat->rows - 1;
56
psg->gen = (matrix_TYP **)calloc(psg->gen_no, sizeof(matrix_TYP *));
57
}
58
59
for (j = 0; j < sg->gen_no; j++){
60
word = row_to_list(mat, j);
61
sg->gen[j] = mapped_word(word, R->gen, Rinv->gen);
62
if (aflag)
63
psg->gen[j] = mapped_word(word, P->gen, Pinv->gen);
64
free(word);
65
}
66
67
/* in Struktur eintragen */
68
/* ===================== */
69
S = (TSubgroup_TYP *)calloc(1, sizeof(TSubgroup_TYP));
70
S->R = sg;
71
S->P = psg;
72
S->orbitlength = mat->array.SZ[mat->rows - 1][0];
73
S->pointgrouporder = mat->array.SZ[mat->rows - 1][1];
74
sg = NULL;
75
}
76
77
78
79
80
81
82
83
/* ---------------------------------------------------------------------- */
84
/* Berechne die maximalen klassengleichen Untergruppen einer Raumgruppe */
85
/* bis auf Konjugation unter der Raumgruppe. */
86
/* ---------------------------------------------------------------------- */
87
/* R: Raumgruppe in Standard affiner Form ohne Translationen */
88
/* P: Punktgruppe von R (korrespondierende Erzeuger an der gleichen */
89
/* Position), P->gen, P->normal und P->cen zusammen muessen */
90
/* N_Gl_n(Z) (P) erzeugen. */
91
/* Der Formenraum muss korrekt sein. */
92
/* pres: Praesentation von P */
93
/* gapmats: Worte fuer die Konjugiertenklassen von maximalen Unter- */
94
/* gruppen von P aus GAP */
95
/* no: Anzahl der Konjugiertenklassen */
96
/* aflag: Raumgruppen bis auf Konjugation unter dem affinen Normalisator */
97
/* der Raumgruppe R */
98
/* cflag: Ausgabe fuer Datenbank */
99
/* aflag wird auf true gesetzt */
100
/* ---------------------------------------------------------------------- */
101
TSubgroup_TYP **tsubgroup(bravais_TYP *R,
102
bravais_TYP *P,
103
matrix_TYP *pres,
104
matrix_TYP **gapmats,
105
int *no,
106
boolean aflag,
107
boolean cflag)
108
{
109
bravais_TYP *Rinv, *Pinv;
110
111
TSubgroup_TYP **sbg, **S;
112
113
int i, j, counter, *orbit,
114
Nanz, Nanzalt, *factor;
115
116
matrix_TYP **base, *M, **N;
117
118
bahn **strong;
119
120
CARATname_TYP Name;
121
122
database *database;
123
124
125
126
if (cflag)
127
aflag = TRUE;
128
129
/* lade Datenbank */
130
database = load_database(DATABASE_NAME, P->dim);
131
132
133
134
135
/* Nur die triviale Raumgruppe ist maximale Untergruppe! */
136
/* ===================================================== */
137
if (no[0] == 1 && gapmats[0]->rows == 1){
138
sbg = (TSubgroup_TYP **)calloc(no[0], sizeof(TSubgroup_TYP *));
139
sbg[0] = (TSubgroup_TYP *)calloc(1, sizeof(TSubgroup_TYP));
140
141
sbg[0]->R = init_bravais(R->dim);
142
sbg[0]->R->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
143
sbg[0]->R->gen_no = 1;
144
sbg[0]->R->gen[0] = init_mat(R->dim, R->dim, "1");
145
146
sbg[0]->orbitlength = 1;
147
sbg[0]->pointgrouporder = 1;
148
149
sbg[0]->P = init_bravais(P->dim);
150
sbg[0]->P->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
151
sbg[0]->P->gen_no = 1;
152
sbg[0]->P->gen[0] = init_mat(P->dim, P->dim, "1");
153
154
if (cflag){
155
Name = name_fct(R, database);
156
printf("#1 %i %i ", Name.zname[0], Name.zname[1]);
157
mpz_out_str(stdout, 10, &Name.aff_name);
158
printf("\n");
159
free_CARATname_TYP(Name);
160
Name = name_fct(sbg[0]->R, database);
161
printf("0 1 %s %i %i ", Name.qname, Name.zname[0], Name.zname[1]);
162
mpz_out_str(stdout, 10, &Name.aff_name);
163
printf("\n");
164
free_CARATname_TYP(Name);
165
}
166
free_database (database);
167
return(sbg);
168
}
169
170
/* Die maximalen Untergruppen sind nicht trivial! */
171
/* ============================================== */
172
S = (TSubgroup_TYP **)calloc(no[0], sizeof(TSubgroup_TYP *));
173
Rinv = init_bravais(R->dim);
174
Rinv->gen_no = R->gen_no;
175
Rinv->gen = (matrix_TYP **)calloc(R->gen_no, sizeof(bravais_TYP *));
176
for (i = 0; i < R->gen_no; i++){
177
Rinv->gen[i] = mat_inv(R->gen[i]);
178
}
179
if (aflag){
180
Pinv = init_bravais(P->dim);
181
Pinv->gen_no = P->gen_no;
182
Pinv->gen = (matrix_TYP **)calloc(P->gen_no, sizeof(bravais_TYP *));
183
for (i = 0; i < P->gen_no; i++){
184
Pinv->gen[i] = mat_inv(P->gen[i]);
185
}
186
}
187
188
for (i = 0; i < no[0]; i++){
189
S[i] = ite_gruppe(R, P, Rinv, Pinv, gapmats[i], aflag);
190
}
191
192
free_bravais(Rinv);
193
194
if (!aflag){
195
free_database(database);
196
return(S);
197
}
198
else{
199
free_bravais(Pinv);
200
201
/* berechne Punktgruppe des affinen Normalisators */
202
/* ============================================== */
203
cen_to_norm(P);
204
N = PoaN(R, P, pres, &Nanz);
205
Nanzalt = Nanz;
206
Nanz = Nanz + P->gen_no;
207
N = (matrix_TYP **)realloc(N, Nanz * sizeof(matrix_TYP *));
208
for (i = 0; i < P->gen_no; i++)
209
N[Nanzalt + i] = copy_mat(P->gen[i]);
210
211
/* Fasse Bahnen unter R zu Bahnen unter affinem Normalisator zusammen */
212
/* ================================================================== */
213
orbit = (int *)calloc(no[0], sizeof(int));
214
factor = (int *)calloc(no[0], sizeof(int));
215
for (i = 0; i < no[0]; i++){
216
orbit[i] = -1;
217
factor[i] = 0;
218
}
219
counter = 0;
220
221
for (i = 0; i < no[0]; i++){
222
if (orbit[i] == -1){
223
orbit[i] = counter;
224
factor[counter] = 1;
225
226
/* Strong generating set berechnen! */
227
base = get_base(S[i]->P);
228
strong = strong_generators(base, S[i]->P, TRUE);
229
for (j = 0; j < P->dim; j++){
230
free_mat(base[j]);
231
}
232
free(base);
233
234
for (j = i + 1; j < no[0]; j++){
235
if(S[i]->pointgrouporder == S[j]->pointgrouporder){
236
237
/* Die Funktion conjugated berechnet Bahn, so
238
dass eigentlich mehrere Gruppen auf einmal getestet
239
werden koennten. */
240
M = conjugated(S[i]->P, S[j]->P, N, Nanz, strong);
241
if (M != NULL){
242
orbit[j] = counter;
243
factor[counter]++;
244
free_mat(M);
245
}
246
}
247
}
248
counter++;
249
for (j = 0; j < P->dim; j++){
250
free_bahn(strong[j]);
251
free(strong[j]);
252
}
253
free(strong);
254
}
255
}
256
257
/* Trage in Struktur ein */
258
/* ===================== */
259
sbg = (TSubgroup_TYP **)calloc(counter, sizeof(TSubgroup_TYP *));
260
j = 0;
261
if (cflag){
262
Name = name_fct(R, database);
263
printf("#%i %i %i ", counter, Name.zname[0], Name.zname[1]);
264
mpz_out_str(stdout, 10, &Name.aff_name);
265
printf("\n");
266
free_CARATname_TYP(Name);
267
}
268
for (i = 0; i < no[0] && j < counter; i++){
269
if (orbit[i] == j){
270
sbg[j] = S[i];
271
sbg[j]->orbitlength *= factor[j];
272
273
if (cflag){
274
Name = name_fct(sbg[j]->R, database);
275
printf("%i %i %s %i %i ", i, sbg[j]->orbitlength,
276
Name.qname, Name.zname[0], Name.zname[1]);
277
mpz_out_str(stdout, 10, &Name.aff_name);
278
printf("\n");
279
free_CARATname_TYP(Name);
280
}
281
282
j++;
283
}
284
else{
285
free_TSubgroup_TYP(S[i]);
286
}
287
}
288
289
no[0] = counter;
290
free(orbit);
291
free(factor);
292
free_database(database);
293
free(S);
294
for (i = 0; i < Nanz; i++)
295
free_mat(N[i]);
296
free(N);
297
return(sbg);
298
}
299
}
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316