int pkprog(void)
{ char ngens, neg, fac, there, saved, gottm, gotsgn, err, digexp, nc, provn,
trd, gotfac, heldc, len, **m0, **m1, *m01, irr; short nvecs, i, j, rno1, rno2, nlty, fnz, adno, sdim, qdim, tdim; int msp;
irr = opt ? 1 : 0; if ((ip = fopen(inf, "r")) == 0) {
fprintf(stderr, "Cannot open %s.\n", inf); return (-1);
}
fscanf(ip, "%hd%hd%hd", &rno1, &dim, &rno2);
prime = rno1;
ngens = rno2; if (prime > mpr) {
fprintf(stderr, "prime too big. Nothing to be done.\n"); return (-1);
} if (dim > mdim) {
fprintf(stderr, "dim too big. Increase MDIM.\n"); return (-1);
} if (ngens >= mm) {
fprintf(stderr, "Too many generators. Nothing to be done.\n"); return (-1);
}
nvecs = dim * (ngens + 1); if (nvecs > mv) {
fprintf(stderr, "Too many vectors. Increase MV.\n"); return (-1);
}
msp = nvecs * dim; if (msp > space) {
fprintf(stderr, "Not enough space. Increase SPACE.\n"); return (-1);
}
seeknln();
setpinv(); /* Set vector and matrix pointers, as usual. We take care only to use ngens+1 matrices, thus saving as much storage as possible. This means using temporary files to store matrices occasionally.
*/ for (i = 0; i < nvecs; i++)
vec[i] = mspace - 1 + i * dim; for (i = 0; i <= ngens; i++)
mat[i] = vec - 1 + i * dim; for (i = 1; i <= ngens; i++)
readmat(mat[i]);
fclose(ip); if (aut) {
printf("Enter maximum value of nullity that should be handled: ");
scanf("%hd", &maxnull);
}
m0 = mat[0];
m1 = mat[1];
m01 = m0[1]; /* The next section reads in the given expression in the generators, and computes the corresponding matrix as m0. A temporary file is used to remember the sum so far, whilst a product is being computed.
*/ while (1) {
printf( "Enter element of group algebra. End expression with $. Example:\n");
printf("Enter 3a[3]a[3]a[2] + a[2] - a[4] as 3.3*3*2 + 2 - 4$\n");
fflush(stdout);
there = 0;
saved = 0;
heldc = 0;
err = 0; while (heldc != '$') {
gotfac = 0;
gotsgn = 0;
gottm = 0;
provn = 0;
digexp = 0;
len = 0; while (gottm == 0) { if (heldc) {
nc = heldc;
heldc = 0;
} else
nc = findc(); if (gotsgn == 0) { if (nc == '-') {
neg = 1;
gotsgn = 1;
digexp = 1; continue;
} elseif (nc == '+') {
neg = 0;
gotsgn = 1;
digexp = 1; continue;
} elseif (there == 0) {
neg = 0;
gotsgn = 1;
digexp = 1;
}
} if ((nc == '+' || nc == '-' || nc == '$') && digexp == 0 &&
(len != 0 || provn != 0)) {
heldc = nc;
gottm = 1; if (gotfac == 0) { if (provn) {
fac = neg ? prime - 1 : 1;
len = 1;
mstr[1] = provn - '0';
}
}
} elseif (nc == '.' && digexp == 0 && provn != 0 && gotfac == 0) {
gotfac = 1;
fac = provn - '0';
fac %= prime;
provn = 0; if (neg)
fac = prime - fac;
digexp = 1;
} elseif (nc == '*' && digexp == 0 && (provn != 0 || len != 0)) { if (gotfac == 0) {
gotfac = 1;
fac = neg ? prime - 1 : 1;
len = 1;
mstr[1] = provn - '0';
}
digexp = 1;
} elseif (digit(nc) && digexp) { if (gotfac == 0)
provn = nc; else {
len++;
mstr[len] = nc - '0';
}
digexp = 0;
} else {
fprintf(stderr, "Format error; Try again.\n");
err = 1; while (getchar() != '\n')
; break;
}
} if (err) break; if (len == 1) { if (there)
sum(fac, mat[mstr[1]], m0); else
ncopy(fac, mat[mstr[1]], m0);
} else { if (there) /* We have a partial sum, and now another product to compute, so we must store the partial sum in a temporary file.
*/
{
op = fopen(temp, "w");
printmat(m0);
saved = 1;
fclose(op);
}
ncopy(fac, mat[mstr[1]], m0); for (i = 2; i <= len; i++)
prod(m0, mat[mstr[i]], m0); if (saved) {
ip = fopen(temp, "r"); for (i = 1; i <= dim; i++)
rvecsum(1, m0[i]);
fclose(ip);
saved = 0;
}
}
there = 1;
} if (err) continue; /* err means the expression input was garbled */ if (intop) for (i = 1; i <= dim; i++) { for (j = 1; j <= dim; j++)
printf("%3d", m0[i][j]);
printf("\n");
} /* Store the matrix m0 in a temporary file temp. Then compute its nullity. (nlty writes generators of the null space to another temporary file, temp)
*/
op = fopen(temp2, "w");
printmat(m0);
fclose(op);
op = fopen(temp, "w");
nlty = null(m0, m1);
fclose(op);
ip = fopen(inf, "r");
seeknln();
readmat(m1);
fclose(ip); if (nlty == 0 || (aut && nlty > maxnull)) continue; if (aut) break;
printf("Shall we use this matrix (y/n)? ");
nc = findc(); if (nc == 'y') break;
} /* Now we have chosen the matrix that we are going to use for the irreducibility test. Next we arrange to consider the one-dimensional subspaces of the null-space in order. cvec is used for this purpose.
*/ for (i = 1; i <= nlty; i++)
cvec[i] = 0;
fnz = nlty;
adno = nlty;
trd = 0; while (fnz != 0) {
cvec[adno]++; for (i = 1; i <= dim; i++)
m01[i] = 0; /* Compute the current vector in the nullspace by reading from the file temp, and store it in m01
*/
ip = fopen(temp, "r"); for (i = 1; i <= nlty; i++) { if ((fac = cvec[i]) == 0)
seeknln(); else {
rvecsum(fac, m01);
seeknln();
}
}
fclose(ip); if (intop) { for (j = 1; j <= dim; j++)
printf("%3d", m01[j]);
printf("\n"); if (opt) {
printf("Shall we skip this one? ");
nc = findc(); if (nc == 'y') goto next;
}
} /* Now compute the subspace it generates */
sdim = spgen(m0, ngens); if (intop) { for (i = 1; i <= dim; i++)
printf("%3d", svec[i]);
printf("\n"); for (i = 1; i <= dim; i++) { for (j = 1; j <= dim; j++)
printf("%3d", m0[i][j]);
printf("\n");
}
} if (sdim < dim) /* sdim<dim means the module is reducible */ if (opt == 0) break; else {
printf("Shall we compute (y/n)? ");
nc = findc(); if (nc == 'y') {
opt = 0; break;
}
irr = 0;
}
next: /* The last vector generated the whole space, so go on to the next */
adno = nlty; while (cvec[adno] == prime - 1) {
cvec[adno] = 0;
adno--;
} if (adno <= fnz) { if (adno == fnz) {
cvec[adno] = 0;
adno--;
}
fnz--;
}
} if (opt || sdim == dim) /* Each vector in the null-space generated the whole space. Finally we have to transpose everything, and try just one vector in the null-space.
*/
{
printf("Transforming.\n");
fflush(stdout);
trd = 1;
ip = fopen(temp2, "r");
readmat(m0);
fclose(ip);
trans(m0, m1);
op = fopen(temp, "w");
null1(m1, m0);
fclose(op); /* That ruined m1 (the first generator), so we must re-read it */
ip = fopen(inf, "r");
seeknln();
readmat(m1);
fclose(ip); for (i = 1; i <= ngens; i++) {
trans(mat[i], m0);
copy(m0, mat[i]);
}
ip = fopen(temp, "r"); for (i = 1; i <= dim; i++) {
fscanf(ip, "%hd", &rno1);
m01[i] = rno1;
}
fclose(ip);
sdim = spgen(m0, ngens); if (opt && sdim < dim) {
printf("Shall we compute (y/n)? ");
nc = findc(); if (nc == 'y')
opt = 0; else
irr = 0;
} if (intop) { for (i = 1; i <= dim; i++)
printf("%3d", svec[i]);
printf("\n"); for (i = 1; i <= dim; i++) { for (j = 1; j <= dim; j++)
printf("%3d", m0[i][j]);
printf("\n");
}
}
}
if (opt && irr == 0) {
unlink(temp);
unlink(temp2); return (0);
} if (sdim == dim) {
printf("Module is irreducible.\n");
unlink(temp);
unlink(temp2); return (0);
} /* Space is reducible. Finally, we compute the generators of the subspace and quotient space
*/
qdim = dim - sdim;
strcpy(outf, inf); if (full) {
strcat(outf, "f");
tdim = dim;
} else {
strcat(outf, "s");
tdim = sdim;
} /* if we have transposed, then we first output to the temporary file, and then later read it back in and transpose it back again.
*/ if (trd)
op = fopen(temp, "w"); else {
op = fopen(outf, "w");
fprintf(op, "%3d%5d%3d\n", prime, tdim, ngens);
}
opnmat(m0, ngens, tdim, 1); if (trd == 0 || full)
fclose(op); if (full == 0) {
strcpy(outf, inf);
strcat(outf, "q"); if (trd == 0) {
op = fopen(outf, "w");
fprintf(op, "%3d%5d%3d\n", prime, qdim, ngens);
}
opnmat(m0, ngens, dim, sdim + 1);
fclose(op);
} if (trd) { if (full == 0)
dim = sdim; /* Retranspose */
ip = fopen(temp, "r");
op = fopen(outf, "w");
fprintf(op, "%3d%5d%3d\n", prime, dim, ngens); for (i = 1; i <= ngens; i++) {
readmat(m0);
trans(m0, m1);
printmat(m1);
}
fclose(op); if (full == 0) {
dim = qdim;
strcpy(outf, inf);
strcat(outf, "s");
op = fopen(outf, "w");
fprintf(op, "%3d%5d%3d\n", prime, dim, ngens); for (i = 1; i <= ngens; i++) {
readmat(m0);
trans(m0, m1);
printmat(m1);
}
fclose(ip);
fclose(op);
}
}
unlink(temp);
unlink(temp2); return (0);
}
void seeknln(void)
{ while (getc(ip) != '\n')
;
}
void 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 findc(void)
{ char c; while ((c = getchar()) == ' ' || c == '\n')
; return (c);
}
int digit(int c)
{ if (c >= '1' && c <= '9') return (1); else return (0);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 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.