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"getput.h"3#include"datei.h"4#include"longtools.h"5/**************************************************************************\6@---------------------------------------------------------------------------7@---------------------------------------------------------------------------8@ FILE: gittstab.c9@---------------------------------------------------------------------------10@---------------------------------------------------------------------------11@12\**************************************************************************/1314static int is_in(M, B)15matrix_TYP *M;16bravais_TYP *B;17{18int i,j,k;19matrix_TYP *mtr;20matrix_TYP *F, *A;21int erg;22erg = TRUE;2324mtr = init_mat(M->cols, M->rows, "");25for(i=0; i<M->cols; i++)26for(j=0; j<M->rows; j++)27mtr->array.SZ[i][j] = M->array.SZ[j][i];2829for(i=0; i<B->form_no && erg == TRUE; i++)30{31A = mat_mul(mtr, B->form[i]);32F = mat_mul(A, M);33free_mat(A);34for(j=0; j<F->rows && erg == TRUE; j++)35for(k=0; k<F->cols && erg == TRUE; k++)36if(F->array.SZ[j][k] != B->form[i]->array.SZ[j][k])37erg = FALSE;38free_mat(F);39}40free_mat(mtr);41return(erg);42}43444546/*--------------------------------------------------------------------*\47| test if a matrix Y is already contained in a list of matices |48| with length 'anz'. |49| If Y is not contained in the list, the result is -1, else |50| the result is the position where Y was found. |51\*--------------------------------------------------------------------*/52static int such(Y, linv, anz)53matrix_TYP *Y;54matrix_TYP **linv;55int anz;56{57int schonda, i;58matrix_TYP *G;5960schonda = -1;61for(i=0; i<anz && schonda == -1; i++)62{63G = mat_mul(linv[i], Y);64Check_mat(G);65if(G->kgv == 1)66schonda = i;67free_mat(G);68}69return schonda;70}7172/*--------------------------------------------------------------------*\73| if A is not the identity-matrix and A is not contained in the |74| geneator-matrices of stab the result is TRUE, else FALSE |75\*--------------------------------------------------------------------*/76static int mat_such(stab, A)77bravais_TYP *stab;78int **A;79{80int i,j,k, neu;81i=0; j=0; neu = 0;82while(i<stab->dim && neu == 0)83{84j=0;85while(j<stab->dim && neu == 0)86{87if(i==j && A[i][j] != 1)88neu = 1;89if(i != j && A[i][j] != 0)90neu = 1;91j++;92}93i++;94}95if(neu == 0)96return(neu);9798if(stab->gen_no == 0)99return(1);100neu = 1;101i=0;102do103{104j=0; k = stab->dim;105while(j<stab->dim && k == stab->dim)106{107k=0;108while(k<stab->dim && A[j][k] == stab->gen[i]->array.SZ[j][k])109k++;110j++;111}112if(j == stab->dim && k == stab->dim)113neu =0;114i++;115}while (neu == 1 && i<stab->gen_no);116return(neu);117}118119120121/**************************************************************************\122@---------------------------------------------------------------------------123@ bravais_TYP *Z_class(B, zen)124@ bravais_TYP *B;125@ matrix_TYP *zen;126@127@---------------------------------------------------------------------------128@129@ calculates the intersection of zen^(-1)*B*zen with GL_n(Z) |130\**************************************************************************/131bravais_TYP *Z_class(B, zen)132bravais_TYP *B;133matrix_TYP *zen;134{135int i,136j;137bravais_TYP *S;138bravais_TYP *C;139bravais_TYP *N;140bravais_TYP *CS;141bravais_TYP *NS;142matrix_TYP *A1, *A2;143matrix_TYP *zinv,144*ztr;145int *count;146int anz;147int *noetig = NULL;148149extern matrix_TYP *einheitsmatrix();150151S = gittstabneu(B, zen);152153/* deleted this output 25/4/97 tilman154put_bravais(S, NULL, "Stabilisator noch nicht konjugiert"); */155156zinv = mat_inv(zen);157for(i=0; i<S->gen_no; i++)158{159A1 = mat_mul(zinv, S->gen[i]);160A2 = mat_mul(A1, zen);161free_mat(A1); free_mat(S->gen[i]);162Check_mat(A2);163S->gen[i] = A2;164}165C = (bravais_TYP *)calloc(1, sizeof(bravais_TYP) );166C->gen_no = B->cen_no;167C->dim = B->dim;168C->gen = (matrix_TYP **) malloc(C->gen_no *sizeof(matrix_TYP *));169for(i=0; i<C->gen_no; i++)170C->gen[i] = B->cen[i];171if(C->gen_no > 0)172CS = gittstabneu(C, zen);173S->form = (matrix_TYP **) malloc(B->form_no *sizeof(matrix_TYP));174S->form_no = B->form_no;175ztr = init_mat(zen->cols, zen->rows, "");176for(i=0; i<zen->rows; i++)177for(j=0; j<zen->cols; j++)178ztr->array.SZ[j][i] = zen->array.SZ[i][j];179for(i=0; i<B->form_no; i++)180{181A1 = mat_mul(ztr, B->form[i]);182S->form[i] = mat_mul(A1, zen);183Check_mat(S->form[i]);184S->form[i]->kgv = 1;185S->form[i]->flags.Integral = TRUE;186free_mat(A1);187}188189/* inserted 05/05/97 tilman: do an rein on the formspace of S190to give a Z-basis */191long_rein_formspace(S->form,S->form_no,1);192193if(C->gen_no > 0)194{195S->cen_no = CS->gen_no;196S->cen = (matrix_TYP **) malloc(S->cen_no *sizeof(matrix_TYP));197for(i=0; i<CS->gen_no; i++)198{199A1 = mat_mul(zinv, CS->gen[i]);200A2 = mat_mul(A1, zen);201free_mat(A1);202Check_mat(A2);203S->cen[i] = A2;204}205}206if(B->normal_no == 1)207Check_mat(B->normal[0]);208if(B->normal_no > 1 || (B->normal_no == 1 && B->normal[0]->flags.Scalar == FALSE))209{210N = (bravais_TYP *)calloc(1, sizeof(bravais_TYP));211N->gen_no = B->normal_no + B->gen_no + B->cen_no;212N->dim = B->dim;213N->gen = (matrix_TYP **) malloc(N->gen_no *sizeof(matrix_TYP *));214for(i=0; i<B->gen_no ; i++)215N->gen[i] = B->gen[i];216for(i=0; i<B->normal_no; i++)217N->gen[i+B->gen_no] = B->normal[i];218for(i=0; i<B->cen_no; i++)219N->gen[i+B->gen_no+B->normal_no] = B->cen[i];220NS = gittstabneu(N, zen);221noetig = (int *) malloc(NS->gen_no *sizeof(int));222for(i=0; i<NS->gen_no; i++)223{224noetig[i] = TRUE;225if(is_in(NS->gen[i], B) == TRUE)226noetig[i] = FALSE;227if(noetig[i] == TRUE)228{229A1 = mat_inv(NS->gen[i]);230for(j=0; j<i && noetig[i] == TRUE; j++)231{232A2 = mat_mul(A1, NS->gen[j]);233if(is_in(A2, B) == TRUE)234noetig[i] = FALSE;235free_mat(A2);236}237free_mat(A1);238}239}240anz = 0;241for(i=0; i<NS->gen_no; i++)242if(noetig[i] == TRUE)243anz++;244if(anz == 0)245anz = 1;246S->normal_no = anz;247S->normal = (matrix_TYP **) malloc(S->normal_no *sizeof(matrix_TYP));248249/* we don't used count at all (as far as I see) : tilman 7/5/97250count = (int *) malloc(NS->gen_no *sizeof(int)); */251252anz = 0;253for(i=0; i<NS->gen_no; i++)254{255if(noetig[i] == TRUE)256{257A1 = mat_mul(zinv, NS->gen[i]);258A2 = mat_mul(A1, zen);259free_mat(A1);260Check_mat(A2);261S->normal[anz] = A2;262anz++;263}264}265free_bravais(NS);266free(N->gen);267free(N);268if(anz == 0)269S->normal[0] = einheitsmatrix(B->dim);270}271if(B->normal_no == 1 && B->normal[0]->flags.Scalar == TRUE)272{273S->normal_no = 1;274S->normal = (matrix_TYP **) malloc(S->normal_no *sizeof(matrix_TYP));275S->normal[0] = einheitsmatrix(B->dim);276}277if(C->gen_no > 0)278free_bravais(CS);279free(C->gen);280free(C);281free_mat(zinv); free_mat(ztr);282283/* inserted 7/6/97 tilman */284if (noetig != NULL) free(noetig);285286return(S);287}288289290291292293/**************************************************************************\294@---------------------------------------------------------------------------295@ bravais_TYP *gittstab(grp, X)296@ bravais_TYP *grp;297@ matrix_TYP *X;298@299@ gittstab calculates the stabilizer of a lattice X under the |300@ operation of the group 'grp' acting via left-multiplication |301@---------------------------------------------------------------------------302@303\**************************************************************************/304bravais_TYP *gittstab(grp, X)305bravais_TYP *grp;306matrix_TYP *X;307{308int i, j, k;309matrix_TYP **list;310matrix_TYP **list_inv;311matrix_TYP **history;312matrix_TYP *Y, *Yinv;313matrix_TYP *Z;314matrix_TYP *G, *Hinv;315bravais_TYP *stab;316int *index;317int num, erz, schonda, norm = 0;318int neu, anz = 0;319int suchanfang;320321extern void store_mat();322extern matrix_TYP *mat_mul();323extern matrix_TYP *mat_inv();324extern matrix_TYP *init_mat();325extern int such();326extern int *factorize();327extern void positivieren();328329if(grp->dim != X->rows)330{331printf("Matrixgruppe und Vektorraum haben unterschiedliche Dimension\n");332exit(3);333}334if(X->cols != X->rows)335{336printf("Teilgitter hat nicht vollen Rang\n");337exit(3);338}339list = (matrix_TYP **) malloc(1 *sizeof(matrix_TYP *));340list_inv = (matrix_TYP **) malloc(1 *sizeof(matrix_TYP *));341history = (matrix_TYP **) malloc(1 *sizeof(matrix_TYP *));342stab = (bravais_TYP *) calloc(1, sizeof(bravais_TYP) );343stab->dim = grp->dim;344stab->gen_no = 0;345stab->form_no = 0;346stab->zentr_no = 0;347stab->normal_no = 0;348stab->order = 0;349Z = init_mat(X->rows, X->rows, "");350for(i=0; i<X->rows; i++)351Z->array.SZ[i][i] = 1;352353Y = init_mat(X->rows, X->rows, "");354for(i=0; i<X->rows; i++)355for(j=0; j<X->cols; j++)356Y->array.SZ[i][j] = X->array.SZ[i][j];357Yinv = mat_inv(Y);358list[anz] = Y; /* init the orbit of X under 'grp' */359list_inv[anz] = Yinv;360history[anz] = Z; /* history[n] * list[0] = list[n] */361anz++;362num = 0;363erz = 0;364/*--------------------------------------------------------------------*\365| algorithmen to calculate the orbit of X |366\*--------------------------------------------------------------------*/367do368{369Y = mat_mul(grp->gen[erz], list[num]);370Z = mat_mul(grp->gen[erz], history[num]);371schonda = such(Y, list_inv, anz);372/*------------------------------------------------------------*\373| if new lattice in the orbit |374\*------------------------------------------------------------*/375if (schonda == -1)376{377list = (matrix_TYP **) realloc(list, (anz+1) *sizeof(matrix_TYP *));378list_inv = (matrix_TYP **) realloc(list_inv, (anz+1) *sizeof(matrix_TYP *));379history = (matrix_TYP **) realloc(history, (anz+1) *sizeof(matrix_TYP *));380Yinv = mat_inv(Y);381list[anz] = Y;382list_inv[anz] = Yinv;383history[anz] = Z;384anz++;385}386/*------------------------------------------------------------*\387| if lattice already found, calculate stabilizer-element |388\*------------------------------------------------------------*/389else390{391Hinv = mat_inv(history[schonda]);392G = mat_mul(Hinv, Z);393neu = mat_such(stab, G->array.SZ);394if(neu == 1)395{396if(stab->gen_no != 0)397stab->gen = (matrix_TYP **) realloc(stab->gen, (stab->gen_no+1) *sizeof(matrix_TYP *));398if(stab->gen_no == 0)399stab->gen = (matrix_TYP **) malloc(1 *sizeof(matrix_TYP *));400stab->gen[stab->gen_no] = G;401stab->gen_no++;402}403else404free_mat(G);405free_mat(Hinv); free_mat(Z); free_mat(Y);406}407if (num == anz-1 && erz == grp->gen_no-1)408break;409if (erz < grp->gen_no-1)410++erz;411else412{erz = 0;413++num;}414}while (1);415/**************416for(i=0; i<anz; i++)417put_mat(list_inv[i], NULL, "list_inv" , 2);418*****************/419/*--------------------------------------------------------------------*\420| calculation of the order of the stabilizer |421\*--------------------------------------------------------------------*/422index = factorize(anz);423for(i=1; i<100; i++)424stab->divisors[i] = grp->divisors[i] - index[i];425if(grp->divisors[0] != 0 || index[0] != 0)426{427stab->divisors[0] = 1;428stab->order = 0;429}430else431{432stab->order = 1;433for(i=2; i<100; i++)434for(j=0; j<stab->divisors[i]; j++)435stab->order *= i;436}437for(i=0; i<anz; i++)438{439free_mat(list[i]);440free_mat(list_inv[i]);441free_mat(history[i]);442}443free(list);444free(list_inv);445free(history);446free(index);447return(stab);448}449450451