GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/****************************************************************************1**2*A commutator.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 "pretty_filterfns.h"12#include "word_types.h"13#include "constants.h"1415/* calculate a solution, x, to the equation1617u_1 * v_1 * x = u_2 * v_21819where u_1, v_1, u_2, v_2 are exponent vectors with20base addresses cp1, cp2, cp3, cp4, respectively;2122the result is stored as an exponent vector with address result;2324with appropriate initial values, this procedure may be25used to calculate a commutator; the algorithm finds a26solution generator by generator */2728void find_commutator(29int cp1, int cp2, int cp3, int cp4, int result, struct pcp_vars *pcp)30{31register int *y = y_address;32int r;33int exp;34register int i;35int str = pcp->lused + 1;36register int p = pcp->p;37register int lastg = pcp->lastg;3839#include "access.h"4041y[str] = 1;4243for (i = 1; i <= lastg; ++i) {4445/* compute r and adjust its value mod p */46r = (y[cp3 + i] + y[cp4 + i]) - (y[cp1 + i] + y[cp2 + i]);47while (r < 0)48r += p;49while (r >= p)50r -= p;5152/* store the exponent of generator i in x */53y[result + i] = r;5455/* now compute the new u_2 */56if (y[cp4 + i] != 0) {57y[str + 1] = PACK2(y[cp4 + i], i);58collect(-str + 1, cp3, pcp);59y[cp3 + i] = 0;60}6162/* compute the residue mod p */63exp = y[cp2 + i] + r;64while (exp < 0)65exp += p;66exp %= p;6768/* now compute the new v_1 */69if (y[cp2 + i] + r >= p)70y[cp2 + i] = p - r;71if (r != 0) {72y[str + 1] = PACK2(r, i);73collect(-str + 1, cp2, pcp);74}7576/* now compute the new u_1 */77if (y[cp1 + i] + exp >= p)78y[cp2 + i] = p - exp;79if (exp != 0) {80y[str + 1] = PACK2(exp, i);81collect(-str + 1, cp1, pcp);82}83}84}8586/* copy a section of the array, y, to another part of y */8788void copy(int old, int length, int new, struct pcp_vars *pcp)89{90register int *y = y_address;9192for (; length > 0; --length)93y[new + length] = y[old + length];94}9596/* calculate a power of a left-normed commutator of supplied depth97by repeated calls to find_commutator; set up the result as an98exponent vector with base address pcp->lused in order to permit99the result to be handed to echelon easily */100101void calculate_commutator(int format, struct pcp_vars *pcp)102{103register int *y = y_address;104105register int ptr, cp1, cp2, cp3, cp4, result;106register int lastg = pcp->lastg;107register int total;108int disp = 0;109int type;110int depth;111int exp;112113total = 6 * lastg + 6;114if (is_space_exhausted(total, pcp))115return;116117cp1 = pcp->submlg - lastg - 2;118cp2 = cp1 - lastg;119cp3 = cp2 - lastg;120cp4 = cp3 - lastg;121result = cp4 - lastg;122ptr = pcp->lused + 1;123124/* fudge the value of submlg because of possible call to power */125pcp->submlg -= total;126127read_value(TRUE, "Input number of components of commutator: ", &depth, 2);128129/* read in a and set it up at cp2 and cp3 */130type = FIRST_ENTRY;131132if (format == BASIC)133read_word(stdin, disp, type, pcp);134else135pretty_read_word(stdin, disp, type, pcp);136137collect_word(ptr, cp2, pcp);138copy(cp2, lastg, cp3, pcp);139140type = NEXT_ENTRY;141disp = y[ptr] + 1;142143while (--depth > 0) {144145/* read in next component, b, and set it up at cp1 and cp4 */146if (format == BASIC)147read_word(stdin, disp, type, pcp);148else149pretty_read_word(stdin, disp, type, pcp);150151collect_word(ptr + disp, cp1, pcp);152copy(cp1, lastg, cp4, pcp);153154/* solve the equation (ba) * x = ab to obtain [a, b] */155find_commutator(cp1, cp2, cp3, cp4, result, pcp);156157copy(result, lastg, cp2, pcp);158copy(result, lastg, cp3, pcp);159}160161read_value(TRUE, "Input required power of this commutator: ", &exp, 1);162power(exp, result, pcp);163164/* print the commutator */165setup_word_to_print("commutator", result, ptr, pcp);166167/* copy result to pcp->lused */168copy(result, lastg, pcp->lused, pcp);169170/* reset the value of submlg */171pcp->submlg += total;172}173174175