/* introduce tails for the class work_class part of class pcp->cc */
/* end_weight is never used, and always equal to 1. We hijack it as follows: if end_weight<0, then we actually want to compute the lower central series up to class -end_weight, by adding p-powers but not
commutators as tails. */ void tails(int type, int work_class, int start_weight, int end_weight, struct pcp_vars *pcp)
{ registerint *y = y_address;
/* recover desired l.c.s. class */ int lcs_class; int lcs_degree[end+1]; if (end_weight < 0) { int gen;
lcs_class = -end_weight;
end_weight = 1; /* compute lcs degrees of generators */ for (gen = 1; gen <= end; gen++) { int pointer = y[pcp->structure+gen]; if (pointer <= 0)
lcs_degree[gen] = 0; /* pointer<=0 means a redundant generator. Ignore */ else { int u = PART2(pointer), v = PART3(pointer); if (u == 0) /* generator */
lcs_degree[gen] = 1; elseif (v == 0) /* power relation */
lcs_degree[gen] = lcs_degree[u]; else/* commutator relation */
lcs_degree[gen] = lcs_degree[u] + lcs_degree[v];
}
}
} else
lcs_class = 0;
if (pcp->complete != 0 && !pcp->multiplicator) return;
if (type == NEW_TAILS || type == BOTH_TAILS) {
/* first, introduce left-normed commutators of class
work_class as generators or pseudo-generators */
for (f = start; f <= end; f++) { /* we're about to add a tail for (f,s) with s a generator. We
only accept f less than the desired class */ if (lcs_class && lcs_degree[f]>=lcs_class) continue;
bound = MIN(f - 1, y[class_end + 1]); if (bound > 0) {
p1 = y[pcp->ppcomm + f]; for (s = 1; s <= bound; s++) {
value = y[p1 + s]; if (value == 0) /* we are inserting generators or pseudo-generators with old entry trivial; if we are inserting pseudo-generators
we do not insert one if (f, s) is defining */
create_tail(p1 + s, f, s, pcp); elseif (value < 0) /* old entry was non-trivial so we deallocate it
and insert pseudo-generator */
extend_tail(p1 + s, f, s, pcp); if (pcp->overflow) return;
lastg = pcp->lastg;
}
}
}
#ifdefined(GROUP) #ifndef EXPONENT_P /* now, introduce pth powers of final_class generators which
are pth powers or correspond to defining generators */
if (!equal) { for (f = ff; f <= end; f++) { /* f is a pth power or corresponds to a defining generator; if we are inserting pseudo-generators, we do not insert
one if f^p is defining */
value = y[pcp->ppower + f]; if (value == 0) /* we are inserting generators or pseudo-generators
with old entry trivial */
create_tail(pcp->ppower + f, f, 0, pcp); elseif (value < 0) /* old entry was non-trivial so we deallocate it
and insert pseudo-generator */
extend_tail(pcp->ppower + f, f, 0, pcp); if (pcp->overflow) return;
lastg = pcp->lastg;
}
} #endif #endif
}
if (type == COMPUTE_TAILS || type == BOTH_TAILS) {
/* calculate pth powers of class final_class generators which
are commutators by doing the appropriate collections */ if (final_class != 1)
calculate_tails(final_class, pcp); if (pcp->overflow) return;
}
pcp->submlg = pcp->subgrp - lastg;
if (work_class == current_class) { /* note first pseudo-generator and number of actual generators */
pcp->first_pseudo = lastg + 1;
pcp->newgen = pcp->first_pseudo - pcp->ccbeg;
}
/* report on the number of new generators added */ if ((pcp->fullop || pcp->diagn) && type != COMPUTE_TAILS)
printf("The number of new generators introduced for weight %d is %d\n",
work_class,
pcp->lastg - nmr_at_start);
}
#if !defined(TAILS_FILTER)
/* calculate pth powers of class final_class generators which
are commutators by doing the appropriate collections */
registerint a, b; registerint value; registerint p1;
#include"access.h"
#ifdefined(GROUP)
if (pcp->fullop || pcp->diagn)
printf("Processing tails for generators of weight %d and %d\n",
final_class,
1);
for (f = start; f <= end; f++) {
#ifdef DEBUG
printf("Processing generator f = %d, Lused = %d\n", f, pcp->lused); #endif
value = y[structure + f];
a = PART3(value); if (a == 0) break;
b = PART2(value);
/* f is the commutator (b, a); calculate the class current_class part of f^p by collecting (b^p) a = b^(p-1) (ba); by formal collection, we see that the class current_class part of f^p is obtained by subtracting
(modulo p) the rhs of the above equation from the lhs */
jacobi(b, b, a, pcp->ppower + f, pcp); if (pcp->overflow) return;
} #endif
/* calculate the non left-normed commutators of class work_class
in the order (work_class - 2, 2), (work_class - 3, 3) .. */
class_end = pcp->clend; while (--final_class >= ++start_class) {
if (pcp->fullop || pcp->diagn)
printf("Processing tails for generators of weight %d and %d\n",
final_class,
start_class);
for (f = start; f <= end; f++) { #ifdef DEBUG
printf("Processing generator f = %d, Lused = %d\n", f, pcp->lused); #endif
s2 = MIN(f - 1, y[class_end + start_class]); if (s2 - s1 < 0) continue;
p1 = y[pcp->ppcomm + f]; for (s = s1; s <= s2; s++) { /* insert the class current_class part on (f, s) */
value = y[structure + s];
b = PART2(value);
a = PART3(value); if (a == 0)
a = b; elseif (pcp->metabelian && PART3(y[structure + f]) != 0) continue;
/* s = (b, a); calculate the class current_class part of (f, (b, a)) by collecting (fb) a = f (ba) or the class current_class part of (f, (b^p)) by collecting (fb) b^(p - 1) = f (b^p); since we require only the class current_class part - the rest has been computed earlier - we calculate it by subtracting (modulo p) the rhs of the above equation
from the lhs (proof by formal collection) */
jacobi(f, b, a, p1 + s, pcp); if (pcp->overflow) return;
}
}
}
}
#endif
/* insert a new generator or pseudo-generator */
void create_tail(int address, int f, int s, struct pcp_vars *pcp)
{ registerint *y = y_address;
/* work out the number of occurrences of each defining generator in the new generator, storing this in a table above y[lused + current_class] -- the entry y[lused + current_class + gen]
is the number of occurrences of defining generator gen */
if (is_space_exhausted(current_class + pcp->ndgen, pcp)) return;
lused = pcp->lused;
pointer = find_definition(lastg, lused, current_class, pcp); for (i = 1, bound = pcp->ndgen; i <= bound; i++)
y[lused + current_class + i] = 0; for (i = pointer, bound = lused + current_class; i <= bound; i++)
++y[lused + current_class + y[i]];
/* see that the number of occurrences of a defining generator
passes some test that has been set up in option */ if (is_genlim_exceeded(pcp)) return;
/* the test wasn't passed, so we discard the new generator */
pcp->lastg--;
y[address] = 0;
}
/* insert a new pseudo-generator, where the old
entry was non-trivial and must be deallocated */
void extend_tail(int address, int f, int s, struct pcp_vars *pcp)
{ registerint *y = y_address;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.