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

563580 views
1
/* author: Oliver Heidbuechel */
2
/* last change: 23.11.2000 by author */
3
4
#include<typedef.h>
5
#include<datei.h>
6
#include<getput.h>
7
#include<matrix.h>
8
#include<longtools.h>
9
#include<tools.h>
10
#include"zass.h"
11
#include <bravais.h>
12
#include <presentation.h>
13
#include <graph.h>
14
15
16
17
/* --------------------------------------------------------------- */
18
/* constructs a matrix and writes M no-times on the diagonal */
19
/* --------------------------------------------------------------- */
20
static matrix_TYP *to_diag(matrix_TYP *M,
21
int dim,
22
int no)
23
{
24
int i, j, k;
25
26
matrix_TYP *D;
27
28
29
D = init_mat(M->rows, M->cols * no, "");
30
31
for (i = 0; i < no; i++){
32
for (j = 0; j < dim; j++){
33
for (k = 0; k < dim; k++){
34
D->array.SZ[i * dim + j][i * dim + k] = M->array.SZ[i * dim + j][k];
35
}
36
}
37
}
38
39
return(D);
40
}
41
42
43
/* --------------------------------------------------------------- */
44
/* transl_aff_normal */
45
/* calculate a generating set of the linear part of */
46
/* N_(Aff(R^n))(R(G,0)) with tranlations in Q^n/Z^n */
47
/* returns the set {((G->gen[i] - I) * Translation_j)_i | j = ...} */
48
/* --------------------------------------------------------------- */
49
/* erzeuger: generators of the point group G */
50
/* erzanz : number of matrices in "erzeuger" */
51
/* anzahl : the number of the translations will be saved here */
52
/* --------------------------------------------------------------- */
53
matrix_TYP **transl_aff_normal(matrix_TYP **erzeuger,
54
int erzanz,
55
int *anzahl)
56
{
57
matrix_TYP *B, *B_diag,
58
*translation,
59
**tmp,
60
**transl;
61
62
int k, j, i, dim, zahl;
63
64
65
dim = erzeuger[0]->rows;
66
67
/* create the matrix (g_1 - I, g_2 - I, ...)^tr */
68
B = calc_B(erzeuger,erzanz);
69
70
/* solve (g_j-I)s = 0 (Z^n) for all j */
71
tmp = cong_solve(B);
72
73
/* create matrices */
74
for (anzahl[0] = 0;
75
anzahl[0] < tmp[3]->cols && tmp[3]->array.SZ[anzahl[0]][anzahl[0]] != 0;
76
anzahl[0]++);
77
78
if (anzahl[0] != 0){
79
/* create matrix diag (g_1 - I, g_2 - I, ...) */
80
B_diag = to_diag(B, dim, erzanz);
81
transl = (matrix_TYP **)calloc(anzahl[0], sizeof(matrix_TYP *));
82
for (j = 0; j < anzahl[0]; j++){
83
translation = init_mat(dim * erzanz, 1,"");
84
for (i = 0; i < dim; i++){
85
zahl = tmp[2]->array.SZ[i][j];
86
for (k = 0; k < erzanz; k++){
87
translation->array.SZ[i + k * dim][0] = zahl;
88
}
89
}
90
translation->kgv = tmp[3]->array.SZ[j][j];
91
translation->flags.Integral = FALSE;
92
Check_mat(translation);
93
transl[j] = mat_mul(B_diag, translation);
94
Check_mat(transl[j]);
95
if (transl[j]->kgv != 1){ /* paranoia test */
96
fprintf(stderr, "ERROR in transl_aff_normal\n");
97
exit(7);
98
}
99
free_mat(translation);
100
}
101
free_mat(B_diag);
102
}
103
else{
104
transl = NULL;
105
}
106
107
/* cleaning up */
108
for (j = 0; j < 4; j++){
109
if (tmp[j] != NULL)
110
free_mat(tmp[j]);
111
}
112
free(tmp);
113
free_mat(B);
114
115
return(transl);
116
}
117
118
119
120
/* ---------------------------------------------------------------- */
121
/* cong_solve_part */
122
/* Calculates one solution of A*s = c (Z^m) */
123
/* If there is no solution, the function returns NULL. */
124
/* ---------------------------------------------------------------- */
125
/* A and c are matrices with A in Z^(nxm) and c in Q^(nx1) */
126
/* ---------------------------------------------------------------- */
127
static matrix_TYP *cong_solve_part(matrix_TYP *A,
128
matrix_TYP *c)
129
{
130
matrix_TYP *R,
131
*L,
132
*D,
133
*r,
134
*hilfsloesung,
135
*loesung;
136
137
int i, last;
138
139
140
/* trivial case */
141
if (equal_zero(A) == 1 && equal_zero(c) == 1){
142
loesung = init_mat(A->cols, 1, "");
143
return(loesung);
144
}
145
146
147
L = init_mat(A->rows,A->rows,"1");
148
R = init_mat(A->cols,A->cols,"1");
149
hilfsloesung = init_mat(A->cols,1,"");
150
151
/* find matrices D,L,R with LAR = D and D is the elemantary divisor matrix
152
and L in Gl_n(Z) and R in Gl_m(Z) */
153
D = long_elt_mat(L, A, R);
154
for (last = 0; last<D->cols && D->array.SZ[last][last] != 0; last++);
155
r = mat_mul(L,c);
156
157
/* change the entries in r such that 0 <= r->array.SZ[i][0] < r->kgv
158
(example: -5/3 will be changed to 1/3) */
159
for (i=0; i<r->rows; i++){
160
r->array.SZ[i][0] %= r->kgv;
161
if (r->array.SZ[i][0] < 0)
162
r->array.SZ[i][0] += r->kgv;
163
}
164
165
/* Find one solution of D*t = r (Z^m) */
166
hilfsloesung->kgv = r->kgv * D->array.SZ[last-1][last-1];
167
for (i=0; i<last; i++){
168
if (r->array.SZ[i][0] == 0)
169
hilfsloesung->array.SZ[i][0] = 0;
170
else{
171
hilfsloesung->array.SZ[i][0] = r->array.SZ[i][0]
172
* D->array.SZ[last-1][last-1] / D->array.SZ[i][i];
173
}
174
}
175
for (i=last; i<D->cols; i++){
176
if (r->array.SZ[i][0] != 0){
177
loesung = NULL;
178
}
179
}
180
181
/* calculate one solution of A*s = c (Z^m) */
182
loesung = mat_mul(R,hilfsloesung);
183
184
/* cleaning up */
185
free_mat(L);
186
free_mat(R);
187
free_mat(D);
188
free_mat(r);
189
free_mat(hilfsloesung);
190
191
Check_mat(loesung);
192
return(loesung);
193
}
194
195
196
197
/* --------------------------------------------------------------------- */
198
/* Let R be a spacegroup, P = P(R), coz = cocycle of R */
199
/* returns one element in the affine normalizer of R with linear part */
200
/* given by 'lin' (has to be possible) */
201
/* --------------------------------------------------------------------- */
202
matrix_TYP *to_aff_normal_element(matrix_TYP *lin,
203
matrix_TYP *coz,
204
int flag,
205
bravais_TYP *P,
206
bravais_TYP *R)
207
{
208
matrix_TYP *N, *cozl, *DIAG, *cozr, *ccc, *B, *lin_inv, *part;
209
210
bravais_TYP *conj;
211
212
int d, j, k;
213
214
rational eins, minuseins;
215
216
217
218
/* prepare */
219
eins.z = eins.n = minuseins.n = 1;
220
minuseins.z = -1;
221
d = lin->rows;
222
N = copy_mat(lin);
223
real_mat(N, d + 1, d + 1);
224
N->array.SZ[d][d] = 1;
225
226
if (flag != 1){
227
conj = init_bravais(P->dim);
228
conj->gen_no = P->gen_no;
229
conj->gen = (matrix_TYP **)calloc(P->gen_no, sizeof(matrix_TYP *));
230
lin_inv = mat_inv(lin);
231
for (j = 0; j < P->gen_no; j++){
232
conj->gen[j] = mat_kon(lin, P->gen[j], lin_inv);
233
}
234
free_mat(lin_inv);
235
cozl = sg(R, conj);
236
237
DIAG = matrix_on_diagonal(lin, P->gen_no);
238
cozr = mat_mul(DIAG,coz);
239
free_mat(DIAG);
240
ccc = mat_add(cozl,cozr,minuseins,eins);
241
free_mat(cozl);
242
free_mat(cozr);
243
Check_mat(ccc);
244
B = calc_B(conj->gen, conj->gen_no);
245
part = cong_solve_part(B,ccc);
246
if (part == NULL){
247
printf("ERROR in aff_normalisator! cong_solve_part returns NULL!\n");
248
exit(23);
249
}
250
free_mat(ccc);
251
free_mat(B);
252
free_bravais(conj);
253
}
254
else{
255
/* one solution is zero if the spacegroup splits */
256
part = init_mat(d, 1, "");
257
}
258
259
/* construct the matrix */
260
if (part->kgv != 1){
261
for (j = 0; j < d; j++)
262
for (k = 0; k < d; k++)
263
N->array.SZ[j][k] *= part->kgv;
264
N->array.SZ[d][d] = part->kgv;
265
N->kgv = part->kgv;
266
}
267
for (j = 0; j < d; j++)
268
N->array.SZ[j][d] = part->array.SZ[j][0];
269
270
Check_mat(N);
271
free_mat(part);
272
273
return(N);
274
}
275
276
277
278