GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/* last change: 07.02.2001 by Oliver Heidbuechel */123#include <ZZ.h>4#include <typedef.h>5#include <presentation.h>6#include <matrix.h>7#include <bravais.h>8#include <base.h>9#include <datei.h>10#include <graph.h>11#include <gmp.h>12#include <zass.h>13#include <tools.h>14#include <longtools.h>15#include <voronoi.h>16#include <symm.h>17#include <autgrp.h>18#include <reduction.h>1920#define MYSIZE 10242122/* boolean GRAPH = FALSE; */232425/* --------------------------------------------------------------------- */26/* Konjugiere bravais_TYP */27/* (genauer berechne T B T^{-1}) */28/* Quellcode konj_bravais.c und normalizer.c entnommen */29/* Es wird nur ->gen, ->gen_no, ->normal, ->normal_no, ->order und */30/* ->divisors, ->form, ->form_no angelegt. */31/* --------------------------------------------------------------------- */32/* B: zu konjugierende Gruppe */33/* T: Matrix mit der konjugiert wird */34/* Ti: Inverse zu T */35/* --------------------------------------------------------------------- */36static bravais_TYP *my_konj_bravais(bravais_TYP *B,37matrix_TYP *T,38matrix_TYP *Ti)39{40int i, dim, Vanz;41bravais_TYP *G, *BG, *BGtr;42matrix_TYP *Titr, *waste, *tmp, *tmp2, *A;43voronoi_TYP **V;4445G = init_bravais(B->dim);4647/* Order */48if (B->order != 0){49G->order = B->order;50memcpy(G->divisors,B->divisors,100*sizeof(int));51}5253/* Generators */54if(B->gen_no != 0)55{56G->gen_no = B->gen_no;57if( (G->gen = (matrix_TYP **)malloc(B->gen_no *sizeof(matrix_TYP *))) == NULL)58{59printf("malloc of 'G->gen' in 'konj_bravais' failed\n");60exit(2);61}62for(i=0;i<B->gen_no;i++)63{64waste = mat_mul(T, B->gen[i]);65G->gen[i] = mat_mul(waste, Ti);66free_mat(waste);67}68}6970/* Normalizer, weiter wird der Formenraum von G angelegt */71BG = bravais_group(G, FALSE);7273/* let's see whether we already got the formspace */74if (BG->form == NULL){75BG->form = formspace(BG->gen, BG->gen_no, 1, &BG->form_no);76}77BGtr = tr_bravais(BG, 1, FALSE);7879/* firstly calculate an positive definite BG-invariant form */80tmp2 = init_mat(BG->dim,BG->dim,"1");81tmp = rform(BG->gen,BG->gen_no,tmp2,101);82free_mat(tmp2);8384/* now calculate the trace bifo */85tmp2 = trace_bifo(BG->form,BGtr->form,BG->form_no);86A = first_perfect(tmp, BG, BGtr->form, tmp2, &Vanz);87free_mat(tmp2);88free_mat(tmp);8990V = normalizer(A, BG, BGtr, 1949, &Vanz);9192/* now we got BG and it's normalizer, so see what we can do with G */93G->normal = normalizer_in_N(G, BG, &G->normal_no, FALSE);9495/* clean */96for(i = 0; i < Vanz; i++){97clear_voronoi(V[i]);98free(V[i]);99}100free(V);101free_mat(A);102free_bravais(BG);103free_bravais(BGtr);104105return(G);106}107108109110111112/* --------------------------------------------------------------------- */113/* Calculate H^1(G, Q^n/Z^n) */114/* G < GL_n(Z) finite, relator: presentation in relator format */115/* relatoranz: number of rows in the presentation */116/* see .../Zassen/zass.c */117/* --------------------------------------------------------------------- */118matrix_TYP **calculate_H1(bravais_TYP *G,119word *relator,120int relatoranz)121{122matrix_TYP **X,123**matinv;124125long dim;126127int i;128129130/* prepare */131matinv = (matrix_TYP **)calloc(G->gen_no, sizeof(matrix_TYP *));132133/* calculate H^1 */134X = cohomology(&dim, G->gen, matinv, relator, G->gen_no, relatoranz);135136/* clean */137for (i = 0; i < G->gen_no; i++){138if (matinv[i] != NULL)139free_mat(matinv[i]);140}141free(matinv);142143return(X);144}145146147148/* --------------------------------------------------------------------- */149/* free the structure coz_TYP */150/* --------------------------------------------------------------------- */151void free_coz_TYP(coz_TYP coz_info)152{153int i;154155mpz_clear(&coz_info.name);156mpz_clear(&coz_info.number);157free_mat(coz_info.std_coz);158free_mat(coz_info.diff);159for (i = 0; coz_info.WORDS != NULL && i < coz_info.WORDS_no; i++)160free(coz_info.WORDS[i]);161if (coz_info.WORDS != NULL)162free(coz_info.WORDS);163if (coz_info.Stab){164for (i = 0; i < coz_info.Stab_no; i++)165free_mat(coz_info.Stab[i]);166free(coz_info.Stab);167}168if (coz_info.darst != NULL)169free_mat(coz_info.darst);170for (i = 0; coz_info.aff_transl != NULL && i < coz_info.aff_transl_no; i++)171free_mat(coz_info.aff_transl[i]);172if (coz_info.aff_transl)173free(coz_info.aff_transl);174if (coz_info.N_darst){175for (i = 0; i < coz_info.N_darst_no; i++)176free_mat(coz_info.N_darst[i]);177free(coz_info.N_darst);178}179for (i = 0; i < coz_info.N_darst_no; i++){180if (coz_info.N_inv[i] != NULL) free_mat(coz_info.N_inv[i]);181}182free(coz_info.N_inv);183free_mat(coz_info.coz);184for (i = 0; i < 3; i++)185free_mat(coz_info.X[i]);186free(coz_info.X);187free_mat(coz_info.GLS);188}189190191192/* --------------------------------------------------------------------- */193/* Calculate information about a cocycle, i. e. fill the structure */194/* coz_TYP for a coz given in coz, G is the corresponding point-group */195/* X contains the return value of cohomology for G */196/* G->normal has to generate together with G->gen N_Gl_n(Z) (G). */197/* G->zentr isn't considered!!! */198/* --------------------------------------------------------------------- */199/* coz_info.Stab = Stabilisator des Cozykels / G !!! */200/* --------------------------------------------------------------------- */201coz_TYP identify_coz(bravais_TYP *G,202matrix_TYP *coz,203matrix_TYP **X)204{205matrix_TYP **TR, **N_inv;206207coz_TYP coz_info;208209rational eins, minuseins;210211MP_INT null;212213int i, zen_no;214215216zen_no = G->zentr_no;217G->zentr_no = 0;218coz_info.GLS = mat_inv(X[2]);219220if (X[0]->cols >= 1){221/* prepare */222eins.z = eins.n = minuseins.n = 1;223minuseins.z = -1;224mpz_init_set_si(&coz_info.name, 0);225mpz_init_set_si(&coz_info.number, 0);226mpz_init_set_si(&null, 0);227coz_info.WORDS = (int **)calloc(MIN_SPEICHER, sizeof(int *));228coz_info.WORDS_no = 0;229N_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));230231/* get information about the cocycle */232TR = identify(X[0], X[1], X[2], G, &coz, &coz_info.name, 1, 1,233&coz_info.WORDS, &coz_info.WORDS_no);234235coz_info.darst = standard_rep(coz, coz_info.GLS, X[1]);236valuation(coz_info.darst, X[1], &coz_info.number);237coz_info.std_coz = convert_to_cozycle(coz_info.darst, X[0], X[1]);238coz_info.diff = mat_add(coz, coz_info.std_coz, eins, minuseins);239240coz_info.Stab = stab_coz(coz_info.WORDS, coz_info.WORDS_no, G->normal,241N_inv, G->normal_no, mpz_cmp(&coz_info.name, &null),242&coz_info.Stab_no);243244/* represenation of G->normal on H^1(G,Q^n/Z^n) */245coz_info.N_darst_no = G->normal_no;246coz_info.N_darst = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));247248/* eigentlich UEBERFLUESSIG:wird schon in identify berechnet */249for (i = 0; i < G->normal_no; i++){250coz_info.N_darst[i] = normalop(X[0], X[1], X[2], G, G->normal[i], 1);251}252253/* clean */254free_mat(TR[0]);255free(TR);256mpz_clear(&null);257for (i = 0; i < G->normal_no; i++){258if (N_inv[i] != NULL) free_mat(N_inv[i]);259}260free(N_inv);261}262else{263/* trivial H^1 */264coz_info.std_coz = init_mat(coz->rows, 1, "");265mpz_init_set_si(&coz_info.name, 0);266mpz_init_set_si(&coz_info.number, 0);267coz_info.diff = copy_mat(coz);268coz_info.WORDS = NULL;269coz_info.Stab = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));270for (i = 0; i < G->normal_no; i++){271coz_info.Stab[i] = copy_mat(G->normal[i]);272}273coz_info.Stab_no = G->normal_no;274coz_info.darst = init_mat(0, 0, "");275coz_info.N_darst = NULL;276coz_info.N_darst_no = 0;277}278G->zentr_no = zen_no;279coz_info.aff_transl = NULL;280coz_info.aff_transl_no = 0;281coz_info.coz = copy_mat(coz);282coz_info.X = (matrix_TYP **)calloc(3, sizeof(matrix_TYP *));283coz_info.N_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));284for (i = 0; i < 3; i++)285coz_info.X[i] = copy_mat(X[i]);286287return(coz_info);288}289290291292/* --------------------------------------------------------------------- */293/* informations about G-invariant sublattices */294/* --------------------------------------------------------------------- */295typedef struct296{297matrix_TYP **lattices; /* sublattices (matrices in long_col_hnf - Form) */298boolean *trivialflag; /* trivialflag == TRUE iff lattice[i] == p_i * Z^n */299int no; /* number of sublattices */300int *orbitlist; /* lattices[i] belongs to orbit orbitlist[i] in 1,2, ... */301int *orbitlength; /* orbitlength[i]: length of the orbits i = 1, 2, ... */302int *smallest; /* smallest[i]: number of the lattice with the lowest303number in orbit[i], i = 1, 2, ... */304int orbit_no; /* number of orbits */305matrix_TYP **conj; /* conj[i] * lattices[smallest[orbitlist[i]]] = lattices[i] */306} sublattice_TYP;307308309310/* --------------------------------------------------------------------- */311/* free the structure sublattice_TYP */312/* --------------------------------------------------------------------- */313static void free_sublattice_TYP(sublattice_TYP SL)314{315int i;316317318for (i = 0; i < SL.no; i++){319free_mat(SL.lattices[i]);320free_mat(SL.conj[i]);321}322free(SL.lattices);323free(SL.conj);324free(SL.orbitlist);325free(SL.orbitlength);326free(SL.smallest);327free(SL.trivialflag);328}329330331332/* --------------------------------------------------------------------- */333/* returns NULL iff cocycle "coz" isn't in the image or is 0 */334/* otherwise returns sol with phi(sol) = coz_darst */335/* (C_a x C_b x ... - representation) */336/* --------------------------------------------------------------------- */337static matrix_TYP *cocycle_in_image(matrix_TYP *coz,338matrix_TYP *coz_darst,339matrix_TYP *phi,340matrix_TYP **image_gen,341int image_gen_no,342matrix_TYP *GLS,343matrix_TYP *D,344int flag,345int erz_no,346boolean *is_in_image)347{348matrix_TYP *sol = NULL,349**images, **koords,350*tmp;351352int i, j, k, pos, first, last, diff,353anz, size = MYSIZE,354*number;355356MP_INT val;357358359360/* two trivial cases */361if (flag == 2 || flag == 3 || equal_zero(coz_darst)){362is_in_image[0] = TRUE;363return(sol);364}365366/* further cases */367if (flag == 1){368is_in_image[0]= FALSE;369}370else if (flag == 0){371if (erz_no == 0){372is_in_image[0] = FALSE;373}374else{375/* prepare */376anz = 1;377for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);378for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);379diff = last - first;380images = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));381images[0] = init_mat(diff, 1, "");382number = (int *)calloc(size, sizeof(int));383koords = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));384koords[0] = init_mat(image_gen_no, 1, "");385mpz_init(&val);386is_in_image[0] = FALSE;387388/* orbit algorithm (surely, there are better methods)*/389for (i = 0; !is_in_image[0] && i < anz; i++){390for (j = 0; !is_in_image[0] && j < image_gen_no; j++){391if (!equal_zero(image_gen[j])){392tmp = add_mod_D(images[i], image_gen[j], D, first, diff);393valuation(tmp, D, &val);394pos = mpz_get_ui(&val);395for (k = 0; k < anz; k++){396if (number[k] == pos)397break;398}399if (k == anz){400/* new element in the orbit */401if (anz >= size){402size += MYSIZE;403images = realloc(images, size * sizeof(matrix_TYP *));404number = realloc(number, size * sizeof(int));405koords = realloc(koords, size * sizeof(matrix_TYP *));406}407images[anz] = tmp;408koords[anz] = copy_mat(koords[i]);409koords[anz]->array.SZ[j][0]++;410number[anz] = pos;411if (cmp_mat(images[anz], coz_darst) == 0){412sol = copy_mat(koords[anz]);413is_in_image[0] = TRUE;414}415anz++;416}417else418free_mat(tmp);419}420}421}422423/* clean */424for (i = 0; i < anz; i++){425free_mat(koords[i]);426free_mat(images[i]);427}428free(koords);429free(images);430free(number);431mpz_clear(&val);432}433}434else{435fprintf(stderr, "This flag isn't allowed. ERROR in cocycle_in_image!\n");436exit(4);437}438439return(sol);440}441442443444/* --------------------------------------------------------------------- */445/* H1: return value of cohomology */446/* koord: koordinates of a cocyle in H^1(...) = C_a x C_b x ... */447/* returns cocycle */448/* --------------------------------------------------------------------- */449matrix_TYP *darst_to_C1(matrix_TYP **H1,450matrix_TYP *koord)451{452matrix_TYP *C1, *tmp;453454int first, last, diff, i, j;455456rational eins, zahl;457458459/* prepare */460for (first = 0; first < H1[1]->cols && H1[1]->array.SZ[first][first] == 1; first++);461for (last = first; last < H1[1]->cols && H1[1]->array.SZ[last][last] != 0; last++);462diff = last - first;463eins.z = eins.n = 1;464465/* paranoia */466if (diff != koord->rows){467fprintf(stderr, "ERROR in darst_to_C1!!!\n");468exit(9);469}470471C1 = init_mat(H1[0]->rows, 1, "");472for (i = 0; i < diff; i++){473if (koord->array.SZ[i][0] != 0){474tmp = init_mat(H1[0]->rows, 1, "");475for (j = 0; j < H1[0]->rows; j++){476tmp->array.SZ[j][0] = H1[0]->array.SZ[j][i];477}478zahl.z = koord->array.SZ[i][0];479zahl.n = H1[1]->array.SZ[i + first][i + first];480Normal(&zahl);481C1 = mat_addeq(C1, tmp, eins, zahl);482free_mat(tmp);483}484}485486return(C1);487}488489490491/* --------------------------------------------------------------------- */492/* adds an element of B^1(G, Q^n/L) to preimage such that afterwarts */493/* phi (preimage) = coz (in C^1) */494/* case: normalizer element is ID */495/* [part of this code is part of the code in coboundary] */496/* --------------------------------------------------------------------- */497static void korrektes_urbild_ID(matrix_TYP *preimage,498matrix_TYP *coz,499bravais_TYP *G)500{501matrix_TYP *diff, *A, *B, *tmp, **erg;502503rational eins, minuseins;504505int i, n, k, l;506507508eins.z = eins.n = minuseins.n = 1; minuseins.z = -1;509diff = mat_add(coz, preimage, eins, minuseins);510511n = G->dim;512513B = init_mat(n * G->gen_no, n, "k");514515/* belegen der matrix B = (g_1 - I, ...)^tr */516for (i = 0; i < G->gen_no; i++){517for (k = 0; k < n; k++){518for (l = 0; l < n; l++){519if (k == l){520B->array.SZ[k+i*n][l] = G->gen[i]->array.SZ[k][l] - 1;521}522else{523B->array.SZ[k+i*n][l] = G->gen[i]->array.SZ[k][l];524}525}526}527}528529A = copy_mat(B);530real_mat(A, A->rows, A->cols + 1);531532/* rechte Seite */533for (i = 0; i < G->gen_no; i++)534for (k = 0; k < n; k++)535A->array.SZ[i * n + k][n] = diff->array.SZ[i * n + k][0];536537k = long_row_gauss(A);538real_mat(A, k, A->cols);539540/* kick out the rows which have 0's in the first n entries */541for (i = A->rows - 1; i > 0; i--){542for (k = 0; k < n && A->array.SZ[i][k] == 0; k++);543if (k == n){544if (A->array.SZ[i][n] % diff->kgv){545fprintf(stderr,"error in korrektes_urbild_ID\n");546exit(3);547}548else{549real_mat(A,A->rows-1,A->cols);550}551}552}553554real_mat(diff, A->rows, 1);555556for (i = 0; i < A->rows; i++)557diff->array.SZ[i][0] = A->array.SZ[i][n];558559real_mat(A,A->rows, n);560561Check_mat(A);562Check_mat(diff);563564/* put_mat(A,0,0,0);565put_mat(diff,0,0,0); */566567erg = long_solve_mat(A, diff);568569if (erg == NULL || erg[0] == NULL){570fprintf(stderr,"error in korrektes_urbild_ID\n");571exit(3);572}573574tmp = mat_mul(B, erg[0]);575576preimage = mat_addeq(preimage, tmp, eins, eins);577578/* clean */579if (erg[0] != NULL) free_mat(erg[0]);580if (erg[1] != NULL) free_mat(erg[1]);581free(erg);582free_mat(A);583free_mat(B);584free_mat(diff);585free_mat(tmp);586}587588589/* --------------------------------------------------------------------- */590/* adds an element of B^1(G, Q^n/L) to preimage such that afterwarts */591/* phi (preimage) = coz (in C^1) */592/* case: normalizer element is possibly NOT ID */593/* [part of this code is part of the code in coboundary] */594/* --------------------------------------------------------------------- */595static void korrektes_urbild(matrix_TYP **preimage,596coz_TYP *coz_info,597bravais_TYP *G,598matrix_TYP *L,599boolean flag)600{601matrix_TYP *rep, *paranoia, **N_darst_inv, **N, **NNN, **orbit, *n, *tmp, **conj;602603bravais_TYP *R, *RR;604605int **words, word_no, i, j, k,606anz, size = MYSIZE, first, last, diff, pos,607*number;608609boolean found;610611MP_INT val;612613614615rep = standard_rep(preimage[0], coz_info->GLS, coz_info->X[1]);616617if (cmp_mat(rep, coz_info->darst) == 0){618korrektes_urbild_ID(preimage[0], coz_info->coz, G);619free_mat(rep);620}621else{622623/* calculate the stabilizer of the lattice */624if (flag){625N = coz_info->N_darst;626NNN = G->normal;627word_no = G->normal_no;628}629else{630words = stab_lattice(L, G->normal, G->normal_no, &word_no, NULL, 0, NULL);631632N_darst_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));633N = (matrix_TYP **)calloc(word_no, sizeof(matrix_TYP *));634NNN = (matrix_TYP **)calloc(word_no, sizeof(matrix_TYP *));635for (i = 0; i < word_no; i++){636NNN[i] = mapped_word(words[i], G->normal, coz_info->N_inv);637paranoia = mat_mul(NNN[i], L);638long_col_hnf(paranoia);639if (cmp_mat(paranoia, L) != 0){640fprintf(stderr, "ERROR in korrektes_urbild!\n");641exit(9);642}643free_mat(paranoia);644N[i] = graph_mapped_word(words[i], coz_info->N_darst, N_darst_inv, coz_info->X[1]);645free(words[i]);646}647free(words);648for (i = 0; i < G->normal_no; i++){649if (N_darst_inv[i] != NULL) free_mat(N_darst_inv[i]);650}651free(N_darst_inv);652}653654/* find n in N with n rep = coz_info->darst */655for (first = 0; first < coz_info->X[1]->cols && coz_info->X[1]->array.SZ[first][first] == 1; first++);656for (last = first; last < coz_info->X[1]->cols && coz_info->X[1]->array.SZ[last][last] != 0; last++);657diff = last - first;658found = FALSE;659anz = 1;660orbit = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));661number = (int *)calloc(size, sizeof(int));662conj = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));663conj[0] = init_mat(G->dim, G->dim, "1");664orbit[0] = copy_mat(rep);665tmp = NULL;666mpz_init(&val);667valuation(orbit[0], coz_info->X[1], &val);668number[0] = mpz_get_ui(&val);669n = NULL;670671/* out of orbit_rep */672for (i = 0; !found && i < anz; i++){673for (j = 0; !found && j < word_no; j++){674tmp = mat_mul(N[j], orbit[i]);675for (k = 0; k < diff; k++){676tmp->array.SZ[k][0] %= coz_info->X[1]->array.SZ[k + first][k + first];677if (tmp->array.SZ[k][0] < 0)678tmp->array.SZ[k][0] += coz_info->X[1]->array.SZ[k + first][k + first];679}680valuation(tmp, coz_info->X[1], &val);681pos = mpz_get_ui(&val);682for (k = 0; k < anz; k++){683if (number[k] == pos)684break;685}686if (k == anz){687/* new element in the orbit */688if (anz >= size){689size += MYSIZE;690orbit = realloc(orbit, size * sizeof(matrix_TYP *));691number = realloc(number, size * sizeof(int));692conj = realloc(conj, size * sizeof(matrix_TYP *));693}694orbit[anz] = tmp;695conj[anz] = mat_mul(NNN[j], conj[i]);696number[anz] = pos;697if (cmp_mat(orbit[anz], coz_info->darst) == 0){698n = copy_mat(conj[anz]);699found = TRUE;700}701anz++;702}703else704free_mat(tmp);705}706}707708/* paranoia test */709if (n == NULL){710fprintf(stderr, "ERROR 1 in korrektes_urbild\n");711exit(3);712}713714/* calculate the correct preimage */715real_mat(n, n->rows + 1, n->cols);716real_mat(n, n->rows, n->cols + 1);717n->array.SZ[G->dim][G->dim] = 1;718my_translation(n, preimage[0], coz_info->coz, G);719R = extract_r(G, preimage[0]);720free_mat(preimage[0]);721RR = konj_bravais(R, n);722preimage[0] = sg(RR, G);723724/* clean */725free_mat(n);726free_bravais(R);727free_bravais(RR);728for (i = 0; i < anz; i++){729free_mat(conj[i]);730free_mat(orbit[i]);731}732free(orbit);733free(conj);734free(number);735mpz_clear(&val);736if (flag){737N = NULL;738NNN = NULL;739}740else{741for (i = 0; i < word_no; i++){742free_mat(N[i]);743free_mat(NNN[i]);744}745free(NNN);746free(N);747}748free_mat(rep);749}750}751752753754/* --------------------------------------------------------------------- */755/* With one preimage and the kernels we can calculate all preimages in */756/* C^1(G, Q^n/L) */757/* --------------------------------------------------------------------- */758static matrix_TYP **calculate_all_preimages(matrix_TYP *preimage,759matrix_TYP **kernel_gen,760matrix_TYP **k_g_darst,761int kernel_gen_no,762matrix_TYP *D,763matrix_TYP **b1_kernel,764int b1_kernel_no,765int *anz)766{767matrix_TYP **preimages, *tmp, **elements;768769int size = MYSIZE,770i, j, k, pos, alt,771*number,772first, last, diff;773774MP_INT val;775776rational eins;777778779eins.z = eins.n = 1;780781/* all preimages up to addition with element of Ker phi | B^1(B, Q^n/L) */782if (kernel_gen_no > 0){783/* prepare */784anz[0] = 1;785preimages = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));786preimages[0] = copy_mat(preimage);787number = (int *)calloc(size, sizeof(int));788elements = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));789elements[0] = init_mat(k_g_darst[0]->rows, 1, "");790mpz_init(&val);791for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);792for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);793diff = last - first;794795/* orbit algorithm */796for (i = 0; i < anz[0]; i++){797for (j = 0; j < kernel_gen_no; j++){798tmp = add_mod_D(elements[i], k_g_darst[j], D, first, diff);799valuation(tmp, D, &val);800pos = mpz_get_ui(&val);801for (k = 0; k < anz[0]; k++){802if (number[k] == pos)803break;804}805if (k == anz[0]){806/* new element in the orbit */807anz[0]++;808if (anz[0] >= size){809size += MYSIZE;810preimages = realloc(preimages, size * sizeof(matrix_TYP *));811number = realloc(number, size * sizeof(int));812elements = realloc(elements, size * sizeof(matrix_TYP *));813}814elements[anz[0] - 1] = tmp;815preimages[anz[0] - 1] = mat_add(preimages[i], kernel_gen[j], eins, eins);816number[anz[0] - 1] = pos;817}818else819free_mat(tmp);820}821}822823/* clean */824mpz_clear(&val);825free(number);826for (i = 0; i < anz[0]; i++)827free_mat(elements[i]);828free(elements);829830alt = anz[0];831anz[0] = anz[0] * b1_kernel_no;832if (size < anz[0])833preimages = realloc(preimages, anz[0] * sizeof(matrix_TYP *));834}835else{836/* trivial case */837alt = 1;838anz[0] = b1_kernel_no;839preimages = (matrix_TYP **)calloc(anz[0], sizeof(matrix_TYP *));840preimages[0] = copy_mat(preimage);841}842843/* add elements of Ker phi | B^1(B, Q^n/L) */844for (i = 1; i < b1_kernel_no; i++){845for (j = 0; j < alt; j++){846preimages[i * alt + j] = mat_add(preimages[j], b1_kernel[i], eins, eins);847}848}849850return(preimages);851}852853854855/* --------------------------------------------------------------------- */856/* calculate the maximal klassengleich subgroups for R(G,coz) with */857/* translation lattice L */858/* --------------------------------------------------------------------- */859/* G: Pointgroup, G->normal and G->gen have to generate N_{Gl_n(Z)}(G) */860/* GL: G mit Gitter L konjugiert */861/* aflag: calculate subgroups up to conjugation of the affine normalizer */862/* of R */863/* anz: Speichere die Anzahl der Raumgruppen hier */864/* length: wenn aflag, dann speichere die Laengen der Bahnen hier */865/* --------------------------------------------------------------------- */866static bravais_TYP **subgroups_for_L(coz_TYP *coz_info,867matrix_TYP *L,868bravais_TYP *G,869bravais_TYP *GL,870matrix_TYP **H_G_Z,871matrix_TYP **H_GL_Z,872int *anz,873int **length,874boolean aflag)875{876boolean is_in_image;877878int i, b1_kernel_no;879880matrix_TYP *diag, *GLS, *tmp, *tmp2, **reps,881*phi, *kernel_mat, **kernel_gen, **image,882*koord, *preimage, **all_preimages,883**k, *nullcoz, **b1_kernel;884885H1_mod_ker_TYP H1_mod_ker;886887int image_gen_no;888889bravais_TYP **SG;890891892/* prepare */893anz[0] = 0;894GLS = mat_inv(H_G_Z[2]);895diag = matrix_on_diagonal(L, G->gen_no);896897/* calculate Phi */898calculate_phi(diag, H_GL_Z[0], H_G_Z, H_GL_Z, GLS, &phi,899&kernel_mat, &image, &image_gen_no, &H1_mod_ker);900901902/* is cocycle in the image (phi koord = coz->darst) */903koord = cocycle_in_image(coz_info->coz, coz_info->darst, phi, image, image_gen_no, GLS,904H_G_Z[1], H1_mod_ker.flag, H1_mod_ker.erz_no, &is_in_image);905906907if (is_in_image){908909/* calculate information about Ker phi | B^1 */910if (coz_info->aff_transl == NULL){ /* we calculate it only once */911coz_info->aff_transl = transl_aff_normal(G->gen, G->gen_no, &coz_info->aff_transl_no);912}913b1_kernel = kernel_factor_fct(coz_info->aff_transl, coz_info->aff_transl_no, G->gen_no, L,914&b1_kernel_no);915916if (!aflag){917/* Berechne alle Untergruppen */918/* ========================== */919920/* calculate preimage of cocycle (in C^1)*/921if (koord == NULL){922preimage = init_mat(coz_info->coz->rows, 1, "");923}924else{925tmp = darst_to_C1(H_GL_Z, koord);926preimage = mat_mul(diag, tmp);927free_mat(tmp);928}929korrektes_urbild(&preimage, coz_info, G, L, FALSE);930931/* calculate generators for Ker(phi on H^1(G,Q^n/L)) such that932phi(gen) = 0 in C^1 */933nullcoz = init_mat(coz_info->coz->rows, 1, "");934kernel_gen = (matrix_TYP **)calloc(kernel_mat->cols, sizeof(matrix_TYP *));935k = col_to_list(kernel_mat);936for (i = 0; i < kernel_mat->cols; i++){937tmp = darst_to_C1(H_GL_Z, k[i]);938kernel_gen[i] = mat_mul(diag, tmp);939free_mat(tmp);940korrektes_urbild_ID(kernel_gen[i], nullcoz, G);941}942free_mat(nullcoz);943944/*945if (coz_info->aff_transl == NULL){946coz_info->aff_transl = transl_aff_normal(G->gen, G->gen_no, &coz_info->aff_transl_no);947}948b1_kernel = kernel_factor_fct(coz_info->aff_transl, coz_info->aff_transl_no, G->gen_no, L,949&b1_kernel_no);950*/951952/* calculate all preimages */953all_preimages = calculate_all_preimages(preimage, kernel_gen, k, kernel_mat->cols,954H_GL_Z[1], b1_kernel, b1_kernel_no, anz);955/* calculate the groups */956SG = (bravais_TYP **)calloc(anz[0], sizeof(bravais_TYP *));957for (i = 0; i < anz[0]; i++){958SG[i] = extract_r(G, all_preimages[i]);959free_mat(all_preimages[i]);960}961962/* clean */963free(all_preimages);964free_mat(preimage);965/*966for (i = 0; i < b1_kernel_no; i++){967free_mat(b1_kernel[i]);968}969if (b1_kernel)970free(b1_kernel);971*/972for (i = 0; i < kernel_mat->cols; i++){973free_mat(kernel_gen[i]);974free_mat(k[i]);975}976free(k);977free(kernel_gen);978}979else{980/* Berechne nur Vertreter unter dem affinen Normalisator */981/* ===================================================== */982reps = calculate_representatives(G, GL, H_G_Z, H_GL_Z, L, phi,983H1_mod_ker, koord, kernel_mat, anz, length);984SG = (bravais_TYP **)calloc(anz[0], sizeof(bravais_TYP *));985for (i = 0; i < anz[0]; i++){986tmp = darst_to_C1(H_GL_Z, reps[i]);987free_mat(reps[i]);988tmp2 = mat_mul(diag, tmp);989free_mat(tmp);990korrektes_urbild(&tmp2, coz_info, G, L, FALSE);991SG[i] = extract_r(G, tmp2);992free_mat(tmp2);993length[0][i] *= b1_kernel_no;994}995free(reps);996}997for (i = 0; i < b1_kernel_no; i++){998free_mat(b1_kernel[i]);999}1000if (b1_kernel)1001free(b1_kernel);1002}1003else{1004SG = NULL;1005}10061007/* clean */1008if (koord != NULL)1009free_mat(koord);1010free_mat(GLS);1011free_mat(diag);1012free_mat(kernel_mat);1013free_mat(phi);1014free_H1_mod_ker_TYP(H1_mod_ker);1015for (i = 0; i < image_gen_no; i++){1016free_mat(image[i]);1017}1018free(image);10191020return(SG);1021}10221023102410251026102710281029/* --------------------------------------------------------------------- */1030/* Returns the maximal klassengleich subgroups of R with p_i-power-index */1031/* where p_i is a prime given in G->divisors */1032/* R has to be in standard affine form without translations */1033/* an G has to be the point group of R */1034/* with correct normalizer */1035/* Returns the number of these subgroups via anz. */10361037/* G->normal and G->gen have to generate the normalizer of G!!!!! */10381039/* aflag: FALSE => calculate all max. k-subgroups */1040/* TRUE => calculate max. k-subgroups up to conjugation of */1041/* the affine normalizer of R */1042/* orbitlength: speichere die Laengen der Bahnen (nur wenn aflag) */1043/* --------------------------------------------------------------------- */1044bravais_TYP **max_k_sub(bravais_TYP *G,1045bravais_TYP *R,1046matrix_TYP *pres,1047int *anz,1048boolean aflag,1049boolean debugflag,1050int **orbitlength)1051{1052sublattice_TYP SL;10531054bravais_TYP **S, *GL, **SG_L;10551056matrix_TYP **H_G_Z, **H_GL_Z,1057*coz, *tmp, *diag, *preimage,1058*L, *Linv, *conj,1059**b1_kernel;10601061word *relator;10621063int i, j, k, sg_L_no, b1_kernel_no,1064size = MYSIZE, counter, *length = NULL;10651066coz_TYP coz_info;10671068rational eins;1069107010711072/* prepare */1073cen_to_norm(G);1074relator = (word *) calloc(pres->rows, sizeof(word));1075for (i = 0; i < pres->rows; i++){1076matrix_2_word(pres, relator + i, i);1077}1078coz = extract_c(R);1079eins.z = eins.n = 1;1080anz[0] = 0;1081S = (bravais_TYP **)calloc(0, sizeof(bravais_TYP *));1082if (aflag)1083orbitlength[0] = (int *)calloc(0, sizeof(int));10841085/* calculate the sublattices */1086SL.lattices = max_sublattices(G, &SL.no, &SL.trivialflag, debugflag);10871088/* calculate H^1(G, Q^n/Z^n) */1089H_G_Z = calculate_H1(G, relator, pres->rows);10901091/* identify the cocyle */1092coz_info = identify_coz(G, coz, H_G_Z);10931094/* calculate the orbits on the lattices under the stabilizer of the cocycle */1095SL.orbitlist = (int *)calloc(SL.no, sizeof(int));1096SL.orbitlength = (int *)calloc(SL.no + 1, sizeof(int));1097SL.smallest = (int *)calloc(SL.no + 1, sizeof(int));1098SL.conj = (matrix_TYP **)calloc(SL.no, sizeof(matrix_TYP *));1099SL.orbit_no = orbit_on_lattices(SL.lattices, SL.no, coz_info.Stab, coz_info.Stab_no,1100SL.orbitlist, SL.orbitlength, SL.smallest, SL.conj);11011102for (i = 1; i <= SL.orbit_no; i++){1103/* calculate the maximal klassengleich subgroups for a representative of each orbit */1104L = SL.lattices[SL.smallest[i]];11051106if ( TRUE ){1107/*1108if (!SL.trivialflag[SL.smallest[i]]){1109*/1110/* lattice != p_i * Z^n */1111Linv = mat_inv(L);1112GL = my_konj_bravais(G, Linv, L);11131114/* calculate H^1(GL, Q^n/Z^n) */1115H_GL_Z = calculate_H1(GL, relator, pres->rows);11161117/* subgroups */1118SG_L = subgroups_for_L(&coz_info, L, G, GL, H_G_Z, H_GL_Z, &sg_L_no, &length, aflag);11191120if (sg_L_no > 0){1121if (aflag){1122S = (bravais_TYP **)realloc(S, (anz[0] + sg_L_no)1123* sizeof(bravais_TYP *));1124orbitlength[0] = (int *)realloc(orbitlength[0], (anz[0] + sg_L_no)1125* sizeof(int));1126}1127else{1128S = (bravais_TYP **)realloc(S, (anz[0] + sg_L_no * SL.orbitlength[i])1129* sizeof(bravais_TYP *));1130}1131for (j = 0; j < sg_L_no; j++){1132plus_translationen(SG_L[j], L);1133S[anz[0] + j] = SG_L[j];1134if (aflag){1135orbitlength[0][anz[0] + j] = length[j] * SL.orbitlength[i];1136}1137}11381139/* corresponding subgroups for the other lattices in this orbit */1140if (!aflag){1141counter = 1;1142for (j = SL.smallest[i] + 1; j < SL.no; j++){1143if (SL.orbitlist[j] == i){1144conj = to_aff_normal_element(SL.conj[j], coz, 0, G, R);1145for (k = 0; k < sg_L_no; k++){1146S[anz[0] + counter * sg_L_no + k] =1147konj_bravais(S[anz[0] + k], conj);1148}1149free_mat(conj);1150counter++;1151}1152}1153if (counter != SL.orbitlength[i]){ /* paranoiatest */1154fprintf(stderr, "ERROR in max_k_sub!\n");1155exit(8);1156}1157anz[0] += (sg_L_no * SL.orbitlength[i]);1158}1159else{1160anz[0] += sg_L_no;1161}1162}11631164/* clean */1165for (j = 0; j < 3; j++)1166free_mat(H_GL_Z[j]);1167free(H_GL_Z);1168free_bravais(GL);1169free_mat(Linv);1170if (SG_L != NULL)1171free(SG_L);1172if (length)1173free(length);1174length = NULL;1175}1176else{1177/* lattice == p_i * Z^n (there is only one lattice in this orbit) */1178/* calculate Ker(phi restricted to B^1(G,Q^n/L)) (here: phi = Id)*/11791180/* this isn't correct!!! there has to be an additional condition1181example: min.56.1.1.1 min.56.1.1 2 3 */11821183/* Das ist nicht korrekt, weil | phi^{-1} (0 + B^1) |1184nicht zwangslaeufig 1 ist. Dann wuerde es funktionieren! */11851186if (coz_info.aff_transl == NULL){ /* we calculate it only once */1187coz_info.aff_transl = transl_aff_normal(G->gen, G->gen_no,1188&coz_info.aff_transl_no);1189}1190b1_kernel = kernel_factor_fct(coz_info.aff_transl, coz_info.aff_transl_no,1191G->gen_no, L, &b1_kernel_no);1192if (size < (anz[0] + b1_kernel_no)){1193S = (bravais_TYP **)realloc(S, (anz[0] + b1_kernel_no) * sizeof(bravais_TYP *));1194size = anz[0] + b1_kernel_no;1195}11961197if (coz_info.darst->cols == 0 || equal_zero(coz_info.darst)){1198preimage = init_mat(coz->rows, 1, "");1199}1200else{1201tmp = darst_to_C1(H_G_Z, coz_info.darst);1202diag = matrix_on_diagonal(L, G->gen_no);1203preimage = mat_mul(diag, tmp);1204free_mat(tmp);1205free_mat(diag);1206}1207korrektes_urbild(&preimage, &coz_info, G, L, TRUE);12081209for (j = 0; j < b1_kernel_no; j++){1210b1_kernel[j] = mat_addeq(b1_kernel[j], preimage, eins, eins);1211S[j + anz[0]] = extract_r(G, b1_kernel[j]);1212free_mat(b1_kernel[j]);1213plus_translationen(S[j + anz[0]], L);1214}1215free(b1_kernel);1216free_mat(preimage);1217anz[0] += b1_kernel_no;1218}1219L = NULL;1220}12211222/* paranoia test */1223if (debugflag){1224for (j = 0; j < anz[0]; j++){1225if (S[j] != NULL && !is_k_subgroup(S[j], R, G, G->gen[0]->rows, pres)){1226fprintf(stderr, "ERROR: das ist gar keine Untergruppe!\n");1227put_bravais(S[j],0,0);1228put_bravais(R,0,0);1229exit(8);1230}1231}1232}12331234/* clean */1235free_sublattice_TYP(SL);1236for (i = 0; i < pres->rows; i++)1237wordfree(relator + i);1238free(relator);1239for (i = 0; i < 3; i++)1240free_mat(H_G_Z[i]);1241free(H_G_Z);1242free_coz_TYP(coz_info);1243free_mat(coz);12441245return(S);1246}1247124812491250125112521253