GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include <typedef.h>1#include <base.h>2#include <bravais.h>3#include <matrix.h>4#include <presentation.h>5#include <tsubgroups.h>67#define DATABASE_NAME TOPDIR "/tables/qcatalog/data"89101112/* -------------------------------------------------------------------- */13/* transform the i-th row of a matrix to a list of integers */14/* -------------------------------------------------------------------- */15static int *row_to_list(matrix_TYP *mat,16int i)17{18int *list, n;1920list = (int *)calloc(mat->cols, sizeof(int));21for (n = 0; n < mat->cols; n++)22list[n] = mat->array.SZ[i][n];2324return(list);25}2627/* ---------------------------------------------------------------------- */28/* Setze R und P (nur falls aflag = TRUE), in die Zeilen von mat ein. */29/* ---------------------------------------------------------------------- */30/* Rinv = R^{-1} */31/* Pinv = P^{-1} */32/* mat: Matrix mit Worten aus GAP */33/* (letzte Zeile: Laenge der Bahn unter Raumgr. und Pkt.gr.ordnung) */34/* ---------------------------------------------------------------------- */35TSubgroup_TYP *ite_gruppe(bravais_TYP *R,36bravais_TYP *P,37bravais_TYP *Rinv,38bravais_TYP *Pinv,39matrix_TYP *mat,40boolean aflag)41{42bravais_TYP *sg, *psg = NULL;4344int j, *word;4546TSubgroup_TYP *S;474849sg = init_bravais(R->dim);50sg->gen_no = mat->rows - 1;51sg->gen = (matrix_TYP **)calloc(sg->gen_no, sizeof(matrix_TYP *));52if (aflag){53psg = init_bravais(P->dim);54psg->gen_no = mat->rows - 1;55psg->gen = (matrix_TYP **)calloc(psg->gen_no, sizeof(matrix_TYP *));56}5758for (j = 0; j < sg->gen_no; j++){59word = row_to_list(mat, j);60sg->gen[j] = mapped_word(word, R->gen, Rinv->gen);61if (aflag)62psg->gen[j] = mapped_word(word, P->gen, Pinv->gen);63free(word);64}6566/* in Struktur eintragen */67/* ===================== */68S = (TSubgroup_TYP *)calloc(1, sizeof(TSubgroup_TYP));69S->R = sg;70S->P = psg;71S->orbitlength = mat->array.SZ[mat->rows - 1][0];72S->pointgrouporder = mat->array.SZ[mat->rows - 1][1];73sg = NULL;74}7576777879808182/* ---------------------------------------------------------------------- */83/* Berechne die maximalen klassengleichen Untergruppen einer Raumgruppe */84/* bis auf Konjugation unter der Raumgruppe. */85/* ---------------------------------------------------------------------- */86/* R: Raumgruppe in Standard affiner Form ohne Translationen */87/* P: Punktgruppe von R (korrespondierende Erzeuger an der gleichen */88/* Position), P->gen, P->normal und P->cen zusammen muessen */89/* N_Gl_n(Z) (P) erzeugen. */90/* Der Formenraum muss korrekt sein. */91/* pres: Praesentation von P */92/* gapmats: Worte fuer die Konjugiertenklassen von maximalen Unter- */93/* gruppen von P aus GAP */94/* no: Anzahl der Konjugiertenklassen */95/* aflag: Raumgruppen bis auf Konjugation unter dem affinen Normalisator */96/* der Raumgruppe R */97/* cflag: Ausgabe fuer Datenbank */98/* aflag wird auf true gesetzt */99/* ---------------------------------------------------------------------- */100TSubgroup_TYP **tsubgroup(bravais_TYP *R,101bravais_TYP *P,102matrix_TYP *pres,103matrix_TYP **gapmats,104int *no,105boolean aflag,106boolean cflag)107{108bravais_TYP *Rinv, *Pinv;109110TSubgroup_TYP **sbg, **S;111112int i, j, counter, *orbit,113Nanz, Nanzalt, *factor;114115matrix_TYP **base, *M, **N;116117bahn **strong;118119CARATname_TYP Name;120121database *database;122123124125if (cflag)126aflag = TRUE;127128/* lade Datenbank */129database = load_database(DATABASE_NAME, P->dim);130131132133134/* Nur die triviale Raumgruppe ist maximale Untergruppe! */135/* ===================================================== */136if (no[0] == 1 && gapmats[0]->rows == 1){137sbg = (TSubgroup_TYP **)calloc(no[0], sizeof(TSubgroup_TYP *));138sbg[0] = (TSubgroup_TYP *)calloc(1, sizeof(TSubgroup_TYP));139140sbg[0]->R = init_bravais(R->dim);141sbg[0]->R->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));142sbg[0]->R->gen_no = 1;143sbg[0]->R->gen[0] = init_mat(R->dim, R->dim, "1");144145sbg[0]->orbitlength = 1;146sbg[0]->pointgrouporder = 1;147148sbg[0]->P = init_bravais(P->dim);149sbg[0]->P->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));150sbg[0]->P->gen_no = 1;151sbg[0]->P->gen[0] = init_mat(P->dim, P->dim, "1");152153if (cflag){154Name = name_fct(R, database);155printf("#1 %i %i ", Name.zname[0], Name.zname[1]);156mpz_out_str(stdout, 10, &Name.aff_name);157printf("\n");158free_CARATname_TYP(Name);159Name = name_fct(sbg[0]->R, database);160printf("0 1 %s %i %i ", Name.qname, Name.zname[0], Name.zname[1]);161mpz_out_str(stdout, 10, &Name.aff_name);162printf("\n");163free_CARATname_TYP(Name);164}165free_database (database);166return(sbg);167}168169/* Die maximalen Untergruppen sind nicht trivial! */170/* ============================================== */171S = (TSubgroup_TYP **)calloc(no[0], sizeof(TSubgroup_TYP *));172Rinv = init_bravais(R->dim);173Rinv->gen_no = R->gen_no;174Rinv->gen = (matrix_TYP **)calloc(R->gen_no, sizeof(bravais_TYP *));175for (i = 0; i < R->gen_no; i++){176Rinv->gen[i] = mat_inv(R->gen[i]);177}178if (aflag){179Pinv = init_bravais(P->dim);180Pinv->gen_no = P->gen_no;181Pinv->gen = (matrix_TYP **)calloc(P->gen_no, sizeof(bravais_TYP *));182for (i = 0; i < P->gen_no; i++){183Pinv->gen[i] = mat_inv(P->gen[i]);184}185}186187for (i = 0; i < no[0]; i++){188S[i] = ite_gruppe(R, P, Rinv, Pinv, gapmats[i], aflag);189}190191free_bravais(Rinv);192193if (!aflag){194free_database(database);195return(S);196}197else{198free_bravais(Pinv);199200/* berechne Punktgruppe des affinen Normalisators */201/* ============================================== */202cen_to_norm(P);203N = PoaN(R, P, pres, &Nanz);204Nanzalt = Nanz;205Nanz = Nanz + P->gen_no;206N = (matrix_TYP **)realloc(N, Nanz * sizeof(matrix_TYP *));207for (i = 0; i < P->gen_no; i++)208N[Nanzalt + i] = copy_mat(P->gen[i]);209210/* Fasse Bahnen unter R zu Bahnen unter affinem Normalisator zusammen */211/* ================================================================== */212orbit = (int *)calloc(no[0], sizeof(int));213factor = (int *)calloc(no[0], sizeof(int));214for (i = 0; i < no[0]; i++){215orbit[i] = -1;216factor[i] = 0;217}218counter = 0;219220for (i = 0; i < no[0]; i++){221if (orbit[i] == -1){222orbit[i] = counter;223factor[counter] = 1;224225/* Strong generating set berechnen! */226base = get_base(S[i]->P);227strong = strong_generators(base, S[i]->P, TRUE);228for (j = 0; j < P->dim; j++){229free_mat(base[j]);230}231free(base);232233for (j = i + 1; j < no[0]; j++){234if(S[i]->pointgrouporder == S[j]->pointgrouporder){235236/* Die Funktion conjugated berechnet Bahn, so237dass eigentlich mehrere Gruppen auf einmal getestet238werden koennten. */239M = conjugated(S[i]->P, S[j]->P, N, Nanz, strong);240if (M != NULL){241orbit[j] = counter;242factor[counter]++;243free_mat(M);244}245}246}247counter++;248for (j = 0; j < P->dim; j++){249free_bahn(strong[j]);250free(strong[j]);251}252free(strong);253}254}255256/* Trage in Struktur ein */257/* ===================== */258sbg = (TSubgroup_TYP **)calloc(counter, sizeof(TSubgroup_TYP *));259j = 0;260if (cflag){261Name = name_fct(R, database);262printf("#%i %i %i ", counter, Name.zname[0], Name.zname[1]);263mpz_out_str(stdout, 10, &Name.aff_name);264printf("\n");265free_CARATname_TYP(Name);266}267for (i = 0; i < no[0] && j < counter; i++){268if (orbit[i] == j){269sbg[j] = S[i];270sbg[j]->orbitlength *= factor[j];271272if (cflag){273Name = name_fct(sbg[j]->R, database);274printf("%i %i %s %i %i ", i, sbg[j]->orbitlength,275Name.qname, Name.zname[0], Name.zname[1]);276mpz_out_str(stdout, 10, &Name.aff_name);277printf("\n");278free_CARATname_TYP(Name);279}280281j++;282}283else{284free_TSubgroup_TYP(S[i]);285}286}287288no[0] = counter;289free(orbit);290free(factor);291free_database(database);292free(S);293for (i = 0; i < Nanz; i++)294free_mat(N[i]);295free(N);296return(sbg);297}298}299300301302303304305306307308309310311312313314315316