GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include <signal.h>1#include "typedef.h"2#include "getput.h"3#include "tools.h"4#include "bravais.h"5#include "base.h"6#include "matrix.h"7#include "longtools.h"8#include "voronoi.h"9#include "ZZ_P.h"10#include "ZZ_irr_const_P.h"11#include "ZZ_lll_P.h"12#include "ZZ_cen_fun_P.h"1314extern int IDEM_NO;15int *SUB_VEC;16matrix_TYP **PrI;17QtoZ_konst_TYP *KONSTITUENTEN = NULL;1819/* eingefuegt von Oliver am 5.2.99 */20int OANZ = 0;21matrix_TYP **OMAT;22int OFLAG = FALSE;23/* ------------------------------- */242526/*============================================================*\27|| ||28|| Enthaelt die speziellen Funktionen des Zentrierungs- ||29|| algorithmus. Zunaechst die Ein- und Ausgaberoutinen ||30|| und ihre Hilfsfunktionen. ||31|| ||32\*============================================================*/3334/*-------------------------------------------------------------------*\35| takes the matrices in MAT as a generating set for a matrix-ring |36| over p and evaluates any linearcombination to get the whole ring |37\*-------------------------------------------------------------------*/3839static matrix_TYP **gen_sys (int *num, int l, matrix_TYP ** MAT);4041static matrix_TYP **gen_sys (num, l, MAT)42int *num;43int l;44matrix_TYP **MAT;45{46int i, j, *s, n, anz, w;47int **Z, **Q1, **Q2;48int row;49matrix_TYP **ring;50int a = 0;5152#if 053if (l == 1) { /* there`s only the identical Endomorphism and all54GF(p) multiples */55ring = MAT;56*num = act_prime - 1;57return (ring);58}59#endif6061a = intpow (act_prime, l);62anz = a - 1;63row = MAT[0]->rows;6465ring = (matrix_TYP **) malloc (anz * sizeof (matrix_TYP *));66*num = anz;67s = (int *)calloc (l, sizeof (int));68n = 0; /* number of the actuell matrix */69anz = 0; /* highest coefficient in s */70s[0] = 1;71ring[0] = MAT[0];72while (anz < l) {73a = 0; /* Laufindex ueber s */74while ((a <= anz) && ((s[a] = S (s[a], 1)) == 0)) {75a++;76}77if (a <= anz) {78n++;79ring[n] = init_mat(row, row, "p");80Z = Q1 = ring[n]->array.SZ;81for (a = 0; a <= anz; a++) {82if ((w = s[a]) == 0) {83continue;84}85Q2 = MAT[a]->array.SZ;86for (i = 0; i < row; i++) {87for (j = 0; j < row; j++) {88Z[i][j] = S(Q1[i][j],89P(Q2[i][j], w));90}91}92}93Check_mat(ring[n]);94} else {95if (++anz < l) {96s[anz] = 1;97s[anz - 1] = 0;98n++;99ring[n] = MAT[anz];100}101}102}103free (MAT);104free (s);105return (ring);106}107108void ZZ_free_node (data, n)109ZZ_data_t *data;110ZZ_node_t *n;111{112int i,j;113ZZ_couple_t *m, *tm;114115if (n->group != NULL){116free_bravais(n->group);117}118if (n->stab_chain != NULL){119for (i=0;i<n->col_group->dim;i++){120free_bahn(n->stab_chain[i]);121free(n->stab_chain[i]);122}123free(n->stab_chain);124}125if (n->col_group != NULL){126free_bravais(n->col_group);127}128if (n->brav != NULL){129free_bravais(n->brav);130}131if (n->perfect != NULL && n->perfect_no > 0){132for (i=0;i<n->perfect_no;i++){133clear_voronoi(n->perfect[i]);134free(n->perfect[i]);135}136free(n->perfect);137n->perfect = NULL;138n->perfect_no = 0;139}140if (n->N_no_orbits > 0 && n->N_orbits != NULL){141for (i=0;i<n->N_no_orbits;i++){142for (j=0;j<n->N_lengths[i];j++)143free_mat(n->N_orbits[i][j]);144free(n->N_orbits[i]);145}146free(n->N_lengths);147free(n->N_orbits);148}149if (n->U != NULL) {150free_mat (n->U);151}152if (n->Q != NULL) {153free_mat (n->Q);154}155if (n->U_inv != NULL) {156free_mat (n->U_inv);157}158if (n->el_div != NULL) {159free_mat (n->el_div);160}161free (n->path);162for (i = 0; i < data->p_consts.k; i++) {163free (n->k_vec[i]);164}165free (n->k_vec);166167if ((m = n->parent) != NULL) {168do {169tm = m->elder;170free (m);171m = tm;172} while (m != NULL);173}174if ((m = n->child) != NULL) {175do {176tm = m->elder;177free (m);178m = tm;179} while (m != NULL);180}181free (n);182}183184/*----------------------------------------------------------------*\185| calculate the Basis of the endomorphisms for any constituent |186| and generate the endomorphism-ring. The matrix set TMAT is |187| copied into data->Endo[i][j] by gen_sys, so there mustn`t be a |188| ZZ_free_mat at TMAT. |189\*----------------------------------------------------------------*/190void ZZ_make_endo (data)191ZZ_data_t *data;192{193int i, j, l;194matrix_TYP **TMAT;195196for (i = 0; i < data->p_consts.k; i++) {197init_prime (data->p_consts.p[i]);198for (j = 0; j < data->p_consts.s[i]; j++) {199l = data->r;200TMAT = p_solve(&l,201data->p_consts.Delta[i][j],202data->p_consts.Delta[i][j], 2);203data->EnCo[i][j].low = l;204data->Endo[i][j] = gen_sys(&data->EnCo[i][j].hi,205l, TMAT);206}207}208}209210211212/* tests if two constituents are isomorphic. Returns 1 if they are,213* 0 otherwise.214*215*/216217static int test_two_constituents(data, i, j, k)218ZZ_data_t *data;219int i, j, k;220{221int ll, l, s;222matrix_TYP **temp;223224#define P_CONST data->p_consts.Delta225if (data->n[i][j] == data->n[i][k]) {226for (ll = 0; ll < data->r; ll++) {227s = 0;228for (l = 0; l < data->n[i][j]; l++) {229s = S(S(s, P_CONST[i][j][ll]->array.SZ[l][l]),230-P_CONST[i][k][ll]->array.SZ[l][l]);231}232if (s != 0) {233break;234}235}236if (s == 0) {237s = data->r;238temp = p_solve(&s, P_CONST[i][j], P_CONST[i][k], 2);239if (s > 0) {240#if DEBUG241printf("p: %d, Konst. %d/%d\n", i, j ,k);242#endif243for (ll = 0; ll < s; ll++) {244free_mat(temp[ll]);245}246free(temp);247data->p_consts.s[i]--;248for (ll = 0; ll < data->r; ll++) {249free_mat(P_CONST[i][k][ll]);250}251free(P_CONST[i][k]);252P_CONST[i][k]= P_CONST[i][data->p_consts.s[i]];253data->n[i][k]= data->n[i][data->p_consts.s[i]];254return 1;255}256}257}258return 0;259#undef P_CONST260}261262/*----------------------------------------------------------------*\263| Test if the set of constituents is redundant, i.e two of them |264| are isomorphic. |265\*----------------------------------------------------------------*/266void ZZ_test_konst (data)267ZZ_data_t *data;268{269int i, j, k;270271for (i = 0; i < data->p_consts.k; i++) {272init_prime (data->p_consts.p[i]);273for (j = 0; j < data->p_consts.s[i] - 1; j++) {274for (k = j + 1; k < data->p_consts.s[i]; k++) {275if (test_two_constituents(data, i, j, k)) {276k--;277}278}279} /* Konstituenten */280} /* Primzahlen */281}282283/*284* Diese Funktion fuellt die Datenstrukturen "data" und "tree"285* insbesondere werden die irreduziblen Konstituenten fuer die286* Primteiler der Gruppenordnung errechnet287* q2z ruft diese Fufnktion ueber ZZ mehrmals auf; einige Daten brauchen nicht mehrmals288* ausgerechnet werden; das kann noch verbessert werden!289*/290void ZZ_get_data (group, gram, divisors, data, tree, projections, konst_flag)291bravais_TYP *group;292matrix_TYP *gram;293int *divisors;294ZZ_data_t *data;295ZZ_tree_t *tree;296int *projections;297int konst_flag;298{299int i, j, k;300matrix_TYP **help2;301QtoZ_konst_TYP *data_neu;302303304if (konst_flag == -3 && GRAPH){305for (i = 0; i < KONSTITUENTEN->k; i++){306for (j = 0; j < KONSTITUENTEN->s[i]; j++){307for (k = 0; k < KONSTITUENTEN->r; k++){308free_mat(KONSTITUENTEN->Delta[i][j][k]);309}310free(KONSTITUENTEN->Delta[i][j]);311}312free(KONSTITUENTEN->Delta[i]);313}314free(KONSTITUENTEN->Delta);315free(KONSTITUENTEN->s);316free(KONSTITUENTEN);317return;318}319320tree->root = tree->last = (ZZ_node_t *) malloc(sizeof(ZZ_node_t));321data->N = group->dim;322323if (ZCLASS > 0){324group->gen_no -= IDEM_NO;325tree->root->col_group = tr_bravais(group,1,FALSE);326group->gen_no += IDEM_NO;327tree->root->group = tr_bravais(tree->root->col_group,1,FALSE);328tree->root->brav = NULL;329tree->root->stab_chain = NULL;330tree->root->N_orbits = NULL;331tree->root->N_lengths = NULL;332tree->root->N_no_orbits = 0;333tree->root->perfect = NULL;334tree->root->perfect_no = 0;335tree->root->Q = init_mat(data->N, data->N, "1");336} else {337tree->root->col_group = NULL;338tree->root->group = NULL;339tree->root->brav = NULL;340tree->root->stab_chain = NULL;341tree->root->N_orbits = NULL;342tree->root->N_lengths = NULL;343tree->root->N_no_orbits = 0;344tree->root->perfect = NULL;345tree->root->perfect_no = 0;346tree->root->Q = NULL;347}348349tree->root->U = init_mat (data->N, data->N, "");350tree->root->U_inv = init_mat (data->N, data->N, "");351/* changed by oliver (6.11.00) from352tree->root->el_div = init_mat (1, data->N, "");353to: */354tree->root->el_div = init_mat (data->N, data->N, "");355for (i = 0; i < data->N; i++) {356tree->root->U->array.SZ[i][i] =357tree->root->U_inv->array.SZ[i][i] =358/* changed by oliver (6.11.00) from359tree->root->el_div->array.SZ[0][i] = 1;360to: */361tree->root->el_div->array.SZ[i][i] = 1;362}363tree->root->number =364tree->node_count =365tree->root->level =366tree->root->index = 1;367tree->root->path = (ZZ_prod_t *) calloc(1, sizeof(ZZ_prod_t));368tree->root->parent = NULL;369tree->root->next = NULL;370tree->root->child = NULL;371372/*373* Read the number of generators and the generators.374*/375376data->r = group->gen_no;377data->DELTA = (matrix_TYP **)malloc(data->r * sizeof(matrix_TYP *));378data->DELTA_M = (matrix_TYP **)malloc(data->r * sizeof(matrix_TYP *));379for (i = 0; i < data->r; i++) {380data->DELTA[i] = group->gen[i];381data->DELTA_M[i] = copy_mat(data->DELTA[i]);382}383384/*385* Read the number of primes386*/387for (i = 0, data->p_consts.k = 0; i < 100; i++) {388if (divisors[i] != 0) {389data->p_consts.k++;390}391}392data->p_consts.p = (int *)malloc(data->p_consts.k * sizeof (int));393for (i = 0, j = 0; j < data->p_consts.k; i++) {394if (divisors[i] != 0) {395data->p_consts.p[j++] = i;396}397}398data->p_consts.s = (int *) malloc(data->p_consts.k * sizeof(int));399data->n = (int **) malloc(data->p_consts.k * sizeof(int *));400data->EnCo = (ZZ_prod_t **)malloc(data->p_consts.k *401sizeof(ZZ_prod_t *));402data->p_consts.Delta =403(matrix_TYP ****)malloc(data->p_consts.k *404sizeof (matrix_TYP ***));405data->Endo =406(matrix_TYP ****)malloc (data->p_consts.k *407sizeof (matrix_TYP ***));408/*409* Read the i'th prime and the number of constituents for i410*/411412/* if - else eingefuegt von Oliver: 8.8.00 */413if (konst_flag == 0 && GRAPH){414for (i = 0; i < KONSTITUENTEN->k; i++) {415data->p_consts.s[i] = KONSTITUENTEN->s[i];416data->n[i] = (int *)malloc(data->p_consts.s[i] * sizeof (int));417data->p_consts.Delta[i] =418(matrix_TYP ***)malloc(data->p_consts.s[i] *419sizeof (matrix_TYP **));420for (j = 0; j < data->p_consts.s[i]; j++) {421data->p_consts.Delta[i][j] =422(matrix_TYP **)malloc(data->r *423sizeof (matrix_TYP *));424for (k = 0; k < KONSTITUENTEN->r; k++) {425data->p_consts.Delta[i][j][k] =426copy_mat(KONSTITUENTEN->Delta[i][j][k]);427data->p_consts.Delta[i][j][k]->prime =428data->p_consts.p[i];429}430data->n[i][j] = data->p_consts.Delta[i][j][0]->rows;431}432}433}434else{435/* alte Version */436for (i = 0; i < data->p_consts.k; i++) {437help2 = ZZ_irr_const (data->DELTA, data->r,438data->p_consts.p[i],439&data->p_consts.s[i]);440441data->n[i] = (int *)malloc(data->p_consts.s[i] * sizeof (int));442data->p_consts.Delta[i] =443(matrix_TYP ***)malloc(data->p_consts.s[i] *444sizeof (matrix_TYP **));445for (j = 0; j < data->p_consts.s[i]; j++) {446data->p_consts.Delta[i][j] =447(matrix_TYP **)malloc(data->r *448sizeof (matrix_TYP *));449for (k = 0; k < data->r; k++) {450data->p_consts.Delta[i][j][k] =451help2[j * data->r + k];452data->p_consts.Delta[i][j][k]->prime =453data->p_consts.p[i];454}455data->n[i][j] = data->p_consts.Delta[i][j][0]->rows;456}457free (help2);458}459ZZ_test_konst(data);460ZZ_test_konst(data);461ZZ_test_konst(data);462}463464/*465* initialize Endomorphisms466*/467for (i = 0; i < data->p_consts.k; i++) {468data->EnCo[i] =469(ZZ_prod_t *)malloc(data->p_consts.s[i] *470sizeof (ZZ_prod_t));471data->Endo[i] =472(matrix_TYP ***)malloc(data->p_consts.s[i] *473sizeof (matrix_TYP **));474}475476data->epi_base = NULL;477data->epi = init_mat(data->N, data->N, "");478tree->root->k_vec = (int **)malloc(data->p_consts.k * sizeof(int *));479data->VK = (int **) malloc (data->p_consts.k * sizeof (int *));480for (i = 0; i < data->p_consts.k; i++) {481tree->root->k_vec[i] =482(int *)calloc(data->p_consts.s[i], sizeof (int));483data->VK[i] = (int *)calloc(data->p_consts.s[i] + 1,484sizeof(int));485data->VK[i]++;486}487ZZ_make_endo (data);488if (SUBDIRECT) {489SUBDIRECT = projections[0];490SUB_VEC = (int *) malloc (SUBDIRECT * sizeof (int));491#ifdef DEBUG492fprintf (stderr, "SUBDIRECT = %d\n", SUBDIRECT);493#endif494for (i = 0; i < SUBDIRECT; i++) {495SUB_VEC[i] = projections[i+1];496#ifdef DEBUG497fprintf(stderr, "Dimension[%d] = %d\n", i, SUB_VEC[i]);498#endif499}500PrI = (matrix_TYP **) malloc(SUBDIRECT * sizeof(matrix_TYP *));501k = 0;502for (i = 0; i < SUBDIRECT; i++) {503PrI[i] = init_mat (data->N, SUB_VEC[i], "");504for (j = 0; j < SUB_VEC[i]; j++) {505PrI[i]->array.SZ[k + j][j] = 1;506#ifdef DEBUG507fput_mat (stderr, PrI[i], "PrI[i]", 0);508#endif509}510k += SUB_VEC[i];511}512}513514515if (konst_flag == 1 && GRAPH){516KONSTITUENTEN = (QtoZ_konst_TYP *)calloc(1, sizeof(QtoZ_konst_TYP));517KONSTITUENTEN->k = data->p_consts.k;518KONSTITUENTEN->s = (int *)calloc(data->p_consts.k, sizeof(int));519KONSTITUENTEN->r = (data->r - IDEM_NO);520KONSTITUENTEN->Delta = (matrix_TYP ****)malloc(KONSTITUENTEN->k *521sizeof (matrix_TYP ***));522523for (i = 0; i < data->p_consts.k; i++) {524KONSTITUENTEN->s[i] = data->p_consts.s[i];525KONSTITUENTEN->Delta[i] = (matrix_TYP ***)malloc(KONSTITUENTEN->s[i] *526sizeof (matrix_TYP **));527for (j = 0; j < KONSTITUENTEN->s[i]; j++) {528KONSTITUENTEN->Delta[i][j] = (matrix_TYP **)malloc(KONSTITUENTEN->r *529sizeof (matrix_TYP *));530for (k = 0; k < KONSTITUENTEN->r; k++) {531KONSTITUENTEN->Delta[i][j][k] =532copy_mat(data->p_consts.Delta[i][j][k]);533}534}535}536}537}538539/*****************************************************************************/540/* */541/* input: global data-structure in data and the tree of Zentrierungen */542/* output: the structure-component group->zentr points to an array of */543/* of matrices, each containing a set of generators of a */544/* Zentrierung as Z-modul. group->zentr_no contains the number */545/* of the computed Zentrierungen */546/* */547/*****************************************************************************/548void ZZ_put_data (group, data, tree)549bravais_TYP *group;550ZZ_data_t *data;551ZZ_tree_t *tree;552{553ZZ_node_t *n, *t;554int i;555ZZ_couple_t *m;556557group->zentr = (matrix_TYP **)malloc(tree->node_count *558sizeof (matrix_TYP *));559group->zentr_no = tree->node_count;560n = tree->root;561i = 0;562do {563group->zentr[i] = copy_mat(n->U);564/* n->U = NULL; oliver: 16.8.00 */565if (SHORTLIST) {566if (SUBDIRECT) {567printf ("\t L%d: Number of Sublattices: %d ",568n->number, n->anz_tg);569} else {570printf ("\t L%d: ", n->number);571}572if ((m = n->child) != NULL) {573do {574printf (" L%d ", m->he->number);575}576while ((m = m->elder) != NULL);577}578printf ("\n");579fflush (stdout);580}581i++;582t = n->next;583/* oliver: 11.8.00584ZZ_free_node (data, n); */585} while ((n = t) != NULL);586}587588void ZZ_fput_data (data, tree, ABBRUCH)589ZZ_data_t *data;590ZZ_tree_t *tree;591int ABBRUCH;592{593ZZ_node_t *n, *t;594ZZ_couple_t *m;595int old_lev = 0, lev_cnt = 0;596597n = tree->root;598if (TEMPORAER) {599fprintf (ZZ_temp,"\n==========================================================================\n");600}601do {602if (old_lev != n->level) {603if (TEMPORAER && (old_lev)) {604fprintf (ZZ_temp, "\n======= %d Lattices on level %d ====================================\n", lev_cnt, old_lev);605}606old_lev = n->level;607lev_cnt = 0;608}609if (TEMPORAER && !(ABBRUCH & 1)) {610fprintf (ZZ_temp,611"\n\t L%3.d: %13s\tConstituent\n",612n->number, "Lattice");613if (SUBDIRECT) {614fprintf (ZZ_temp,615"\n Number of sublattices: %d ",616n->anz_tg);617}618if ((m = n->parent) != NULL) {619fprintf (ZZ_temp, " parents :\n");620do {621fprintf(ZZ_temp,622"%25s%3-d\t(p=%d,Nr.=%d)\n",623"L", m->he->number,624data->p_consts.p[m->she.i],625m->she.j + 1);626} while ((m = m->elder) != NULL);627}628if ((m = n->child) != NULL) {629fprintf (ZZ_temp, " children :\n");630do {631fprintf (ZZ_temp,632"%25s%3-d\t(p=%d,Nr.=%d)\n",633"L",634m->he->number,635data->p_consts.p[m->she.i],636m->she.j + 1);637} while ((m = m->elder) != NULL);638}639}640lev_cnt++;641t = n->next;642} while ((n = t) != NULL);643if (TEMPORAER) {644fprintf (ZZ_temp,645"\n======= %d Lattices on level %d ====================================\n", lev_cnt, old_lev);646}647if (ABBRUCH & 2) {648if (TEMPORAER) {649fprintf (ZZ_temp, " \t ============================================================\n \t Algorithmus nach Berechnung von %d Zentrierungen abgebrochen \n \t ============================================================\n", NUMBER);650}651}652if (ABBRUCH & 4) {653if (TEMPORAER) {654fprintf (ZZ_temp, " \t ============================================================\n \t Algorithmus nach Berechnung von %d Levels abgebrochen \n \t ============================================================\n", LEVEL);655}656}657}658659void ZZ_free_data (data)660ZZ_data_t *data;661{662int i, j, k;663664if (SUBDIRECT) {665if (PrI) {666for (i = 0; i < SUBDIRECT; i++) {667if (PrI[i]) {668free_mat (PrI[i]);669}670}671free (PrI);672PrI = NULL;673}674if (SUB_VEC) {675free (SUB_VEC);676SUB_VEC = NULL;677}678}679680for (i = 0; i < data->p_consts.k; i++) {681for (j = 0; j < data->p_consts.s[i]; j++) {682for (k = 0; k < data->r; k++) {683free_mat (data->p_consts.Delta[i][j][k]);684}685for (k = 0; k < data->EnCo[i][j].hi; k++) {686free_mat (data->Endo[i][j][k]);687}688free (data->p_consts.Delta[i][j]);689free (data->Endo[i][j]);690}691free (data->p_consts.Delta[i]);692free (data->Endo[i]);693free (data->EnCo[i]);694data->VK[i]--;695free (data->VK[i]);696free (data->n[i]);697}698699free (data->p_consts.Delta);700free (data->Endo);701free (data->EnCo);702free (data->VK);703free (data->n);704705for (i = 0; i < data->r; i++) {706free_mat (data->DELTA_M[i]);707}708free (data->DELTA);709free (data->DELTA_M);710711free_mat (data->epi);712free (data->p_consts.s);713free (data->p_consts.p);714if (ZZ_temp) {715fclose (ZZ_temp);716ZZ_temp = NULL;717}718}719720/*------------------------------------------------------------*\721| Variation of p_solve, it differs in the way of output |722\*------------------------------------------------------------*/723matrix_TYP *ZZ_p_vsolve (anz, L_mat, R_mat)724int *anz;725matrix_TYP **L_mat, **R_mat;726727{728int **M, **N, *v, f, help;729int *M_j, *M_act, numax;730matrix_TYP *E;731boolean L_null, R_null;732int *ss, *nuin, p, i, j, jj, k, kk, l, cR, cL, cM, rR, rL, rM, rN;733int rg = 0, act;734735736p = act_prime;737L_null = (L_mat == NULL);738R_null = (R_mat == NULL);739740cL = L_null ? 1 : L_mat[0]->cols;741rL = L_null ? 1 : L_mat[0]->rows;742rR = R_null ? 1 : R_mat[0]->rows;743cR = R_null ? 1 : R_mat[0]->cols;744745cM = cL * rR;746rM = *anz * rL * cR;747rN = rL * cR;748rg = *anz * cR;749N = (int **)malloc(rN * sizeof(int *));750M = (int **)malloc(rM * sizeof(int *));751752/* changed tilman 6/2/97 from753* nuin = (int *)malloc(cM * sizeof(int));754* to755*/756nuin = (int *)malloc((cM+1) * sizeof(int));757758ss = (int *) malloc(cM * sizeof(int));759760for (i = 0; i < *anz; i++) {761if (!L_null) {762if ((L_mat[i]->cols != cL) || (L_mat[i]->rows != rL)) {763fprintf (stderr, "Error in input\n");764exit (3);765}766}767if (!R_null) {768if ((R_mat[i]->rows != rR) || (R_mat[i]->cols != cR)) {769fprintf (stderr, "Error in input\n");770exit (3);771}772}773774for (j = 0; j < rN; j++) {775N[j] = (int *) calloc (cM, sizeof (int));776}777778if (!L_null) {779for (j = 0, jj = 0; j < rL; j++, jj += rR) {780for (k = 0, kk = 0; k < cL; k++, jj -= rR) {781if ((help=L_mat[i]->array.SZ[j][k] % p)782< 0) {783help += p;784}785if (help) {786for (l = 0;787l < rR; l++, jj++, kk++) {788N[jj][kk] = help;789}790} else {791jj += rR;792kk += rR;793}794}795}796}797if (!R_null) {798for (j = 0; j < cR; j++) {799for (k = 0; k < rR; k++) {800if ((help=R_mat[i]->array.SZ[k][j] % p)801< 0) {802help += p;803}804if (help) {805for (l = 0, jj = j, kk = k;806l < cL;807l++, jj += cR, kk += rR) {808N[jj][kk]= S(N[jj][kk],809-help);810}811}812}813}814}815816/* permutierte Eingabe in Liste */817for (j = 0; j < rL; j++) {818for (k = 0; k < cR; k++) {819M[j*rg + i*cR + k] = N[(rL - 1 - j) * cR + k];820}821}822}823rg = 0;824/*825* Gauss Algorithm826*/827for (i = 0; i < cM; i++) {828ss[i] = -1;829/*830* Find the row with non-zero entry in i-th column831*/832for (j = rg; (j < rM) && (M[j][i] == 0); j++);833if (j == rM) {834continue;835}836act = j;837/*838* Normalize act-th row and mark the non-zero entries839*/840nuin[0] = 1;841f = P (1, -M[j][i]);842for (k = i; k < cM; k++) {843if ((help = M[act][k])) {844M[act][k] = P (help, f);845nuin[nuin[0]++] = k;846}847}848/*849* Swap act-th row and rg-th row850*/851v = M[rg];852M[rg] = M[act];853M[act] = v;854ss[rg] = i;855act = rg++;856/*857* Clear i-th column downwards858*/859M_act = M[act];860for (j = act + 1; j < rM; j++) {861if ((f = S (0, -M[j][i])) != 0) {862M_j = M[j];863M_j[i] = 0;864numax = nuin[0];865if (f == 1) {866for (k = 2, kk = nuin[2];867k < numax; kk = nuin[++k]) {868M_j[kk] = S(M_j[kk],M_act[kk]);869}870} else {871for (k = 2, kk = nuin[2];872k < numax; kk = nuin[++k]) {873M_j[kk] = S(M_j[kk],874P(M_act[kk], f));875}876}877}878}879}880if ((*anz = cM - rg) != 0) {881/*882* Matrix has not full rank: clear it upwards883*/884for (i = rg - 1; i > 0; i--) {885nuin[0] = 2;886nuin[1] = ss[i];887M_act = M[i];888for (j = ss[i] + 1; j < cM; j++) {889if (M_act[j]) {890nuin[nuin[0]++] = j;891}892}893if (nuin[0] == 2) {894j = ss[i];895for (k = i - 1; k > 0; k--) {896M[k][j] = 0;897}898} else {899for (j = i - 1; j >= 0; j--) {900if ((f = S (0, -M[j][ss[i]])) != 0) {901M_j = M[j];902M_j[ss[i]] = 0;903numax = nuin[0];904if (f == 1) {905for (k= 2,kk = nuin[2];906k < numax;907kk = nuin[++k]) {908M_j[kk] = S(M_j[kk], M_act[kk]);909}910} else {911for (k= 2, kk= nuin[2];912k < numax;913kk = nuin[++k]) {914M_j[kk] = S (M_j[kk], P (M_act[kk], f));915}916}917}918}919}920}921E = init_mat (rR, rR, "");922for (i = 0, k = 0, l = 0; i < cM; i++) {923if (i == ss[k]) {924E->array.SZ[l + (i / rR)][i % rR] = p;925l++;926k++;927continue;928}929for (j = 0; j < k; j++) {930if (M[j][i] != 0) {931E->array.SZ932[l + (ss[j] / rR)]933[ss[j] % rR] = p - M[j][i];934}935}936E->array.SZ[l + (i / rR)][i % rR] = 1;937l++;938}939}940for (i = 0; i < rM; i++) {941free (M[i]);942}943free (M);944free (N);945free (ss);946free (nuin);947948return (E);949}950951/*---------------------------------------------------------------*\952| Take the kk-th epimorphism from DELTA_M onto p_consts.Delta[ii][jj], |953| determine its kernel, extend to a generating set of the new |954| centering and calculate the common factors and index of that |955| centering. Return the possibly new node for checking, wether it |956| occured already earlier in the algorithm or not. |957\*---------------------------------------------------------------*/958ZZ_node_t *ZZ_center (data, father, ii, jj)959ZZ_data_t *data;960ZZ_node_t *father;961int ii, jj;962{963int flag, sg, i, j, d;964matrix_TYP *ker;965ZZ_node_t *n;966967n = (ZZ_node_t *) malloc (sizeof (ZZ_node_t));968n->col_group = NULL;969n->group = NULL;970n->brav = NULL;971n->N_orbits = NULL;972n->N_lengths = NULL;973n->N_no_orbits = 0;974n->stab_chain = NULL;975n->perfect = NULL;976n->perfect_no = 0;977n->number = -1;978n->index = -1;979n->level = father->level + 1;980n->U = n->Q = n->U_inv = n->el_div = NULL;981n->next = NULL;982n->parent = n->child = NULL;983n->k_vec = (int **) malloc (data->p_consts.k * sizeof (int *));984for (i = 0; i < data->p_consts.k; i++) {985n->k_vec[i] =986(int *)malloc(data->p_consts.s[i] * sizeof (int));987memcpy (n->k_vec[i], father->k_vec[i],988data->p_consts.s[i] * sizeof (int));989}990n->k_vec[ii][jj]++;991d = father->level;992n->path = (ZZ_prod_t *) malloc ((d + 1) * sizeof (ZZ_prod_t));993memcpy (n->path, father->path, d * sizeof (ZZ_prod_t));994n->path[d].hi = ii;995n->path[d].low = jj;996997/*------------------------------------------------------------*\998| Determine the kernel of the epimorphism |999\*------------------------------------------------------------*/1000d = 1;1001ker = ZZ_p_vsolve (&d, NULL, &data->epi);1002if (d != 0) {1003/*1004* Express that kernel in the basis of the original lattice1005*/1006n->U = mat_mul (ker, father->U);1007free_mat (ker);1008/*1009* Make n->U a generating set of the new ZZ_centering by1010* appending to n->U p times the basis of father.1011*/1012} else {1013n->U = copy_mat (father->U);1014iscal_mul (n->U, act_prime);1015}1016/*1017* Calculate the invariant factors of that generating set1018*/1019Check_mat (n->U);10201021if (U_option) {1022n->el_div = long_elt_mat(NULL,n->U, NULL);1023/*1024* Calculate index as product of the invariant factors1025*/1026n->index = n->el_div->array.SZ[0][0];1027for (i = 1; i < n->el_div->cols; i++) {1028/* changed by oliver (6.11.00) from:1029n->index *= n->el_div->array.SZ[0][i];1030to: */1031n->index *= n->el_div->array.SZ[i][i];1032}1033} else {1034n->el_div = init_mat (1, 1, "");1035sg = n->U->array.SZ[0][0];1036for (i = 0; ((sg != 1) && (i < n->U->rows)); i++) {1037for (j = 0; ((sg != 1) && (j < n->U->cols)); j++) {1038sg = GGT (sg, n->U->array.SZ[i][j]);1039}1040}1041n->el_div->array.SZ[0][0] = (sg > 0) ? sg : -sg;1042}1043sg = n->el_div->array.SZ[0][0];1044if (sg != 1) {1045flag = TRUE;1046for (i = 0; flag && (i < data->p_consts.k); i++) {1047if (data->p_consts.p[i] == sg) {1048if (data->VK[i][-1] != 0) {1049for (j = 0;1050j < data->p_consts.s[i]; j++) {1051n->k_vec[i][j]-=data->VK[i][j];1052}1053n->level -= data->VK[i][-1];1054} else {1055data->VK[i][-1] = n->level - 1;1056memcpy (data->VK[i], n->k_vec[i],1057data->p_consts.s[i] *1058sizeof (int));1059memset(n->k_vec[i], 0,1060data->p_consts.s[i] *1061sizeof (int));1062n->level = 1;1063}1064flag = FALSE;1065}1066}1067}1068return (n);1069}10701071/*---------------------------------------------------------------*\1072| Let E be an epimorphism from DELTA_M onto p_consts.Delta[ii][jj] |1073| Solve the matrix-equation DELTA_M * E = E * p_consts.Delta[ii][jj] |1074| over F(p) and return a basis of the space of all solutions |1075\*---------------------------------------------------------------*/1076int ZZ_epimorphs (data, ii, jj)1077ZZ_data_t *data;1078int ii, jj;1079{1080int d, i, j, k, x, e;1081int **X, **M;1082int *bas, found, row, col, sae;1083int actlist, vor;1084int a = 0;1085matrix_TYP *TMP, *AMP, **liste;10861087init_prime (data->p_consts.p[ii]);10881089d = data->r;1090data->epi_base = p_solve(&d, data->DELTA_M,1091data->p_consts.Delta[ii][jj], 2);1092if (d > 1) {1093data->epi->cols = data->epi_base[0]->cols;1094if (data->EnCo[ii][jj].low != 1) {1095a = intpow (act_prime, d);1096if (d == data->EnCo[ii][jj].low) {1097/* All Epimorphisms differs only by an1098* endomorphism1099*/1100for (i = 1; i < d; i++) {1101free_mat (data->epi_base[i]);1102}1103data->epi_base =1104(matrix_TYP **)realloc(data->epi_base,1105sizeof(matrix_TYP *));1106d = 1;1107return (d);1108}1109sae = d / data->EnCo[ii][jj].low;1110liste = (matrix_TYP **) malloc(a*sizeof(matrix_TYP *));1111actlist = 0;1112bas = (int *) calloc (d, sizeof (int));1113row = data->epi_base[0]->rows;1114col = data->epi_base[0]->cols;1115found = 0;1116for (x = 0; x < d - 1; x++) {1117if (bas[x] == 1) {1118/* epim already found previously */1119continue;1120}1121if ((++found) == sae) {1122/* got a complete set of epi`s */1123for (++x; x < d; x++) {1124bas[x] = 1;1125}1126break;1127}1128/* Calculate the produts of the1129* Epimorphism X with all1130* Endomorphisms and compare to the1131* other Epi`s1132*/1133vor = actlist;1134for (e = 0; e < data->EnCo[ii][jj].hi; e++) {1135TMP = mat_mul (data->epi_base[x],1136data->Endo[ii][jj][e]);1137liste[actlist++] = TMP;1138M = TMP->array.SZ;1139for (i = x + 1; i < d; i++) {1140X= data->epi_base[i]->array.SZ;1141j = 0;1142while (1143(j < row) && ((memcmp (M[j], X[j], 4 * col)) == 0)) {1144j++;1145}1146if (j == row) {1147bas[i] = 1;1148break;1149}1150}1151for (k = 0; k < vor; k++) {1152AMP = pmat_add (TMP, liste[k],11531, 1);1154liste[actlist++] = AMP;1155for (i = x + 1; i < d; i++) {1156X = data->epi_base[i]->array.SZ;1157j = 0;1158while (1159(j < row) && ((memcmp (M[j], X[j], 4 * col)) == 0)) {1160j++;1161}1162if (j == row) {1163bas[i] = 1;1164break;1165}1166}1167}1168}1169}1170/*1171* prepare the new epi_base for output1172*/1173for (i = 0; i < actlist; i++) {1174free_mat (liste[i]);1175}1176free (liste);1177found = 1;1178for (i = 1; i < d; i++) {1179if (bas[i] == 1) {1180free_mat (data->epi_base[i]);1181} else {1182data->epi_base[found++] =1183data->epi_base[i];1184}1185}1186d = found;1187data->epi_base =1188(matrix_TYP **)realloc(data->epi_base,1189d*sizeof(matrix_TYP *));1190}1191} else {1192if (d != 0) {1193data->epi->cols = data->epi_base[0]->cols;1194} else {1195data->epi->cols = 0;1196}1197}1198return (d);1199}12001201boolean ZZ_successor (data, act)1202ZZ_data_t *data;1203ZZ_node_t **act;12041205{1206int i;12071208if ((*act = (*act)->next) == NULL) {1209return (FALSE);1210}1211for (i = 0; i < data->r; i++) {1212free_mat (data->DELTA_M[i]);1213data->DELTA_M[i] = mat_kon((*act)->U, data->DELTA[i],1214(*act)->U_inv);1215}1216return (TRUE);1217}1218121912201221/*------------------------------------------------------------------------------- */1222static int suche_mat(matrix_TYP *mat,1223matrix_TYP **liste,1224int anz)1225{1226int i;12271228for (i = 0; i < anz; i++){1229if (cmp_mat(mat, liste[i]) == 0)1230return(i);1231}1232return(-1);1233}1234123512361237/*------------------------------------------------------------------------------- */1238int ZZ_ins_node (Gram, data, tree, father, new, ii, jj, inzidenz, nr, NEU, flagge, g, nnn)1239matrix_TYP *Gram;1240ZZ_data_t *data;1241ZZ_tree_t *tree;1242ZZ_node_t *father, *new;1243int ii, jj;1244QtoZ_TYP *inzidenz;1245int *nr;1246int *NEU;1247int *flagge;1248int *g;1249ZZ_node_t **nnn;1250{1251ZZ_node_t *n;1252ZZ_couple_t *c;1253matrix_TYP *Tmp1, *Tmp2, *U_vor, *tmp;1254matrix_TYP *Mat, *Trf, *el, *GMat;1255int **U, **CC, sum, f;1256int i, j, k, nl, flag, ff, gg;1257int ABBRUCH;12581259/* inserted tilman 6/2/97 */1260char filename[32];12611262sum =1263f =1264g[0] = 0;1265U = new->U->array.SZ;1266ABBRUCH = FALSE;12671268/*1269* Determine gcd of common factors of new->U1270*/12711272if (new->el_div->array.SZ[0][0] == 1) {1273n = father;1274} else {1275n = tree->root;1276}1277while ((n != NULL) && (n->level < new->level)) {1278n = n->next;1279}12801281if (n != NULL) {1282/* We found a node on the same level, now look for1283all on this level for an identical lattice */1284g[0] = new->el_div->array.SZ[0][0];1285nl = new->level;1286do {1287f = n->U_inv->kgv;1288f *= g[0];1289flag = TRUE;1290for (i = 0; (i < data->p_consts.k) && flag; i++) {1291flag = memcmp (n->k_vec[i],1292new->k_vec[i],1293data->p_consts.s[i] *1294sizeof (int)) == 0;1295}1296if (flag) {1297CC = n->U_inv->array.SZ;1298/*1299* Index-condition satisfied1300*/13011302/* Multiply new->U and n->U_inv and check1303* divisibility condition for each entry1304*/1305for (i = 0; i < new->U->rows; i++) {1306for (j = 0; j < new->U->cols; j++) {1307sum = 0;1308for (k = 0;1309k < n->U_inv->rows;1310k++) {1311sum += U[i][k] * CC[k][j];1312}1313if ((sum % f) != 0) {1314goto next;1315}1316}1317}1318c = father->child;1319while (c != NULL) {1320if (c->he == n) {1321ZZ_free_node (data, new);1322/* next 7 lines by oliver: 9.8.00: for graph for QtoZ */1323if (ZCLASS == 1 && GRAPH){1324nr[0] = suche_mat(n->U, inzidenz->gitter, inzidenz->anz);1325if (nr[0] == -1){1326fprintf(stderr,"ERROR 1 in ZZ_ins_node!\n");1327exit(2);1328}1329flagge[0] += 1;1330}1331return ABBRUCH;1332}1333c = c->elder;1334}1335break;1336}1337next:1338continue;1339} while (((n = n->next) != NULL) && (n->level == new->level));1340}13411342if ((n == NULL) || (n->level > nl)) {1343/* this is really a new lattice */13441345if (SUBDIRECT) {1346for (i = 0; i < SUBDIRECT; i++) {1347Tmp1 = mat_mul (new->U, PrI[i]);1348Tmp2 = long_elt_mat(NULL,Tmp1, NULL);1349free_mat (Tmp1);1350/* changed 30/06/97 tilman form:1351if (Tmp2->array.SZ[0][Tmp2->cols - 1] != 1) {1352to: */1353if (Tmp2->array.SZ[Tmp2->cols - 1]1354[Tmp2->cols - 1] != 1) {1355i = SUBDIRECT + 1;1356}1357free_mat (Tmp2);1358}1359if (i > SUBDIRECT) {1360ZZ_free_node (data, new);13611362/* next 2 lines by oliver: 9.8.00: for graph for QtoZ */1363if (GRAPH)1364nr[0] = -1;13651366return ABBRUCH;1367}1368}13691370if (ZCLASS == 1){1371/* second call of ZZ by q2z */1372if (orbit_under_normalizer(data,tree,father,new,ii,jj,inzidenz,nr,nnn)){1373ZZ_free_node (data, new);1374flagge[0] += 10;1375return ABBRUCH;1376}1377}1378if (ZCLASS == 2){1379/* first call of ZZ by q2z */1380if (deal_with_ZCLASS(data, tree, father, new)){1381ZZ_free_node (data, new);1382return ABBRUCH;1383}1384}13851386/*1387* New lattice:1388* Calculate the scalarproducts of the generating system1389*/1390NEU[0] = 1;13911392if (ZCLASS == 2 && GRAPH){1393U_vor = mat_inv(new->U);1394}13951396/* !!!!!!!!!!!!!! new->U is changed in scal_pr !!!!!!!!!!!!!!!!!!! */1397GMat = Mat = scal_pr (new->U, Gram, FALSE);1398if (ZCLASS == 2 && GRAPH){1399/* save transformation matrix */1400tmp = mat_mul(new->U, U_vor);1401new->Q = tr_pose(tmp);1402free_mat(tmp);1403free_mat(U_vor);1404}14051406if (ZCLASS == 1 && GRAPH){1407/* now calculate the (integral) representation1408on the new lattice (bare in mind that it is1409row invariant. There is a flaw: normalizer and1410centralizer won't be correct */1411ff = tree->root->group->normal_no;1412tree->root->group->normal_no = 0;1413gg = tree->root->group->cen_no;1414tree->root->group->cen_no = 0;1415new->group = konj_bravais(tree->root->group, new->U);1416tree->root->group->normal_no = ff;1417tree->root->group->cen_no = gg;14181419/* the second flaw of konj_bravais is the formspace */1420for (f = 0; f < new->group->form_no; f++)1421new->group->form[f]->kgv = 1;1422long_rein_formspace(new->group->form, new->group->form_no, 1);1423new->col_group = tr_bravais(new->group, 1, FALSE);1424}14251426if (LLLREDUCED) {1427/*1428* Perform MLLL-Reduction1429*/1430Trf = ZZ_lll (Mat, 0);1431real_mat (Trf, Mat->rows, Trf->cols);1432/* Store the new Gram matrix and the invariant1433* factors1434*/1435GMat = Mat;1436/* Apply the LLL-Transformation to the basis1437*/1438Mat = new->U;1439new->U = mat_mul (Trf, Mat);1440free_mat (Mat);1441free_mat(Trf);1442}1443if (G_option) {1444el = long_elt_mat(NULL,GMat, NULL);1445}1446/*1447* Invert the Basis-Transformation1448*/1449new->U_inv = mat_inv (new->U);1450new->number = ++tree->node_count;1451new->level = father->level + 1;1452tree->last->next = new;1453tree->last = new;14541455if (new->number > NUMBER) {1456ABBRUCH = 2;1457}1458if (new->level >= LEVEL) {1459ABBRUCH = 4;1460}14611462if (!QUIET) {1463fprintf (stderr, "L%d with (%d,%d) yields L%d\n",1464father->number, ii, jj, tree->node_count);1465}1466/*1467* write new lattice to temporary file ZZ.tmp1468*/1469if (TEMPORAER && !NURUMF) {1470fprintf (ZZ_temp, "L%d with (%d,%d) yields L%d\n",1471father->number, ii, jj, tree->node_count);14721473if (U_option) {1474fput_mat (ZZ_temp, new->el_div,1475"Elementary divisors :", 2);1476}1477ZZ_transpose_array(new->U->array.SZ, new->U->cols);1478/* fput_mat (ZZ_temp, new->U,1479"Change of basis :", 4); */1480ZZ_transpose_array(new->U->array.SZ, new->U->cols);14811482if (G_option) {1483fput_mat(ZZ_temp, el,1484"Elementary divisors of the Gram matrix:", 2);1485}1486fput_mat (ZZ_temp, GMat,1487"Gram matrix :", 2);1488fflush (ZZ_temp);1489}1490if (TEMPORAER && NURUMF) {1491ZZ_transpose_array(new->U->array.SZ, new->U->cols);1492fput_mat (ZZ_temp, new->U,1493"Change of basis:", 4);1494ZZ_transpose_array(new->U->array.SZ, new->U->cols);1495ZZ_transpose_array(new->U_inv->array.SZ, new->U->cols);1496fput_mat (ZZ_temp, new->U_inv,1497"Inverse of it :", 4);1498ZZ_transpose_array(new->U_inv->array.SZ, new->U->cols);1499fflush (ZZ_temp);1500}15011502/* eingefuegt von Oliver am 5.2.99 */1503if (OFLAG){1504OMAT[OANZ] = copy_mat(new->U);1505OANZ += 1;1506}1507/* ------------------ */15081509if (G_option) {1510free_mat (el);1511}1512free_mat (GMat);1513} else {1514/*1515* We got that lattice already1516*/1517if (!QUIET) {1518fprintf (stderr, "L%d with (%d,%d) yields %d.L%d\n",1519father->number, ii, jj, g[0], n->number);1520}1521if (TEMPORAER && !NURUMF) {1522fprintf (ZZ_temp, "L%d with (%d,%d) yields %d.L%d\n",1523father->number, ii, jj, g[0], n->number);1524}15251526/* next 7 lines by oliver: 9.8.00: for graph for QtoZ */1527if (ZCLASS == 1 && GRAPH){1528nr[0] = suche_mat(n->U, inzidenz->gitter, inzidenz->anz);1529if (nr[0] == -1){1530fprintf(stderr,"ERROR 2 in ZZ_ins_node!\n");1531exit(3);1532}1533flagge[0] += 100;1534}1535ZZ_free_node (data, new);1536new = n;1537}15381539/*1540* Tell the son, who's father1541*/1542c = (ZZ_couple_t *) malloc (sizeof (ZZ_couple_t));1543c->he = father;1544c->she.i = ii;1545c->she.j = jj;1546c->factor = g[0];1547c->elder = new->parent;1548new->parent = c;15491550/*1551* Tell father, he's got a new son1552*/1553c = (ZZ_couple_t *) malloc (sizeof (ZZ_couple_t));1554c->he = new;1555c->she.i = ii;1556c->she.j = jj;1557c->factor = g[0];1558c->elder = father->child;1559father->child = c;1560return ABBRUCH;1561}15621563156415651566/*}}} */1567/*{{{ ZZ_pick_epi */1568void1569ZZ_pick_epi (data, number, ii, jj)1570ZZ_data_t *data;1571int number, ii, jj;1572{1573int **E, **hh;1574int q, i, j, k, f;1575matrix_TYP *H;15761577init_prime (data->p_consts.p[ii]);1578q = data->EnCo[ii][jj].hi + 1;1579E = data->epi->array.SZ;1580for (i = 0; i < data->epi->rows; i++)1581{1582for (j = 0; j < data->epi->cols; j++)1583{1584E[i][j] = 0;1585}1586}1587for (i = 0; number != 0; number /= q, i++)1588{1589if ((f = (number % q)) != 0)1590{1591H = mat_mul (data->epi_base[i], data->Endo[ii][jj][f - 1]);1592hh = H->array.SZ;1593for (j = 0; j < data->epi->rows; j++)1594{1595for (k = 0; k < data->epi->cols; k++)1596{1597E[j][k] = S (E[j][k], hh[j][k]);1598}1599}1600free_mat (H);1601}1602}1603}16041605/*}}} */160616071608