int ingp(int inp) /* Input a group with pcp. Normally inp=1, and file inf1 is opened inside procedure. inp=0 when file is already open - i.e. when act=1, and pcp is the output from scrun.
*/
{ int i, j, k, l, sum, jump; int *orpf, *orpb, **pcp, **pcpj, m; if (inp) {
ip = fopen(inf1, "r"); if (ip == 0) {
fprintf(stderr, "Cannot open %s\n", inf1); return (-1);
}
fscanf(ip, "%d%d%d%d%d%d", &prime, &exp, &facexp, &no, &class, &m); if (exp >= mexp) {
fprintf(stderr, "exp too big. Increase MEXP.\n"); return (-1);
} if (m != 0) {
fprintf(stderr, "Wrong version of nq.\n"); return (-1);
}
}
nng = 0;
sum = (stage == 2 || stage == 4) ? exp + dim : exp; if (inp) for (i = 1; i <= sum; i++)
fscanf(ip, "%d", wt + i); if (stage < 2) { if (exp > facexp) for (i = 1; i <= exp; i++)
fscanf(ip, "%d", dpth + i); else for (i = 1; i <= exp; i++)
dpth[i] = 0;
depth = dpth[exp];
} for (i = 1; i <= sum; i++)
fscanf(ip, "%d", d1 + i); for (i = 1; i <= sum; i++)
fscanf(ip, "%d", d2 + i); /* Now we start to read the pcp into rel, setting the commutator and power pointers comptr and powptr, as we go. Defs and powers [d[j],d[i]] and d[j]^p are only in the file for j<=no, so for the remaining ones we zero them. pcp is the current place of the pointer in array of pointers pcptr. opcb,pcb,npcb and npcb2 are externals used to record the values of pcp at various key places, for use in outgp and prnrel. Roughly, opcb=value of pcp at end of PCP of P itself. (=pcb when stage=0). pcb=value at end of definition of commutators in [d(M),P] (d(M)=dual of M). npcb=value at end. npcb2 is only used for ch1.
*/
rpf = rel;
rpb = rel + rsp - 1;
pcp = pcptr; for (i = 2; i <= no; i++) {
comptr[i] = pcp - 1 - tails;
m = (i > facexp) ? facexp : i - 1; for (j = 1; j <= m; j++) {
fscanf(ip, "%d%d", &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, "%d", orpf);
} if (tails)
*(pcp++) = 0;
}
} if (tails || no < facexp) for (i = no + 1; i <= exp; i++) {
comptr[i] = pcp - 1 - tails;
m = (i > facexp) ? facexp : i - 1; for (j = 1; j <= m; j++) {
*(pcp++) = 0; if (tails)
*(pcp++) = 0;
}
}
m = (no >= facexp) ? facexp : no; for (i = 1; i <= m; i++) {
powptr[i] = pcp;
fscanf(ip, "%d%d", &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, "%d", orpf);
} if (tails)
*(pcp++) = 0;
} for (i = no + 1; i <= facexp; i++) {
powptr[i] = pcp;
*(pcp++) = 0; if (tails)
*(pcp++) = 0;
} if (stage == 3)
no = exp; if (stage == 0)
pcb = pcp - 1; /* End of input of PCP of P */ else {
opcb = pcp - 1;
nd1 = d1 + exp + dim;
nd2 = d2 + exp + dim; if (stage == 2 || stage == 4) {
fscanf(ip, "%d", &nng); for (i = 1; i <= nng; i++)
fscanf(ip, "%d", nd1 + i); for (i = 1; i <= nng; i++)
fscanf(ip, "%d", nd2 + i); if (stage == 4) {
jump = exp * dim;
pcpj = pcp + jump;
}
} for (i = exp + 1; i <= exp + dim; i++) {
comptr[i] = pcp - 1; if (stage == 4)
powptr[i] = pcpj - 1; for (j = 1; j <= exp; j++) if (stage == 3 || stage == 1)
*(pcp++) = 0; else {
fscanf(ip, "%d%d", &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, "%d", orpf);
} if (stage == 4) {
fscanf(ip, "%d%d", &k, &l); if (l == 0)
*(pcpj++) = 0; else {
orpf = rpb - l;
*(pcpj++) = orpf;
*(orpf - 1) = k;
*orpf = l; while ((++orpf) <= rpb)
fscanf(ip, "%d", orpf);
rpb -= (l + 2);
}
}
}
}
pcb = pcp - 1; if (stage != 4 && stage != 2) for (i = exp + 1; i <= exp + dim; i++) {
powptr[i] = pcp - 1; for (j = 1; j <= facexp; j++)
*(pcp++) = 0;
} elseif (stage == 4)
pcp += jump;
npcb = pcp - 1;
npcb2 = npcb;
}
wsp = 0;
eexpnt = expnt + exp; if (stage)
eexpnt += dim;
enexpnt = nexpnt + nng; if (stage == 2) {
extno = pcptr + ptrsp - 1 - nng;
subno = extno - nng; for (i = 1; i <= nng; i++) {
extno[i] = 0;
subno[i] = 0;
}
fscanf(ip, "%d", &chpdim); for (i = 1; i <= chpdim; i++) {
fscanf(ip, "%d", &j);
extno[j] = rpf;
fscanf(ip, "%d", rpf);
l = *rpf;
rpf++; for (j = 1; j <= l; j++) {
fscanf(ip, "%d", rpf);
rpf++;
}
}
fscanf(ip, "%d", &chsdim); for (i = 1; i <= chsdim; i++) {
fscanf(ip, "%d", &j);
subno[j] = rpf;
fscanf(ip, "%d", rpf);
l = *rpf;
rpf++; for (j = 1; j <= l; j++) {
fscanf(ip, "%d", rpf);
rpf++;
}
}
} if (pcp - pcptr > ptrsp) {
fprintf(stderr, "Not enough pointer space. Increase PTRSP.\n"); return (-1);
} if (rpf - rel > rsp) {
fprintf(stderr, "Not enough space. Increase RSP.\n"); return (-1);
} if (inp)
fclose(ip); return (0);
}
int outgp(void) /* A group is output to outf1 */
{ int i, k, l, sum, nexp, jump; int **pcp, *b, *c, *e, *f, **pcpj; char jtl;
op = fopen(outf1, "w");
sum = (stage) ? exp + dim : (tails) ? exp + nng : exp; if (tails)
no = exp;
nexp = stage ? exp : sum; class = 1; for (i = 1; i <= sum; i++) if (wt[i] > class) class = wt[i];
fprintf(op, "%3d %5d %4d %5d %3d%3d\n", prime, nexp, facexp, no, class, 0); for (i = 1; i <= sum; i++)
fprintf(op, " %3d", wt[i]);
fprintf(op, "\n"); if (stage == 0) { for (i = 1; i <= sum; i++)
fprintf(op, " %3d", dpth[i]);
fprintf(op, "\n");
} for (i = 1; i <= sum; i++)
fprintf(op, " %3d", d1[i]);
fprintf(op, "\n"); for (i = 1; i <= sum; i++)
fprintf(op, " %3d", d2[i]);
fprintf(op, "\n");
jtl = 0;
pcp = pcptr; while (pcp <= pcb) {
b = *pcp;
c = tails ? *(pcp + 1) : 0; if (b != 0) {
k = *(*pcp - 1);
l = **pcp;
e = b + l;
} else {
k = 0;
l = 0;
} if (c != 0) {
l += *c;
f = c + *c;
} if (k == 0 && l == 0)
fprintf(op, "%d %d", 0, 0); else
fprintf(op, "%3d %3d", k, l); if (b != 0) while (++b <= e)
fprintf(op, " %3d", *b); if (c != 0) while (++c <= f) {
fprintf(op, " %3d", *c + exp);
fprintf(op, " %3d", *(++c));
} if (jtl) { for (i = 1; i <= 10 - l; i++)
fprintf(op, " "); if (l == 0)
fprintf(op, " ");
pcpj++;
b = *pcpj; if (b != 0) {
l = *b;
k = *(b - 1);
} else {
k = 0;
l = 0;
}
e = b + l;
fprintf(op, "%3d %3d", k, l); while (++b <= e)
fprintf(op, " %3d", *b);
}
fprintf(op, "\n"); if (stage && pcp == opcb) {
fprintf(op, " %3d\n", onng); for (i = 1; i <= onng; i++)
fprintf(op, " %3d", nd1[i]);
fprintf(op, "\n"); for (i = 1; i <= onng; i++)
fprintf(op, " %3d", nd2[i]);
fprintf(op, "\n"); if (stage == 4) {
jump = dim * exp;
pcpj = pcp + jump;
jtl = 1;
}
}
pcp += (1 + tails);
} if (stage == 2) {
fprintf(op, "%3d\n", chpdim); for (i = 1; i <= onng; i++) if ((b = extno[i]) != 0) {
fprintf(op, "%3d %4d", i, *b);
c = b + *b; while (++b <= c)
fprintf(op, " %3d", *b);
fprintf(op, "\n");
}
fprintf(op, "%3d\n", chsdim); if (chsdim != 0) for (i = 1; i <= onng; i++) if ((b = subno[i]) != 0) {
fprintf(op, "%3d %4d", i, *b);
c = b + *b; while (++b <= c)
fprintf(op, " %3d", *b);
fprintf(op, "\n");
}
}
fclose(op); return (0);
}
int zero(int * p1, int * p2)
{ while ((++p1) <= p2)
*p1 = 0;
}
int setnr(int * p) /* Really a subprocedure of collect. Adjusts nexpnt by fac times string p. */
{ int *p1, *p2;
p1 = p + *p; while (++p < p1) {
p2 = nexpnt + *p;
*p2 += (fac * *(++p));
*p2 %= prime;
}
}
int collect(int * spc, int * spf, int sgn) /* The basic collection routine. Taken basically from Canberra NQA. There are several complications. 1) The basic word is collected into an exponent vector expnt[1-exp], but collection also generates terms in the new generators, 1-nng. These are all central, and these terms come from the tails in the PCP. They are collected in the vector nexpnt. The procedure setnr is always used for this. 2) Negative powers can occur in the string to be collected. 3) Generators i with i>exp are generators of d(M). These do not need to be collected themselves; they are only there to generatoe terms in nng. They are not accumulated in expnt, but dealt with in blocks, as they occur. 4) Generators i of P with i>facexp form an elementary abelian group. It saves time (particularly for larger primes) to use this fact when collecting
*/
{ int gen, ex, pgen, pex, pugen, stkp, exsgn, *e, *p1, *p2, *p3, *p4, **dp, i,
j, fpg, fpex, *p0, *pe, *q; char done;
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 setpinv(void)
{ int i, j; for (i = 0; i < prime; i++)
pinv[i] = 0; for (i = 1; i < prime; i++) if (pinv[i] == 0) for (j = 1; j < prime; j++) if (i * j % prime == 1) {
pinv[i] = j;
pinv[j] = i; break;
}
}
int intgen(int i, int j) /* A new generator is introduced for commutator [i,j] or (if i=j) i^p */
{ int **dp, *p, *nrpb; int sum;
dp = (stage) ? comptr[i] + j : (i == j) ? powptr[i] : comptr[i] + 2 * j; if (*dp != 0 &&
*(*dp - 1) != 0) { /*printf("Reln [%d,%d] is already a defn.\n",i,j);*/ return (1);
} if (stage >= 2)
dp = powptr[i] + j; if (stage == 0)
dp++; if (*dp !=
0) { /*fprintf(stderr,"Reln [%d,%d] already has a tail.\n",i,j);*/ return (1);
}
nng++;
enexpnt++; if (nng >= mng) {
fprintf(stderr, "Too many new gens. Increase MNG.\n"); return (-1);
} if (stage) {
nd1[nng] = i;
nd2[nng] = j;
rpb -= 4;
*(rpb + 1) = nng;
*(rpb + 2) = 2;
*(rpb + 3) = nng;
*(rpb + 4) = 1;
*dp = rpb + 2;
} else {
sum = exp + nng;
d1[sum] = i;
d2[sum] = j;
dpth[nng + exp] = depth;
wt[sum] = (i == j) ? wt[i] + 1 : wt[i] + wt[j];
rpb -= 3;
*(rpb + 1) = 2;
*(rpb + 2) = nng;
*(rpb + 3) = 1;
*dp = rpb + 1;
dp--; if (*dp == 0) {
rpf++;
*dp = rpf;
*rpf = 0;
rpf++;
}
*(*dp - 1) = sum;
} if (rpb + 1 - rpf < marg) {
printf("Running out of space in intgen. Remains,marg,wsp=%d,%d,%d.\n",
rpb + 1 - rpf, marg, wsp); if (wsp > marg)
bgc(); else return (-1);
} return (0);
}
int subrel(int i, int j) /* Value of [i,j] or i^p is computed using an associativity condition. */
{ int **dp, *p, *nrpb; int x, y, z;
dp = (stage) ? comptr[i] + j : (i == j) ? powptr[i] : comptr[i] + 2 * j; if (*dp != 0 &&
*(*dp - 1) != 0) { /*printf("Reln [%d,%d] is already a defn.\n",i,j);*/ return (0);
} if (stage >= 2)
dp = powptr[i] + j; if (stage == 0)
dp++; if (*dp != 0) {
fprintf(stderr, "Reln [%d,%d] already has a tail.\n", i, j); return (-1);
}
z = 0; for (x = nng; x >= 1; x--) if ((y = nexpnt[x]) != 0) { if (y < 0)
y += prime;
*rpb = y;
*(rpb - 1) = x;
rpb -= 2;
z += 2;
}
*rpb = z; if (stage) {
*dp = rpb;
rpb -= 2;
*(rpb + 1) = 0;
} else {
*dp = rpb;
rpb--;
} if (rpb + 1 - rpf < marg) {
printf("Running out of space in subrel. Remains,marg,wsp=%d,%d,%d.\n",
rpb + 1 - rpf, marg, wsp); if (wsp > marg)
bgc(); else return (-1);
} return (0);
}
int assoc(int g1, int g2, int g3) /* Associativity relation is collected. */
{ char eq12, eq23, prnt, triv; int * p; int i, l, e, sum;
sum = stage ? exp + dim : exp; 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 <= sum; 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(void) /* The new relation in nexpnt is processed, and a new generator eliminated or made redundant if necessary.
*/
{ int i, j, k, l, nl, w, x, y, ct, elno, fac, pow, len, gno; int *p, *q, *eprvec, **dp, **edp; char sub, triv, gth, u;
u = (stage) ? 1 : 0;
pow = 0;
len = 0; for (i = nng; i >= 1; i--) if ((x = nexpnt[i]) != 0) {
len++; if (pow == 0 || (stage == 0 && wt[i + exp] < w)) {
pow = x;
gno = i;
w = wt[i + exp];
}
} if (len == 0) return (1); /* When stage=2 and gno<=onng, we do not eliminate a generator. In this case, the relation is in fact a generator of the dual of H^2(P,M), and it is stored as such. Otherwise we will be eliminating gno.
*/ if (stage == 2 && gno <= onng) return (1 + gno);
sub = len > 1; if (sub) { if (pow < 0)
pow += prime;
fac = pinv[pow];
p = nexpnt; while (++p <= enexpnt) {
*p *= fac;
*p %= prime;
} /* printf("New gen no %d is redundant.\n",gno); */
} /* else printf("New gen no %d is eliminated.\n",gno); */
eprvec = prvec + nng;
elno = (u) ? gno : exp + gno; if (stage >= 2) {
dp = pcb + 1;
edp = (stage > 2) ? npcb2 : npcb;
} elseif (stage == 1) {
dp = opcb + facexp + 1;
ct = facexp + 1;
edp = pcb;
} else {
dp = pcptr;
edp = pcb;
} /* Now we edit the PCP relations, wasting as little space as possible */ while (dp <= edp) {
p = *dp; if (p != 0) {
p--; if (*p > elno)
(*p)--; elseif (*p == elno)
*p = 0;
p++;
} if (stage == 0) {
dp++;
p = *dp;
} if (p != 0) {
l = *p;
q = p + l;
gth = 0; while (++p < q) { if (gth) {
*(p - 2) = *p - 1;
*(p - 1) = *(p + 1);
} elseif (*p > gno)
(*p)--; elseif (*p == gno) {
gth = 1; if (sub) break;
(**dp) -= 2; if (**dp == 0) {
*dp = 0;
wsp += (3 + u);
} else
wsp += (2 + u);
}
p++;
} if (gth && sub) {
zero(prvec, eprvec);
p = *dp; while (++p < q) {
prvec[*p] = *(p + 1);
p++;
}
y = prvec[gno];
nl = l - 2; for (j = 1; j <= nng; j++) if (j != gno && (k = nexpnt[j]) != 0) {
q = prvec + j; if (*q == 0)
nl += 2;
*q -= y * k;
*q %= prime; if (*q < 0)
*q += prime; if (*q == 0)
nl -= 2;
} if (nl == 0) {
*dp = 0;
wsp += (l + 1 + u);
} else { if (nl > l) { if (rpb + 1 - rpf < marg) {
printf("Running out of space in prnrel. " "Remains,marg,wsp=%d,%d,%d.\n",
rpb + 1 - rpf, marg, wsp); if (wsp > marg)
bgc(); else return (-1);
} if (stage) {
rpb -= (nl + 2);
*(rpb + 1) = *(*dp - 1);
*dp = rpb + 2;
wsp += (l + 2);
} else {
rpb -= (nl + 1);
*dp = rpb + 1;
wsp += (l + 1);
}
} for (j = gno; j < nng; j++)
prvec[j] = prvec[j + 1];
p = *dp;
*p = nl; for (j = 1; j < nng; j++) if ((y = prvec[j]) > 0) {
*(++p) = j;
*(++p) = y;
}
}
}
}
dp++; if (stage == 1) { if (ct == exp) {
dp += facexp;
ct = facexp + 1;
} else
ct++;
}
} for (i = gno; i < nng; i++) if (stage) {
nd1[i] = nd1[i + 1];
nd2[i] = nd2[i + 1];
} else {
j = exp + i;
k = j + 1;
d1[j] = d1[k];
d2[j] = d2[k];
wt[j] = wt[k];
}
nng--;
enexpnt--; if (nng == 0) {
printf("All new generators eliminated.\n"); return (0);
} return (1);
}
int bgc(void) /* Garbage collection by outputting to a temporary file and reading in again Occurs after wasted space accumulates from eleiemnating generators.
*/
{ int ** pcp, *p, *q, **epcp; int l, k, d, ct; char gcfile[80];
FILE * wt;
strcpy(gcfile, inf);
strcat(gcfile, "wrd.t");
printf("Back garbage collection. wsp=%d.\n", wsp);
fflush(stdout);
fflush(stderr);
wt = fopen(gcfile, "w"); if (stage >= 2) {
pcp = pcb + 1;
epcp = (stage > 2) ? npcb2 : npcb;
d = 1;
} elseif (stage == 1) {
pcp = opcb + facexp + 1;
ct = facexp + 1;
epcp = pcb;
d = 1;
} else {
pcp = pcptr;
epcp = pcb;
d = 0;
} while (pcp <= epcp) { if (stage == 0)
pcp++; if ((p = *pcp) != 0) {
q = p + *p;
p -= (1 + d); while (++p <= q)
fprintf(wt, "%d ", *p);
}
pcp++; if (stage == 1) { if (ct == exp) {
pcp += facexp;
ct = facexp + 1;
} else
ct++;
}
}
rpb = rel + rsp - 1;
printf("Written to file.\n");
fflush(stdout);
fclose(wt);
wt = fopen(gcfile, "r"); if (stage >= 2) {
pcp = pcb + 1;
epcp = (stage > 2) ? npcb2 : npcb;
} elseif (stage == 1) {
pcp = opcb + facexp + 1;
ct = facexp + 1;
epcp = pcb;
} else {
pcp = pcptr;
epcp = pcb;
} while (pcp <= epcp) { if (stage == 0)
pcp++; if (*pcp != 0) { if (stage) {
fscanf(wt, "%d%d", &k, &l);
rpb -= (l + 2);
p = rpb + 2;
*(p - 1) = k;
} else {
fscanf(wt, "%d", &l);
rpb -= (l + 1);
p = rpb + 1;
}
*pcp = p;
*p = l;
q = p + l; while (++p <= q)
fscanf(wt, "%d", p);
}
pcp++; if (stage == 1) { if (ct == exp) {
pcp += facexp;
ct = facexp + 1;
} else
ct++;
}
}
wsp = 0;
fclose(wt);
unlink(gcfile);
printf("Reread file.\n");
fflush(stdout);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.4 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.