#include "defs.h"
#define MSP 100000
#define MM 101
#define MV 1000
#define MPT 2000
#define MPR 2000
#define MDIM 300
#define MARG 3000
int msp = MSP;
short prime, dim, *spv, **spm, nmat, ordim, npt, *fptr, *nfptr, **sp, **imsp,
*endsp, mspace[MSP], *vec[MV], **mat[MM], pinv[MPR], *pptr[MM],
*spptr[MPT + 1], mm = MM, mv = MV, mpt = MPT, mpr = MPR, mdim = MDIM,
marg = MARG;
char orvec;
FILE *ip, *op;
int main(int argc, char * argv[])
{
short nm, nv, i, j, pt, perm, *p1, *p2, *q1, arg;
char inf[80], outf[80], err;
int x;
/* Defaults: inf=gpname.inmat outf=gpname.inperm */
arg = 1;
err = 0;
if (argc <= arg) {
err = 1;
goto error;
}
strcpy(inf, argv[1]);
strcat(inf, ".");
strcpy(outf, inf);
arg++;
if (argc <= arg)
strcat(inf, "inmat");
else
strcat(inf, argv[arg]);
arg++;
if (argc <= arg)
strcat(outf, "inperm");
else
strcat(outf, argv[arg]);
if ((ip = fopen(inf, "r")) == 0) {
fprintf(stderr, "Cannot open %s.\n", inf);
exit(1);
}
fscanf(ip, "%hd%hd%hd", &prime, &dim, &nmat);
if (prime > mpr) {
fprintf(stderr, "prime too big. Increase MPR.\n");
exit(1);
}
if (dim > mdim) {
fprintf(stderr, "dim too big. Increase MDIM.\n");
exit(1);
}
if (nmat > mm) {
fprintf(stderr, "Too many mats. Increase MM.\n");
exit(1);
}
setpinv();
nm = nmat + 1;
nv = (nm + 2) * dim;
if (nv >= mv) {
fprintf(stderr, "Too many vectors. Increase MV.\n");
exit(1);
}
x = (nv + 1) * dim;
if (x > msp - marg) {
fprintf(stderr, "Out of space. Increase MSP.\n");
exit(1);
}
/* Set matrix pointers as in mcp.c */
for (i = 0; i <= nv; i++)
vec[i] = mspace - 1 + i * dim;
for (i = 0; i <= nmat; i++) {
mat[i] = vec - 1 + i * dim;
if (i > 0)
readmat(mat[i]);
}
fclose(ip);
endsp = mspace + msp - marg;
spm = mat[0];
spv = spm[1];
sp = vec - 1 + nm * dim;
imsp = sp + dim;
fptr = vec[nv];
for (i = 1; i <= nmat; i++) {
pptr[i] = fptr;
fptr += MPT;
}
if (fptr >= endsp) {
fprintf(stderr, "Out of space. Increase MSP.\n");
exit(1);
}
reenter:
printf("Input dim of orbit space (-1 for orbit of vector): ");
scanf("%hd", &ordim);
if (ordim < -1 || ordim == 0 || ordim > dim) {
printf("Inappropriate dimension.\n");
while (getchar() != '\n')
;
goto reenter;
}
else if (ordim == -1) {
ordim = 1;
orvec = 1;
}
else
orvec = 0;
printf("Input generating vectors of orbit space.\n");
for (i = 1; i <= ordim; i++) {
p1 = imsp[i];
for (j = 1; j <= dim; j++)
scanf("%hd", p1 + j);
}
npt = 1;
if (orvec == 0)
normalize();
encode();
spptr[1] = fptr;
fptr = nfptr;
if (fptr >= endsp) {
fprintf(stderr, "Out of space. Increase MSP.\n");
exit(1);
}
for (pt = 1; pt <= npt; pt++) {
decode(pt);
for (perm = 1; perm <= nmat; perm++) {
for (j = 1; j <= ordim; j++)
im(sp[j], imsp[j], mat[perm]);
if (orvec == 0)
normalize();
encode();
for (i = 1; i <= npt; i++) {
p1 = fptr;
p2 = nfptr;
q1 = spptr[i] + 1;
while (++p1 <= p2) {
if (*p1 != *q1)
break;
q1++;
}
if (p1 > p2)
break;
}
pptr[perm][pt] = i;
if (i > npt) {
npt++;
if (npt > mpt) {
fprintf(stderr, "Too many points.\n");
exit(1);
}
spptr[npt] = fptr;
fptr = nfptr;
if (fptr >= endsp) {
fprintf(stderr, "Out of space. Increase MSP.\n");
exit(1);
}
if (npt % 10 == 0)
printf("npt=%d.\n", npt);
}
}
}
op = fopen(outf, "w");
fprintf(op, "%4d%4d%4d%4d\n", npt, nmat, 0, 0);
for (i = 1; i <= nmat; i++)
if (npt >= 1000) {
for (j = 1; j <= npt; j++)
fprintf(op, "%5d", pptr[i][j]);
fprintf(op, "\n");
}
else {
for (j = 1; j <= npt; j++)
fprintf(op, "%4d", pptr[i][j]);
fprintf(op, "\n");
}
error:
if (err) {
fprintf(stderr, "Usage: matperm gpname [inf] [outf]\n");
exit(1);
}
exit(0);
}
int encode(void)
{
short i, *p1, *p2, *q;
char c;
nfptr = fptr;
for (i = 1; i <= ordim; i++) {
c = orvec;
p1 = imsp[i];
p2 = p1 + dim;
q = p1;
while (++q <= p2)
if (*q != 0)
if (c == 0) {
c = 1;
*(++nfptr) = q - p1;
}
else {
*(++nfptr) = q - p1;
*(++nfptr) = *q;
}
*(++nfptr) = 0;
}
}
int decode(int n)
{
short i, *p1, *p2, *ptr, *q;
char c;
ptr = spptr[n];
for (i = 1; i <= ordim; i++) {
c = orvec;
p1 = sp[i];
p2 = p1 + dim;
q = p1;
while (++q <= p2)
*q = 0;
while (*(++ptr) != 0)
if (c == 0) {
p1[*ptr] = 1;
c = 1;
}
else {
p1[*ptr] = *(ptr + 1);
ptr++;
}
}
}
int normalize(void)
{
short rst, i, j, k, fac, *p1, *p2, *q1;
int n;
rst = 1;
for (i = 1; i <= dim; i++)
for (j = rst; j <= ordim; j++)
if (imsp[j][i] != 0) {
p1 = imsp[j];
if (j > rst) {
imsp[j] = imsp[rst];
imsp[rst] = p1;
}
fac = pinv[p1[i]];
p2 = p1 + dim + 1;
while (--p2 > p1) {
n = *p2 * fac;
n %= prime;
*p2 = n;
}
for (k = 1; k <= ordim; k++) {
if (imsp[k][i] == 0 || k == rst)
continue;
fac = prime - imsp[k][i];
p2 = p1 + dim + 1;
q1 = imsp[k] + dim;
while (--p2 > p1) {
n = *q1 + fac * *p2;
n %= prime;
*q1 = n;
q1--;
}
}
if (rst == ordim)
return (0);
rst++;
break;
}
}
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;
}
}
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland
|
|