GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/* last change: 28.09.00 by Oliver Heidbuechel */123#include<typedef.h>4#include<getput.h>5#include<matrix.h>6#include<longtools.h>7#include<tools.h>8#include"zass.h"9#include <bravais.h>10#include <sort.h>11#include <presentation.h>12#include <base.h>13#include <graph.h>1415161718/* -------------------------------------------------------------------------- */19/* returns 1 iff mat = Id */20/* -------------------------------------------------------------------------- */21static int is_id(matrix_TYP *mat)22{23int i, j;2425for (i = 0; i < mat->rows; i++){26for (j = 0; j < mat->cols; j++){27if (i == j && mat->array.SZ[i][i] != 1)28return(0);29if (i != j && mat->array.SZ[i][j] != 0);30return(0);31}32}33return(1);34}35363738/* -------------------------------------------------------------------- */39/* Setze Matrizen (gegeben in N) in Worte ein. */40/* Streiche Identitaet und doppelte. */41/* -------------------------------------------------------------------- */42/* words: Worte */43/* no_of_words: Anzahl der Worte */44/* N: Matrizen, die eingesetzt werden sollen */45/* (muss zu words "passen") */46/* N_inv: Inversen von N (werden bei Bedarf berechnet) */47/* anz: Anzahl von N */48/* flag: wenn = 0, wird einfach N zurueckgegeben */49/* stab_gen_no: hier wird die Anzahl der Elemente zurueckgegeben */50/* -------------------------------------------------------------------- */51matrix_TYP **stab_coz(int **words,52int no_of_words,53matrix_TYP **N,54matrix_TYP **N_inv,55int anz,56int flag,57int *stab_gen_no)58{59int i, counter = 0;6061matrix_TYP **stab;62636465if (flag == 0){66/* the stabilizer of the cocycle is the full normalizer */67stab = (matrix_TYP **)calloc(anz, sizeof(matrix_TYP *));68stab_gen_no[0] = anz;69for (i = 0; i < anz; i++){70stab[i] = copy_mat(N[i]);71}72}73else{74stab = (matrix_TYP **)calloc(no_of_words, sizeof(matrix_TYP *));75for (i = 0; i < no_of_words; i++){76normalize_word(words[i]);77stab[counter] = mapped_word(words[i], N, N_inv);7879if (!is_id(stab[counter])){80if (mat_search(stab[counter], stab, counter, mat_comp) != -1){81free_mat(stab[counter]);82}83else{84mat_quicksort(stab, 0, counter, mat_comp);85counter++;86}87}88else{89free_mat(stab[counter]);90}91}92stab_gen_no[0] = counter;93}9495return(stab);96}979899100/* -------------------------------------------------------------------------- */101/* Did we have this lattice bevore? If not, insert the lattice in the tree! */102/* -------------------------------------------------------------------------- */103static int search_in_tree(struct tree *Baum,104matrix_TYP **list,105matrix_TYP *lattice,106int number)107{108int flag, no;109110no = Baum->no;111flag = cmp_mat(list[no], lattice);112113if (flag == 0)114return(no);115if (flag < 0){116if (Baum->left == NULL){117Baum->left = (struct tree *)calloc(1, sizeof(struct tree));118Baum->left->no = number;119return(-1);120}121else{122return(search_in_tree(Baum->left, list, lattice, number));123}124}125else{126if (Baum->right == NULL){127Baum->right = (struct tree *)calloc(1, sizeof(struct tree));128Baum->right->no = number;129return(-1);130}131else{132return(search_in_tree(Baum->right, list, lattice, number));133}134135}136}137138139140/* -------------------------------------------------------------------------- */141/* mark the lattices in the orbit under the stablizer of a cocycle */142/* -------------------------------------------------------------------------- */143static void mark_lattice(boolean *lattice_orbit,144matrix_TYP **LIST,145int anz,146matrix_TYP *mat)147{148int i;149150for (i = 0; i < anz; i++){151if (cmp_mat(mat, LIST[i]) == 0){152lattice_orbit[i] = TRUE;153return;154}155}156fprintf(stderr, "ERROR in mark_lattice!\n");157exit(7);158}159160161162/* -------------------------------------------------------------------------- */163/* Calculate the stabilizer of a lattice and return the words; */164/* save the number of words in no */165/* -------------------------------------------------------------------------- */166int **stab_lattice(matrix_TYP *lattice,167matrix_TYP **N,168int N_gen_no,169int *no,170matrix_TYP **LIST,171int anz,172boolean *lattice_orbit)173{174int i, j, k, flag,175counter = 1, number,176**words, **WORDS;177178matrix_TYP **list;179180struct tree *Baum;181182183list = (matrix_TYP **)calloc(MIN_SPEICHER, sizeof(matrix_TYP *));184words = (int **)calloc(MIN_SPEICHER, sizeof(int *));185WORDS = (int **)calloc(MIN_SPEICHER, sizeof(int *));186list[0] = lattice;187Baum = (struct tree *)calloc(1, sizeof(struct tree));188Baum->no = i = no[0] = 0;189190while (i < counter){191for (j = 0; j < N_gen_no; j++){192list[counter] = mat_mul(N[j], list[i]);193long_col_hnf(list[counter]);194flag = search_in_tree(Baum, list, list[counter], counter);195if (flag == -1){196/* new lattice */197words[counter] = (int *)calloc(MIN_SPEICHER, sizeof(int));198if (i != 0){199memcpy(words[counter], words[i], (words[i][0] + 1) * sizeof(int));200words[counter][words[i][0] + 1] = -(j+1);201words[counter][0]++;202}203else{204words[counter][0] = 1;205words[counter][1] = -(j+1);206}207if (lattice_orbit != NULL && LIST != NULL && anz != 0)208mark_lattice(lattice_orbit, LIST, anz, list[counter]);209counter++;210}211else{212/* we got this lattice already */213free_mat(list[counter]);214WORDS[no[0]] = (int *)calloc(MIN_SPEICHER, sizeof(int));215if (i != 0){216memcpy(WORDS[no[0]], words[i], (words[i][0] + 1) * sizeof(int));217WORDS[no[0]][words[i][0] + 1] = -(j+1);218WORDS[no[0]][0]++;219}220else{221WORDS[no[0]][0] = 1;222WORDS[no[0]][1] = -(j+1);223}224if (flag != 0){225number = WORDS[no[0]][0] + words[flag][0];226for (k = 0; k < words[flag][0]; k++){227WORDS[no[0]][number - k] = -words[flag][k + 1];228}229WORDS[no[0]][0] = number;230}231no[0]++;232}233}234i++;235}236237/* clean */238for (i = 1; i < counter; i++){239free(words[i]);240free_mat(list[i]);241}242free(words);243free(list);244free_tree(Baum);245246return(WORDS);247}248249250251/* -------------------------------------------------------------------------- */252/* returns 1 if word[n] == word[i] for a 0 <= i < n */253/* returns 0 otherwise */254/* -------------------------------------------------------------------------- */255int word_already_there(int **WORDS,256int n)257{258int i, j, flagge = 0;259260for (i = 0; i < n && flagge == 0; i++){261flagge = 1;262for (j = 0; j <= WORDS[i][0]; j++){263if (WORDS[i][j] != WORDS[n][j]){264flagge = 0;265break;266}267}268}269return(flagge);270}271272273274/* -------------------------------------------------------------------------- */275/* Calculate the stabilizer of lattice under N and return the words; */276/* save the number of words in no */277/* -------------------------------------------------------------------------- */278matrix_TYP **calculate_S1(matrix_TYP *lattice,279matrix_TYP **N,280int anz,281int *no,282matrix_TYP **dataN,283matrix_TYP **dataNinv,284matrix_TYP *dataX)285{286int i, j, k, flag, i__, addmem,287counter = 1, number,288**words, **WORDS;289290matrix_TYP **list, **S1,291**Ninv, *tmp;292293struct tree *Baum;294295if (GRAPH_DEBUG){296Ninv = (matrix_TYP **)calloc(anz, sizeof(matrix_TYP *));297}298299list = (matrix_TYP **)calloc(1024, sizeof(matrix_TYP *));300words = (int **)calloc(1024, sizeof(int *));301WORDS = (int **)calloc(1024, sizeof(int *));302list[0] = lattice;303Baum = (struct tree *)calloc(1, sizeof(struct tree));304Baum->no = i = no[0] = 0;305306while (i < counter){307for (j = 0; j < anz; j++){308if (counter % 1024 == 0){309list = (matrix_TYP **)realloc(list, (counter + 1024) * sizeof(int *));310}311list[counter] = mat_mul(N[j], list[i]);312long_col_hnf(list[counter]);313flag = search_in_tree(Baum, list, list[counter], counter);314if (flag == -1){315/* new lattice */316if (counter % 1024 == 0){317words = (int **)realloc(words, (counter + 1024) * sizeof(int *));318}319/* words[counter] = (int *)calloc(1024, sizeof(int)); */320if (i != 0){321words[counter] = (int *)calloc(words[i][0] + 2, sizeof(int));322/*memcpy(words[counter], words[i], (words[i][0] + 1) * sizeof(int));*/323for (i__ = 0; i__ < words[i][0] + 1; i__++){324words[counter][i__] = words[i][i__];325}326words[counter][words[i][0] + 1] = -(j+1);327words[counter][0]++;328}329else{330words[counter] = (int *)calloc(2, sizeof(int));331words[counter][0] = 1;332words[counter][1] = -(j+1);333}334counter++;335}336else{337/* we got this lattice already */338free_mat(list[counter]);339if (no[0] % 1024){340WORDS = (int **)realloc(WORDS, (no[0] + 1024) * sizeof(int *));341}342/*WORDS[no[0]] = (int *)calloc(1024, sizeof(int));*/343if (flag != 0){344addmem = words[flag][0];345}346else{347addmem = 0;348}349if (i != 0){350WORDS[no[0]] = (int *)calloc(words[i][0] + 2 + addmem, sizeof(int));351/*memcpy(WORDS[no[0]], words[i], (words[i][0] + 1) * sizeof(int));*/352for (i__ = 0; i__ < words[i][0] + 1; i__++){353WORDS[no[0]][i__] = words[i][i__];354}355WORDS[no[0]][words[i][0] + 1] = -(j+1);356WORDS[no[0]][0]++;357}358else{359WORDS[no[0]] = (int *)calloc(2 + addmem, sizeof(int));360WORDS[no[0]][0] = 1;361WORDS[no[0]][1] = -(j+1);362}363if (flag != 0){364number = WORDS[no[0]][0] + words[flag][0];365for (k = 0; k < words[flag][0]; k++){366WORDS[no[0]][number - k] = -words[flag][k + 1];367}368WORDS[no[0]][0] = number;369}370no[0]++;371}372}373i++;374}375376if (GRAPH_DEBUG){377/* is this really an element of the stabilizer? */378for (i = 0; i < no[0]; i++){379tmp = mapped_word(WORDS[i], N, Ninv);380tmp = mat_muleq(tmp, lattice);381long_col_hnf(tmp);382if (cmp_mat(tmp, lattice) != 0){383fprintf(stderr, "MIST!\n");384exit(9);385}386free_mat(tmp);387}388for (i = 0; i < anz; i++){389if (Ninv[i] != NULL) free_mat(Ninv[i]);390}391free(Ninv);392}393394/* clean */395for (i = 1; i < counter; i++){396free(words[i]);397free_mat(list[i]);398}399free(words);400free(list);401free_tree(Baum);402403/* now calculate the matrices */404counter = 0;405S1 = (matrix_TYP **)calloc(no[0], sizeof(matrix_TYP *));406for (i = 0; i < no[0]; i++){407/* simplify the words */408normalize_word(WORDS[i]);409if (WORDS[i][0] == 1 && WORDS[i][1] < 0)410WORDS[i][1] *= (-1);411if (word_already_there(WORDS, i) == 0){412S1[counter] = graph_mapped_word(WORDS[i], dataN, dataNinv, dataX);413if (mat_search(S1[counter], S1, counter, mat_comp) != -1){414free_mat(S1[counter]);415}416else{417mat_quicksort(S1, 0, counter, mat_comp);418counter++;419}420}421}422for (i = 0; i < no[0]; i++)423free(WORDS[i]);424free(WORDS);425426no[0] = counter;427return(S1);428}429430431432433434435436