int ingp(int inp) /* Input a group with pcp. Normally inp=1, and file inf1 is opened inside procedure.inp=0whenfileisalreadyopen-i.e.whenact=1,andpcpis theoutputfromscrun.
*/
{ 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 pointerscomptrandpowptr,aswego. Defsandpowers[d[j],d[i]]andd[j]^pareonlyinthefileforj<=no,so fortheremainingoneswezerothem. pcpisthecurrentplaceofthepointerinarrayofpointerspcptr. opcb,pcb,npcbandnpcb2areexternalsusedtorecordthevaluesofpcp atvariouskeyplaces,foruseinoutgpandprnrel. Roughly,opcb=valueofpcpatendofPCPofPitself.(=pcbwhen stage=0).pcb=valueatendofdefinitionofcommutatorsin[d(M),P] (d(M)=dualofM). npcb=valueatend.npcb2isonlyusedforch1.
*/
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. Thereareseveralcomplications. 1)Thebasicwordiscollectedintoanexponentvectorexpnt[1-exp], butcollectionalsogeneratestermsinthenewgenerators,1-nng. Theseareallcentral,andthesetermscomefromthetailsinthePCP. Theyarecollectedinthevectornexpnt.Theproceduresetnris alwaysusedforthis. 2)Negativepowerscanoccurinthestringtobecollected. 3)Generatorsiwithi>exparegeneratorsofd(M).Thesedonotneedtobe collectedthemselves;theyareonlytheretogeneratoetermsinnng. Theyarenotaccumulatedinexpnt,butdealtwithinblocks,asthey occur. 4)GeneratorsiofPwithi>facexpformanelementaryabeliangroup.It savestime(particularlyforlargerprimes)tousethisfactwhen 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 ormaderedundantifnecessary.
*/
{ 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,therelationisinfactageneratorofthedualofH^2(P,M),andit isstoredassuch.Otherwisewewillbeeliminatinggno.
*/ 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);
}
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.