GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "matrix.h"2#include "voronoi.h"3#include "tools.h"4#include "ZZ_P.h"5#include "ZZ_gen_vs_P.h"67#define TOPLEVEL -189#define TRACE(level, foo) \10if (level <= TOPLEVEL) { \11foo; \12}1314/* Calculate the irreducible constituents of an order as input for the15* centering algorithm (to determine the invariant lattices) and for16* determine the radical. The order is supposed to be normalized,17* i.e. the standard maximal order Mn(R,dim) is an over_order of the18* given one.19*20* first a help-programm: Do the calculation for a matrix- set of21* generators and use this recursivly.22*/2324/*25*26* input:27* matrix_TYP **generators:28* die Generatoren, fuer jeden Generator eine Matrix29* int num_gens: Anzahl der Generatoren30* int *num_irr_const: die Anzahl der irrduziblen Konstituenten.31*32* output:33* matrix_TYP **: die irreduziblen Konstituenten mod p fuer34* jeden Generator. Zuerst die Matrizen aller35* Generatoren fuer den ersten Konstituenten,36* dann fuer den zweiten, usf.37*38*/3940static matrix_TYP **irr_help(matrix_TYP ** generators,41int num_gens,42int *num_irr_const,43int rec_cnt)44{45matrix_TYP *help, *mat, **upset1, **upset2, **gen1, **gen2;46matrix_TYP **r_gen, **p_gen, *VS;47int dim, rg, notfound, i, j, act, cnt;48int **V, **T1, **T2;4950/* p_gen enthaelt die Generatoren mod p */51p_gen = ZZ_mod_gen(generators, num_gens);52for (i = 0; i < num_gens; i++) {53TRACE(1, fprintf(stderr, "generator nr %d\n", i));54TRACE(1, fput_mat(stderr, p_gen[i], "generator mod p", 0));55}56if (p_gen[0]->rows == 1) { /* really nothing to do */57*num_irr_const = 1;58return p_gen;59}60dim = p_gen[0]->rows;61VS = ZZ_gen_vs(act_prime, dim);62TRACE(2, fput_mat(stderr, VS, "Vektorraum", 0));63for (notfound = 1, i = 0; (i < VS->rows) && notfound; i++) {64/* help enthaelt eine Basis der VR, der von der Bahn65* aufgespannt wird66*/67help = ZZ_vec_bahn(VS->array.SZ[i], p_gen, num_gens);68TRACE(2, fput_mat(stderr, help, "Bahn", 0));69notfound = help->rows == dim;70if (notfound) {71free_mat(help);72}73}74free_mat(VS);75if (notfound) {76*num_irr_const = 1;77TRACE(0,fprintf(stderr, "Kein Basiswechsel\n"));78return p_gen;79}80r_gen=(matrix_TYP **)malloc(num_gens * sizeof(matrix_TYP *));81TRACE(1,fprintf(stderr,82"Found submodule of dimension %d, recursion count %d.\n",83help->rows, rec_cnt));84/* Submodule found: begin the recursion.85* Start with filling up help to a basis86*/87mat = init_mat(dim, dim, "p");88mat->prime = act_prime;89rg = help->rows;90act = 0;91TRACE(1, fput_mat(stderr, help, "Invarianter Teilraum", 0));92for (i = 0; i < help->rows; i++) {93memcpy(mat->array.SZ[i],94help->array.SZ[i], dim * sizeof(int));95while(mat->array.SZ[i][act] == 0) {96mat->array.SZ[rg][act] = 1;97rg++;98act++;99}100act++;101}102for (; rg < mat->rows; rg++, act++) {103mat->array.SZ[rg][act] = 1;104}105TRACE(2, fput_mat(stderr, mat, "Basis?", 0));106rg = help->rows;107free_mat(help);108help = mat_inv(mat);109TRACE(0,fprintf(stderr, "Recursion: %d", rec_cnt));110TRACE(0,fput_mat(stderr, mat, "Basiswechsel", 0));111112/* Do the projection to the submoduls113*/114upset1 = (matrix_TYP **) malloc(num_gens * sizeof(matrix_TYP *));115upset2 = (matrix_TYP **) malloc(num_gens * sizeof(matrix_TYP *));116for (i = 0; i < num_gens; i++) {117/* Basiswechsel fuer die Generatoren durchfuehren118* diese operieren dann auf den Standardbasisvektoren119* so dass gen_vc wieder benutzt werden kann120* diese sollten jetzt eine Blockmatrix darstellen.121*/122r_gen[i] = mat_kon(mat, p_gen[i], help);123TRACE(2,fprintf(stderr,124"Transformierter Generator %d mod p, rg: %d\n",125i, rg));126TRACE(2,fput_mat(stderr, r_gen[i], "Generator transformiert",1270));128upset1[i] = init_mat(rg, rg, "ik");129upset2[i] = init_mat(dim - rg, dim - rg, "ik");130upset1[i]->prime = act_prime;131upset2[i]->prime = act_prime;132V = r_gen[i]->array.SZ;133T1 = upset1[i]->array.SZ;134T2 = upset2[i]->array.SZ;135for (j = 0; j < dim; j++) {136if (j < rg) {137/* Generatoren fuer den138invarianten Teilraum */139memcpy(T1[j], V[j],rg * sizeof(int));140} else {141/* Generatoren fuer den Rest */142memcpy(T2[j - rg], &V[j][rg],143(dim - rg) * sizeof(int));144}145}146/* die neuen Generatoren sind in upset_i */147free_mat(r_gen[i]);148free_mat(p_gen[i]);149}150free_mat(mat);151free_mat(help);152free(r_gen);153free(p_gen);154/*----------------------------------------------------*\155| Create the recursion-input |156\*----------------------------------------------------*/157gen1 = upset1;158gen2 = upset2;159TRACE(0, fprintf(stderr, "Teilraum\n"));160upset1 = irr_help(upset1, num_gens, &i, rec_cnt + 1);161TRACE(0, fprintf(stderr, "Faktorraum\n"));162upset2 = irr_help(upset2, num_gens, &j, rec_cnt + 1);163for (cnt = 0; cnt < num_gens; cnt++) {164free_mat(gen1[cnt]);165free_mat(gen2[cnt]);166}167free(gen1);168free(gen2);169*num_irr_const = i + j;170p_gen = (matrix_TYP **) malloc(*num_irr_const * num_gens * sizeof(matrix_TYP *));171memcpy(p_gen, upset1, i * num_gens * sizeof(matrix_TYP *));172memcpy(p_gen + num_gens * i, upset2,173j * num_gens * sizeof(matrix_TYP *));174free(upset1);175free(upset2);176return p_gen;177}178179/***********************************************************************/180/* */181/* input: */182/* matrix_TYP **generators: */183/* die Generatoren, fuer jeden Generator eine Matrix */184/* int num_gens: Anzahl der Generatoren */185/* int *num_irr_const: die Anzahl der irrduziblen Konstituenten. */186/* int p: die Primzahl, modulo derer die Konstituenten berechnet */187/* werden */188/* */189/* output: */190/* matrix_TYP **: die irreduziblen Konstituenten mod p fuer */191/* jeden Generator. Zuerst die Matrizen aller */192/* Generatoren fuer den ersten Konstituenten, */193/* dann fuer den zweiten, usf. */194/* */195/***********************************************************************/196197matrix_TYP **ZZ_irr_const(matrix_TYP **generators,198int num_gens, int p, int *num_irr_const)199{200matrix_TYP **irrconst;201int i, j;202203init_prime(p);204irrconst = irr_help(generators, num_gens, num_irr_const, 0);205#if DEBUG206fprintf(stderr, "Primzahl: %d\n",p );207#endif208for (i = 0; i < *num_irr_const; i++) {209for (j = 0; j < num_gens; j++) {210TRACE(1, fprintf(stderr, "Konstituent: %d\n", i));211TRACE(1, fprintf(stderr, "Generator: %d\n", j));212TRACE(1, fput_mat(stderr, irrconst[i*num_gens + j], " :", 2));213}214}215return irrconst;216}217218219