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
/**************************************************************************\
3
@---------------------------------------------------------------------------
4
@---------------------------------------------------------------------------
5
@ FILE: orbit_subdivision.c
6
@---------------------------------------------------------------------------
7
@---------------------------------------------------------------------------
8
@
9
\**************************************************************************/
10
11
12
typedef struct {
13
int dim;
14
int len;
15
int n;
16
int **v;
17
} veclist;
18
19
static int *st_w;
20
21
22
static void vecmatmul(x, A, y, dim)
23
int *x, **A, *y, dim;
24
{
25
int i, j, xi, *Ai;
26
27
for (j = 0; j < dim; ++j)
28
y[j] = 0;
29
for (i = 0; i < dim; ++i)
30
{
31
if ((xi = x[i]) != 0)
32
{
33
Ai = A[i];
34
for (j = 0; j < dim; ++j)
35
y[j] += xi * Ai[j];
36
}
37
}
38
}
39
40
static int comp(x, y, n)
41
int *x, *y, n;
42
{
43
int i;
44
45
for (i = 0; i < n && x[i] == y[i]; ++i);
46
if (i == n)
47
return(0);
48
else if (x[i] > y[i])
49
return(1);
50
else
51
return(-1);
52
}
53
54
static int numberof(vec, V)
55
veclist V;
56
int *vec;
57
{
58
int i, sign, dim, low, high, search, cmp;
59
60
sign = 1;
61
dim = V.dim;
62
low = 1;
63
high = V.n;
64
for (i = 0; i < dim && vec[i] == 0; ++i);
65
if (i < dim && vec[i] < 0)
66
{
67
sign = -1;
68
for (i = 0; i < dim; ++i)
69
vec[i] *= -1;
70
}
71
while (low <= high)
72
{
73
search = low + (high-low)/2;
74
cmp = comp(vec, V.v[search], dim);
75
if (cmp == 1)
76
low = search + 1;
77
else if (cmp == -1)
78
high = search - 1;
79
else
80
return(sign * search);
81
}
82
return(sign * (V.n+low));
83
}
84
85
86
87
static void quicksort(v, inf, sup, dim) /***** standard quicksort *****/
88
int **v, inf, sup, dim;
89
{
90
int *tmp, low, med, high;
91
92
if(inf+1 < sup)
93
{
94
/* interchange v[inf] and v[med] to avoid worst case for pre-sorted lists */
95
med = (inf+1+sup)/2;
96
tmp = v[inf];
97
v[inf] = v[med];
98
v[med] = tmp;
99
low = inf+1;
100
high = sup;
101
while(low < high)
102
{
103
while(comp(v[inf], v[low], dim) >= 0 && low < sup)
104
++low;
105
while(comp(v[inf], v[high], dim) <= 0 && high > inf)
106
--high;
107
if(low < high)
108
{
109
tmp = v[high];
110
v[high] = v[low];
111
v[low] = tmp;
112
}
113
}
114
if(inf != high)
115
{
116
tmp = v[high];
117
v[high] = v[inf];
118
v[inf] = tmp;
119
}
120
quicksort(v, inf, high-1, dim);
121
quicksort(v, high+1, sup, dim);
122
}
123
if(inf+1 == sup)
124
{
125
if(comp(v[inf], v[sup], dim) == 1)
126
{
127
tmp = v[inf];
128
v[inf] = v[sup];
129
v[sup] = tmp;
130
}
131
}
132
}
133
134
static void sortvecs(V)
135
veclist *V;
136
{
137
int i, j;
138
139
quicksort(V->v, 1, V->n, V->dim);
140
j = 1;
141
for (i = 1; i+j <= V->n; ++i)
142
{
143
while (i+j <= V->n && comp(V->v[i], V->v[i+j], V->dim) == 0)
144
{
145
free(V->v[i+j]);
146
++j;
147
}
148
if (i+j <= V->n)
149
{
150
V->v[i+1] = V->v[i+j];
151
if (comp(V->v[i], V->v[i+1], V->dim) == 1)
152
{
153
fprintf(stderr, "Error: v[%d] > v[%d]\n", i, i+1);
154
exit (3);
155
}
156
}
157
}
158
V->n -= j-1;
159
}
160
161
162
static int operate(nr, A, V)
163
veclist V;
164
int nr, **A;
165
{
166
int i, im;
167
168
vecmatmul(V.v[abs(nr)], A, st_w, V.dim);
169
if (nr < 0)
170
{
171
for (i = 0; i < V.dim; ++i)
172
st_w[i] *= -1;
173
}
174
/**********************************
175
for(i=0;i<V.dim;i++)
176
printf("%d ", st_w[i]);
177
printf("\n");
178
**********************************/
179
im = numberof(st_w, V);
180
if (abs(im) > V.n)
181
{
182
fprintf(stderr, "Error: image of vector %d not found\n", nr);
183
exit (3);
184
}
185
return(im);
186
}
187
188
189
190
191
/**************************************************************************\
192
@---------------------------------------------------------------------------
193
@ int *orbit_subdivision(vecs, G, orbit_no)
194
@ matrix_TYP *vecs;
195
@ bravais_TYP *G;
196
@ int *orbit_no;
197
@
198
@ 'orbit_subdivision' calculates representatives of the orbit
199
@ of the group 'G' on the rows of the matrix 'vecs'
200
@ The action is assumed to be v -> vg^{tr} for v a row of 'vecs'
201
@ and g in 'G'.
202
@ It is assumed that -Identity is an element of 'G'
203
@ and for a row v the -v must not be contained as a row of 'vecs'.
204
@ Furthermore it is assumed, that the rows of 'vecs' are closed under
205
@ the action of 'G', so if vg^{tr} or -vg^{tr} is no row of 'vecs'
206
@ the programm exits (v rows of 'vecs'. g in 'G').
207
@
208
@ The number of orbits is returned via (int *orbit_no) and
209
@ the result is a pointer to integer of length 'orbit_no'
210
@ where the i-th entry of this pointer is the number of the
211
@ row of 'vecs' that is an representative of the i-th orbit.
212
@
213
@---------------------------------------------------------------------------
214
@
215
\**************************************************************************/
216
int *orbit_subdivision(vecs, G, orbit_no)
217
matrix_TYP *vecs;
218
bravais_TYP *G;
219
int *orbit_no;
220
{
221
veclist V;
222
int i, j, k, n, dim, nG, orblen, orbsum, orbnr, im, cnd;
223
int *orb, *flag, ***grp;
224
int *Vvi;
225
226
nG = G->gen_no;
227
dim = G->gen[0]->cols;
228
V.dim = dim;
229
V.len = vecs->cols;
230
V.n = vecs->rows;
231
if ((orb = (int*)malloc(V.n * sizeof(int))) == 0)
232
exit (2);
233
if ((flag = (int*)malloc((V.n + 1) * sizeof(int))) == 0)
234
exit (2);
235
for (i = 0; i <= V.n; ++i)
236
flag[i] = 0;
237
if ((st_w = (int*)malloc(V.dim * sizeof(int))) == 0)
238
exit (2);
239
if ((V.v = (int**)malloc(((V.n)+1) * sizeof(int*))) == 0)
240
exit (2);
241
for(i=0;i<V.n;i++)
242
V.v[i+1] = vecs->array.SZ[i];
243
if( (grp = (int ***)malloc(nG *sizeof(int **))) == NULL)
244
{
245
printf("malloc of 'grp' in 'orbit_subdivision' failed\n");
246
exit(2);
247
}
248
for(i=0;i<nG;i++)
249
{
250
if( (grp[i] = (int **)malloc(dim *sizeof(int *))) == NULL)
251
{
252
printf("malloc of 'grp[%d]' in 'orbit_subdivision' failed\n",i);
253
exit(2);
254
}
255
for(j=0;j<dim;j++)
256
{
257
if( (grp[i][j] = (int *)malloc(dim *sizeof(int))) == NULL)
258
{
259
printf("malloc of 'grp[%d][%d]' in 'orbit_subdivision' failed\n", i, j);
260
exit(2);
261
}
262
for(k=0;k<dim;k++)
263
grp[i][j][k] = G->gen[i]->array.SZ[k][j];
264
}
265
}
266
for (i = 1; i <= V.n; ++i)
267
{
268
Vvi = V.v[i];
269
for (j = 0; j < V.dim && Vvi[j] == 0; ++j);
270
if (j < V.dim && Vvi[j] < 0)
271
{
272
for (j = 0; j < V.dim; ++j)
273
Vvi[j] *= -1;
274
}
275
}
276
sortvecs(&V);
277
for (i = 1; i <= V.n; ++i)
278
vecs->array.SZ[i-1] = V.v[i];
279
orbsum = 0;
280
orbnr = 1;
281
while (orbsum < 2*V.n)
282
{
283
for (i = 1; i <= V.n && flag[i] != 0; ++i);
284
orb[0] = i;
285
flag[i] = orbnr;
286
orblen = 1;
287
cnd = 0;
288
while (cnd < orblen)
289
{
290
for (i = 0; i < nG; ++i)
291
{
292
im = abs(operate(orb[cnd], grp[i], V));
293
if (flag[im] == 0)
294
{
295
++orblen;
296
orb[orblen-1] = im;
297
flag[im] = orbnr;
298
}
299
}
300
++cnd;
301
}
302
/**********************************
303
for (i = 0; i < V.dim; ++i)
304
printf(" %2d", V.v[orb[0]][i]);
305
printf("\t Length %d\n", 2*orblen);
306
**********************************/
307
orbsum += 2*orblen;
308
++orbnr;
309
}
310
*orbit_no = orbnr-1;
311
312
/* inserted the next 8 lines 15/1/97 */
313
for (i=0;i<nG;i++){
314
for (j=0;j<dim;j++){
315
free(grp[i][j]);
316
}
317
free(grp[i]);
318
}
319
free(grp);
320
free(V.v);
321
322
free(orb);
323
free(st_w);
324
for (i = 1; i <= V.n; ++i)
325
flag[i-1] = flag[i];
326
return(flag);
327
}
328
329