int ingp(void) /* The PCP for P (output from pcrun) is read in, and all of the associated pointers are set. If -a is true, then the input comes from a preceding run of nqrun, and tails are also read in.
*/
{ short i, j, k, l, m, x, y, no, *orpf, *orpb, **pcp; char tails;
FILE * ip; if ((ip = fopen(inf1, "r")) == 0) {
fprintf(stderr, "Cannot open %s.\n", inf1); return (-1);
}
fscanf(ip, "%hd%hd%hd%hd%hd%hd", &prime, &exp, &nng, &no, &class, &m); if (exp > mexp) {
fprintf(stderr, "exp too big. Increase MEXP.\n"); return (-1);
} if (nng > mng) {
fprintf(stderr, "nng too big. Increase MNG.\n"); return (-1);
} if (m != 1) {
fprintf(stderr, "Wrong version of nq.\n"); return (-1);
}
tails = exp == no; if (tails == 0)
nng = 0; for (i = 1; i <= exp; i++)
fscanf(ip, "%hd", wt + i); for (i = 1; i <= exp + nng; i++)
fscanf(ip, "%hd", d1 + i); for (i = 1; i <= exp + nng; i++)
fscanf(ip, "%hd", d2 + i); for (i = 1; i <= nng; i++)
fscanf(ip, "%hd", cord + i);
rpf = rel;
rpb = rel + rsp - 1;
pcp = pcptr; for (i = 2; i <= no; i++) {
comptr[i] = pcp - 2; for (j = 1; j < i; j++) {
fscanf(ip, "%hd%hd", &k, &l); if (l == 0)
*(pcp++) = 0; else {
*(pcp++) = rpf + 1;
*(rpf++) = k;
*rpf = l;
orpf = rpf;
rpf += (l + 1); while ((++orpf) < rpf)
fscanf(ip, "%hd", orpf);
} if (tails) {
fscanf(ip, "%hd%hd", &k, &l); if (l == 0)
*(pcp++) = 0; else {
orpb = rpb - nng;
*(pcp++) = orpb;
*orpb = k; while (rpb > orpb)
*(rpb--) = 0;
l /= 2; for (k = 1; k <= l; k++) {
fscanf(ip, "%hd%hd", &x, &y);
rpb[x] = y;
}
rpb--;
}
} else
*(pcp++) = 0;
}
} for (i = no + 1; i <= exp; i++) {
comptr[i] = pcp - 2; for (j = 1; j < i; j++) {
*(pcp++) = 0;
*(pcp++) = 0;
}
} for (i = 1; i <= no; i++) {
powptr[i] = pcp;
fscanf(ip, "%hd%hd", &k, &l); if (l == 0)
*(pcp++) = 0; else {
*(pcp++) = rpf + 1;
*(rpf++) = k;
*rpf = l;
orpf = rpf;
rpf += (l + 1); while ((++orpf) < rpf)
fscanf(ip, "%hd", orpf);
} if (tails) {
fscanf(ip, "%hd%hd", &k, &l); if (l == 0)
*(pcp++) = 0; else {
orpb = rpb - nng;
*(pcp++) = orpb;
*orpb = k; while (rpb > orpb)
*(rpb--) = 0;
l /= 2; for (k = 1; k <= l; k++) {
fscanf(ip, "%hd%hd", &x, &y);
rpb[x] = y;
}
rpb--;
}
} else
*(pcp++) = 0;
} for (i = no + 1; i <= exp; i++) {
powptr[i] = pcp;
*(pcp++) = 0;
*(pcp++) = 0;
}
pcb = pcp - 1; if (pcb - pcptr >= ptrsp) {
fprintf(stderr, "Out of ptr space. Increase PTRSP.\n"); return (-1);
} if (rpb - rpf < wksp) {
fprintf(stderr, "Out of space. Increase RSP.\n"); return (-1);
}
fclose(ip); return (0);
}
void outgp(void) /* The PCP is output, together with tails */
{ short i, k, l, **pcp, *b, *e, *c;
FILE * op;
op = fopen(outf, "w");
fprintf(op, "%4d%4d%4d%4d%4d%4d\n", prime, exp, nng, exp, class, 1); for (i = 1; i <= exp; i++)
fprintf(op, "%4d", wt[i]);
fprintf(op, "\n"); for (i = 1; i <= exp + nng; i++)
fprintf(op, "%4d", d1[i]);
fprintf(op, "\n"); for (i = 1; i <= exp + nng; i++)
fprintf(op, "%4d", d2[i]);
fprintf(op, "\n"); if (nng > 0) { for (i = 1; i <= nng; i++)
fprintf(op, "%4d", cord[i]);
fprintf(op, "\n");
}
pcp = pcptr; while (pcp < pcb) { if (*pcp == 0) {
fprintf(op, "%3d %3d", 0, 0);
l = 0;
} else {
l = **pcp;
fprintf(op, "%3d %3d", *(*pcp - 1), l);
b = *pcp;
e = b + l; while (++b <= e)
fprintf(op, "%4d", *b);
} if (l < 10) {
l = 10 - l; for (k = 1; k <= l; k++)
fprintf(op, " ");
}
pcp++; if (*pcp == 0)
fprintf(op, "%3d %3d", 0, 0); else {
fprintf(op, "%3d ", **pcp);
b = *pcp;
e = b + nng;
c = cord + 1;
l = 0; while (++b <= e) { while (*b < 0)
(*b) += *c; if (*b != 0)
l += 2;
c++;
}
fprintf(op, "%3d", l);
b = *pcp; while (++b <= e) if (*b != 0)
fprintf(op, "%4d%4d", (int)(b - (*pcp)), *b);
}
fprintf(op, "\n");
pcp++;
}
fclose(op);
}
void zero(short * p1, short * p2)
{ while ((++p1) <= p2)
*p1 = 0;
}
void setnr(short * p) /* This is called only by collect, which follows */
{ short *p1, *p2, *c;
p1 = nexpnt;
p2 = p1 + nng;
c = cord + 1; while ((++p1) <= p2) {
p++;
*p1 += fac * (*p);
*p1 %= *c;
c++;
}
}
int collect(short * spc, short * spf, int sgn) /* The basic collecting algorithm. The word to be collected is stored as a gen-pow string. spc points to the last gen, and spf to the first, in this string. The collected word is put into expnt, as a vector, and its tail is added to nexpnt (or subtracted if sgn= -1). The algorithm is similar to that used in the Canberra NQA, but negative exponents are allowed.
*/
{ short gen, ex, pgen, pex, pugen, stkp, exsgn, *e, *p1, *p2, *p3, *p4, **dp;
stkp = 0;
pgen = 0;
pex = 0;
pugen = 0;
exsgn = 1;
powdone:
pgen = spgen[stkp];
spc = sspc[stkp];
spf = sspf[stkp];
pex = spex[stkp];
pugen = abs(spugen[stkp]);
ex--; if (ex == 0) { if (spc == spf) {
stkp--; if (stkp == 0) return (0);
gen = sgen[stkp];
ex = sex[stkp]; if (pex == -1) goto powdone;
spc = sspc[stkp];
spf = sspf[stkp];
pugen = spugen[stkp]; goto loop;
} else { if (spc < spf) {
spc += 2;
gen = *spc;
ex = -*(spc + 1);
} else {
spc -= 2;
gen = *spc;
ex = *(spc + 1);
}
sgen[stkp] = gen;
sspc[stkp] = spc;
sex[stkp] = ex;
pugen = pgen; goto loop;
}
} else { if (pugen > pgen) {
pgen = pugen;
pex = expnt[pgen];
}
sex[stkp] = ex; goto loop;
}
}
int intgen(int i, int j) /* A new generator is introduced into the tail of the relation [i,j], or i^p if i=j.
*/
{ short **dp, *p, *nrpb, sum; if (i == j)
dp = powptr[i]; else
dp = comptr[i] + 2 * j; if (*dp != 0 && *(*dp - 1) != 0) {
printf("Reln [%d,%d] is already a defn.\n", i, j); return (0);
}
p = *(dp + 1); if (p != 0) {
fprintf(stderr, "Reln [%d,%d] already has a tail.\n", i, j); return (-1);
}
nng++;
sum = exp + nng; if (sum > mng) {
fprintf(stderr, "Too many newgens. Increase MNG.\n"); return (-1);
}
d1[sum] = i;
d2[sum] = j;
cord[nng] = mord;
enexpnt++;
nrpb = rpb - mnng; if (nrpb - rpf < wksp) {
fprintf(stderr, "Out of space. Increase RSP.\n"); return (-1);
}
zero(nrpb, rpb);
*(dp + 1) = nrpb;
nrpb[nng] = 1;
*nrpb = sum;
rpb = nrpb - 1; return (0);
}
int subrel(int i, int j) /* The element currently in nexpnt, is introduced as the tail of the relation [i,j]
*/
{ short **dp, *p, *nrpb; if (i == j)
dp = powptr[i]; else
dp = comptr[i] + 2 * j; if (*dp != 0 && *(*dp - 1) != 0) {
printf("Reln [%d,%d] is already a defn.\n", i, j); return (0);
}
p = *(dp + 1); if (p != 0) {
fprintf(stderr, "Reln [%d,%d] already has a tail.\n", i, j); return (-1);
}
nrpb = rpb - mnng; if (nrpb - rpf < wksp) {
fprintf(stderr, "Out of space. Increase RSP.\n"); return (-1);
}
zero(nrpb, rpb);
*(dp + 1) = nrpb;
*nrpb = 0;
rpb = nrpb - 1; for (i = 1; i <= nng; i++)
nrpb[i] = nexpnt[i]; return (0);
}
int assoc(int g1, int g2, int g3) /* The difference between the tails of the elements (g1g2)g3 and g1(g2g3) is computed into nexpnt. Thisdifference will of course have to be made trivial later. If g1=g2, we use (g1^p)g2 and g1(g1^(p-1)g2), and similarly if g2=g3.
*/
{ char eq12, eq23, prnt, triv; short i, e, *p; if (g3 < 0) {
prnt = 1;
g3 = -g3;
} else
prnt = 0;
eq12 = g1 == g2;
eq23 = g2 == g3 && g1 != g2;
zero(nexpnt, enexpnt);
zero(expnt, eexpnt);
p = rpf;
*(p++) = g1;
*(p++) = eq12 ? prime - 1 : 1;
*p = g2;
*(p + 1) = 1;
collect(p, rpf, 1);
p = rpf; for (i = 1; i <= exp; i++) {
e = expnt[i]; if (e != 0) {
*(p++) = i;
*(p++) = e;
}
} if (p != rpf) {
zero(expnt, eexpnt);
expnt[g3] = eq23 ? prime - 1 : 1;
collect(p - 2, rpf, 1);
}
zero(expnt, eexpnt); if (eq12 && g2 == g3)
expnt[g2] = 2; else {
p = rpf;
*(p++) = g2;
*(p++) = 1;
*p = g3;
*(p + 1) = eq23 ? prime - 1 : 1;
collect(p, rpf, -1);
}
p = rpf;
*p = g1;
*(p + 1) = eq12 ? prime - 1 : 1;
collect(p, rpf, -1); if (prnt) {
p = nexpnt; while (++p <= enexpnt)
printf("%3d", *p);
printf("\n");
}
triv = 1; for (i = 1; i <= nng; i++) if (triv && nexpnt[i] != 0)
triv = 0; if (triv) return (0); else return (1);
}
int prnrel(int corrtl) /* The element stored in nexpnt is made trivial. This involves eliminating or reducing the order of one or more new generators. corrtl is true when -a is set, and images of generators in the Sylow intersection have their own tails, which require updating. When orders involve larger powers of primes, sometimes more than one run is necessary to complete the reductions. Hence label "restart".
*/
{ short i, j, k, len, hp, ct, fac, x, y, a, b, c, hpi, gno, *p, **dp,
term[30]; char elim, sub, rep, triv;
a = 0;
b = 0;
gno = 0;
restart:
hp = exp / 2;
len = 0;
rep = 0; for (i = nng; i >= 1; i--) {
hpi = 0;
x = nexpnt[i]; if (x != 0) {
len++; while (x % prime == 0) {
hpi++;
x /= prime;
} if (hpi < hp || (hpi == hp && cord[i] < b)) {
gno = i;
hp = hpi;
a = x;
b = cord[i];
}
}
} if (len == 0) return (0);
elim = hp == 0;
sub = len > 1;
x = 1; for (i = 1; i <= hp; i++)
x *= prime; if (sub) {
ct = 0;
c = cord[gno] / x; if (a < 0)
a += cord[gno]; while (a != 1) {
ct++;
term[ct] = c / a;
b = c % a;
c = a;
a = b;
} if (ct == 0)
fac = 1; else {
term[ct + 1] = 1;
term[ct + 2] = 0;
p = term + ct + 1; while (--p > term)
*p = -(*p) * *(p + 1) + *(p + 2);
fac = term[1];
}
p = nexpnt; while (++p <= enexpnt) {
*p *= fac;
*p /= x;
*p %= cord[p - nexpnt];
}
dp = pcptr; while (++dp <= pcb) {
p = *dp; if (p != 0) {
y = p[gno]; if (y != 0) { for (j = 1; j <= nng; j++) if (j == gno) continue; elseif ((k = nexpnt[j]) != 0) {
p[j] -= (y * k);
p[j] %= cord[j];
}
}
}
dp++;
} if (corrtl) { for (i = 3; i <= intexp; i++) if ((p = tlintg[i]) != 0) {
y = p[gno]; if (y != 0) { for (j = 1; j <= nng; j++) if (j == gno) continue; elseif ((k = nexpnt[j]) != 0) {
p[j] -= (y * k);
p[j] %= cord[j];
}
}
}
}
a = cord[gno];
p = nexpnt; while (++p <= enexpnt) {
*p *= a;
*p %= cord[p - nexpnt]; if (*p != 0)
rep = 1;
}
} if (elim) {
printf("New gen no %d is eliminated.\n", gno);
dp = pcptr; while (++dp <= pcb) {
p = *dp; if (p != 0) { if (*p > (exp + gno))
(*p)--; elseif (*p == (exp + gno))
*p = 0;
triv = 1; for (j = 1; j < gno; j++) if (p[j] != 0)
triv = 0; for (j = gno; j < nng; j++) {
p[j] = p[j + 1]; if (triv && p[j] != 0)
triv = 0;
}
p[nng] = 0; if (triv)
*dp = 0;
}
dp++;
} for (j = gno; j < nng; j++) {
cord[j] = cord[j + 1];
d1[exp + j] = d1[exp + j + 1];
d2[exp + j] = d2[exp + j + 1];
nexpnt[j] = nexpnt[j + 1];
} if (corrtl) for (i = 3; i <= intexp; i++) if ((p = tlintg[i]) != 0) for (j = gno; j < nng; j++)
p[j] = p[j + 1];
nng--;
mnng--;
enexpnt--; if (nng == 0) { if (gap) {
FILE * op = fopen(outfm, "w");
fprintf(op, "COHOMOLO.Multiplier:=[];\n");
fclose(op);
printf("All new generators eliminated. Multiplier is trivial.\n");
} else
fprintf(stderr, "All new generators eliminated. Multiplier is trivial.\n"); return (-1);
}
} else {
printf("New order of new gen no %d is %d.\n", gno, x);
cord[gno] = x;
dp = pcptr; while (++dp <= pcb) {
p = *dp; if (p != 0)
p[gno] %= x;
dp++;
} if (corrtl) for (i = 3; i <= intexp; i++) if ((p = tlintg[i]) != 0)
p[gno] %= x;
} if (rep) goto restart; return (1);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.3 Sekunden
(vorverarbeitet)
¤
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 und die Messung sind noch experimentell.