GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/****************************************************************************1**2*A central_auts.c ANUPQ source Eamonn O'Brien3**4*Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany5*Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia6**7*/89#include "pq_defs.h"10#include "pcp_vars.h"11#include "pga_vars.h"12#include "pq_functions.h"1314/* determine which of the central outer automorphisms of the immediate15descendant are required for iteration purposes; set up those16which are necessary in the array central, which is returned */1718int ***central_automorphisms(struct pga_vars *pga, struct pcp_vars *pcp)19{20register int *y = y_address;2122int ***central;23int **commutator; /* result of commutator calculations */24char **redundant; /* automorphisms which are not required */25Logical found;26register int gamma = 0;27register int i, j, k;28register int u, v;2930/* number of generators of last class in group */31int x = y[pcp->clend + pcp->cc - 1] - y[pcp->clend + pcp->cc - 2];32register int nmr_columns;3334/* dummy variable -- not used in this routine but35required for echelonise_matrix call */36/*37int *subset;38subset = allocate_vector (x, 0, 0);39echelonise_matrix (commutator, x, nmr_columns, pcp->p, subset, pga);40free_vector (subset, 0);41*/4243/* maximum number of central outer automorphisms */44nmr_columns = pga->nmr_centrals = pga->ndgen * pga->s;4546commutator = commutator_matrix(pga, pcp);47if (pga->print_commutator_matrix) {48printf("The commutator matrix is \n");49print_matrix(commutator, x, nmr_columns);50}5152reduce_matrix(commutator, x, nmr_columns, pcp->p, pga);5354redundant = allocate_char_matrix(pga->ndgen, pga->s, 0, TRUE);55for (i = 0; i < x; ++i) {56found = FALSE;57j = 0;58while (j < nmr_columns && !(found = (commutator[i][j] == 1)))59++j;60if (found) {61u = j / pga->s;62v = j % pga->s;63redundant[u][v] = TRUE;64--pga->nmr_centrals;65}66}6768/* set up, in the array central, all necessary automorphisms of the form69u --> u * (pcp->ccbeg + v)70k --> k71where both u and k are defining generators, k distinct from u,72and v runs from 0 to pga->s - 1 */7374if (pga->nmr_centrals != 0) {75central = allocate_array(pga->nmr_centrals, pga->ndgen, pcp->lastg, TRUE);7677for (u = 0; u < pga->ndgen; ++u) {78for (v = 0; v < pga->s; ++v) {79if (redundant[u][v] == FALSE) {80++gamma;81for (k = 0; k < pga->ndgen; ++k) {82central[gamma][k + 1][k + 1] = 1;83if (k == u)84central[gamma][k + 1][pcp->ccbeg + v] = 1;85}86}87}88}89}9091free_matrix(commutator, x, 0);92free_char_matrix(redundant, pga->ndgen);9394return central;95}9697/* for each of the x generators of highest class - 1, look up98its commutator with each of the pga->ndgen defining generators;99set up the exponents of the pga->s new generators which occur100in the commutator as part of a row of an101x by pga->ndgen * pga->s matrix, commutator, which is returned */102103int **commutator_matrix(struct pga_vars *pga, struct pcp_vars *pcp)104{105register int *y = y_address;106107/* first and last generator of last class of parent */108int first = y[pcp->clend + pcp->cc - 2] + 1;109int last = y[pcp->clend + pcp->cc - 1];110111int x = last - first + 1;112int **commutator;113int *result;114int pointer, value, entry, length;115int offset;116int u, v;117register int i, j, k;118#include "access.h"119120#ifdef CARANTI121commutator = allocate_matrix(x, pga->ndgen * pga->s, 0, TRUE);122return commutator;123#else124commutator = allocate_matrix(x, pga->ndgen * pga->s, 0, FALSE);125#endif126127for (i = first; i <= last; ++i) {128129offset = 0;130131for (j = 1; j <= pga->ndgen; ++j) {132133/* store the result of [i, j] */134result = allocate_vector(pga->s, 0, 1);135136if (i != j) {137138if (i < j) {139u = i;140v = j;141} else {142u = j;143v = i;144}145146/* look up the value of [v, u] */147pointer = y[pcp->ppcomm + v];148entry = y[pointer + u];149if (entry > 0)150result[entry - pcp->ccbeg] = 1;151else if (entry < 0) {152length = y[-entry + 1];153for (k = 1; k <= length; ++k) {154value = y[-entry + 1 + k];155result[FIELD2(value) - pcp->ccbeg] = FIELD1(value);156}157}158159/* since, we want the value of [i, j], we may now160need to invert [v, u] */161if (j == v) {162for (k = 0; k < pga->s; ++k)163if (result[k] != 0)164result[k] = (pga->p - result[k]) % pga->p;165}166}167168/* now copy the result to commutator */169for (k = 0; k < pga->s; ++k)170commutator[i - first][k + offset] = result[k];171offset += pga->s;172173free_vector(result, 0);174}175}176177return commutator;178}179180181