GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "voronoi.h"2#include "getput.h"3#include "matrix.h"4#include "bravais.h"5#include "longtools.h"6#include "symm.h"7#include "autgrp.h"8#include "voronoi.h"9#include "reduction.h"10#include "sort.h"11#include "tools.h"1213extern int INFO_LEVEL;1415matrix_TYP *is_z_equivalent_datei(bravais_TYP *G,bravais_TYP *G_tr,16bravais_TYP *H,bravais_TYP *H_tr,voronoi_TYP ***gp,int *anz_gperfect)17{18int i,19j,20dim,21epsilon = 101,22ming,23minh,24prime = 1949,25anz_hneighbours,26anz_gneighbours,27max; /* will hold the maximal diagonal entry of a form */2829bravais_TYP *GB; /* the bravais group of G for temporary purposes */3031matrix_TYP *gtrbifo, /* the tracebifo of G,G_tr */32*htrbifo, /* the tracebifo of H,H_tr */33*tmp,34*tmp2,35*id,36*gperfect, /* will hold ONE G-perfect form modulo the37operation of the normalizer */38*hperfect, /* will hold ONE H-perfect form */39*HSV, /* will hold the short vectors of hperfect */40*GSV,41**hneighbours, /* holds all neighbours of hperfect */42**gneighbours,43*h_pair=NULL, /* h will be transformed in a way such that44we get a "nice" basis of the formspace */45*conj; /* the matrix that conjugates these both groups,46if this exists */4748if (INFO_LEVEL & 4){49fprintf(stderr,"Entered is_z_equivalent_ZZ\n");50}5152dim = G->dim;5354/* checking all the trivialities */55if (G->dim != H->dim){56conj = NULL;57if (INFO_LEVEL & 4){58fprintf(stderr,"the groups don't even live in the same universe\n");59}60}61else if(G->form_no != H->form_no){62conj = NULL;63if (INFO_LEVEL & 4){64fprintf(stderr,"the groups are not conjugated\n");65fprintf(stderr,"Dimension of the Formspace of G: %d\n",G->form_no);66fprintf(stderr,"Dimension of the Formspace of H: %d\n",H->form_no);67}68}69/* the order is an criterion if it's known */70else if((G->order != H->order) && (G->order !=0) && (H->order !=0)){71conj = NULL;72if (INFO_LEVEL & 4){73fprintf(stderr,"the groups are not conjugated\n");74fprintf(stderr,"Order of G: %d\n",G->order);75fprintf(stderr,"Order of H: %d\n",H->order);76}77}78else{79/* now start the real bussiness */8081/* firstly calculate the trace_bifo for G,H */82gtrbifo = trace_bifo(G->form,G_tr->form,G->form_no);83htrbifo = trace_bifo(H->form,H_tr->form,H->form_no);8485/* inserted tilman 30.5.97 */86for (i=0;i<G->form_no;i++){87Check_mat(G->form[i]);88Check_mat(H->form[i]);89}9091/* output for debugging92put_mat(gtrbifo,NULL,"gtrbifo",2);93put_mat(htrbifo,NULL,"htrbifo",2); */9495/* the two trace bifos should have the same elementary devisors */96tmp = long_elt_mat(NULL,gtrbifo,NULL);97tmp2 = long_elt_mat(NULL,htrbifo,NULL);9899if (mat_comp(tmp,tmp2) == 0){100free_mat(tmp);101free_mat(tmp2);102103id = init_mat(dim,dim,"1");104105if (INFO_LEVEL & 4){106fprintf(stderr,"\n");107}108109/* now calculate one G-perfect form */110if (gp[0] == NULL && anz_gperfect[0] == 0){111tmp = rform(G->gen,G->gen_no,id,epsilon);112gperfect = first_perfect(tmp,G,G_tr->form,gtrbifo,&ming);113free_mat(tmp);114}115else{116gperfect = NULL;117}118119/* now calculate one H-perfect form, and the short vectors120of it */121tmp = rform(H->gen,H->gen_no,id,epsilon);122hperfect = first_perfect(tmp,H,H_tr->form,htrbifo,&minh);123free_mat(tmp);124125/* reduce H by pair_reduction, and transform H_tr accordingly */126h_pair = init_mat(H->dim,H->dim,"1");127tmp = pair_red(hperfect,h_pair);128free_mat(hperfect);129130transform_pair(H,H_tr,h_pair);131132free_mat(htrbifo);133htrbifo = trace_bifo(H->form,H_tr->form,H->form_no);134hperfect = first_perfect(tmp,H,H_tr->form,htrbifo,&minh);135free_mat(tmp);136137max = max_diagonal_entry(hperfect);138HSV = short_vectors(hperfect,max,0,0,0,&i);139140if (INFO_LEVEL & 4){141fprintf(stderr,"Got perfect forms for G and H.\n");142}143144/* output for debugging */145if (INFO_LEVEL & 4){146put_mat(hperfect,NULL,"hperfect",2);147put_mat(htrbifo,NULL,"htrbifo",2);148printf("maximaler diagonaleintrag von hperfect %d\n",max);149}150151/* now calculate all perfect neigbours of hperfect */152hneighbours = (matrix_TYP **) malloc(sizeof(matrix_TYP *));153hneighbours[0] = hperfect;154anz_hneighbours = neighbours(&hneighbours,H,H_tr->form,htrbifo,155HSV,minh);156157if (INFO_LEVEL & 4){158fprintf(stderr,"Calculated the neighbours of hperfect.\n");159}160161/* and calculate all G-perfect forms which represent the orbit162of the normalizer on them, i.e. the quotient graph */163if (gp[0]== NULL && anz_gperfect[0]==0){164GB = bravais_group(G,TRUE);165gp[0] = normalizer(gperfect,GB,G_tr,prime,anz_gperfect);166G->normal = GB->normal; G->normal_no = GB->normal_no;167GB->normal = NULL; GB->normal_no = 0;168free_bravais(GB);169}170171if (INFO_LEVEL & 4){172fprintf(stderr,"Calculated the normalizer of G.\n");173}174175/* now search for a G-perfect form which is isometric to the176H-perfect form and all of its neighbours are also */177conj = NULL;178i = 0;179while ((i<anz_gperfect[0]) && (conj == NULL)){180181/* calculate the short vectors of the G-perfect form in question */182GSV = short_vectors(gp[0][i]->gram,max,0,0,0,&j);183184/* let's see whether there is an isometry between this form185and hperfect */186conj = isometry(&hperfect,&gp[0][i]->gram,1,HSV,GSV,NULL,0,NULL);187188if (INFO_LEVEL & 4){189fprintf(stderr,"calculating isometries\n");190fprintf(stderr,"%d-th of %d\n",i+1,anz_gperfect[0]);191if (conj!=NULL){192fprintf(stderr,"found a new isometry.\n");193put_mat(conj,NULL,"conj",2);194put_mat(hperfect,NULL,"hperfect",2);195put_mat(gp[0][i]->gram,NULL,"gp[i]->gram",2);196}197}198199/* output for debugging200put_mat(hperfect,NULL,"hperfect",2);201put_mat(gp[i]->gram,NULL,"gp[i]->gram",2);202put_mat(conj,NULL,"conj",2);203put_mat(HSV,NULL,"HSV",2);204put_mat(GSV,NULL,"GSV",2); */205206if (conj != NULL){207/* there is an isometry, let's see whether it respects the208neighbours also */209/* because we have an isometry, the forms will have the same210minimum */211ming = minh;212213/* now calculate all perfect neigbours of hperfect */214gneighbours = (matrix_TYP **) malloc(sizeof(matrix_TYP));215gneighbours[0] = gp[0][i]->gram;216anz_gneighbours = neighbours(&gneighbours,G,G_tr->form,gtrbifo,217GSV,ming);218219free_mat(conj);220conj = NULL;221222if (anz_hneighbours == anz_gneighbours){223224if (INFO_LEVEL & 4){225printf("anz_hneighbours %d\n",anz_hneighbours);226for (j=0;j<=anz_hneighbours;j++){227put_mat(hneighbours[j],NULL,"hneighbours[j]",2);228put_mat(gneighbours[j],NULL,"gneighbours[j]",2);229}230}231232conj = extends_to_isometry(hneighbours,HSV,233anz_hneighbours+1,gneighbours,GSV,234anz_gneighbours+1,H->form_no,1);235236237}238/* cleaning up memory */239for (j=0;j<anz_gneighbours;j++){240free_mat(gneighbours[j+1]);241}242free(gneighbours);243244}245246free_mat(GSV);247i++;248}249250/* clean up memory used only here */251free_mat(id);252free_mat(hperfect);253if (gperfect != NULL) free_mat(gperfect);254free_mat(HSV);255for (i=0;i<anz_hneighbours;i++){256free_mat(hneighbours[i+1]);257}258free(hneighbours);259260}261else{262/* the groups are not conjugated, so clean up the memory used263so far and return NULL */264if (INFO_LEVEL & 4){265put_mat(tmp,NULL,"tmp",2);266put_mat(tmp2,NULL,"tmp2",2);267fprintf(stderr,268"The groups are not conjugated: elementary divisors\n");269}270free_mat(tmp);271free_mat(tmp2);272conj = NULL;273}274275/* clean up memory used only in this stage */276free_mat(gtrbifo);277free_mat(htrbifo);278}279280/* retransform H, H_tr to the original value, and fiddle around with281conj a bit */282if (h_pair != NULL){283tmp = long_mat_inv(h_pair);284transform_pair(H,H_tr,tmp);285if (conj != NULL){286mat_muleq(conj,h_pair);287}288free_mat(tmp);289free_mat(h_pair);290}291292/* we will return the transposed matrix if there was one at all */293if (conj != NULL){294tmp = tr_pose(conj);295free_mat(conj);296conj = tmp;297}298299return conj;300}301302303