Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346/****************************************************************************1**2*A echelon.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 CAREFUL1314/* echelonise the relation stored in exponent form in two parts;15left-hand side is in y[lused + 1] to y[lused + lastg];16right-hand side is in y[lused + lastg + 1] to y[lused + 2 * lastg];1718the relation should be homogeneous of class pcp->cc;19if the result is nontrivial, set it up as a new relation pointed20to by the appropriate y[structure + ..]; then remove all occurrences21of newly found redundant generator from the other equations */2223int echelon(struct pcp_vars *pcp)24{25register int *y = y_address;2627register int i;28register int j;29register int k;30register int p1;31register int exp;32register int redgen = 0;33register int count = 0;34register int factor;35register int bound;36register int offset;37register int temp;38register int value;39register int free;4041register Logical trivial;42register Logical first;4344register int p = pcp->p;45register int pm1 = pcp->pm1;4647#include "access.h"4849pcp->redgen = 0;50pcp->eliminate_flag = FALSE;5152/* check that the relation is homogeneous of class pcp->cc */53if (pcp->cc != 1) {54offset = pcp->lused - 1;55temp = pcp->lastg;56for (i = 2, bound = pcp->ccbeg; i <= bound; i++) {57if (y[offset + i] != y[offset + temp + i]) {58text(6, pcp->cc, 0, 0, 0);59pcp->eliminate_flag = TRUE;60return -1;61}62}63}6465/* compute quotient of the relations and store quotient as an exponent66vector in y[pcp->lused + pcp->ccbeg] to y[pcp->lused + pcp->lastg] */67k = 0;68offset = pcp->lused;69for (i = pcp->ccbeg, bound = pcp->lastg; i <= bound; i++) {70y[offset + i] -= y[offset + bound + i];71if ((j = y[offset + i])) {72if (j < 0)73y[offset + i] += p;74k = i;75}76}7778if (k <= 0)79return -1;8081/* print out the quotient of the relations */82if (pcp->diagn) {83/* a call to compact is not permitted at this point */84if (pcp->lused + 4 * pcp->lastg + 2 < pcp->structure) {85/* first copy relevant entries to new position in y */86free = pcp->lused + 2 * pcp->lastg + 1;87for (i = 1; i < pcp->ccbeg; ++i)88y[free + i] = 0;89for (i = pcp->ccbeg; i <= pcp->lastg; ++i)90y[free + i] = y[pcp->lused + i];91setup_word_to_print(92"quotient relation", free, free + pcp->lastg + 1, pcp);93}94}9596first = TRUE;9798while (first || --k >= pcp->ccbeg) {99/* does generator k occur in the unechelonised relation? */100if (!first && y[pcp->lused + k] <= 0)101continue;102103/* yes */104first = FALSE;105exp = y[pcp->lused + k];106if ((i = y[pcp->structure + k]) <= 0) {107if (i < 0) {108/* generator k was previously redundant, so eliminate it */109p1 = -y[pcp->structure + k];110count = y[p1 + 1];111offset = pcp->lused;112for (i = 1; i <= count; i++) {113value = y[p1 + i + 1];114j = FIELD2(value);115/* integer overflow can occur here; see comments in collect */116y[offset + j] = (y[offset + j] + exp * FIELD1(value)) % p;117}118}119y[pcp->lused + k] = 0;120} else {121/* generator k was previously irredundant; have we already122found a generator to eliminate using this relation? */123if (redgen > 0) {124/* yes, so multiply this term by the appropriate factor125and note that the value of redgen is not trivial */126trivial = FALSE;127/* integer overflow can occur here; see comments in collect */128y[pcp->lused + k] = (y[pcp->lused + k] * factor) % p;129} else {130/* no, we will eliminate k using this relation */131redgen = k;132trivial = TRUE;133134/* we want to compute the value of k so we will multiply the135rest of the relation by the appropriate factor;136integer overflow can occur here; see comments in collect */137factor = pm1 * invert_modp(exp, p);138139/* we carry out this mod computation to reduce possibility140of integer overflow */141#if defined(CAREFUL)142factor = factor % p;143#endif144y[pcp->lused + k] = 0;145}146}147}148149if (redgen <= 0)150return -1;151else152pcp->redgen = redgen;153154/* the relation is nontrivial; redgen is either trivial or redundant */155156if (trivial) {157/* mark redgen as trivial */158y[pcp->structure + redgen] = 0;159160if (pcp->fullop)161text(3, redgen, 0, 0, 0);162163complete_echelon(1, redgen, pcp);164} else {165/* redgen has value in exponent form in y[pcp->lused + pcp->ccbeg]166to y[pcp->lused + redgen(-1)] */167count = 0;168offset = pcp->lused;169for (i = pcp->ccbeg; i <= redgen; i++)170if (y[offset + i] > 0) {171count++;172y[offset + count] = PACK2(y[offset + i], i);173}174offset = pcp->lused + count + 1;175for (i = 1; i <= count; i++)176y[offset + 2 - i] = y[offset - i];177178/* set up the relation for redgen */179y[pcp->lused + 1] = pcp->structure + redgen;180y[pcp->lused + 2] = count;181y[pcp->structure + redgen] = -(pcp->lused + 1);182183pcp->lused += count + 2;184185if (pcp->fullop)186text(4, redgen, 0, 0, 0);187188complete_echelon(0, redgen, pcp);189}190191pcp->eliminate_flag = TRUE;192if (redgen < pcp->first_pseudo)193pcp->newgen--;194if (pcp->newgen != 0 || pcp->multiplicator)195return count;196197/* group is completed because all actual generators are redundant,198so it is not necessary to continue calculation of this class */199pcp->complete = 1;200last_class(pcp);201202if (pcp->fullop || pcp->diagn)203text(5, pcp->cc, p, pcp->lastg, 0);204205return -1;206}207208/* complete echelonisation of this relation by removing all occurrences209of redgen from the other relations; if the generator redgen is210trivial, then the flag trivial is TRUE */211212void complete_echelon(Logical trivial, int redgen, struct pcp_vars *pcp)213{214register int *y = y_address;215216int k;217int i, j, jj, exp;218int p1;219int factor;220int count, count1, count2;221int predg;222int offset;223int temp;224int value;225int bound;226int l;227int p = pcp->p;228229#include "access.h"230231if (trivial) {232/* delete all occurrences of redgen from other equations */233for (k = redgen + 1, bound = pcp->lastg; k <= bound; k++) {234if (y[pcp->structure + k] >= 0)235continue;236p1 = -y[pcp->structure + k];237count = y[p1 + 1];238for (j = 1; j <= count; j++)239if ((temp = FIELD2(y[p1 + j + 1])) >= redgen)240break;241if (j > count || temp > redgen)242continue;243244/* redgen occurs in this relation, so eliminate it;245is redgen in the last word? */246count1 = count - 1;247248if (j < count) {249/* no, so pack up relation */250for (jj = j; jj <= count1; jj++)251y[p1 + jj + 1] = y[p1 + jj + 2];252}253254if (j < count || (j >= count && count1 > 0)) {255/* deallocate last word and fix count in header block */256y[p1 + count + 1] = -1;257y[p1 + 1] = count1;258continue;259}260261/* old relation is to be eliminated (it was 1 word long) */262y[p1] = 0;263y[pcp->structure + k] = 0;264}265} else {266p1 = -y[pcp->structure + redgen];267count = y[p1 + 1];268269/* eliminate all occurrences of redgen from the other relations270by substituting its value */271for (k = redgen + 1, bound = pcp->lastg; k <= bound; k++) {272if (y[pcp->structure + k] >= 0)273continue;274if (is_space_exhausted(pcp->lastg + 1, pcp))275return;276p1 = -y[pcp->structure + k];277count1 = y[p1 + 1];278for (j = 1; j <= count1; j++)279if ((temp = FIELD2(y[p1 + j + 1])) >= redgen)280break;281if (j > count1 || temp > redgen)282continue;283284/* redgen occurs in this relation, so eliminate it */285factor = FIELD1(y[p1 + j + 1]);286predg = -y[pcp->structure + redgen];287288/* merge old relation with factor * (new relation), deleting redgen;289old relation is longer than new relation since it contains redgen */290291/* commence merge */292count2 = 0;293offset = pcp->lused + 2;294for (i = 1, l = 1;;) {295temp = FIELD2(y[p1 + i + 1]) - FIELD2(y[predg + l + 1]);296if (temp < 0) {297count2++;298y[offset + count2] = y[p1 + i + 1];299i++;300} else if (temp > 0) {301count2++;302/* integer overflow can occur here; see comments in collect */303value = y[predg + l + 1];304y[offset + count2] =305PACK2((factor * FIELD1(value)) % p, FIELD2(value));306if (++l > count)307break;308} else {309/* integer overflow can occur here; see comments in collect */310value = y[p1 + i + 1];311exp = (FIELD1(value) + factor * FIELD1(y[predg + l + 1])) % p;312if (exp > 0) {313count2++;314y[offset + count2] = PACK2(exp, FIELD2(value));315}316i++;317if (++l > count)318break;319}320}321322/* all of the value of redgen has been merged in;323copy in the remainder of the old relation with redgen deleted */324offset = pcp->lused + 2;325for (jj = i; jj <= count1; jj++)326if (jj != j) {327count2++;328y[offset + count2] = y[p1 + jj + 1];329}330331/* new relation is now in y[lused + 2 + 1] to y[lused + 2 + count2] */332333/* new relation indicates generator k is trivial; deallocate old */334if (count2 <= 0) {335y[p1] = 0;336y[pcp->structure + k] = 0;337continue;338}339340/* new relation is nontrivial */341342if (count2 < count1) {343/* new relation is shorter than old; copy in new relation */344for (i = 1; i <= count2; i++)345y[p1 + i + 1] = y[pcp->lused + 2 + i];346347/* reset count field for new relation */348y[p1 + 1] = count2;349350/* deallocate rest of old relation */351if (count1 == count2 + 1)352y[p1 + count2 + 2] = -1;353else {354y[p1 + count2 + 2] = 0;355y[p1 + count2 + 3] = count1 - count2 - 2;356}357} else if (count1 == count2) {358/* new relation has same length as old; overwrite old relation */359offset = pcp->lused + 2;360for (i = 1; i <= count2; i++)361y[p1 + i + 1] = y[offset + i];362} else {363/* new relation is longer than old; deallocate old relation */364y[p1] = 0;365366/* set up pointer to new relation and header block */367y[pcp->structure + k] = -(pcp->lused + 1);368y[pcp->lused + 1] = pcp->structure + k;369y[pcp->lused + 2] = count2;370pcp->lused += count2 + 2;371}372}373}374}375376377