GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "matrix.h"2#include "idem.h"3#include "bravais.h"4#include "orbit.h"5#include "sort.h"67/*extern matrix_TYP ** orbit_alg();*/89/*Wahrscheinlich verursacht das Rechnen mit Matrizen, die nicht Ganzzahlig sind10Probleme. */11extern void free_tree(struct tree *p);1213/* This function compares two matrices in lexicographic order.14It is supposed that they behave well (cols etc equal). */15static int cmp_mat_lex (matrix_TYP *A, matrix_TYP *B)16{17int i, j;181920for (i=0; i<A->rows; i++)21for (j=0; j<A->cols; j++)22if (A->array.SZ[i][j] != B->array.SZ[i][j])23if (A->array.SZ[i][j] < B->array.SZ[i][j])24return -1;25else26return 1;2728return 0;29}3031static int hash_number(matrix_TYP *M)32{33int i,j,h;34int **SZ = M->array.SZ;35/*K: Wahrscheinlich weniger Arbeit fuer Rechner durch Einfueheren von36"Zwischenpointer"*/37h = 0;38for(i=0; i<M->rows; i++)39for(j=0; j<M->cols; j++)40h += SZ[i][j];4142return h;43}4445static void sort_cols (matrix_TYP *N)46{4748int i, j, is_different, swap_cols;4950for (i=1; i<N->cols; i++)51{52is_different = FALSE, swap_cols = FALSE;5354for (j=0; j<N->rows && is_different == FALSE; j++)55if (N->array.SZ[j][i] > N->array.SZ[j][i-1])56is_different = TRUE;57else if (N->array.SZ[j][i] < N->array.SZ[j][i-1])58is_different = TRUE,59swap_cols = TRUE;6061if (swap_cols)62{63col_per (N, i-1, i);64i = 0;65}6667}6869}7071static void permute_and_sort (matrix_TYP *N, int number)72{73int i, j, k = 1;74matrix_TYP **set;75int used = -1, unused = 0;7677if (number != 1)78{79for (i=2; i<=number; i++)80k *= i;8182if ( (set = (matrix_TYP **) malloc ((k+1) * sizeof (matrix_TYP *))) == NULL)83{84perror ("set");85exit (2);86}8788set [0] = copy_mat (N);8990while (used < unused)91{9293used ++;9495set [unused + 1] = copy_mat (set [used]);9697row_per (set [unused + 1], N->rows - number, N->rows - number + 1);9899for (i=0; i<=unused && cmp_mat_lex (set [unused + 1], set [i]) != 0; i++)100;101102103if (i == unused + 1)104unused ++;105else106free_mat (set [unused + 1]);107108109110set [unused + 1] = copy_mat (set [used]);111112row_per (set [unused + 1], N->rows - number, N->rows - 1);113114for (i=1; i <= number - 1; i++)115row_per (set [unused + 1], N->rows - i - 1, N->rows - i);116117for (i=0; i<=unused && cmp_mat_lex (set [unused + 1], set [i]) != 0; i++)118;119120if (i == unused + 1)121unused ++;122else123free_mat (set [unused + 1]);124125}126127128for (i=0; i<=used; i++)129sort_cols (set[i]);130131132k = 0;133for (i=1; i<=used; i++)134if (cmp_mat_lex (set [k], set [i]) > 0)135k = i;136137138for (i=0; i<N->rows; i++)139for (j=0; j<N->cols; j++)140N->array.SZ [i][j] = set [k]->array.SZ [i][j];141142for (i=0; i<=unused; i++)143free_mat (set [i]);144145free (set);146}147else148{149sort_cols (N);150}151}152153static int order(matrix_TYP *A)154{155156int i = 1;157158matrix_TYP *B;159160B = copy_mat(A);161Check_mat(B);162163while (! ( B->flags.Scalar && B->array.SZ[0][0] == 1)){164mat_muleq(B,A);165Check_mat(B);166i++;167}168169free_mat(B);170return i;171}172173matrix_TYP *compute_q_matrix (bravais_TYP *G)174{175matrix_TYP **Group, **Idem, **representant, **conjugacy_class, *REP;176matrix_TYP *I, *F, *output_mat;177matrix_TYP *waste, *waste2;178int orb_alg_options[6];179int group_order, *length_conj_class;180/* int reserved_conj_class = 0; */181int class_counter = 0;182int idem_no;183int i, j, h;184185186I = einheitsmatrix( G->dim );187F = rform(G->gen, G->gen_no, I, 101);188Idem = idempotente(G->gen, G->gen_no, F, &idem_no, &i, &j, NULL);189free_mat(F);190for (h=0; h<i+j; h++)191free_mat(Idem[idem_no+h]);192/* Here we free some Idem-elements that are not needed for our aims. */193194/* As a first step compute the whole group out of the195Generators given by the "bravais_TYP *G".196This is done by getting the orbit of the unit element197under operation of the group.*/198199orb_alg_options[0] = 0;200orb_alg_options[1] = 0;201orb_alg_options[2] = 0,202orb_alg_options[3] = 0,203orb_alg_options[4] = 0,204orb_alg_options[5] = 0;205206Group = orbit_alg( I, G, NULL, orb_alg_options, &group_order);207mat_quicksort(Group, 0 , group_order - 1,mat_comp);208209/* The next step simply consists in dividing the whole group into its210conjugacy classes. This is done by getting the orbit under conjugation211for every group element that has not yet been found to lie in another212conjugacy class.213Technically this is done by setting up a list "not_yet_found" that214contains a flag for every group element saying if it was already found.215Das Programm startet am Anfang der Liste der Gruppenelemente und berechnet216nach einander von ...*/217218219orb_alg_options[0] = 4;220orb_alg_options[1] = 0;221orb_alg_options[2] = 0;222orb_alg_options[3] = FALSE;223orb_alg_options[4] = 0;224orb_alg_options[5] = 0;225226227REP = orbit_representatives(Group,228group_order,229G,230orb_alg_options,231&class_counter,2321);233234if ( (representant = (matrix_TYP **) malloc(class_counter * sizeof(matrix_TYP *)) ) == NULL)235{236perror ("representant");237exit (2);238}239240for (i=0;i<class_counter;i++){241representant[i] = Group[REP->array.SZ[0][i]];242Group[REP->array.SZ[0][i]] = NULL;243}244length_conj_class = REP->array.SZ[1];245REP->array.SZ[1] = (int *) malloc(1*sizeof(int));246247for(i=0; i<group_order; i++){248if (Group[i] != NULL) free_mat(Group[i]);249}250free(Group);251free_mat(REP);252253output_mat = init_mat( 9 + idem_no, class_counter, "");254255/* Achtung: Probleme bei nicht ganzzahligen Matrizen !!! */256257/* Put the length of the conjugation classes into the 0-th row of the258output matrix. */259for( i=0; i<class_counter; i++)260output_mat->array.SZ[0][i] = length_conj_class[i];261free(length_conj_class);262263/* Put the order of the representant into the 1-st row of the output matrix*/264for( i=0; i<class_counter; i++)265output_mat->array.SZ[1][i] = order( representant[i] );266267/* Put the trace of the conjugation classes into the 2-nd row of the268output matrix. */269for( i=0; i<class_counter; i++)270output_mat->array.SZ[2][i] = trace( representant[i] );271272273/* Put the trace of the square of elements of every conjugation classes274into the 3-nd row of the output matrix. */275for( i=0; i<class_counter; i++)276{277waste = mat_mul( representant[i], representant[i]);278279output_mat->array.SZ[3][i] = trace(waste);280281free_mat(waste);282}283284/* Put the trace of the cube of elements of every conjugation classes285into the 4-th row of the output matrix. */286for( i=0; i<class_counter; i++)287{288waste2 = mat_mul( representant[i], representant[i]);289waste = mat_mul( waste2, representant[i] );290291output_mat->array.SZ[4][i] = trace( waste );292293free_mat(waste);294free_mat(waste2);295}296297/* Get the rank of the fixspace of every element */298for (i=0; i<class_counter; i++)299{300waste = copy_mat( representant[i] );301302for (j=0; j<I->rows; j++)303waste->array.SZ[j][j]--; /* This means: matrix minus identity */304305Check_mat( waste );306output_mat->array.SZ[5][i] = tgauss( waste );307free_mat( waste );308}309310/* Compute the rank of the antifixspace of every element. */311for (i=0; i<class_counter; i++)312{313waste = copy_mat( representant[i] );314315for (j=0; j<I->rows; j++)316waste->array.SZ[j][j]++;/* This means: matrix plus identity */317318Check_mat( waste );319output_mat->array.SZ[6][i] = tgauss( waste );320free_mat( waste );321}322323/* get the rank of (x-1)^2 */324for (i=0; i<class_counter; i++)325{326waste = copy_mat( representant[i] );327for (j=0; j<I->rows; j++)328waste->array.SZ[j][j]--;329330Check_mat( waste );331mat_muleq(waste,waste);332Check_mat( waste );333output_mat->array.SZ[7][i] = tgauss( waste );334free_mat( waste );335}336337/* put the rank of (x+1)^2 into the 8-th row of the output_mat*/338for (i=0; i<class_counter; i++)339{340waste = copy_mat( representant[i] );341342for (j=0; j<I->rows; j++)343waste->array.SZ[j][j]++;344345Check_mat( waste );346mat_muleq( waste, waste );347Check_mat( waste );348output_mat->array.SZ[8][i] = tgauss( waste );349free_mat( waste );350}351352/* Write into the 9-th row of output_mat the trace of idem??? */353for (i=0; i<class_counter; i++)354for (j=0; j<idem_no; j++)355{356waste = mat_mul(Idem[j],representant[i]);357output_mat->array.SZ[9+j][i] = trace(waste)/waste->kgv;358free_mat(waste);359}360for(i=0; i<idem_no; i++)361free_mat(Idem[i]);362free(Idem);363364/* The matrix has now to be ordered by shuffling columns and rows. */365permute_and_sort (output_mat, idem_no);366367368369370free_mat(I);371372for(i=0; i<class_counter; i++)373free_mat(representant[i]);374free(representant);375376return output_mat;377}378379380