GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/* last change: 01.03.01 by Oliver Heidbuechel */123#include <typedef.h>4#include <matrix.h>5#include <bravais.h>6#include <base.h>7#include <graph.h>8#include <presentation.h>9#include <longtools.h>10111213extern int INFO_LEVEL;141516/* -------------------------------------------------------------------- */17/* transform the i-th row of a matrix to a list of integers */18/* -------------------------------------------------------------------- */19static int *row_to_list(matrix_TYP *mat,20int i)21{22int *list, n;2324list = (int *)calloc(mat->cols, sizeof(int));25for (n = 0; n < mat->cols; n++)26list[n] = mat->array.SZ[i][n];2728return(list);29}30313233/* -------------------------------------------------------------------- */34/* in mats we have words for the generators of one represenative of */35/* each conjugacy class of maximal subgroups of G */36/* in the last row there has to be the number of elements in the */37/* conjugacy class */38/* fill a t_sub_TYP - structure with the generators for each */39/* representative of a conjugacy class */40/* -------------------------------------------------------------------- */41static t_sub_TYP *t_sub_info(matrix_TYP **mats,42int anz,43bravais_TYP *G,44matrix_TYP **G_geninv)45{46t_sub_TYP *sub;4748int i, j, no;4950matrix_TYP **base;515253/* prepare */54sub = (t_sub_TYP *)calloc(1, sizeof(t_sub_TYP));55sub->con_no = anz;56sub->groups = (bravais_TYP **)calloc(anz, sizeof(bravais_TYP *));57sub->worte = (int ***)calloc(anz, sizeof(int **));58sub->elem_no = (int *)calloc(anz, sizeof(int));59sub->strong = (bahn ***)calloc(anz, sizeof(bahn **));60sub->orders = (int *)calloc(anz, sizeof(int));61sub->total = 0;6263for (i = 0; i < anz; i++){64no = mats[i]->rows - 1;65sub->groups[i] = init_bravais(G->dim);66if (no == 0)67sub->groups[i]->gen = NULL;68else69sub->groups[i]->gen = (matrix_TYP **)calloc(no, sizeof(matrix_TYP *));70sub->groups[i]->gen_no = no;71sub->worte[i] = (int **)calloc(no, sizeof(int *));72for (j = 0; j < no; j++){73sub->worte[i][j] = row_to_list(mats[i], j);74sub->groups[i]->gen[j] = mapped_word(sub->worte[i][j], G->gen, G_geninv);75}76/* in the last row there is the number of elements in the conjugacy class77and the order of the elements */78sub->elem_no[i] = mats[i]->array.SZ[no][0];79sub->orders[i] = sub->groups[i]->order = mats[i]->array.SZ[no][1];80sub->total += sub->elem_no[i];8182/* calculate strong generating set */83base = get_base(G);84/*85???????????????????????????????????????????????????????????????????????86*/87sub->strong[i] = strong_generators(base, sub->groups[i], TRUE);88for (j = 0; j < G->dim; j++){89free_mat(base[j]);90}91free(base);92}9394return(sub);95}96979899/* -------------------------------------------------------------------- */100/* free a t_sub_TYP - structure */101/* -------------------------------------------------------------------- */102static void free_t_sub_TYP(t_sub_TYP *sub)103{104int i, j, dim = sub->groups[0]->dim;105106107for (i = 0; i < sub->con_no; i++){108for (j = 0; j < sub->groups[i]->gen_no; j++){109free(sub->worte[i][j]);110}111free(sub->worte[i]);112free_bravais(sub->groups[i]);113for (j = 0; j < dim; j++){114free_bahn(sub->strong[i][j]);115free(sub->strong[i][j]);116}117free(sub->strong[i]);118}119free(sub->strong);120free(sub->worte);121free(sub->groups);122free(sub->elem_no);123free(sub->orders);124free(sub);125}126127128129/* --------------------------------------------------------------------130Suppose the matrices in G->gen generate a finite matrix group, and N131generates a matrix group with the condition that the orbit of N132on the conjugated of G under N is finite.133134The groups in the orbit will be given by the element that conjugates them!135136Declaration of variables:137G: matrices generating G,138N: see above139Nanz: number of elements in N140strong: a set of base/strong generators for G returned by strong_generators141142Sideefects: None of the variables given nor global variables should be affected.143144The code is out of Base/conjugate.c!145-------------------------------------------------------------------- */146static matrix_TYP **conjugated_groups(bravais_TYP *G,147matrix_TYP **N,148int Nanz,149bahn **strong,150int *anz)151{152153matrix_TYP **orbit, /* represents the orbit of G under N by the154conjugating element */155*test_subgroup,156*tmp,157*tmp2,158*tmp3,159*tmp4;160161int found=1, /* number of conjugated subgroups found so far */162dealt=0, /* number of those dealt with */163i,164j,165k,166flag;167168if (INFO_LEVEL & 4){169fprintf(stderr,"entering conjugated\n");170}171172173orbit = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));174orbit[0] = init_mat(G->gen[0]->cols, G->gen[0]->cols, "1");175176/* start the orbit calculation */177while (dealt < found){178179/* output for debugging */180if (INFO_LEVEL & 4){181fprintf(stderr,"got %i conjugated subgroups so far\n",found);182fprintf(stderr,"dealt with %i of these\n",dealt);183}184/* loop over the generators of N */185for (i=0; i < Nanz;i++){186187/* calculating the new element */188test_subgroup = mat_mul(orbit[dealt],N[i]);189190/* see if this gives really a new element */191j=0;192tmp = mat_inv(test_subgroup);193while ((test_subgroup != NULL) && (j< found)){194tmp2 = mat_mul(orbit[j],tmp);195tmp3 = mat_inv(tmp2);196k=0;197flag = TRUE;198while (flag && (k<G->gen_no)){199tmp4 = mat_mul(tmp2,G->gen[k]);200tmp4 = mat_muleq(tmp4,tmp3);201if (!is_element(tmp4,G,strong,NULL)){202flag = FALSE;203}204free_mat(tmp4);205k++;206}207208if (flag){209free_mat(test_subgroup);210test_subgroup = NULL;211}212free_mat(tmp2);213free_mat(tmp3);214j++;215}216217/* get more memory */218if (test_subgroup != NULL){219orbit = (matrix_TYP **) realloc(orbit, (found + 1) * sizeof(matrix_TYP*));220orbit[found] = test_subgroup;221found++;222}223free_mat(tmp);224225} /* for (i= .... */226dealt++;227}228229anz[0] = found;230231return(orbit);232}233234235236/* -------------------------------------------------------------------- */237/* Let G and H be two groups with the same finite order. */238/* strong has to be the result of a call of strong_generators() for G */239/* returns TRUE iff H == G */240/* -------------------------------------------------------------------- */241static boolean equal_groups(bravais_TYP *H,242bravais_TYP *G,243bahn **strong)244{245int i;246247boolean FLAG = TRUE;248249250for (i = 0; FLAG && i < H->gen_no; i++){251if (!is_element(H->gen[i], G, strong, NULL)) FLAG = FALSE;252}253254return(FLAG);255}256257258259/* -------------------------------------------------------------------- */260/* If the elements in conjugacy class i and j are in one orbit, the */261/* conjugacy classes have to have the same number of elements and the */262/* representatives have to have the same order. */263/* -------------------------------------------------------------------- */264static int *construct_help_list(t_sub_TYP *sub)265{266int *help, i, j, counter = 1;267268boolean flag;269270271help = (int *)calloc(sub->con_no, sizeof(int));272for (i = 0; i < sub->con_no; i++){273if (help[i] == 0){274help[i] = -counter;275flag = FALSE;276for (j = i + 1; j < sub->con_no; j++){277if (sub->orders[j] == sub->orders[i] &&278sub->elem_no[j] == sub->elem_no[i]){279help[j] = -counter;280flag = TRUE;281}282}283if (flag == FALSE){284/* there is only one conjugacy class with this combination285of order and length */286help[i] = 0;287}288counter++;289}290}291292return(help);293}294295296297/* -------------------------------------------------------------------- */298/* mats: matrices with information about the maximal subgroups of G out */299/* of a GAP-programm */300/* no: no of mats */301/* pres: presentation for G */302/* aff_no: save the number of affine classes here */303/* aff_cons: save the no of conjugacy classes of each affine class here */304/* aff_cons_no: save the no of elements in each conjugacy class of each */305/* affine class here */306/* R: save representatives for the affine classes here */307/* flag: 0: only representatives are calculated */308/* 1: all subgroups are calculated */309310/* G->normal and G->gen have to generate the normalizer of G!!!!! */311312/* -------------------------------------------------------------------- */313bravais_TYP ****t_subgroups(bravais_TYP *G,314matrix_TYP **mats,315int no,316matrix_TYP *pres,317int *aff_no,318int **aff_cons,319int ***aff_cons_no,320bravais_TYP ***R,321int flag)322{323t_sub_TYP *sub;324325bravais_TYP ****S, **group;326327int i, j, k, l, counter, together,328cen_no, orbit_no, coho_size,329*stab_genno, ***WORDS, *NUMBER_OF_WORDS, *trashlist,330*help_list;331332matrix_TYP **G_geninv, **coz, **X, **trash, **G_norminv, ***stab,333**conj, **Rinv, *inv, *cocycle;334335MP_INT *names;336337338/* deal with trivial case */339if (no == 0){340/* there is no subgroup */341R[0] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));342R[0][0] = init_bravais(G->dim + 1);343R[0][0]->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));344R[0][0]->gen_no = 1;345R[0][0]->gen[0] = init_mat(G->dim + 1, G->dim + 1, "1");346aff_cons[0] = NULL;347aff_cons_no[0] = NULL;348aff_no[0] = 0;349return(NULL);350}351352/* prepare */353cen_no = G->cen_no; G->cen_no = 0;354G_geninv = (matrix_TYP **)calloc(G->gen_no, sizeof(matrix_TYP *));355sub = t_sub_info(mats, no, G, G_geninv);356WORDS = (int ***)calloc(MIN_SPEICHER, sizeof(int **));357NUMBER_OF_WORDS = (int *)calloc(MIN_SPEICHER, sizeof(int));358coz = all_cocycles(pres, G, aff_no, G_geninv, &X, &names, WORDS, NUMBER_OF_WORDS,359&trash, &coho_size, &trashlist, 1);360if (trash != NULL){361for (i = 0; i < G->normal_no; i++)362if (trash[i] != NULL) free_mat(trash[i]);363free(trash);364}365for (i = 0; i < G->gen_no; i++)366if (G_geninv[i] != NULL) free_mat(G_geninv[i]);367free(G_geninv);368aff_cons[0] = (int *)calloc(aff_no[0], sizeof(int));369aff_cons_no[0] = (int **)calloc(aff_no[0], sizeof(int *));370R[0] = (bravais_TYP **)calloc(aff_no[0], sizeof(bravais_TYP *));371for (i = 0; i < aff_no[0]; i++){372aff_cons_no[0][i] = (int *)calloc(sub->con_no, sizeof(int));373R[0][i] = extract_r(G, coz[i]);374}375S = (bravais_TYP ****)calloc(aff_no[0], sizeof(bravais_TYP ***));376377/* is it another trivial case */378if (no == 1 && mats[0]->rows == 1){379/* only the trivial group is a subgroup */380for (i = 0; i < aff_no[0]; i++){381S[i] = (bravais_TYP ***)calloc(1, sizeof(bravais_TYP **));382S[i][0] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));383S[i][0][0] = init_bravais(G->dim + 1);384S[i][0][0]->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));385S[i][0][0]->gen_no = 1;386S[i][0][0]->gen[0] = init_mat(G->dim + 1, G->dim + 1, "1");387aff_cons[0][i] = 1;388aff_cons_no[0][i][0] = 1;389}390}391else{392/* get the point group of the affine normalizer for each affine class representative */393G_norminv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));394stab = (matrix_TYP ***)calloc(aff_no[0], sizeof(matrix_TYP **));395stab_genno = (int *)calloc(aff_no[0], sizeof(int));396for (i = 0; i < aff_no[0]; i++){397stab[i] = stab_coz(WORDS[i], NUMBER_OF_WORDS[i], G->normal, G_norminv,398G->normal_no, i, &stab_genno[i]);399stab[i] = realloc(stab[i], (stab_genno[i] + G->gen_no) * sizeof(matrix_TYP *));400for (j = 0; j < G->gen_no; j++)401stab[i][j + stab_genno[i]] = G->gen[j];402}403404/* which subgroups are in the same orbit */405for (i = 0; i < aff_no[0]; i++){406Rinv = (matrix_TYP **)calloc(R[0][i]->gen_no, sizeof(matrix_TYP *));407counter = 0;408help_list = construct_help_list(sub);409S[i] = (bravais_TYP ***)calloc(sub->con_no, sizeof(bravais_TYP **));410for (j = 0; j < sub->con_no; j++){411if (help_list[j] <= 0){412413if (help_list[j] < 0){414/* possibly we have to join this conjugacy class with another one */415help_list[j] *= -1;416417/* calculate orbit */418conj = conjugated_groups(sub->groups[j], stab[i], stab_genno[i] + G->gen_no,419sub->strong[j], &orbit_no);420group = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));421422if (orbit_no % sub->elem_no[j] != 0){ /* paranoia test */423fprintf(stderr, "ERROR 1 in t_subgroups\n");424exit(6);425}426427together = orbit_no / sub->elem_no[j];428/* we have to join "together" conjugacy classes - which? */429if (together > 1){430for (k = 1; together > 1 && k < orbit_no; k++){431inv = long_mat_inv(conj[k]);432group[k] = konj_bravais(sub->groups[j], inv);433free_mat(inv);434for (l = j + 1; together > 1 && l < sub->con_no; l++){435if (equal_groups(group[k], sub->groups[l], sub->strong[l])){436together--;437help_list[l] *= -1;438}439}440}441}442if (together != 1){ /* paranoia test */443fprintf(stderr, "ERROR 2 in t_subgroups\n");444exit(5);445}446}447else{448/* only the elements in this conjugacy class are in an orbit under449the normalizer */450if (sub->elem_no[j] == 1){451/* only one element in the conjugacy class */452conj = NULL;453orbit_no = 1;454group = NULL;455}456else{457conj = conjugated_groups(sub->groups[i], G->gen, G->gen_no,458sub->strong[i], &orbit_no);459group = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));460}461}462if (flag == 0)463S[i][counter] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));464else465S[i][counter] = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));466467/* calculate the first element in the conjugacy class */468S[i][counter][0] = init_bravais(R[0][i]->dim);469S[i][counter][0]->gen_no = sub->groups[j]->gen_no;470S[i][counter][0]->gen = (matrix_TYP **)calloc(sub->groups[j]->gen_no,471sizeof(matrix_TYP *));472for (k = 0; k < sub->groups[j]->gen_no; k++){473S[i][counter][0]->gen[k] = mapped_word(sub->worte[j][k], R[0][i]->gen, Rinv);474}475476if (flag != 0){477/* calculate the other groups in this conjugacy class */478for (k = 1; k < orbit_no; k++){479if (group[k] == NULL){480inv = long_mat_inv(conj[k]);481group[k] = konj_bravais(sub->groups[j], inv);482free_mat(inv);483}484cocycle = sg(R[0][i], group[k]);485S[i][counter][k] = extract_r(group[k], cocycle);486free_mat(cocycle);487}488}489aff_cons_no[0][i][counter] = orbit_no;490counter++;491492for (k = 0; group != NULL && k < orbit_no; k++)493if (group[k] != NULL) free_bravais(group[k]);494if (group != NULL) free(group);495for (k = 0; conj != NULL && k < orbit_no; k++)496free_mat(conj[k]);497if (conj != NULL) free(conj);498}499}500free(help_list);501aff_cons[0][i] = counter;502for (j = 0; j < R[0][i]->gen_no; j++)503if (Rinv[j] != NULL) free_mat(Rinv[j]);504free(Rinv);505}506507/* clean */508for (i = 0; i < aff_no[0]; i++){509for (j = 0; j < stab_genno[i]; j++)510free_mat(stab[i][j]);511free(stab[i]);512}513free(stab);514free(stab_genno);515for (i = 0; i < G->normal_no; i++)516if (G_norminv[i] != NULL) free_mat(G_norminv[i]);517free(G_norminv);518}519520/* clean */521free_t_sub_TYP(sub);522for (i = 0; i < 3; i++)523free_mat(X[i]);524free(X);525for (i = 0; i < aff_no[0]; i++){526free_mat(coz[i]);527if (WORDS[i] != NULL){528for (j = 0; j < NUMBER_OF_WORDS[i]; j++)529if (WORDS[i][j] != NULL)530free(WORDS[i][j]);531free(WORDS[i]);532}533mpz_clear(names + i);534}535free(coz);536if (WORDS != NULL) free(WORDS);537free(NUMBER_OF_WORDS);538free(names);539540G->cen_no = cen_no;541return(S);542}543544545546547548549550551552553554