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
4
/**************************************************************************\
5
@---------------------------------------------------------------------------
6
@---------------------------------------------------------------------------
7
@ FILE: rform.c
8
@---------------------------------------------------------------------------
9
@---------------------------------------------------------------------------
10
@
11
\**************************************************************************/
12
13
#define DEFEPS 100
14
#define DEFPRIME 5
15
#define MAXDEN 1000000
16
#define MAXSTEP 10000
17
#define JUMP 5
18
#define EPS 0.000001
19
20
static double ***g, **x, **xt, **t, **t1, diff, diff1;
21
static int dim, num;
22
static double **sxt, **st, **st1, err, sdiff, sdiff1;
23
24
25
26
27
static int ggt(a, b)
28
int a, b;
29
{
30
int r;
31
32
if (b == 0)
33
return(abs(a));
34
35
while ((r = a % b) != 0)
36
{
37
a = b;
38
b = r;
39
}
40
return (abs(b));
41
}
42
43
44
45
static void rmatfac(A, m, B, n)
46
double **A, **B, m;
47
int n;
48
{
49
double *a, *b;
50
int i, j;
51
52
53
for (i = 0; i < n; ++i)
54
{
55
a = A[i];
56
b = B[i];
57
for (j = 0; j < n; ++j)
58
b[j] = a[j] * m;
59
}
60
}
61
62
63
64
static int rmatone(A, n)
65
double **A;
66
int n;
67
{
68
int i, j;
69
70
71
for (i = 0; i < n; ++i)
72
{
73
if (fabs(A[i][i] - 1.0) > EPS)
74
return 0;
75
for (j = 0; j < n; ++j)
76
{
77
if (j != i && fabs(A[i][j]) > EPS)
78
return 0;
79
}
80
}
81
return 1;
82
}
83
84
85
static void rmatadd(A, B, C, n)
86
double **A, **B, **C;
87
int n;
88
{
89
double *a, *b, *c;
90
int i, j;
91
92
93
for (i = 0; i < n; ++i)
94
{
95
a = A[i];
96
b = B[i];
97
c = C[i];
98
for (j = 0; j < n; ++j)
99
c[j] = a[j] + b[j];
100
}
101
}
102
103
104
105
static void rmatmul(A, B, C, n)
106
double **A, **B, **C;
107
int n;
108
{
109
double *a, c;
110
int i, j, k;
111
112
113
for (i = 0; i < n; ++i)
114
{
115
a = A[i];
116
for (j = 0; j < n; ++j)
117
{
118
c = 0;
119
for (k = 0; k < n; ++k)
120
{
121
if (a[k] != 0.0 && B[k][j] != 0.0)
122
c += a[k] * B[k][j];
123
}
124
C[i][j] = c;
125
}
126
}
127
}
128
129
130
static void rmattrans(A, B, C, n)
131
double **A, **B, **C;
132
int n;
133
{
134
double **D, *d, c;
135
int i, j, k;
136
137
138
if ((D = (double**)malloc(n * sizeof(double))) == 0)
139
exit (2);
140
for (i = 0; i < n; ++i)
141
{
142
if ((D[i] = (double*)malloc(n * sizeof(double))) == 0)
143
exit (2);
144
}
145
146
rmatmul(B, A, D, n);
147
148
for (i = 0; i < n; ++i)
149
{
150
d = D[i];
151
for (j = 0; j < n; ++j)
152
{
153
c = 0;
154
for (k = 0; k < n; ++k)
155
c += d[k] * B[j][k];
156
C[i][j] = c;
157
}
158
}
159
160
for (i = 0; i < n; ++i)
161
free(D[i]);
162
free(D);
163
}
164
165
166
167
168
169
static int gcd(f, dim)
170
int **f, dim;
171
{
172
int n, i, j;
173
174
n = f[0][0];
175
for (i = 0; i < dim; ++i)
176
{
177
for (j = 0; j < dim; ++j)
178
{
179
if (f[i][j] != 0)
180
n = ggt(n, f[i][j]);
181
if (n == 1)
182
return 1;
183
}
184
}
185
if (n == 0)
186
return 1;
187
else
188
return n;
189
}
190
191
static int rond(X)
192
double X;
193
{
194
if (X >= 0)
195
return (int)(2*fabs(X) + 1.0) / 2;
196
else
197
return -((int)(2*fabs(X) + 1.0) / 2);
198
}
199
200
static int chain(X, e)
201
double X, e;
202
{
203
double *r, rest;
204
int i, *a, step, temp, nm = 0, dn = 1;
205
double cond;
206
207
/* inserted tilman 05/06/97 */
208
if (e<EPS) e = EPS;
209
cond = e;
210
211
if ((r = (double*)malloc(sizeof(double))) == 0)
212
exit (2);
213
if ((a = (int*)malloc(sizeof(int))) == 0)
214
exit (2);
215
temp = fabs(X);
216
rest = fabs(X) - temp;
217
step = 0;
218
r[0] = rest;
219
220
/* added the cond restriction because of numerical problems.
221
for the formula of it see the expansion of 1/(x + epsilon) */
222
while ((fabs(rest - (double)nm / (double)dn) > e ) &&
223
((cond = fabs(cond / r[step]/ r[step]))< 1.0))
224
{
225
++step;
226
if ((r = (double*)realloc(r, (step+1) * sizeof(double))) == 0)
227
exit (2);
228
if ((a = (int*)realloc(a, step * sizeof(int))) == 0)
229
exit (2);
230
231
a[step-1] = rond(1/r[step-1]);
232
r[step] = 1/r[step-1] - a[step-1];
233
nm = 1;
234
dn = a[step-1];
235
for (i = step-2; i >= 0; --i)
236
{
237
temp = dn;
238
dn = a[i] * dn + nm;
239
nm = temp;
240
}
241
242
}
243
free(r);
244
free(a);
245
return abs(dn);
246
}
247
248
249
250
static int dtoi(y, f, ep, dim)
251
double **y, ep;
252
int **f, dim;
253
{
254
int i, j, den, max;
255
256
max = 1;
257
for (i = 0; i < dim; ++i)
258
{
259
for (j = 0; j < dim; ++j)
260
{
261
den = 1;
262
/* changed 05/06/97 tilman from
263
f[i][j] = y[i][j]; to: */
264
f[i][j] = floor(y[i][j] + 0.5);
265
if (fabs(y[i][j] - (double)f[i][j]) >= ep)
266
{
267
if (y[i][j] > 0 &&
268
fabs(y[i][j]-(double)f[i][j]-1.0) < ep)
269
f[i][j] += 1;
270
else if (y[i][j] < 0 &&
271
fabs(y[i][j]-(double)f[i][j]+1.0) < ep)
272
f[i][j] -= 1;
273
else
274
{
275
den = chain(y[i][j], ep);
276
if (den > max)
277
max = den;
278
}
279
}
280
}
281
}
282
return max;
283
}
284
285
286
287
static int iterate(step, x, g, num, dim)
288
double **x, ***g;
289
int step, num, dim;
290
{
291
double factor;
292
int i, j, k;
293
294
rmatfac(x, 1.0, st, dim);
295
rmatfac(x, 1.0, sxt, dim);
296
for (k = 0; k < JUMP; ++k)
297
{
298
++step;
299
for (i = 0; i < num; ++i)
300
{
301
rmattrans(x, g[i], st1, dim);
302
rmatadd(st, st1, st, dim);
303
}
304
for (i = 0; i < dim; ++i)
305
{
306
for (j = 0; j < dim; ++j)
307
{
308
st[i][j] *= 1/(double)(num+1);
309
x[i][j] = st[i][j];
310
}
311
}
312
}
313
314
sdiff1 = 0;
315
for (i = 0; i < dim; ++i)
316
{
317
for (j = 0; j < dim; ++j)
318
{
319
if (sdiff1 < fabs(sxt[i][j] - x[i][j]))
320
sdiff1 = fabs(sxt[i][j] - x[i][j]);
321
}
322
}
323
324
rmatfac(x, 1.0, sxt, dim);
325
for (k = 0; k < JUMP; ++k)
326
{
327
++step;
328
for (i = 0; i < num; ++i)
329
{
330
rmattrans(x, g[i], st1, dim);
331
rmatadd(st, st1, st, dim);
332
}
333
for (i = 0; i < dim; ++i)
334
{
335
for (j = 0; j < dim; ++j)
336
{
337
st[i][j] *= 1/(double)(num+1);
338
x[i][j] = st[i][j];
339
}
340
}
341
}
342
343
sdiff = 0;
344
for (i = 0; i < dim; ++i)
345
{
346
for (j = 0; j < dim; ++j)
347
{
348
if (sdiff < fabs(sxt[i][j] - x[i][j]))
349
sdiff = fabs(sxt[i][j] - x[i][j]);
350
}
351
}
352
353
if (sdiff == 0 || sdiff1 == 0)
354
err = 0.0;
355
else
356
{
357
factor = pow(sdiff/sdiff1, 1.0/(double)JUMP);
358
if (factor >= 1)
359
err = 1;
360
else
361
err = sdiff*sdiff/(sdiff1-sdiff);
362
/* printf("step %d: sdiff = %.12lf err: %.12lf factor: %.12lf\n",
363
step, sdiff, err, 1/factor); */
364
}
365
return step;
366
}
367
368
369
static int symel(x, g, num, dim, eps, f)
370
double **x, ***g;
371
int num, dim, eps, **f;
372
{
373
int gc, i, j, k, den, maxden, step, neweps;
374
375
if ((sxt = (double**)malloc(dim * sizeof(double*))) == 0)
376
exit (2);
377
if ((st = (double**)malloc(dim * sizeof(double*))) == 0)
378
exit (2);
379
if ((st1 = (double**)malloc(dim * sizeof(double*))) == 0)
380
exit (2);
381
for (i = 0; i < dim; ++i)
382
{
383
if ((sxt[i] = (double*)malloc(dim * sizeof(double))) == 0)
384
exit (2);
385
if ((st[i] = (double*)malloc(dim * sizeof(double))) == 0)
386
exit (2);
387
if ((st1[i] = (double*)malloc(dim * sizeof(double))) == 0)
388
exit (2);
389
}
390
for (i = 0; i < dim; ++i)
391
{
392
for (j = 0; j < dim; ++j)
393
st[i][j] = x[i][j];
394
}
395
396
step = 0;
397
err = 1.0;
398
step = iterate(step, x, g, num, dim);
399
while (err > 0.3/(double)eps && step < MAXSTEP)
400
step = iterate(step, x, g, num, dim);
401
if (step >= MAXSTEP)
402
{
403
printf("Verfahren hat nach %d Schritten nicht konvergiert !\n", step);
404
exit(3);
405
return 0;
406
}
407
den = 0;
408
while (den != 1)
409
{
410
den = dtoi(x, f, 2*err, dim);
411
if (den != 1)
412
{
413
maxden = den+1;
414
while (maxden > den && maxden < MAXDEN)
415
{
416
neweps = (maxden < eps) ? eps*maxden : maxden*maxden;
417
418
/* inserted tilman 09/06/97 */
419
if (1/(double) neweps < EPS) neweps = 1/EPS;
420
421
while (err > 0.3/(double)neweps && step < MAXSTEP)
422
step = iterate(step, x, g, num, dim);
423
if (step >= MAXSTEP)
424
{
425
printf("Verfahren hat nach %d Schritten nicht konvergiert !\n", step);
426
exit(3);
427
return 0;
428
}
429
den = maxden;
430
/* printf("Versuch mit %d\n", den); */
431
maxden = dtoi(x, f, 2*err, dim);
432
}
433
rmatfac(x, (double)maxden, x, dim);
434
/* printf("Nenner mit %d multipliziert\n", maxden);*/
435
err *= maxden;
436
}
437
}
438
439
gc = gcd(f, dim);
440
/* printf("ggt %d\n", gc);
441
*/ for (i = 0; i < dim; ++i)
442
{
443
for (j = 0; j < dim; ++j)
444
{
445
f[i][j] /= gc;
446
st[i][j] = (double)f[i][j];
447
}
448
}
449
for (i = 0; i < num; ++i)
450
{
451
rmattrans(st, g[i], st1, dim);
452
for (j = 0; j < dim; ++j)
453
{
454
for (k = 0; k < dim; ++k)
455
{
456
if (st1[j][k] != st[j][k])
457
{
458
printf("Matrix tuts nicht !\n");
459
exit(3);
460
return 0;
461
}
462
}
463
}
464
}
465
for(i=0;i<dim;i++)
466
{ free(sxt[i]); free(st[i]); free(st1[i]);}
467
free(sxt); free(st); free(st1);
468
return (step);
469
}
470
471
472
473
static double try()
474
{
475
double conv;
476
int i, j, k;
477
478
rmatfac(x, 1.0, t, dim);
479
for (k = 0; k < 4; ++k)
480
{
481
for (i = 0; i < num; ++i)
482
{
483
rmattrans(x, g[i], t1, dim);
484
rmatadd(t, t1, t, dim);
485
}
486
for (i = 0; i < dim; ++i)
487
{
488
for (j = 0; j < dim; ++j)
489
{
490
t[i][j] *= 1/(double)(num+1);
491
x[i][j] = t[i][j];
492
}
493
}
494
}
495
496
rmatfac(x, 1.0, xt, dim);
497
for (k = 0; k < 3; ++k)
498
{
499
for (i = 0; i < num; ++i)
500
{
501
rmattrans(x, g[i], t1, dim);
502
rmatadd(t, t1, t, dim);
503
}
504
for (i = 0; i < dim; ++i)
505
{
506
for (j = 0; j < dim; ++j)
507
{
508
t[i][j] *= 1/(double)(num+1);
509
x[i][j] = t[i][j];
510
}
511
}
512
}
513
514
diff1 = 0;
515
for (i = 0; i < dim; ++i)
516
{
517
for (j = 0; j < dim; ++j)
518
{
519
if (diff1 < fabs(xt[i][j] - x[i][j]))
520
diff1 = fabs(xt[i][j] - x[i][j]);
521
}
522
}
523
524
rmatfac(x, 1.0, xt, dim);
525
for (k = 0; k < 3; ++k)
526
{
527
for (i = 0; i < num; ++i)
528
{
529
rmattrans(x, g[i], t1, dim);
530
rmatadd(t, t1, t, dim);
531
}
532
for (i = 0; i < dim; ++i)
533
{
534
for (j = 0; j < dim; ++j)
535
{
536
t[i][j] *= 1/(double)(num+1);
537
x[i][j] = t[i][j];
538
}
539
}
540
}
541
542
diff = 0;
543
for (i = 0; i < dim; ++i)
544
{
545
for (j = 0; j < dim; ++j)
546
{
547
if (diff < fabs(xt[i][j] - x[i][j]))
548
diff = fabs(xt[i][j] - x[i][j]);
549
}
550
}
551
552
conv = pow(diff/diff1, 1.0/3.0);
553
return (1/conv);
554
}
555
556
557
/**************************************************************************\
558
@---------------------------------------------------------------------------
559
@ matrix_TYP *rform(B, Banz, Fo, epsilon)
560
@ matrix_TYP **B;
561
@ int Banz;
562
@ matrix_TYP *Fo;
563
@ int epsilon;
564
@
565
@ If G denotes the group generated by B[0],...,B[Banz-1],
566
@ then 'rform' calculates a matrix A that is the sum over all g in G of
567
@ g^{tr} * Fo * g
568
@ This matrix is divided by the gcd of its entries and returned.
569
@ The algorithm uses an appoximation and the precession is 1/epsilon.
570
@ If epsilon < 100, the function sets epsilon = 100.
571
@---------------------------------------------------------------------------
572
@
573
\**************************************************************************/
574
575
matrix_TYP *rform(B, Banz, Fo, epsilon)
576
matrix_TYP **B;
577
int Banz;
578
matrix_TYP *Fo;
579
int epsilon;
580
{
581
double try();
582
double **save, **pres, *fac, factor;
583
int eps, best, d, i, j, k;
584
matrix_TYP *erg;
585
int test;
586
587
eps = epsilon;
588
if (eps < DEFEPS)
589
eps = DEFEPS;
590
dim = B[0]->cols;
591
if(B[0]->rows != dim)
592
{
593
printf("error in rform: non-square matrix in group 'B'\n");
594
exit(3);
595
}
596
for(i=1;i<Banz;i++)
597
{
598
if(B[i]->rows != dim || B[i]->cols != dim)
599
{
600
printf("error in rform: different dimesion of group elements\n");
601
exit(3);
602
}
603
}
604
num = Banz;
605
erg = init_mat(dim,dim, "k");
606
if ((g = (double***)malloc(num * sizeof(double**))) == 0)
607
exit (2);
608
if ((fac = (double*)malloc(num * sizeof(double))) == 0)
609
exit (2);
610
for (i = 0; i < num; ++i)
611
{
612
if ((g[i] = (double**)malloc(dim * sizeof(double*))) == 0)
613
exit (2);
614
for (j = 0; j < dim; ++j)
615
{
616
if ((g[i][j] = (double*)malloc(dim*sizeof(double)))==0)
617
exit (2);
618
for (k = 0; k < dim; ++k)
619
g[i][j][k] = (double)B[i]->array.SZ[k][j];
620
}
621
}
622
623
if ((x = (double**)malloc(dim * sizeof(double*))) == 0)
624
exit (2);
625
if ((xt = (double**)malloc(dim * sizeof(double*))) == 0)
626
exit (2);
627
if ((t = (double**)malloc(dim * sizeof(double*))) == 0)
628
exit (2);
629
if ((t1 = (double**)malloc(dim * sizeof(double*))) == 0)
630
exit (2);
631
if ((save = (double**)malloc(dim * sizeof(double*))) == 0)
632
exit (2);
633
if ((pres = (double**)malloc(dim * sizeof(double*))) == 0)
634
exit (2);
635
for (i = 0; i < dim; ++i)
636
{
637
if ((x[i] = (double*)malloc(dim * sizeof(double))) == 0)
638
exit (2);
639
if ((xt[i] = (double*)malloc(dim * sizeof(double))) == 0)
640
exit (2);
641
if ((t[i] = (double*)malloc(dim * sizeof(double))) == 0)
642
exit (2);
643
if ((t1[i] = (double*)malloc(dim * sizeof(double))) == 0)
644
exit (2);
645
if ((save[i] = (double*)malloc(dim * sizeof(double))) == 0)
646
exit (2);
647
if ((pres[i] = (double*)malloc(dim * sizeof(double))) == 0)
648
exit (2);
649
}
650
d = Fo->cols;
651
if (d != dim)
652
{
653
printf("Fehler : Unkompatible Dimensionen\n");
654
exit (3);
655
}
656
for (i = 0; i < dim; ++i)
657
{
658
for (j = 0; j < dim; ++j)
659
x[i][j] = (double) Fo->array.SZ[i][j];
660
}
661
for (i = 0; i < dim; ++i)
662
{
663
for (j = 0; j < dim; ++j)
664
save[i][j] = x[i][j];
665
}
666
667
/*
668
factor = try();
669
for (i = 0; i < num; ++i)
670
{
671
for (j = 0; j < num; ++j)
672
{
673
if (j != i)
674
{
675
rmatfac(g[i], 1.0, pres, dim);
676
rmatmul(g[i], g[j], t1, dim);
677
rmatfac(t1, 1.0, g[i], dim);
678
fac[j] = try();
679
rmatfac(pres, 1.0, g[i], dim);
680
rmatfac(save, 1.0, x, dim);
681
}
682
}
683
fac[i] = factor;
684
best = i;
685
for (j = 0; j < num; ++j)
686
{
687
if (fac[j] > fac[best])
688
best = j;
689
}
690
if (best != i)
691
{
692
rmatmul(g[i], g[best], t1, dim);
693
rmatfac(t1, 1.0, g[i], dim);
694
i = -1;
695
}
696
factor = fac[best];
697
}
698
*/
699
700
test = symel(x, g, num, dim, eps, erg->array.SZ);
701
702
for(i=0;i<num;i++)
703
{
704
for(j=0;j<dim;j++)
705
free(g[i][j]);
706
free(g[i]);
707
}
708
free(g);
709
for(i=0;i<dim;i++)
710
{
711
free(x[i]); free(xt[i]); free(t[i]); free(t1[i]);
712
free(save[i]); free(pres[i]);
713
}
714
free(x); free(xt); free(t); free(t1);
715
free(save); free(pres);
716
free(fac);
717
718
if(test != 0)
719
return(erg);
720
else
721
{ free_mat(erg); return(NULL);}
722
}
723
724