/****************************************************************************
**
*A collectp2.c ANUPQ source Eamonn O'Brien
**
*Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
*Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia
**
*/
#include "pq_defs.h"
#include "pcp_vars.h"
#include "constants.h"
void
add_p2string(int string, int length, int collected_part, struct pcp_vars *pcp);
/* collection procedure for the prime 2;
this routine is documented in the file collect.c */
void collectp2(int pointer, int collected_part, struct pcp_vars *pcp)
{
register int *y = y_address;
register int p1; /* string pointer */
register int cg; /* collected generator */
register int ug; /* uncollected generator */
register int sp = 0; /* stack pointer */
register int len = 1; /* length */
register int str; /* string pointer */
register int halfwt; /* last generator with weight <= cc/2 */
register int weight_diff; /* current class - weight of ug */
register int firstcg; /* first collected generator for loop counter */
register int lastcg; /* last collected generator for loop counter */
register int cp = collected_part;
register int class_end = pcp->clend;
register int current_class = pcp->cc;
register int p_pcomm = pcp->ppcomm;
register int p_power = pcp->ppower;
register int structure = pcp->structure;
int strstk[STACK_SIZE]; /* string stack */
int lenstk[STACK_SIZE]; /* length stack */
register int i;
#include "access.h"
/* Step (0) --
initialize collector */
if (pointer < 0)
lenstk[0] = y[-pointer + 1];
else if (pointer == 0)
return;
halfwt = y[class_end + current_class / 2];
strstk[0] = pointer;
/* Step (1) --
process next word on stack */
while (sp >= 0) {
str = strstk[sp];
if (str < 0) {
/* we have a genuine string */
len = lenstk[sp];
sp--;
/* get first generator from string */
i = y[-str + 2];
ug = FIELD2(i);
/* if ug > halfwt, whole string can be added to the
collected part without creating any commutators */
if (ug > halfwt) {
add_p2string(str, len, cp, pcp);
continue;
}
if (len != 1) {
/* stack remainder of string */
strstk[++sp] = str - 1;
lenstk[sp] = len - 1;
}
} else {
/* str is a generator */
ug = str;
sp--;
/* if ug > halfwt, ug commutes with all higher generators */
if (ug > halfwt) {
add_p2string(ug, 1, cp, pcp);
continue;
}
}
/* Step (2) --
combinatorial collection;
move ug past entries in the collected part, adding
commutators directly to the collected part;
if 2 * WT(cg) + WT(ug) > current_class then [cg, ug]
commutes with all generators k such that k >= cg;
scan collected part towards the left, bypassing
generators we know must commute with ug */
weight_diff = current_class - WT(y[structure + ug]);
firstcg = y[class_end + weight_diff];
lastcg = y[class_end + weight_diff / 2];
for (cg = firstcg; cg > ug; cg--) {
if (y[cp + cg] != 0) {
/* add [cg, ug] directly to the collected part */
p1 = y[p_pcomm + cg];
p1 = y[p1 + ug];
if (p1 != 0) {
if (cg <= lastcg)
break;
if (p1 < 0)
len = y[-p1 + 1];
add_p2string(p1, len, cp, pcp);
}
}
}
if (cg == ug) {
/* we have reached the ug position during combinatorial collection;
check whether we can avoid stacking collected part */
if (y[cp + ug] == 0) {
y[cp + ug] = 1;
continue;
} else {
if (y[p_power + ug] == 0) {
y[cp + ug] = 0;
continue;
}
}
}
/* we do have to stack some of the collected part */
for (i = firstcg; i > cg; i--) {
if (y[cp + i] != 0) {
/* set entry to zero and stack i */
y[cp + i] = 0;
if (++sp >= STACK_SIZE)
stack_overflow();
strstk[sp] = i;
}
}
/* Step (3) --
ordinary collection; continue scanning towards the left,
stacking up commutators and entries in collected part
until we reach ug position */
for (; cg > ug; cg--) {
if (y[cp + cg] != 0) {
/* zero the cg entry of collected part */
y[cp + cg] = 0;
/* get [cg, ug] */
p1 = y[p_pcomm + cg];
p1 = y[p1 + ug];
/* move ug past cg stacking [cg, ug] and cg */
if (sp + 2 >= STACK_SIZE)
stack_overflow();
if (p1 != 0) {
/* stack [cg, ug] if it is non-trivial */
strstk[++sp] = p1;
if (p1 < 0)
lenstk[sp] = y[-p1 + 1];
}
/* stack cg */
strstk[++sp] = cg;
}
}
add_p2string(ug, 1, cp, pcp);
continue;
}
}
/* prime = 2;
add the string with address string and length length
directly to the collected part with base address collected_part,
recursively adding powers as required */
void
add_p2string(int string, int length, int collected_part, struct pcp_vars *pcp)
{
register int *y = y_address;
register int cp = collected_part;
register int str = string;
register int len = length;
register int ug;
register int class_begin = pcp->ccbeg;
register int p_power = pcp->ppower;
register int i;
int lower, upper;
#include "access.h"
if (str > 0) {
/* Step (4) --
we have moved generator str to the correct position;
add 1 to the str entry of the collected part; reduce
entry modulo 2 and add str^2 to collected part if necessary */
if (y[cp + str] == 0)
y[cp + str] = 1;
else {
/* we need to recursively add in str^2 */
y[cp + str] = 0;
if (str < class_begin) {
str = y[p_power + str];
if (str != 0) {
if (str < 0)
len = y[-str + 1];
add_p2string(str, len, cp, pcp);
}
}
}
} else {
/* Step (5) --
add string with base address -str and length len directly
to the collected part; if this creates an entry >= 2, reduce
entry modulo 2 and recursively add in the appropriate power */
lower = -str + 2;
upper = -str + len + 1;
/* get one generator exponent pair at a time from string */
for (i = lower; i <= upper; i++) {
ug = FIELD2(y[i]);
if (y[cp + ug] == 0)
y[cp + ug] = 1;
else {
y[cp + ug] = 0;
if (ug < class_begin) {
/* we need to recursively add in ug^2 */
str = y[p_power + ug];
if (str != 0) {
if (str < 0)
len = y[-str + 1];
add_p2string(str, len, cp, pcp);
}
}
}
}
}
}
¤ Dauer der Verarbeitung: 0.3 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland