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

563667 views
1
#include "typedef.h"
2
#include "matrix.h"
3
#include "gmp.h"
4
#include "zass.h"
5
#include "getput.h"
6
#include "tools.h"
7
#include "contrib.h"
8
9
/**************************************************************************
10
@
11
@--------------------------------------------------------------------------
12
@
13
@ FILE: torsionfree.c
14
@
15
@--------------------------------------------------------------------------
16
@
17
***************************************************************************/
18
19
/* compare two matrix */
20
static int is_equal(matrix_TYP *x,
21
matrix_TYP *y)
22
{
23
int i,
24
j,
25
cols,
26
rows;
27
28
cols = x->cols;
29
rows = x->rows;
30
31
for (i = 0 ; i < rows ; i++){
32
for(j = 0 ; j < cols ; j++){
33
if ((y->kgv * x->array.SZ[i][j]) != (x->kgv * y->array.SZ[i][j])){
34
return FALSE;
35
}
36
}
37
}
38
39
return TRUE;
40
}
41
42
43
/* compare two matrix (linear part only) */
44
static int lin_is_equal(matrix_TYP *x,
45
matrix_TYP *y)
46
{
47
int i,
48
j,
49
cols,
50
rows;
51
52
cols = x->cols - 1;
53
rows = x->rows - 1;
54
55
for (i = 0 ; i < rows ; i++)
56
for(j = 0 ; j < cols ; j++)
57
if ((x->array.SZ[i][j] * y->kgv) != (y->array.SZ[i][j] * x->kgv))
58
return FALSE;
59
return TRUE;
60
}
61
62
63
/* calculate the linear part P of R */
64
matrix_TYP *lin(matrix_TYP *x)
65
{
66
matrix_TYP *y;
67
y = copy_mat (x);
68
real_mat (y, y->rows-1, y->cols-1);
69
Check_mat (y);
70
return y;
71
}
72
73
/* calculate the cyclotomic polyn */
74
static matrix_TYP *pol_cycl(matrix_TYP *x,
75
int p)
76
{
77
rational one;
78
79
int i;
80
81
matrix_TYP *y,
82
*Id,
83
*RES;
84
85
one.z = 1;
86
one.n = 1;
87
88
y = copy_mat(x);
89
Id = init_mat(x->rows, x->cols, "i1");
90
RES = init_mat(x->rows, x->cols, "i1");
91
92
for(i=1 ; i < p ; i++){
93
RES = mat_muleq( RES , y );
94
RES = mat_addeq( RES, Id , one , one);
95
}
96
free_mat (y);
97
free_mat (Id);
98
99
return RES;
100
}
101
102
/* calculate the n-power of a matrix */
103
static matrix_TYP *power(matrix_TYP *x,
104
int n)
105
{
106
int i;
107
108
matrix_TYP *y;
109
110
y = init_mat(x->rows, x->cols, "i1");
111
if (n == 0){
112
return y;
113
}
114
else{
115
for(i=0 ; i < n ; i++){
116
y = mat_muleq( y , x );
117
}
118
119
return y;
120
121
}
122
}
123
124
125
/* calculate the order of a matrix */
126
static int ORDER(matrix_TYP *A)
127
{
128
129
int i = 1;
130
131
matrix_TYP *B;
132
133
B = copy_mat(A);
134
Check_mat(B);
135
136
while (! ( B->flags.Scalar && B->array.SZ[0][0] == 1)){
137
mat_muleq(B,A);
138
Check_mat(B);
139
i++;
140
}
141
142
free_mat(B);
143
return i;
144
}
145
146
147
/**************************************************************************
148
@
149
@--------------------------------------------------------------------------
150
@
151
@ int *torsionfree(bravais_TYP *R,
152
@ int *order_out,
153
@ int *number_of_conjugacy_classes){
154
@
155
@ decides whether the space group in R is torsion free, and ONLY
156
@ IN THIS CASES decides whether the group has trivial center or
157
@ not.
158
@ The result is a pointer A, say, which points to two integers with
159
@ the following convention:
160
@ A[0] == TRUE iff the group R is torsion free.
161
@ A[1] == TRUE iff A[0] == TRUE and the group R has trivial center.
162
@
163
@ bravais_TYP *R: a bravais_TYP with generators which together
164
@ with Z^n generate the space group in Question.
165
@ int *order : The order of the point group is stored here after
166
@ the calculation has been done
167
@ int *number_of_conjugacy_classes: The number of conjugacy classes of
168
@ the point group of R is stored here.
169
@--------------------------------------------------------------------------
170
@
171
***************************************************************************/
172
int *torsionfree(bravais_TYP *R,
173
int *order_out,
174
int *number_of_conjugacy_classes){
175
176
int i,
177
j,
178
k,
179
l,
180
new_index,
181
act_number,
182
dim,
183
*mirror,
184
*processed,
185
*list_primes,
186
num_gen,
187
order,
188
*RES;
189
190
191
matrix_TYP **ele,
192
**gen,
193
**repres,
194
**gen_inv,
195
**gen_ident,
196
*conj,
197
*new_elem,
198
*M,
199
*X,
200
*linear,
201
*w,
202
*y,
203
*bahn,
204
*bahn1,
205
*bahn2,
206
*ed1,
207
*ed2;
208
209
RES = (int *) calloc(2 , sizeof(int));
210
211
num_gen = R->gen_no;
212
gen = R->gen;
213
dim = R->dim;
214
215
216
ele = (matrix_TYP **) malloc(110000 * sizeof(matrix_TYP *));
217
gen_inv = (matrix_TYP **) malloc(num_gen * sizeof(matrix_TYP *));
218
repres = (matrix_TYP **) malloc(110000 * sizeof(matrix_TYP *));
219
gen_ident = (matrix_TYP **) malloc(num_gen * sizeof(matrix_TYP *));
220
221
/* We will generate a list ele[] of elements of R that are pre image P */
222
/* "order" is the order of P */
223
224
ele[0] = init_mat(dim, dim, "i1");
225
226
order = 1;
227
228
for(i=0; i < order ; i++){
229
for(j=0 ; j < num_gen ; j++){
230
new_elem = mat_mul(ele[i] , gen[j]);
231
Check_mat(new_elem);
232
for(k=0 ; k < order && lin_is_equal(new_elem, ele[k])==FALSE; k++);
233
if (k == order){
234
ele[order] = new_elem;
235
order++;
236
}
237
else{
238
free_mat(new_elem);
239
}
240
}
241
}
242
243
/* If P is trivial, then it's torsion-free ( Z^n) */
244
245
if (order == 1){
246
RES[0] = TRUE;
247
order_out[0] = 1;
248
number_of_conjugacy_classes[0] = 1;
249
free_mat (ele[0]);
250
free (ele);
251
}
252
else{
253
/* for (i=0 ; i< order ; i++)
254
put_mat(ele[i] , NULL , "" , 2); */
255
256
order_out[0] = order;
257
258
/* Now we calculate the (pre-images of) conjugacy classes of elements of P */
259
260
mirror = (int *) malloc(order * sizeof(int));
261
processed = (int *) malloc(order * sizeof(int));
262
263
264
act_number = 0 ;
265
266
for( i=0 ; i < order ; i++){
267
mirror[i] = -1;
268
processed[i] = 0;
269
}
270
271
for (i=0; i < num_gen ; i++){
272
gen_inv[i] = mat_inv(gen[i]);
273
}
274
275
for (i=0 ; i < order ; i++){
276
if (mirror[i] == -1){
277
act_number++;
278
mirror[i] = act_number;
279
280
for ( j = i ; j < order ; j++){
281
new_index = j;
282
if (mirror[j] == act_number && processed[j] == 0){
283
processed[j] = 1;
284
285
for (k=0 ; k < num_gen ; k++){
286
conj = mat_kon( gen[k] , ele[j] , gen_inv[k]);
287
for(l=0 ; l < order && lin_is_equal(conj, ele[l])==FALSE; l++);
288
mirror[l] = act_number;
289
if (l < new_index && processed[l] == 0){
290
new_index = l - 1;
291
}
292
free_mat(conj);
293
}
294
}
295
j = new_index;
296
}
297
}
298
}
299
number_of_conjugacy_classes[0] = act_number;
300
301
for (i=0; i<num_gen; i++)
302
free_mat (gen_inv[i]);
303
free (gen_inv);
304
305
/* we will generate a list repres[] of repres of conjug classes */
306
/* act_number is the number of classes. */
307
308
if(act_number == order){
309
for (i=0 ; i < order ; i++)
310
repres[i] = ele[i];
311
}
312
else{
313
for( i=0 ; i < act_number ; i++){
314
for(j = 0 ; j < order && mirror[j] != i+1 ; j++);
315
repres[i] = ele[j];
316
}
317
}
318
319
free (mirror); free (processed);
320
321
list_primes = factorize(order);
322
323
for (i=2 ; i < 98 ; i++){
324
if ( list_primes[i] != 0){
325
for (j = 0 ; j < act_number ; j++){
326
linear = lin(repres[j]);
327
if (i == ORDER (linear)){
328
329
bahn = pol_cycl(linear, i);
330
bahn1 = tr_pose (bahn);
331
332
free_mat (bahn);
333
free_mat (linear);
334
335
w = power (repres[j],i);
336
y = init_mat(1,dim - 1,"");
337
338
for (l=0; l < dim-1; l++){
339
y->array.SZ[0][l] = w->array.SZ[l][dim-1];
340
}
341
342
bahn2 = copy_mat (bahn1);
343
real_mat (bahn2 , dim , dim-1);
344
for (k=0; k < dim-1; k++){
345
bahn2->array.SZ[dim-1][k] = y->array.SZ[0][k];
346
}
347
348
ed1 = elt_div(bahn1);
349
ed2 = elt_div(bahn2);
350
351
if(is_equal(ed1 , ed2) == TRUE){
352
free (list_primes);
353
free (gen_ident);
354
free_mat (bahn1); free_mat (ed1);
355
free_mat (bahn2); free_mat (ed2);
356
free_mat (y); free_mat (w);
357
for (i=0; i<order; i++)
358
free_mat (ele[i]);
359
free (ele);
360
free (repres);
361
return RES;
362
}
363
free_mat (bahn1); free_mat(ed1);
364
free_mat (bahn2); free_mat(ed2);
365
free_mat (y); free_mat (w);
366
}
367
else{
368
free_mat (linear);
369
}
370
}
371
}
372
}
373
RES[0] = TRUE;
374
375
376
377
for (i=0; i<order; i++)
378
free_mat (ele[i]);
379
free (ele);
380
free (repres);
381
free (list_primes);
382
383
384
/** CALCULATE THE CENTRE **/
385
386
/* We look for the module L^P, the elements of the lattice
387
L centralized by P, the point-group */
388
389
/* We create a list of matrix, gen_ident, equal to linear part
390
of gen minus the Identity */
391
392
for(i=0 ; i < num_gen ; i++){
393
gen_ident[i] = init_mat(dim-1,dim-1,"");
394
for (j=0 ; j < dim -1 ; j++){
395
for (k = 0 ; k < dim - 1 ; k++){
396
if (k == j ){
397
gen_ident[i]->array.SZ[j][k] = (gen[i]->array.SZ[j][k]/gen[i]->kgv) - 1;
398
}
399
else{
400
gen_ident[i]->array.SZ[j][k] = gen[i]->array.SZ[j][k]/gen[i]->kgv;
401
}
402
}
403
}
404
}
405
406
407
/* construct a greater matrix M with the ones above */
408
409
410
M = init_mat (num_gen*(dim-1) , dim-1 , "");
411
412
for (i = 0 ; i < num_gen ; i++){
413
for (j = i*(dim-1) ; j < (i+1)*(dim-1) ; j++){
414
for (k = 0 ; k < dim - 1 ; k++){
415
M->array.SZ[j][k] = gen_ident[i]->array.SZ[j-i*(dim-1)][k];
416
}
417
}
418
}
419
420
for (i=0; i<num_gen; i++)
421
free_mat (gen_ident[i]);
422
free (gen_ident);
423
424
X = solve_mat(M);
425
/* the rows of X are Z-basis for the solution of MX = 0 */
426
free_mat (M);
427
428
if (X->rows == 0){
429
RES[1] = TRUE;
430
}
431
else if (X->rows == 1){
432
for (i = 0 ; i < dim-1 && X->array.SZ[0][i] == 0; i++);
433
if (i == dim-1){
434
RES[1] = TRUE;
435
}
436
}
437
free_mat (X);
438
439
}
440
441
return RES;
442
}
443
444