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

563665 views
1
#include"typedef.h"
2
#include"matrix.h"
3
#include"idem.h"
4
#include"gmp.h"
5
#include"symm.h"
6
#include"bravais.h"
7
#include"longtools.h"
8
9
extern int INFO_LEVEL;
10
11
/**************************************************************************
12
@
13
@--------------------------------------------------------------------------
14
@--------------------------------------------------------------------------
15
@ FILE: centr.c
16
@--------------------------------------------------------------------------
17
@--------------------------------------------------------------------------
18
@
19
***************************************************************************/
20
21
/**************************************************************************
22
@
23
@--------------------------------------------------------------------------
24
@
25
@ matrix_TYP **solve_endo(matrix_TYP **A,matrix_TYP **B,int anz,int *dim)
26
@
27
@ Let A[0],..,A[anz-1] be mxm matrices, and B[0],..,B[anz-1] nxn matrices.
28
@ The function returns a Q-basis of the space of mxn matrices with
29
@ A[i] * X = X * B[i] for all i. The dimension is returned via dim[0].
30
@
31
@ SIDEEFFECTS: The matrices in A,B are checked with Check_mat and
32
@ converted with rat2kgv.
33
@--------------------------------------------------------------------------
34
@
35
***************************************************************************/
36
matrix_TYP **solve_endo(matrix_TYP **A,matrix_TYP **B,int anz,int *dim)
37
{
38
int i,
39
j,
40
k,
41
l,
42
m,
43
act_row,
44
Arows=A[0]->rows,
45
Brows=B[0]->rows;
46
47
matrix_TYP *GLS, /* the linar system of equation to be solved */
48
**sols, /* the solutions */
49
**rows; /* the solution as rows */
50
51
if (INFO_LEVEL & 4){
52
fprintf(stderr,"entered solve_endo\n");
53
}
54
55
/* check some trivialities to avoid trouble */
56
for (i=0;i<anz;i++){
57
if ((A[i]->cols != Arows) || (A[i]->cols != Arows) ||
58
(B[i]->cols != Brows) || (B[i]->rows != Brows)){
59
fprintf(stderr,"error in solve_endo\n");
60
exit(3);
61
}
62
rat2kgv(A[i]);
63
Check_mat(A[i]);
64
rat2kgv(B[i]);
65
Check_mat(B[i]);
66
67
/* it shouldn't matter whether or not the matrices are rational
68
if (A[i]->kgv != 1){
69
fprintf(stderr,"error in solve_endo\n");
70
exit(3);
71
}
72
if (B[i]->kgv != 1){
73
fprintf(stderr,"error in solve_endo\n");
74
exit(3);
75
} */
76
}
77
78
/* set the linear system of equations, no big entries will occur */
79
dim[0] = 0;
80
GLS = init_mat(anz*Arows*Brows,Arows*Brows,"");
81
82
for (i=0;i<anz;i++){
83
for (j=0;j<Arows;j++){
84
for (k=0;k<Brows;k++){
85
86
/* set the (i*Arows*Brows + j*Brows + k)-th row of the
87
system of equations */
88
act_row = i*Arows*Brows + j*Brows + k;
89
for (l=0;l<Arows;l++){
90
for (m=0;m<Brows;m++){
91
if (m==k && A[i]->array.SZ[j][l] !=0)
92
GLS->array.SZ[act_row][l*Brows+m] = A[i]->array.SZ[j][l];
93
if (l==j && B[i]->array.SZ[m][k] !=0)
94
GLS->array.SZ[act_row][l*Brows+m] -= B[i]->array.SZ[m][k];
95
}
96
}
97
}
98
}
99
}
100
101
Check_mat(GLS);
102
103
if (INFO_LEVEL & 4){
104
put_mat(GLS,NULL,"GLS",2);
105
}
106
107
/* we got the relevant system of equations, solve it, and use
108
multiple precision integer to avoid overflow */
109
rows = long_solve_mat(GLS,NULL);
110
111
/* we won't need the system of equations anymore */
112
free_mat(GLS);
113
114
if (rows[0] != NULL){
115
fprintf(stderr,"error in solve_endo, rows[0] should be NULL\n");
116
free_mat(rows[0]);
117
}
118
119
if (rows[1] != NULL){
120
/* there is a solution */
121
dim[0] = rows[1]->cols;
122
sols = (matrix_TYP **) malloc(dim[0] * sizeof(matrix_TYP *));
123
124
for (i=0;i<rows[1]->cols;i++){
125
sols[i] = init_mat(Arows,Brows,"");
126
for (l=0;l<Arows;l++)
127
for (m=0;m<Brows;m++)
128
sols[i]->array.SZ[l][m] = rows[1]->array.SZ[l*Brows+m][i];
129
}
130
free_mat(rows[1]);
131
}
132
else{
133
sols = NULL;
134
}
135
136
free(rows);
137
138
return sols;
139
}
140
141
/**************************************************************************
142
@
143
@--------------------------------------------------------------------------
144
@
145
@ matrix_TYP **calc_ccentralizer(matrix_TYP **centr,int dim_centr,
146
@ matrix_TYP **gen,int gen_no,int *dim_cc)
147
@
148
@
149
@--------------------------------------------------------------------------
150
@
151
***************************************************************************/
152
matrix_TYP **calc_ccentralizer(matrix_TYP **centr,int dim_centr,
153
matrix_TYP **gen,int gen_no,int *dim_cc)
154
{
155
int anz = dim_centr + gen_no;
156
157
matrix_TYP **tmp,
158
**erg;
159
160
tmp = (matrix_TYP **) malloc(anz * sizeof(matrix_TYP *));
161
162
/* the first matrices of tmp will be those of centr */
163
memcpy(tmp,centr,dim_centr * sizeof(matrix_TYP*));
164
165
/* the next will be those of gen */
166
memcpy(tmp+dim_centr,gen,gen_no * sizeof(matrix_TYP*));
167
168
erg = solve_endo(tmp,tmp,anz,dim_cc);
169
170
free(tmp);
171
172
return erg;
173
174
}
175
176
177
int is_zero(matrix_TYP *pol,int x)
178
{
179
MP_INT sum,
180
pot,
181
tmp;
182
183
int i;
184
185
mpz_init_set_ui(&sum,0);
186
mpz_init_set_ui(&pot,1);
187
mpz_init(&tmp);
188
189
for (i=0;i<pol->cols;i++){
190
mpz_set_si(&tmp,pol->array.SZ[0][i]);
191
mpz_mul(&tmp,&pot,&tmp);
192
mpz_add(&sum,&sum,&tmp);
193
mpz_set_si(&tmp,x);
194
mpz_mul(&pot,&pot,&tmp);
195
}
196
197
if (mpz_cmp_si(&sum,0) == 0)
198
i = TRUE;
199
else
200
i = FALSE;
201
202
mpz_clear(&sum);
203
mpz_clear(&pot);
204
mpz_clear(&tmp);
205
206
return i;
207
208
}
209
210
void div_by_root(matrix_TYP *pol,int x)
211
{
212
int i,
213
*l;
214
215
l = (int *) malloc((pol->cols-1)*sizeof(int));
216
217
l[pol->cols-2] = pol->array.SZ[0][pol->cols-1];
218
219
for (i=pol->cols-3;i>=0 ;i--){
220
l[i] = pol->array.SZ[0][i+1] + l[i+1] * x;
221
}
222
223
pol->cols--;
224
free(pol->array.SZ[0]);
225
pol->array.SZ[0] = l;
226
227
}
228
229
/***************************************************************************
230
@
231
@---------------------------------------------------------------------------
232
@
233
@ matrix_TYP *zeros(matrix_TYP *minpol)
234
@
235
@---------------------------------------------------------------------------
236
@
237
***************************************************************************/
238
matrix_TYP *zeros(matrix_TYP *minpol)
239
{
240
int i,
241
j,
242
found = 0;
243
244
matrix_TYP *erg,
245
*tmp;
246
247
erg = init_mat(1,minpol->cols,"");
248
tmp = copy_mat(minpol);
249
250
/* split of all root which are zero */
251
while(tmp->array.SZ[0][0] == 0){
252
div_by_root(tmp,0);
253
erg->array.SZ[0][found] = 0;
254
found++;
255
}
256
257
/* and now all others */
258
for (i=1;i<=abs(tmp->array.SZ[0][0]);i++){
259
if (tmp->array.SZ[0][0] % i == 0){
260
for (j= -1;j<=1;j+=2){ /* describes the sign */
261
if (is_zero(tmp,j*i)){
262
div_by_root(tmp,i*j);
263
erg->array.SZ[0][found] = i * j;
264
found++;
265
i=0;
266
j=3;
267
}
268
}
269
}
270
}
271
272
free_mat(tmp);
273
real_mat(erg,1,found);
274
275
return erg;
276
277
} /* zeros(...) */
278
279
/**************************************************************************
280
@
281
@--------------------------------------------------------------------------
282
@
283
@ int pos(matrix_TYP **list,int no,matrix_TYP *x)
284
@
285
@--------------------------------------------------------------------------
286
@
287
***************************************************************************/
288
int pos(matrix_TYP **list,int no,matrix_TYP *x)
289
{
290
int i;
291
292
for (i=0;i<no;i++)
293
if (mat_comp(list[i],x) == 0) return i;
294
295
return -1;
296
} /* pos (....) */
297
298
static matrix_TYP *matrix_in_pol(matrix_TYP *pol,matrix_TYP *x)
299
{
300
int i;
301
302
matrix_TYP *erg,
303
*pot;
304
305
if (x->cols != x->rows && x->flags.Integral == FALSE){
306
fprintf(stderr,"exit in matrix_in_pol\n");
307
exit(3);
308
}
309
310
pot = init_mat(x->cols,x->cols,"1");
311
erg = init_mat(x->cols,x->cols,"");
312
313
for (i=0;i<pol->cols;i++){
314
imat_addeq(erg,pot,1,pol->array.SZ[0][i]);
315
mat_muleq(erg,x);
316
}
317
318
free_mat(pot);
319
320
return erg;
321
322
} /* matrix_in_pol(...) */
323
324
int min_trace(matrix_TYP **A,int no)
325
{
326
327
int i,
328
min,
329
p,
330
trac;
331
332
min = trace(A[0]);
333
p = 0;
334
if (min % A[0]->kgv != 0){
335
fprintf(stderr,"error in min_trace\n");
336
exit(3);
337
}
338
else{
339
min = abs(min/A[0]->kgv);
340
}
341
342
for (i=1;i<no;i++){
343
trac = trace(A[i]);
344
if (trac % A[i]->kgv != 0){
345
fprintf(stderr,"error in min_trace\n");
346
exit(3);
347
}
348
else{
349
trac = abs(trac/A[i]->kgv);
350
}
351
if (trac < min){
352
min = trac;
353
p=i;
354
}
355
}
356
357
return p;
358
}
359
360
/*************************************************************************
361
@
362
@-------------------------------------------------------------------------
363
@
364
@ static matrix_TYP **get_idem2(matrix_TYP **gen,int number,int *anz)
365
@
366
@
367
@-------------------------------------------------------------------------
368
@
369
**************************************************************************/
370
static matrix_TYP **get_idem2(matrix_TYP **gen,int number,int *anz)
371
{
372
int i,
373
j,
374
k,
375
found,
376
dim_new1,
377
dim_new2,
378
vec[100]; /* I don't belivieve we will ever get a
379
centre of a centralizer which has bigger dimension */
380
381
matrix_TYP *ONE,
382
*e1,
383
*e2,
384
*tmp,
385
*min,
386
*zero,
387
**gentrans,
388
**gen_new1,
389
**gen_new2,
390
**erg;
391
392
/* number == 0 is a technical statement */
393
if (number == 0){
394
anz[0] = 0;
395
return NULL;
396
}
397
398
/* if the algbra has only got dimension one, we are finished */
399
if (number == 1){
400
min = min_pol(gen[0]);
401
zero = zeros(min);
402
erg = (matrix_TYP **) malloc(1 * sizeof(matrix_TYP *));
403
erg[0] = copy_mat(gen[0]);
404
if (zero->cols == 1)
405
erg[0]->kgv = zero->array.SZ[0][0];
406
else
407
erg[0]->kgv = zero->array.SZ[0][1];
408
Check_mat(erg[0]);
409
anz[0] = 1;
410
free_mat(min);
411
free_mat(zero);
412
return erg;
413
}
414
415
/* calculate the right regular representation */
416
/* assume the matrices in gen to be a Z-BASIS */
417
gentrans = (matrix_TYP **) malloc(number * sizeof(matrix_TYP *));
418
for (i=0;i<number;i++){
419
gentrans[i] = init_mat(number,number,"");
420
for (j=0;j<number;j++){
421
tmp = mat_mul(gen[i],gen[j]);
422
form_to_vec_modular(gentrans[i]->array.SZ[j],tmp,gen,number);
423
free_mat(tmp);
424
}
425
}
426
427
/* search for a matrix which has a reducible minimal polynomial */
428
found = FALSE;
429
for (i=0;i<number && !found;i++){
430
min = min_pol(gentrans[i]);
431
432
/* here is one part which has to be altered if one want's to
433
be able to handle bigger fields, ie. do not only check whether
434
min has got zero, but other factors */
435
zero = zeros(min);
436
if (zero->cols > 1 ||
437
(zero->cols == 1 && min->cols > 3)){
438
found = TRUE;
439
}
440
else{
441
free_mat(min);
442
free_mat(zero);
443
}
444
}
445
i--;
446
447
/* calculate the identity in this algebra (which sounds a bit crazy) */
448
tmp = init_mat(number,number,"1");
449
form_to_vec(vec,tmp,gentrans,number,&j);
450
ONE = vec_to_form(vec,gen,number);
451
ONE->kgv = j;
452
free_mat(tmp);
453
454
/* free gentrans, which isn't needed anymore */
455
for (j=0;j<number;j++){
456
free_mat(gentrans[j]);
457
}
458
free(gentrans);
459
460
if (found){
461
462
/* the definition of e1 is the next part which has to be altered
463
formaly e1 = min/factor (gen[i]). if these two things are changed,
464
we are able to handle bigger fields */
465
466
/* split the algebra in two of it's components
467
by multiplying whith the two factors of min */
468
e1 = imat_add(gen[i],ONE,1,-zero->array.SZ[0][0]);
469
div_by_root(min,zero->array.SZ[0][0]);
470
471
gen_new1 = (matrix_TYP **) malloc(number * sizeof(matrix_TYP *));
472
for (j=0;j<number;j++){
473
gen_new1[j] = mat_mul(gen[j],e1);
474
}
475
dim_new1 = long_rein_formspace(gen_new1,number,0);
476
477
/* free space before doing the recursion */
478
free_mat(zero);
479
free_mat(min);
480
free_mat(e1);
481
482
/* do the first recursion */
483
erg = get_idem2(gen_new1,dim_new1,&i);
484
485
/* now ONE - \sum erg[i] will be an idempotent */
486
e2 = copy_mat(ONE);
487
for (j=0;j<i;j++){
488
tmp = imat_add(e2,erg[j],1,-1);
489
free_mat(e2);
490
e2 = tmp;
491
}
492
493
gen_new2 = (matrix_TYP **) malloc(number * sizeof(matrix_TYP *));
494
for (j=0;j<number;j++){
495
gen_new2[j] = mat_mul(gen[j],e2);
496
gen_new2[j]->kgv = 1;
497
Check_mat(gen_new2[j]);
498
}
499
free_mat(e2);
500
dim_new2 = long_rein_formspace(gen_new2,number,0);
501
502
/* do the second recursion */
503
gentrans = get_idem2(gen_new2,dim_new2,&j);
504
505
/* copy the idempotents to the right place */
506
if (j>0) erg = (matrix_TYP **) realloc(erg,(i+j) * sizeof(matrix_TYP *));
507
anz[0] = i+j;
508
for (k=0;k<j;k++) erg[i+k] = gentrans[k];
509
510
/* free the rest of the space */
511
for (i=0;i<number;i++){
512
free_mat(gen_new1[i]);
513
free_mat(gen_new2[i]);
514
}
515
free(gen_new1);
516
free(gen_new2);
517
if (j>0) free(gentrans);
518
519
/* remove duplicates in erg */
520
for (i=1;i<anz[0];i++){
521
if (pos(erg,i,erg[i]) != -1){
522
free_mat(erg[i]);
523
anz[0]--;
524
erg[i] = erg[anz[0]];
525
}
526
}
527
}
528
else{
529
erg = (matrix_TYP **) malloc(1 * sizeof(matrix_TYP));
530
anz[0] = 1;
531
erg[0] = ONE;
532
}
533
534
if (found) free_mat(ONE);
535
536
return erg;
537
}
538
539
void reduce_by_idem(matrix_TYP *id,matrix_TYP **cen,int no,int offset)
540
{
541
int i,
542
j,
543
k;
544
545
rational one,
546
minus_one;
547
548
matrix_TYP *lines,
549
*tmp;
550
551
one.n = 1;
552
one.z =1;
553
minus_one.n =1;
554
minus_one.z =-1;
555
556
for (i=offset;i<no;i++){
557
put_mat(cen[i],NULL,"red",2);
558
tmp = mat_mul(id,cen[i]);
559
mat_addeq(cen[i],tmp,one,minus_one);
560
Check_mat(cen[i]);
561
cen[i]->kgv = 1;
562
put_mat(cen[i],NULL,"red",2);
563
free_mat(tmp);
564
}
565
566
lines = init_mat(no-offset,id->rows*id->cols,"");
567
for (i=offset;i<no;i++)
568
for (j=0;j<id->rows;j++)
569
for (k=0;k<id->cols;k++)
570
lines->array.SZ[i-offset][j*id->cols+k] = cen[i]->array.SZ[j][k];
571
572
tmp = long_rein_mat(lines);
573
574
free_mat(cen[offset]);
575
cen[offset] = copy_mat(id);
576
577
for (i=offset+1;i<no;i++)
578
for (j=0;j<id->rows;j++)
579
for (k=0;k<id->cols;k++)
580
cen[i]->array.SZ[j][k] = tmp->array.SZ[i-1-offset][j*id->cols + k];
581
582
for (i=0;i<no;i++) Check_mat(cen[i]);
583
584
if (INFO_LEVEL & 4){
585
put_mat(lines,NULL,"lines",2);
586
put_mat(tmp,NULL,"tmp",2);
587
for (i=0;i<no;i++){
588
put_mat(cen[i],NULL,"cen in reduce_by_idem",2);
589
}
590
}
591
592
free_mat(tmp);
593
free_mat(lines);
594
595
return;
596
} /* reduce_by_idem(...) */
597
598
/************************************************************************
599
@
600
@------------------------------------------------------------------------
601
@
602
@ matrix_TYP **idempotente(matrix_TYP **gen,int gen_no,matrix_TYP *form,
603
@ int *anz,int *dimc,int *dimcc,int *options)
604
@
605
@------------------------------------------------------------------------
606
@
607
*************************************************************************/
608
matrix_TYP **idempotente(matrix_TYP **gen,int gen_no,matrix_TYP *form,
609
int *anz,int *dimc,int *dimcc,int *options)
610
{
611
612
matrix_TYP **centralizer, /* holds a Q-basis for the centralizer of
613
QG (as enveloping algebra) */
614
**ccentralizer, /* holds a Q-basis for the centre of
615
centralizer */
616
*tmp,
617
*tmp2,
618
*test,
619
**eigenspace,
620
*min, /* the minpol of a result to be */
621
*forminv, /* inverse of form */
622
*action, /* describes the action of form on
623
ccentralizer via (form * Z * form^(-1))^Tr */
624
**idem; /* the result will be stucked in here */
625
626
int i,
627
j,
628
*l, /* holds a temporaly vector for vec_to_form */
629
k,
630
d,
631
den,
632
flag;
633
634
/* transform all generators to kgv format */
635
for (i=0;i<gen_no;i++){
636
rat2kgv(gen[i]);
637
}
638
639
/* calculate the centralizer */
640
centralizer = solve_endo(gen,gen,gen_no,dimc);
641
642
/* calculate the centre of the centralizer */
643
ccentralizer = calc_ccentralizer(centralizer,dimc[0],gen,gen_no,dimcc);
644
645
/* output for debugging */
646
if (INFO_LEVEL & 4){
647
for (i=0;i<dimc[0];i++) put_mat(centralizer[i],NULL,"cen",2);
648
for (i=0;i<dimcc[0];i++) put_mat(ccentralizer[i],NULL,"ccen",2);
649
}
650
651
/* calculate action, actualy d * action, because I don't like denominators.
652
we calculate action as acting on rows, because this is very convient */
653
forminv = long_mat_inv(form);
654
rat2kgv(forminv);
655
d = forminv->kgv;
656
forminv->kgv=1;
657
action = init_mat(dimcc[0],dimcc[0],"");
658
659
for (i=0;i<dimcc[0];i++){
660
tmp = mat_kon(form,ccentralizer[i],forminv);
661
tmp2 = tr_pose(tmp);
662
free_mat(tmp);
663
tmp = tmp2;
664
665
if (INFO_LEVEL & 4){
666
for (j=0;j<dimcc[0];j++) put_mat(ccentralizer[j],NULL,"ccen",2);
667
put_mat(tmp,NULL,"tmp",2);
668
put_mat(form,NULL,"form",2);
669
put_mat(forminv,NULL,"forminv",2);
670
}
671
672
/* express tmp as linear combination of the matrices in
673
ccentralizer. This is possible in an integral way, because
674
we have a Z-basis in ccentralizer */
675
form_to_vec(action->array.SZ[i],tmp,ccentralizer,dimcc[0],&den);
676
if (den != 1){
677
fprintf(stderr,"error in idempotente, expression should be possible\n");
678
fprintf(stderr,"in an integral way\n");
679
exit(3);
680
}
681
free_mat(tmp);
682
}
683
684
/* calculate the 1 eigenspace of action, or strictly speeking the
685
d eigenspace of d*action */
686
for (i=0;i<action->rows;i++) action->array.SZ[i][i] -= d;
687
tmp = tr_pose(action);
688
free_mat(action);
689
action = tmp;
690
eigenspace = long_solve_mat(action,NULL);
691
if (eigenspace[0] != NULL || eigenspace[1] == NULL){
692
fprintf(stderr,"error in idempotente\n");
693
exit(3);
694
}
695
tmp = eigenspace[1];
696
free(eigenspace);
697
eigenspace = (matrix_TYP **) malloc(tmp->cols*sizeof(matrix_TYP *));
698
l = (int *) malloc(dimcc[0] * sizeof(int));
699
for (i=0;i<tmp->cols;i++){
700
for (j=0;j<tmp->rows;j++) l[j] = tmp->array.SZ[j][i];
701
eigenspace[i] = vec_to_form(l,ccentralizer,dimcc[0]);
702
}
703
704
d = tmp->cols;
705
706
if (INFO_LEVEL & 4){
707
put_mat(action,NULL,"action",2);
708
}
709
710
/* clean up again */
711
free(l);
712
free_mat(tmp);
713
free_mat(action);
714
free_mat(forminv);
715
716
if (INFO_LEVEL & 4){
717
for (i=0;i<d;i++) put_mat(eigenspace[i],NULL,"eigenspace",2);
718
}
719
720
idem = get_idem2(eigenspace,d,anz);
721
722
/* clean up the last space */
723
for (i=0;i<d;i++) free_mat(eigenspace[i]);
724
free(eigenspace);
725
726
/* put the centralizer and it's centre on the same pointer as idem */
727
idem = (matrix_TYP **) realloc(idem,(anz[0]+dimc[0]+dimcc[0])
728
* sizeof(matrix_TYP));
729
for (i=0;i<dimc[0];i++) idem[anz[0]+i] = centralizer[i];
730
for (i=0;i<dimcc[0];i++) idem[anz[0]+dimc[0]+i] = ccentralizer[i];
731
732
/* clear the pointer's needed */
733
free(centralizer);
734
free(ccentralizer);
735
736
return idem;
737
738
}
739
740