GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/****************************************************************************1**2*A Extend_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 "pq_functions.h"12#define SIZE 10013#define DEFAULT_SIZE 10000014#define DEBUG11516/* for each automorphism, compute its action on each of the generators;1718this code is a modified version of the code to be found in the file19extend_automorphisms -- the modifications are introduced in order20to store the automorphims much more efficiently than the 3-dimensional21array used in that code; the efficiency is achieved by storing the22description using two 1-dimensional arrays, head and list;2324these vectors are organised as follows --25ptr = head[(alpha - 1) * lastg + i] is a pointer to action of26automorphism alpha on generator i;27length = list[ptr + 1] = length of generator-exponent string28storing action;29list[ptr + 2] ... list[ptr + 1 + length] contains the string */3031void Extend_Auts(int **head, int **list, int start, struct pcp_vars *pcp)32{33register int lastg = pcp->lastg;34register int offset;35register int alpha;36int index = 0;37int max_length;38FILE *fp;39int nmr_saved;40int list_length;4142int saved_length; /* total length of description saved to file */43int restored_length = 0; /* amount of description restored from file */44int new; /* new storage requirement */4546/* this used to be 5 * lastg + 4 -- April 1994 */47if (is_space_exhausted(7 * lastg + 4, pcp))48return;4950fp = TemporaryFile();5152save_auts(fp, *head, *list, pcp);5354fread(&nmr_saved, sizeof(int), 1, fp);55fread(&saved_length, sizeof(int), 1, fp);5657max_length = MIN(SIZE, lastg) * lastg;58list_length = max_length + DEFAULT_SIZE;5960if (pcp->cc != 1) {61if ((*head)[0] < lastg)62*head = reallocate_vector(63*head, 1 + (*head)[0] * pcp->m, 1 + lastg * pcp->m, 0, FALSE);64if ((*list)[0] < list_length)65*list = reallocate_vector(66*list, (*list)[0] + 1, list_length + 1, 0, FALSE);67else68list_length = (*list)[0];69}7071for (alpha = 1; alpha <= pcp->m; ++alpha) {72offset = (alpha - 1) * lastg;73restored_length +=74restore_auts(fp, offset, nmr_saved, start - 1, &index, *head, *list);75Extend_Aut(76start, max_length, &list_length, *head, list, offset, &index, pcp);77#ifdef DEBUG78if (alpha != pcp->m) {79printf("*** After automorphism %d, allocation is %d\n",80alpha,81list_length);82printf("*** Value of index is now %d\n", index);83}84#endif8586if ((new = saved_length - restored_length + index) > list_length) {87*list = reallocate_vector(*list, list_length + 1, new + 1, 0, FALSE);88list_length = new;89#ifdef DEBUG90printf("*** Allocation is increased to %d\n", list_length);91#endif92}93}9495(*head)[0] = lastg;96(*list)[0] = list_length;9798CloseFile(fp);99100#ifdef DEBUG1101printf("*** Final allocated space for automorphisms is %d\n", list_length);102printf("*** Final amount used is %d\n", index);103#endif104}105106/* list the action of each automorphism on each of the107pcp generators, first .. last, by their image */108109void List_Auts(int *head, int *list, int first, int last, struct pcp_vars *pcp)110{111register int alpha, i, j, ptr, length;112int offset = 0;113#include "access.h"114115for (alpha = 1; alpha <= pcp->m; ++alpha) {116for (i = first; i <= MIN(last, pcp->lastg); ++i) {117ptr = head[offset + i];118length = list[ptr + 1];119printf("%d --> ", i);120for (j = ptr + 2; j <= ptr + length + 1; ++j) {121printf("%d^%d ", FIELD2(list[j]), FIELD1(list[j]));122}123printf("\n");124}125offset += pcp->lastg;126}127}128129/* set up description of action of automorphisms on defining generators */130131void Setup_Action(int **head,132int **list,133int ***auts,134int nmr_of_exponents,135struct pcp_vars *pcp)136{137register int *y = y_address;138139register int i, generator;140int position, max_length, exp, alpha, offset;141int lastg = pcp->lastg;142int fq_rank = y[pcp->clend + 1];143int list_length;144int index = 0;145146#include "access.h"147148*head = allocate_vector(fq_rank * pcp->m + 1, 0, FALSE);149max_length = MIN(SIZE, lastg) * lastg;150list_length = max_length + DEFAULT_SIZE;151*list = allocate_vector(list_length + 1, 0, FALSE);152153for (alpha = 1; alpha <= pcp->m; ++alpha) {154offset = (alpha - 1) * fq_rank;155for (generator = 1; generator <= fq_rank; ++generator) {156position = (*head)[offset + generator] = index;157(*list)[++position] = 0;158++index;159for (i = 1; i <= nmr_of_exponents; ++i) {160if ((exp = auts[alpha][generator][i]) != 0) {161++(*list)[position];162(*list)[++index] = PACK2(exp, i);163}164}165}166}167168(*head)[0] = fq_rank;169(*list)[0] = list_length;170}171172/* extend the automorphism whose action on the defining generators173of the group is described in the two 1-dimensional arrays, head174and list, to act on the generators of the group; the first175generator whose image is computed is start */176177void Extend_Aut(int start,178int max_length,179int *list_length,180int *head,181int **list,182int offset,183int *index,184struct pcp_vars *pcp)185{186register int *y = y_address;187188register int i, generator;189register int lastg = pcp->lastg;190register int structure = pcp->structure;191int cp1 = pcp->submlg - lastg - 2;192int cp2 = cp1 - lastg;193int result = cp2 - lastg;194register int value;195int u, v;196int exp;197int position, new;198199#include "access.h"200201/* update submlg because of possible call to power */202pcp->submlg -= (3 * lastg + 2);203204/* for each specified generator, compute its image under205the action of the automorphism */206207for (generator = start; generator <= lastg; ++generator) {208209#ifdef DEBUG210if (generator % 100 == 0)211printf("Processed generator %d\n", generator);212#endif213214/* check if there is sufficient space allocated */215if (generator % SIZE == 1 && (new = *index + max_length) > *list_length) {216*list = reallocate_vector(*list, *list_length + 1, new + 1, 0, FALSE);217*list_length = new;218}219220/* examine the definition of generator */221value = y[structure + generator];222223if (value <= 0) {224evaluate_image(head, *list, offset, -value, result, pcp);225} else {226227u = PART2(value);228v = PART3(value);229230if (v == 0)231Extend_Pow(cp1, cp2, u, offset, head, *list, pcp);232else233Extend_Comm(cp1, cp2, u, v, offset, head, *list, pcp);234235#if defined(GROUP)236/* solve the appropriate equation, storing the image237of generator under the action of alpha at result;238in the Lie Program, Extend_Comm has already239set up the answer at location result */240241solve_equation(cp1, cp2, result, pcp);242243#endif244}245246/* now copy the result to list */247248position = head[offset + generator] = *index;249(*list)[++position] = 0;250++*index;251252253for (i = 1; i <= lastg; ++i) {254if ((exp = y[result + i]) != 0) {255++(*list)[position];256(*list)[++*index] = PACK2(exp, i);257}258}259}260261/* reset value of submlg */262pcp->submlg += (3 * lastg + 2);263}264265void evaluate_image(266int *head, int *list, int offset, int ptr, int cp, struct pcp_vars *pcp)267{268register int *y = y_address;269270int lastg = pcp->lastg;271int i, j, start, u;272int pointer;273int exp;274int image_length, relation_length;275int next_gen, next_exp;276int p = pcp->p;277#include "access.h"278279for (i = 1; i <= lastg; ++i)280y[cp + i] = 0;281282if (ptr == 0)283return;284285/* length of redundant relation */286relation_length = y[ptr + 1];287288/* first generator in redundant relation */289u = FIELD2(y[ptr + 1 + 1]);290291/* its exponent */292exp = FIELD1(y[ptr + 1 + 1]);293294/* set up exp power of the image of u under alpha as exponent vector at cp */295traverse_list(exp, head[offset + u], list, cp, pcp);296297/* now reduce the entries mod p */298for (i = 1; i <= lastg; ++i)299y[cp + i] %= p;300301/* now set up image of second generator as word with302base address pointer */303304pointer = pcp->lused + 1;305for (i = 2; i <= relation_length; ++i) {306next_gen = FIELD2(y[ptr + 1 + i]);307next_exp = FIELD1(y[ptr + 1 + i]);308start = head[offset + next_gen];309image_length = list[++start];310y[pointer + 1] = image_length;311for (j = 1; j <= image_length; ++j)312y[pointer + 1 + j] = list[start + j];313for (; next_exp > 0; --next_exp)314collect(-pointer, cp, pcp);315}316}317318/* given generator t of the p-multiplicator, whose definition is319u^p; hence, we have the equation320321u^p = W * t322323where W is a word (possibly trivial) in the generators of the group;324find the image of t under alpha by setting up (W)alpha at cp1,325((u)alpha)^p at cp2, and then call solve_equation */326327void Extend_Pow(int cp1,328int cp2,329int u,330int offset,331int *head,332int *list,333struct pcp_vars *pcp)334{335register int *y = y_address;336337register int i;338register int value;339register int lastg = pcp->lastg;340341for (i = 1; i <= lastg; ++i)342y[cp1 + i] = y[cp2 + i] = 0;343344/* set up the image of u under alpha at cp2 */345traverse_list(1, head[offset + u], list, cp2, pcp);346347/* raise the image of u under alpha to its pth power */348power(pcp->p, cp2, pcp);349350/* set up image of W under alpha at cp1 */351if ((value = y[pcp->ppower + u]) < 0)352Collect_Image_Of_Str(-value, cp1, offset, head, list, pcp);353}354355#if defined(GROUP)356357/* given generator t of the p-multiplicator, whose definition is358[u, v]; hence, we have the equation359360[u, v] = W * t, or equivalently, u * v = v * u * W * t361362where W is a word (possibly trivial) in the generators of the group;363find the image of t under alpha by setting up364(v)alpha * (u)alpha * (W)alpha at cp1, (u)alpha * (v)alpha at cp2365and then call solve_equation */366367void Extend_Comm(int cp1,368int cp2,369int u,370int v,371int offset,372int *head,373int *list,374struct pcp_vars *pcp)375{376register int *y = y_address;377378register int i;379register int pointer, value;380register int lastg = pcp->lastg;381382for (i = 1; i <= lastg; ++i)383y[cp1 + i] = y[cp2 + i] = 0;384385/* set up the image of u under alpha at cp2 */386traverse_list(1, head[offset + u], list, cp2, pcp);387388/* collect image of v under alpha at cp2 */389Collect_Image_Of_Gen(cp2, head[offset + v], list, pcp);390391/* set up image of v under alpha at cp1 */392traverse_list(1, head[offset + v], list, cp1, pcp);393394/* collect image of u under alpha at cp1 */395Collect_Image_Of_Gen(cp1, head[offset + u], list, pcp);396397/* collect image of W under alpha at cp1 */398pointer = y[pcp->ppcomm + u];399if ((value = y[pointer + v]) < 0)400Collect_Image_Of_Str(-value, cp1, offset, head, list, pcp);401}402403#endif404405/* there may be a case where each of the exponent and p is large406to use the power routine to compute the exp power of the407image of generator under automorphism -- it does not seem to408be worthwhile where p = 5 -- needs further investigation */409410void Pq_Collect_Image_Of_Gen(411int exp, int cp, int head, int *list, struct pcp_vars *pcp)412{413register int *y = y_address;414415register int lused = pcp->lused;416int str = lused + pcp->lastg;417register int i;418419for (i = 1; i <= pcp->lastg; ++i)420y[lused + i] = 0;421422traverse_list(1, head, list, lused, pcp);423power(exp, lused, pcp);424vector_to_string(lused, str, pcp);425426collect(-str, cp, pcp);427}428429/* collect image of a generator under the430action of an automorphism and store the result at cp */431432void Collect_Image_Of_Gen(int cp, int head, int *list, struct pcp_vars *pcp)433{434register int *y = y_address;435436register int lused = pcp->lused;437register int length = list[++head];438register int i;439440y[lused + 1] = length;441442for (i = 1; i <= length; ++i)443y[lused + 1 + i] = list[head + i];444445collect(-lused, cp, pcp);446}447448/* collect image of supplied string under the action of449supplied automorphism and store the result at cp */450451void Collect_Image_Of_Str(452int string, int cp, int offset, int *head, int *list, struct pcp_vars *pcp)453{454register int *y = y_address;455456register int i;457register int generator, exp;458register int value;459register int length = y[string + 1] - 1; /* last element of string460is in p-multiplicator */461#include "access.h"462463/* process the string generator by generator, collecting exp464copies of the image of generator under action of automorphism465-- should power routine be used? */466467for (i = 1; i <= length; ++i) {468value = y[string + 1 + i];469generator = FIELD2(value);470exp = FIELD1(value);471while (exp > 0) {472Collect_Image_Of_Gen(cp, head[offset + generator], list, pcp);473--exp;474}475}476}477478479