palp-2.21/0000775000177600017760000000000014572606012011741 5ustar skarkeskarkepalp-2.21/Rat.c0000664000177600017760000002477214572603263012654 0ustar skarkeskarke#include "Global.h" #include "Rat.h" Rat rI(Long a) /* a -> a/1 */ { Rat c; c.N=a; c.D=1; return c; } Rat rR(Long a, Long b) /* (a,b) -> a/b */ { Rat c; register Long g=Fgcd(a,b); if( (c.D=(b/g)) < 0 ) {c.D=-c.D; c.N=-a/g;} else c.N=a/g; #ifdef TEST if(c.D<=0) {Rpr(c); puts(" *** c.D<=0 in rR! ***"); exit(0);} #endif return c; } Rat irP(Long i, Rat c) /* (int) * (Rat) */ { register Long g=Fgcd(i,c.D); if(g < 0) g=-g; c.N *= (i/g); c.D/=g; #ifdef TEST if(c.D<=0) {Rpr(c); puts(" *** c.D<=0 in irP! ***"); exit(0);} #endif return c; } Rat rS(Rat a, Rat b) /* a + b */ { Rat c; register Long g=Fgcd(a.D,b.D); g = Fgcd(c.N=a.N*(b.D/g)+b.N*(a.D/g), c.D=a.D*(b.D/g)); if(g < 0) g=-g; c.N/=g; c.D/=g; /* LONG in line above ... */ #ifdef TEST if(c.D<=0) {Rpr(c); puts(" *** c.D<=0 in rS! ***"); exit(0);} #endif return c; } Rat rD(Rat a, Rat b) /* a - b */ { Rat c; register Long g=Fgcd(a.D,b.D); g = Fgcd(c.N=a.N*(b.D/g)-b.N*(a.D/g), c.D=a.D*(b.D/g)); if(g < 0) g=-g; c.N/=g; c.D/=g; /* LONG in line above ... */ #ifdef TEST if(c.D<=0) {Rpr(c); puts(" *** c.D<=0 in rD! ***"); exit(0);} #endif return c; } Rat rP(Rat a, Rat b) /* a * b */ { register Long g=Fgcd(a.N,b.D); register Long h=Fgcd(b.N,a.D); Rat c; c.N=(a.N/g)*(b.N/h); if((c.D=(a.D/h)*(b.D/g)) < 0) {c.D=-c.D; c.N=-c.N;} return c; } Rat rQ(Rat a, Rat b) /* a / b */ { register Long g=NNgcd(a.N,b.N); register Long h=Fgcd(b.D,a.D); Rat c; c.N=(a.N/g)*(b.D/h); if((c.D=(a.D/h)*(b.N/g)) < 0) {c.N=-c.N; c.D=-c.D;} return c; } int rC(Rat a, Rat b) /* Compare = [1 / 0 / -1] iff a [gt/eq/lt] b */ { register Long g=Fgcd(a.D,b.D); if((g=a.N*(b.D/g)-b.N*(a.D/g))) {if(g>0) return 1; else return -1;} else return 0; } void Rpr(Rat c) /* write "c.N/c.D" -> outFN */ { fprintf(outFILE,"%d/%d",(int) c.N, (int) c.D); } #ifdef TEST void TEST_Rat() { Rat a, b; int i, j, k, l; puts(" type 4 numbers: "); scanf("%d%d%d%d",&i,&j,&k,&l); Rpr(rS(rR(i,j),rR(k,l))); puts(" i/j + k/l"); Rpr(rD(rR(i,j),rR(k,l))); puts(" i/j - k/l"); } #endif /* ========== END of Rational Operations ========== */ /* ========== (Extended) Greatest Common Divisor ========= */ /* * Fgcd() computes the GCD for two positive integers (F -> fast) * NNgcd() computes the non-negative GCD for two arbitrary integers * * Egcd() computes the EGCD for two integers * REgcd() recursively computes the EGCD for a number of integers */ Long Fgcd(register Long a, register Long b) /* Fast greatest common div */ { while( a %= b ) if ( !(b %= a) ) return a; return b; } Long NNgcd(register Long a, register Long b) /* NonNegative gcd handling 0 */ { a = (a<0) ? -a:a; b = (b<0) ? -b:b; if (!b) return a; while( a %= b ) if ( !(b %= a) ) return a; return b; } /* ========== Egcd(a,b,*x,*y)=a *x+b *y; REgcd(Vin, *dim, Vout) = Vin.Vout; * * a_i+1=a_i-1 % a_i, a_I+1==0 => egcd(a_0,a_1)=a_I; Vout={x_I,y_I} * a_i==x_ia_0+y_ia_1a_i+1 and a_i+1=a_i-1 -(a_i-1 /a_i)a_i => * x_i+1=x_i-1 -(a_i-1 /a_i)x_i with x_0=1; x_1=0; y_I=(a_I-a_0 x_I)/a_1 * */ Long Egcd(register Long A0, register Long A1, Long *Vout0, Long *Vout1) { register Long V0=A0, V1=A1, A2, X0=1, X1=0, X2=0; while((A2 = A0 % A1)) { X2=X0-X1*(A0/A1); A0=A1; A1=A2; X0=X1; X1=X2; } *Vout0=X1, *Vout1=(A1-(V0) * X1)/ (V1); return A1; } /* * g = v0 x0 + ... + v(n-1) x(n-1), G= A g+ B vn => * G = v0 x0 + ... + vn xn with xn=B, xi*=A, * */ Long REgcd(Long *Vin, int *_n, Long *Vout) /* recursive Egcd(a_1,...,a_n) */ { Long Ain[2], Aout[2], gcd; int N=*_n-1, i; if (*_n==2) return Egcd(*Vin,(Vin[1]),Vout,&(Vout[1])); *Ain=REgcd(Vin,&N,Vout); Ain[1]=Vin[N]; gcd= Egcd(*Ain,(Ain[1]),Aout,&(Aout[1])); Vout[N]=Aout[1]; for(i=0; iN) ? F-1 : F; } Long CeilQ(Long N,Long D) { return -FloorQ(-N,D); } Long RoundQ(Long N,Long D) { Long F; if(D<0) {D=-D; N=-N;} F=N/D; return F+(2*(N-F*D))/D; } Long W_to_GLZ(Long *W, int *d, Long **GLZ) { int i, j; Long G, *E=*GLZ, *B=GLZ[1]; for(i=0;i<*d;i++) assert(W[i]!=0); for(i=1;i<*d;i++)for(j=0;j<*d;j++)GLZ[i][j]=0; G=Egcd(W[0],W[1],&E[0],&E[1]); B[0]=-W[1]/G; B[1]=W[0]/G; for(i=2;i<*d;i++) { Long a, b, g=Egcd(G,W[i],&a,&b); B=GLZ[i]; B[i]= G/g; G=W[i]/g; for(j=0;j %d] ",(int)B[j],(int)Y[j],(int)rB); printf(" [%d/%d -> %d] ",(int)E[j],(int)Y[j],(int)rE); */ for(n=0;n<=j;n++) { B[n] -= rB*Y[n]; E[n] -= rE*Y[n]; } } G=g; } return G; } /* Map Permutations: Do "ArgFun" for all permutations pi of *d elements */ void Map_Permut(int *d,int *pi,int *pinv,ARG_FUN,void *AuxPtr) { int i, j, n_rem_perm, n_perm=1, a, b, perm_j; for (i=1;i<=*d;i++) n_perm*=i; for (i=0;i0;j--) { n_rem_perm/=j; a=b/n_rem_perm; b=b%n_rem_perm; perm_j=*d; while (a>=0) { perm_j--; if (pinv[perm_j]<0) a--;} pi[j-1]=perm_j; pinv[perm_j]=j-1; } (ArgFun)(d,pi,pinv,AuxPtr); } } /* ========== END of GLZ-matrix=(Egcd, B_1, B_2, ...) ========= */ LRat LrI(LLong a) /* a -> a/1 */ { LRat c; c.N=a; c.D=1; return c; } LRat LrR(LLong a, LLong b) /* (a,b) -> a/b */ { LRat c; register LLong g=LFgcd(a,b); if( (c.D=(b/g)) < 0 ) {c.D=-c.D; c.N=-a/g;} else c.N=a/g; #ifdef TEST if(c.D<=0) {LRpr(c); puts(" *** c.D<=0 in rR! ***"); exit(0);} #endif return c; } LRat LirP(LLong i, LRat c) /* (int) * (LRat) */ { register LLong g=LFgcd(i,c.D); if(g < 0) g=-g; c.N *= (i/g); c.D/=g; #ifdef TEST if(c.D<=0) {LRpr(c); puts(" *** c.D<=0 in irP! ***"); exit(0);} #endif return c; } LRat LrS(LRat a, LRat b) /* a + b */ { LRat c; register LLong g=LFgcd(a.D,b.D); g = LFgcd(c.N=a.N*(b.D/g)+b.N*(a.D/g), c.D=a.D*(b.D/g)); if(g < 0) g=-g; c.N/=g; c.D/=g; /* LLong in line above ... */ #ifdef TEST if(c.D<=0) {LRpr(c); puts(" *** c.D<=0 in rS! ***"); exit(0);} #endif return c; } LRat LrD(LRat a, LRat b) /* a - b */ { LRat c; register LLong g=LFgcd(a.D,b.D); g = LFgcd(c.N=a.N*(b.D/g)-b.N*(a.D/g), c.D=a.D*(b.D/g)); if(g < 0) g=-g; c.N/=g; c.D/=g; /* LLong in line above ... */ #ifdef TEST if(c.D<=0) {LRpr(c); puts(" *** c.D<=0 in rD! ***"); exit(0);} #endif return c; } LRat LrP(LRat a, LRat b) /* a * b */ { register LLong g=LFgcd(a.N,b.D); register LLong h=LFgcd(b.N,a.D); LRat c; c.N=(a.N/g)*(b.N/h); if((c.D=(a.D/h)*(b.D/g)) < 0) {c.D=-c.D; c.N=-c.N;} return c; } LRat LrQ(LRat a, LRat b) /* a / b */ { register LLong g=LNNgcd(a.N,b.N); register LLong h=LFgcd(b.D,a.D); LRat c; c.N=(a.N/g)*(b.D/h); if((c.D=(a.D/h)*(b.N/g)) < 0) {c.N=-c.N; c.D=-c.D;} return c; } int LrC(LRat a, LRat b) /* Compare = [1 / 0 / -1] iff a [gt/eq/lt] b */ { register LLong g=LFgcd(a.D,b.D); if((g=a.N*(b.D/g)-b.N*(a.D/g))) {if(g>0) return 1; else return -1;} else return 0; } void LRpr(LRat c) /* write "c.N/c.D" -> outFN */ { fprintf(outFILE,"%lld/%lld",(LLong) c.N, (LLong) c.D); } #ifdef TEST void TEST_LRat() { LRat a, b; int i, j, k, l; puts(" type 4 numbers: "); scanf("%d%d%d%d",&i,&j,&k,&l); LRpr(LrS(rR(i,j),LrR(k,l))); puts(" i/j + k/l"); LRpr(LrD(LrR(i,j),LrR(k,l))); puts(" i/j - k/l"); } #endif /* ========== END of LRational OpeLRations ========== */ /* ========== (Extended) Greatest Common Divisor ========= */ /* * LFgcd() computes the GCD for two positive integers (F -> fast) * LNNgcd() computes the non-negative GCD for two arbitrary integers * * LEgcd() computes the LEgcd for two integers * LREgcd() recursively computes the LEgcd for a number of integers */ LLong LFgcd(register LLong a, register LLong b) /* Fast greatest common div */ { while( a %= b ) if ( !(b %= a) ) return a; return b; } LLong LNNgcd(register LLong a, register LLong b) /* NonNegative gcd handling 0 */ { a = (a<0) ? -a:a; b = (b<0) ? -b:b; if (!b) return a; while( a %= b ) if ( !(b %= a) ) return a; return b; } /* ========== LEgcd(a,b,*x,*y)=a *x+b *y; LREgcd(Vin, *dim, Vout) = Vin.Vout; * * a_i+1=a_i-1 % a_i, a_I+1==0 => LEgcd(a_0,a_1)=a_I; Vout={x_I,y_I} * a_i==x_ia_0+y_ia_1a_i+1 and a_i+1=a_i-1 -(a_i-1 /a_i)a_i => * x_i+1=x_i-1 -(a_i-1 /a_i)x_i with x_0=1; x_1=0; y_I=(a_I-a_0 x_I)/a_1 * */ LLong LEgcd(register LLong A0, register LLong A1, LLong *Vout0, LLong *Vout1) { register LLong V0=A0, V1=A1, A2, X0=1, X1=0, X2=0; while((A2 = A0 % A1)) { X2=X0-X1*(A0/A1); A0=A1; A1=A2; X0=X1; X1=X2; } *Vout0=X1, *Vout1=(A1-(V0) * X1)/ (V1); return A1; } /* * g = v0 x0 + ... + v(n-1) x(n-1), G= A g+ B vn => * G = v0 x0 + ... + vn xn with xn=B, xi*=A, * */ LLong LREgcd(LLong *Vin, int *_n, LLong *Vout) /* recursive LEgcd(a_1,...,a_n) */ { LLong Ain[2], Aout[2], gcd; int N=*_n-1, i; if (*_n==2) return LEgcd(*Vin,(Vin[1]),Vout,&(Vout[1])); *Ain=LREgcd(Vin,&N,Vout); Ain[1]=Vin[N]; gcd= LEgcd(*Ain,(Ain[1]),Aout,&(Aout[1])); Vout[N]=Aout[1]; for(i=0; inf; i++){ for (j = 0; j < _FVl->vl[i].nv; j++) fprintf(outFILE, " %d ", _FVl->vl[i].v[j]); fprintf(outFILE, "nv: %d\n",_FVl->vl[i].nv);fflush(0); } } void Print_M(MMatrix *_M, int *_nf, const char *comment){ int i, j, k; fprintf(outFILE,"%s\n",comment); for (i = 0; i < *_nf; i++){ fprintf(outFILE, "\n\n facet %d:\n", i); for(j = 0; j < _M[i].codim; j++){ fprintf(outFILE, "m[%d]: ",j); for(k = 0; k < _M[i].d; k++) fprintf(outFILE, "%d ",_M[i].M[k][j]); fprintf(outFILE,"\n"); } } } void Dir_Product(PartList *_PTL, VertexNumList *_V, PolyPointList *_P){ int i, j, k, d, rank; CEqList CEtemp; VertexNumList Vtemp; PolyPointList *_PV = (PolyPointList *) malloc(sizeof(PolyPointList)); if(_PV == NULL) Die("Unable to alloc space for PolyPointList _PV"); _PV->n = _P->n; for(i = 0; i < _PTL->n; i++){ rank = 0; for(j = 0; j < _PTL->codim; j++){ _PV->np = 0; for(k = 0; k < _PTL->nv; k++) if(_PTL->S[i][k] == j){ for(d = 0; d < _P->n; d++) _PV->x[_PV->np][d] = _P->x[_V->v[k]][d]; _PV->np += 1; } for(d = 0; d < _P->n; d++) _PV->x[_PV->np][d] = 0; _PV->np += 1; rank += GLZ_Start_Simplex(_PV, &Vtemp, &CEtemp); } if(rank == _P->n) _PTL->DirProduct[i] = 1; else _PTL->DirProduct[i] = 0; } free(_PV); } void Set_To_Vlist(int *_S, VertexNumList *_V, PolyPointList *_P, PolyPointList *_PV, Subset *_Pset){ int i, d; _PV->n = _P->n; _PV->np = 0; for(i = 0; i < _V->nv; i++) if( _Pset->A[_S[i]] == 1){ for(d = 0; d < _P->n; d++) _PV->x[_PV->np][d] = _P->x[_V->v[i]][d]; _PV->np ++; } for(d = 0; d < _P->n; d++) _PV->x[_PV->np][d] = 0; _PV->np += 1; } int New_Set(int i, Subset *_Pset, Subset *_CPset){ if(_Pset->A[i] == 0){ _Pset->A[i] = 1; _Pset->m++; _CPset->A[i] = 0; _CPset->m--; return 1; } else return 0; } void Old_Set(int i, Subset *_Pset, Subset *_CPset){ _Pset->A[i] = 0; _Pset->m--; _CPset->A[i] = 1; _CPset->m++; } void Select_Set(int *_S, VertexNumList *_V, PolyPointList *_P, PolyPointList *_PV, CEqList *_CEtemp, VertexNumList *_Vtemp, int * _DirFlag, Subset *_Pset, Subset *_CPset, int nmax_old){ int rank, nmax; Set_To_Vlist(_S, _V, _P, _PV, _Pset); rank = GLZ_Start_Simplex(_PV, _Vtemp, _CEtemp); Set_To_Vlist(_S, _V, _P, _PV, _CPset); rank += GLZ_Start_Simplex(_PV, _Vtemp, _CEtemp); /*{int i; for(i=0;i<_Pset->M;i++) printf(" %d",_Pset->A[i]); printf("\n");}*/ if(rank == _P->n) *_DirFlag = 1; else{ if(_Pset->m < (_Pset->M/2 + (_Pset->M % 2))){ nmax = (nmax_old + 1); while(!*_DirFlag && (nmax < _Pset->M)){ /*printf("aaa");*/ if (New_Set(nmax, _Pset, _CPset)){ Select_Set(_S, _V, _P, _PV, _CEtemp, _Vtemp, _DirFlag, _Pset, _CPset, nmax); Old_Set(nmax, _Pset, _CPset); } nmax++; } } } } void REC_Dir_Product(PartList *_PTL, VertexNumList *_V, PolyPointList *_P){ int i, j, k; CEqList *_CEtemp; VertexNumList *_Vtemp; PolyPointList *_PV; Subset Pset, CPset; _PV = (PolyPointList *) malloc(sizeof(PolyPointList)); if(_PV == NULL) Die("Unable to alloc space for PolyPointList _PV"); _CEtemp = (CEqList *) malloc(sizeof(CEqList)); if(_CEtemp == NULL) Die("Unable to alloc space for CEqList _CEtemp"); _Vtemp = (VertexNumList *) malloc(sizeof(VertexNumList)); if(_Vtemp == NULL) Die("Unable to alloc space for VertexNumList _Vtemp"); for(i = 0; i < _PTL->n; i++){ _PTL->DirProduct[i] = 0; j = 0; /*printf("\n*********************************\n");*/ while((j < _PTL->codim) && !_PTL->DirProduct[i]){ for(k = 0; k < _PTL->codim; k++){ if(k == j){ Pset.A[k] = 1; CPset.A[k] = 0; } else{ Pset.A[k] = 0; CPset.A[k] = 1; } } Pset.m = 1; Pset.M = _PTL->codim; CPset.m = (_PTL->codim - 1); CPset.M = _PTL->codim; Select_Set(_PTL->S[i], _V, _P, _PV, _CEtemp, _Vtemp, &_PTL->DirProduct[i], &Pset, &CPset, 0); j++; } } free(_Vtemp); free(_CEtemp); free(_PV); } int COMP_S(int SA[], int SB[], int *_nv){ int eq_flag = 1, i = 0; while((i < *_nv) && eq_flag){ if((SA[i] > SB[i]) || (SA[i] < SB[i])) eq_flag = 0; i++; } if(eq_flag) return 0; else{ if(SA[i-1] > SB[i-1]) return 1; else return -1; } } void NForm_S(int S[], int *_nv){ int s[POLY_Dmax], d=0, n_flag, i, j; for(i = 0; i < *_nv; i++){ n_flag = 1; j = 0; while((j < i) && n_flag){ if(S[j] == S[i]) n_flag = 0; j++; } if(n_flag){ s[S[i]] = d; d++; } } for(i = 0; i < *_nv; i++) S[i] = s[S[i]]; } int Bisection_PTL(PartList *_PTL, int s[], int S[]){ int min_pos = -1, max_pos = _PTL->n, pos = 1, c = 1; while((max_pos - min_pos ) > 1){ pos = (max_pos + min_pos) / 2; c = COMP_S(S, _PTL->S[s[pos]], &_PTL->nv); if (c == 1) min_pos = pos; else if (c == -1) max_pos = pos; else min_pos = max_pos; } assert (c == 0); return s[pos]; } void Bubble_PTL(PartList *_PTL, int s[]){ int i, j, diff=0; for(i = 0; i < _PTL->n; i++) s[i] = i; for(i = 0; i < _PTL->n - 1; ++i) for(j = _PTL->n - 1; j > i; --j) if(COMP_S(_PTL->S[s[j-1]], _PTL->S[s[j]], &_PTL->nv) == 1) swap(&s[j-1], &s[j]); for(i = 1; i < _PTL->n; i++){ if(COMP_S(_PTL->S[s[i-1]], _PTL->S[s[i]], &_PTL->nv) == 0) diff += 1; else s[i - diff] = s[i]; } _PTL->n = _PTL->n - diff; } void Remove_Sym(SYM *_VP, PartList *_PTL, PartList *_S_PTL){ int *_s, *_s_sym, *_p; int n=1, i, j, k; PartList *_SYM_PTL; _s = (int*) calloc(_PTL->n, sizeof(int)); assert(_s != NULL); _s_sym = (int*) calloc(_VP->ns, sizeof(int)); assert(_s_sym != NULL); _p = (int*) calloc(_PTL->n, sizeof(int)); assert(_p != NULL); _SYM_PTL = (PartList*) malloc(sizeof(PartList)); assert(_SYM_PTL != NULL); if(Nef_Max < SYM_Nmax) Die("\nNeed Nef_Max >= SYM_Nmax!!!\n"); for(i = 0; i < _PTL->n; i++){ _p[i] = 0; _s[i] = 0; } for(i = 0; i < _PTL->n; i++) NForm_S(_PTL->S[i], &_PTL->nv); Bubble_PTL(_PTL, _s); for(i = 0; i < _PTL->n; i++){ if(_p[_s[i]] == 0){ _p[_s[i]] = n; for(j = 0; j < _VP->ns; j++){ for(k = 0; k < _PTL->nv; k++) _SYM_PTL->S[j][k] = _PTL->S[_s[i]][_VP->Vp[j][k]]; } _SYM_PTL->n = _VP->ns; _SYM_PTL->nv = _PTL->nv; for(j = 0; j < _VP->ns; j++) NForm_S(_SYM_PTL->S[j], &_SYM_PTL->nv); Bubble_PTL(_SYM_PTL, _s_sym); for(j = 1; j < _VP->ns; j++) if(COMP_S(_SYM_PTL->S[_s_sym[j]], _SYM_PTL->S[_s_sym[j-1]], &_PTL->nv) != 0) _p[Bisection_PTL(_PTL, _s, _SYM_PTL->S[_s_sym[j]])] = n; n++; } } n--; _S_PTL->nv = _PTL->nv; _S_PTL->n = 0; _S_PTL->codim = _PTL->codim; while(n > 0){ i = 0; while(_p[_s[i]] != n) i++; for(j = 0; j < _PTL->nv; j ++) _S_PTL->S[_S_PTL->n][j] = _PTL->S[_s[i]][j]; _S_PTL->n += 1; n--; } free(_s);free(_s_sym);free(_p);free(_SYM_PTL); } void M_TO_MM(MMatrix *_M, MMatrix *_MM, GMatrix *_G, int *_nf){ int i, l, c, j; for(i = 0; i < *_nf; i++){ for(l = 0; l < _M[i].d; l++) for(c = 0; c < _M[i].codim; c++){ _MM[i].M[l][c] = 0; for(j = 0; j < _M[i].d; j++) _MM[i].M[l][c] += _G[i].G[j][l] * _M[i].M[j][c]; } _MM[i].d = _M[i].d; _MM[i].codim =_M[i].codim; } } int Convex_Check(MMatrix *_M, GMatrix *_G, XMatrix *_X, int S[], FVList *_FVl, NEF_Flags *_F){ MMatrix *_MM; int c_flag = 1, i, j, k, l, d, IP; if (_F->noconvex) return 1; _MM = (MMatrix *) calloc(_FVl->nf, sizeof(MMatrix)); assert(_MM != NULL); M_TO_MM(_M, _MM, _G, &_FVl->nf); i = 0; while((i < _FVl->nf) && c_flag){ j = 0; while((j < _FVl->nf) && c_flag){ if(i != j){ k = 0; while((k < _MM[i].codim) && c_flag){ l = 0; while((l < _X[i].nv) && c_flag){ if(S[_FVl->vl[i].v[l]] == k) IP = 1; else IP = 0; for(d = 0; d < _MM[i].d; d++) IP += - _X[i].X[d][l] * _MM[j].M[d][k]; if (IP < 0) c_flag = 0; l++; } k++; } } j++; } i++; } if (c_flag && _F->Test) Print_M(_MM, &_FVl->nf, "M-Matrix:"); free(_MM); return c_flag; } int Codim_Check(int S[], int *_codim, int *_Nv){ int gp[POLY_Dmax] = {0}, gp_flag = 1, i, j=0; while( (j < *_codim) && gp_flag){ i = 0; while( (i < *_Nv) && (gp[j] == 0)){ if (S[i] == j) gp[j] = 1; i++; } gp_flag = gp[j]; j++; } return gp_flag; } int Fix_M(Step *_step, XMatrix *_Y, MMatrix *_M, int S[], M_Rank *_MR, FVList *_FVl){ int f_flag=1, i=0, j, m, IP; while(f_flag && (i!=_M[_step->f].codim)){ if(i == S[_FVl->vl[_step->f].v[_step->v]]) IP = 1; else IP = 0; for(j = 0; j < _MR->m[_step->f]; j++) IP += -_Y[_step->f].X[j][_step->v] * _M[_step->f].M[j][i]; m = (IP / _Y[_step->f].X[_MR->m[_step->f]][_step->v]); if((IP - m * _Y[_step->f].X[_MR->m[_step->f]][_step->v]) != 0) f_flag=0; else _M[_step->f].M[_MR->m[_step->f]][i] = m; i++; } return f_flag; } int Check_Consistence(Step *_step, XMatrix *_Y, MMatrix *_M, int S[], M_Rank *_MR, FVList *_FVl){ int c_flag=1, i=0, j, IP; while(c_flag && (i!=_M[_step->f].codim)){ IP = 0; for(j = 0; j < _MR->m[_step->f]; j++) IP += _Y[_step->f].X[j][_step->v] * _M[_step->f].M[j][i]; if(i == S[_FVl->vl[_step->f].v[_step->v]]){ if(IP != 1) c_flag = 0; } else{ if(IP != 0) c_flag = 0; } i++; } return c_flag; } int New_V(V_Flag *_VF, int *_i){ int new_flag = 0; if (!_VF->s[*_i]){ _VF->s[*_i] = 1; new_flag = 1; } return new_flag; } int Next_Step(FVList *_FVl, Step *_step){ int step_flag = 1; if(_step->v == _FVl->vl[_step->f].nv-1){ _step->f += 1; _step->v = 0; } else _step->v += 1; if(_step->f == _FVl->nf) step_flag = 0; return step_flag; } void New_VFlag(V_Flag *_VF, /* int *_Nv, */ int *_n){ _VF->s[*_n] = 1; } void Old_VFlag(V_Flag *_VF, /* int *_Nv, */ int *_n){ _VF->s[*_n] = 0; } void Raise_M_Rank(M_Rank *_MR, int *_facet){ _MR->m[*_facet] += 1; } void Lower_M_Rank(M_Rank *_MR, int *_facet){ _MR->m[*_facet] -= 1; } void Zero_M_Rank(M_Rank *_MR, int *_facet){ _MR->m[*_facet] = 0; } void Initial_Conditions(MMatrix *_M, XMatrix *_Y, M_Rank *_MR, Step *_step, FVList *_FVl, V_Flag *_VF, int S[], int *_codim, int *_dim, PartList *_PTL){ int i; for(i = 0; i < _FVl->nf; i++){ _M[i].codim = *_codim; _M[i].d = *_dim; _MR->m[i] = 0; } _step->f = 0; _step->v = 0; for(i = 0; i < _FVl->Nv; i++) _VF->s[i] = 0; _VF->s[_FVl->vl[0].v[0]] = 1; _MR->m[0] = 1; assert((_Y[0].X[0][0] == 1) || (_Y[0].X[0][0] == -1)); for(i = 0; i < *_codim; i++) _M[0].M[0][i] = 0; _M[0].M[0][0] = _Y[0].X[0][0]; S[_FVl->vl[0].v[0]] = 0; _PTL->n = 0; _PTL->nv = _FVl->Nv; _PTL->codim = *_codim; } void INCI_To_VList( INCI *_X, VList *_Vl, int *_N){ /* INCI X -> {3, 5, 7, ...} ... List of Vertices in VertexNumList of corresponding face */ int i, n=0; INCI Y = *_X; for (i = 0; i < *_N; i++) { if (INCI_M2(Y)){ _Vl->v[n] = *_N-i-1; n++; } Y = INCI_D2(Y); } _Vl->nv = n; } void INCI_To_FVList(FaceInfo *_I, PolyPointList *_P, FVList *_FVl){ /* FaceInfo I -> {3, 5, 7, ...}, {1, 4, 8, ...}, ... Lists of Vertices in VertexNumList of all facets */ int i; for (i = 0; i < _I->nf[_P->n - 1]; i++) INCI_To_VList( &_I->v[_P->n - 1][i], &_FVl->vl[i], &_I->nf[0]); _FVl->nf = _I->nf[_P->n - 1]; _FVl->Nv = _I->nf[0]; } void Sort_FVList(FVList *_FVl, FVList *_FVl_new, int f[]){ /* gives f[] = LIST OF SORTED FACETS IN _FVl: f[0]: facet with max # of Vertices f[k != 0]: facet with max # of Vertices in f[0],...,f[k-1] _FVl->vl[k] -> _FVl->vl[f[k]] = {v in f[0],...,f[k-1]}U{v not in f[0],...,f[k-1]} =: FVl_new->vl[k] */ int i, j, k, l, n, Vequal, vequal, newfacet, newvertex, v[VERT_Nmax], w[VERT_Nmax], nv, nw; f[0] = 0; for (i = 1; i < _FVl->nf; i++) /* first facet */ if (_FVl->vl[i].nv > _FVl->vl[f[0]].nv) f[0] = i; for(i = 0; i < _FVl->vl[f[0]].nv; i++) v[i] = _FVl->vl[f[0]].v[i]; nv = _FVl->vl[f[0]].nv; for (n = 1; n < _FVl->nf; n++){ /* next facet */ Vequal = 0; for (i = 0; i < _FVl->nf; i++){ newfacet = 1; k = 0; while((k < n) && newfacet){ if (f[k] == i) newfacet = 0; k++; } if(newfacet){ vequal = 0; for(j = 0; j < _FVl->vl[i].nv; j++){ newvertex = 1; k = 0; while((k < nv) && newvertex){ if (v[k] == _FVl->vl[i].v[j]) newvertex = 0; k++; } if(!newvertex) vequal++; } if(vequal >= Vequal){ Vequal = vequal; f[n] = i; } } } nw = 0; for(j = 0; j < _FVl->vl[f[n]].nv; j++){ newvertex = 1; k = 0; while((k < nv) && newvertex){ if (v[k] == _FVl->vl[f[n]].v[j]) newvertex = 0; k++; } if(newvertex){ v[nv] = _FVl->vl[f[n]].v[j]; nv++; } else{ w[nw] = _FVl->vl[f[n]].v[j]; nw++; } } for(l = 0; l < nw; l++) _FVl->vl[f[n]].v[l] = w[l]; for(l = 0; l < _FVl->vl[f[n]].nv - nw; l++) _FVl->vl[f[n]].v[nw+l] = v[nv-l-1]; } for(i = 0; i < _FVl->nf; i++){ for(j = 0; j <_FVl->vl[f[i]].nv; j++) _FVl_new->vl[i].v[j] = _FVl->vl[f[i]].v[j]; _FVl_new->vl[i].nv = _FVl->vl[f[i]].nv; } _FVl_new->nf = _FVl->nf; _FVl_new->Nv = _FVl->Nv; } void Make_Matrix(XMatrix * _X, XMatrix * _Y, VList *_Vl, PolyPointList *_P, VertexNumList *_V){ /* Vl -> Matrix X */ int d, j; for (d=0; d < _P->n; d++) for (j=0; j < _Vl->nv; j++){ _X->X[d][j] = _P->x[_V->v[_Vl->v[j]]][d]; _Y->X[d][j] = _P->x[_V->v[_Vl->v[j]]][d]; } _X->d = _P->n; _X->nv = _Vl->nv; _Y->d = _P->n; _Y->nv = _Vl->nv; } void Copy_PTL(PartList *_IN_PTL, PartList *_OUT_PTL){ int i, j; for(i = 0; i < _IN_PTL->n; i++) for(j = 0; j < _IN_PTL->nv; j++) _OUT_PTL->S[i][j] = _IN_PTL->S[i][j]; _OUT_PTL->n = _IN_PTL->n; _OUT_PTL->nv = _IN_PTL->nv; _OUT_PTL->codim = _IN_PTL->codim; } void Select_Sv(int S[], V_Flag *_VF, MMatrix *_M, GMatrix *_G, XMatrix *_X, XMatrix *_Y, M_Rank * _MR, FVList *_FVl, Step step, PartList *_PTL, NEF_Flags* _F){ int i; if(Next_Step(_FVl, &step)){ if(step.v == 0) Zero_M_Rank(_MR, &step.f); if(!New_V(_VF, &_FVl->vl[step.f].v[step.v])){ if (_F->Test){ char c; fprintf(outFILE, "\nold vertex f:%d v:%d\n",step.f,step.v); scanf("%c",&c); } if((_MR->m[step.f] == _M[step.f].d) || (_Y[step.f].X[_MR->m[step.f]][step.v] == 0)){ if(Check_Consistence(&step, _Y, _M, S, _MR, _FVl)){ if (_F->Test) fprintf(outFILE, "f:%d v:%d consistent\n",step.f,step.v); Select_Sv(S, _VF, _M, _G, _X, _Y, _MR, _FVl, step, _PTL, _F); } } else{ if(Fix_M(&step, _Y, _M, S, _MR, _FVl)){ if (_F->Test) fprintf(outFILE, "f:%d v:%d fixed\n",step.f,step.v); Raise_M_Rank(_MR, &step.f); Select_Sv(S, _VF, _M, _G, _X, _Y, _MR, _FVl, step, _PTL, _F); } } } else{ if (_F->Test){ fprintf(outFILE, "\nnew vertex f:%d v:%d",step.f,step.v); } New_VFlag(_VF, /* &_FVl->Nv,*/ &_FVl->vl[step.f].v[step.v]); for(i = 0; i < _M[step.f].codim; i++){ S[_FVl->vl[step.f].v[step.v]] = i; if (_F->Test) fprintf(outFILE, "to partition: %d\n",i); if((_MR->m[step.f] == _M[step.f].d) || (_Y[step.f].X[_MR->m[step.f]][step.v] == 0)){ if(Check_Consistence(&step, _Y, _M, S, _MR, _FVl)){ if (_F->Test) fprintf(outFILE, "f:%d v:%d consistent\n",step.f,step.v); Select_Sv(S, _VF, _M, _G, _X, _Y, _MR, _FVl, step, _PTL, _F); } } else{ if(Fix_M(&step, _Y, _M, S, _MR, _FVl)){ if (_F->Test) fprintf(outFILE, "f:%d v:%d fixed\n",step.f,step.v); Raise_M_Rank(_MR, &step.f); Select_Sv(S, _VF, _M, _G, _X, _Y, _MR, _FVl, step, _PTL, _F); Lower_M_Rank(_MR, &step.f); } } } Old_VFlag(_VF, /* &_FVl->Nv, */ &_FVl->vl[step.f].v[step.v]); } } else{ if(_F->Test){ fprintf(outFILE, "\n********************************************\n"); for(i = 0; i < _FVl->Nv; i++) fprintf(outFILE, " %d ", S[i]); fprintf(outFILE, "\n"); fprintf(outFILE, "**********************************************\n"); fflush(0); } if (Codim_Check(S, &_M[step.f-1].codim, &_FVl->Nv)) if (Convex_Check(_M, _G, _X, S, _FVl, _F)){ assert(_PTL->n < Nef_Max); for(i = 0; i < _FVl->Nv; i++) _PTL->S[_PTL->n][i] = S[i]; _PTL->n += 1; } } } void part_nef(PolyPointList *_P, VertexNumList *_V, EqList *_E, PartList *_OUT_PTL, int *_codim, NEF_Flags* _F){ FaceInfo I; FVList FVl_temp, FVl; XMatrix *_X, *_Y; MMatrix *_M; GMatrix *_G; Step step; V_Flag VF; M_Rank MR; int i, f[FACE_Nmax], S[VERT_Nmax] = {0}; PartList *_PTL = (PartList *) malloc(sizeof(PartList)); assert(_PTL != NULL); Make_Incidence(_P, _V, _E, &I); FVl.vl = (VList *) calloc(I.nf[_P->n - 1], sizeof(VList)); assert(FVl.vl != NULL); if (_F->Sort){ FVl_temp.vl = (VList *) calloc(I.nf[_P->n - 1], sizeof(VList)); assert(FVl_temp.vl != NULL); INCI_To_FVList(&I, _P, &FVl_temp); Sort_FVList(&FVl_temp, &FVl, f); free(FVl_temp.vl); } else INCI_To_FVList(&I, _P, &FVl); if (_F->Test){ Print_VL(_P, _V, "Vertices of P:"); Print_FVl(&FVl, "Facets/Vertices:"); } _X = (XMatrix *) calloc(FVl.nf, sizeof(XMatrix)); assert(_X != NULL); _Y = (XMatrix *) calloc(FVl.nf, sizeof(XMatrix)); assert(_Y != NULL); _M = (MMatrix *) calloc(FVl.nf, sizeof(MMatrix)); assert(_M != NULL); _G = (GMatrix *) calloc(FVl.nf, sizeof(GMatrix)); assert(_G != NULL); for(i = 0; i < FVl.nf; i++){ Make_Matrix(&_X[i], &_Y[i], &FVl.vl[i], _P, _V); GLZ_Make_Trian_NF(_Y[i].X, &_P->n, &FVl.vl[i].nv, _G[i].G); } Initial_Conditions(_M, _Y, &MR, &step, &FVl, &VF, S, _codim, &_P->n, _PTL); Select_Sv(S, &VF, _M, _G, _X, _Y, &MR, &FVl, step, _PTL, _F); free(_X); free(_Y); free(_M); free(_G); free(FVl.vl); if(_F->Sym){ SYM *_VP = (SYM *) malloc(sizeof(SYM)); assert(_VP != NULL); Poly_Sym(_P, _V, _E, &_VP->ns, _VP->Vp); Remove_Sym(_VP, _PTL, _OUT_PTL); free(_VP); } else Copy_PTL(_PTL, _OUT_PTL); /*Dir_Product(_OUT_PTL, _V, _P);*/ if(*_codim > 1) REC_Dir_Product(_OUT_PTL, _V, _P); free(_PTL); } palp-2.21/GNUmakefile0000664000177600017760000001346414572603263014030 0ustar skarkeskarke# M A K E F I L E # main programs: class.c cws.c poly.c nef.c mori.c CC ?= gcc CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE CFLAGS ?= -O3 -g -W -Wall # CFLAGS=-O3 -g # add -g for GNU debugger gdb # CFLAGS=-Ofast -O3 -mips4 -n32 # SGI / 32 bit # CFLAGS=-Ofast -O3 -mips4 -64 # SGI / 64 bit # CFLAGS=-O3 -fast -non_shared -arch pca56 # statically linked for alpha_PC # targets : dependencies ; command # command # ... # The list of programs to build, without the ".x" extension. Having # these in a variable makes it easy to loop through them. Likewise, # the list of dimensions (POLY_Dmax) that we want to build executables # for. PROGRAMS = poly class cws nef mori DIMENSIONS = 4 5 6 11 # The "all" target builds only the 6d-optimized versions that have # historically been built by running "make". .PHONY: all all: $(foreach p,$(PROGRAMS),$(p).x) # The "all-dims" target, however, builds each PROGRAM, once, optimized # for each dimension listed in DIMENSIONS. Here we have "all-dims" # depend only on the traditional foo.x names, but the template below # will add foo-4d.x, foo-5d.x, etc. to the list of prerequisites. .PHONY: all-dims all-dims: all .PHONY: clean clean: ; rm -f *.o .PHONY: cleanall cleanall: ; rm -f *.o *.x palp_* core define PROG_DIM_template = # # Define separate build rules for every combination of PROGRAMS and # DIMENSIONS. This really is necessary: we can't reuse an object file # that was compiled with (say) POLY_Dmax=4 to link the executable # foo-11d.x, because then foo-11d.x will just wind up with the code # for dimension <= 4. And that's the best case: mixing and matching # POLY_Dmax across multiple files could easily cause a crash. # # Arguments: # # $(1) - program name, e.g. "poly" or "mori" # $(2) - the current value of POLY_Dmax, e.g. "4" or "11" # # A list of common objects needed by all executables of this dimension OBJECTS_$(2) = Coord-$(2)d.o Rat-$(2)d.o Vertex-$(2)d.o Polynf-$(2)d.o # List the additional objects needed by the individual programs of # this dimension poly_OBJ_$(2) = LG-$(2)d.o class_OBJ_$(2) = Subpoly-$(2)d.o Subadd-$(2)d.o Subdb-$(2)d.o cws_OBJ_$(2) = LG-$(2)d.o nef_OBJ_$(2) = E_Poly-$(2)d.o Nefpart-$(2)d.o LG-$(2)d.o mori_OBJ_$(2) = MoriCone-$(2)d.o SingularInput-$(2)d.o LG-$(2)d.o # Build the object foo-Nd.o from foo.c. The COMPILE.c macro is built # in to GNU Make. There's a special case for an empty DIMENSION as an # indicator that we should not override the value of POLY_Dmax in # Global.h. This is used to build the foo.x programs using the value # in Global.h, since editing Global.h has long been documented as the # way to change POLY_Dmax in foo.x. ifeq ($(2),) %-$(2)d.o: %.c $(COMPILE.c) -o $$@ $$< else %-$(2)d.o: %.c $(COMPILE.c) -DPOLY_Dmax=$(2) -o $$@ $$< endif # Link the program foo-Nd.x from foo-Nd.o, OBJECTS_N, and foo_OBJ_N. # The LINK.c macro is built in to GNU Make. $(1)-$(2)d.x: $(1)-$(2)d.o $$(OBJECTS_$(2)) $$($(1)_OBJ_$(2)) $(LINK.c) -o $$@ $$^ # Add foo-Nd.x to the "all-dims" target all-dims: $(1)-$(2)d.x # Specify some additional dependencies (beyond the corresponding *.c file) # for our *.o files. Coord-$(2)d.o: Rat.h Global.h Polynf-$(2)d.o: Rat.h Global.h Rat-$(2)d.o: Rat.h Global.h Subpoly-$(2)d.o: Rat.h Subpoly.h Global.h Subadd-$(2)d.o: Subpoly.h Global.h Vertex-$(2)d.o: Rat.h Global.h Subdb-$(2)d.o: Subpoly.h Global.h LG-$(2)d.o: Rat.h LG.h Global.h E_Poly-$(2)d.o: Nef.h Rat.h Global.h Nefpart-$(2)d.o: Nef.h Global.h MoriCone-$(2)d.o: Rat.h Mori.h Global.h SingularInput-$(2)d.o: Mori.h Global.h poly-$(2)d.o: LG.h Global.h class-$(2)d.o: Subpoly.h Global.h cws-$(2)d.o: LG.h Rat.h Global.h nef-$(2)d.o: Nef.h LG.h Global.h mori-$(2)d.o: LG.h Mori.h Global.h endef # Call the PROG_DIM_template once for each PROGRAM "p" and # DIMENSION "d". $(foreach p,$(PROGRAMS),$(foreach d,$(DIMENSIONS),\ $(eval $(call PROG_DIM_template,$(p),$(d)))\ )) # Typically (i.e. by default) foo.x will be identical to foo-6d.x, # since Global.h defines POLY_Dmax=6. However, the procedure to change # POLY_Dmax has long been documented as "edit Global.h and re-run # make." If we simply copy foo-6d.x to foo.x, then changes to Global.h # will have no effect on the resulting executables. Instead, we build # a separate copy of each program with DIMENSION set to the empty # string. This alerts the build rule to omit the -DPOLY_Dmax line that # overrides the value in Global.h. The resulting foo-d.x executables # can then be copied to foo.x so that the documented procedure still # works. The special INTERMEDIATE rule avoids rebuilding foo-d.x after # we've moved it to foo.x. $(foreach p,$(PROGRAMS),\ $(eval $(call PROG_DIM_template,$(p),))\ ) .INTERMEDIATE: $(foreach p,$(PROGRAMS),$(p)-d.x) %.x: %-d.x mv $< $@ # For lack of anything less silly, define a newline this way. # We need it to run multiple commands in a $(foreach) loop. # The $(blank) is apparently required to keep it from eating # the newline. blank := define newline $(blank) endef # Testing # ####### # # Each test script should take the dimension DIM from the environment # with default 6. Optionally, the LONG variable can be set to a # non-null value to enable the tests that take a long time. Some # documentation on this test "protocol" is contained in tests/README. # TESTS = $(wildcard tests/*.sh) # The test suite depends on all of the dimension-optimized programs. # The main "make check" routine runs each of the tests/*.sh scripts # with each applicable value of DIM. .PHONY: check check: $(foreach p,$(PROGRAMS),$(foreach d,$(DIMENSIONS),$(p)-$(d)d.x)) $(foreach t,$(TESTS),$(foreach d,$(DIMENSIONS),\ $(newline)@DIM=$(d) $(t)\ )) .PHONY: checklong checklong: LONG=1 $(MAKE) check palp-2.21/COPYING0000664000177600017760000000063614572603263013006 0ustar skarkeskarkePALP is freely available under the GNU General Public License version 3, as specified at >> http://www.gnu.org/copyleft/gpl.html The latest version of PALP can be obtained at >> http://hep.itp.tuwien.ac.at/~kreuzer/CY/ Copyright: Maximilian Kreuzer and Harald Skarke Institute for Theoretical Physics University of Technology Vienna Wiedner Hautpstrasse 8-10 1040 Vienna, AUSTRIA palp-2.21/Nef.h0000664000177600017760000000417014572603263012631 0ustar skarkeskarke#define Nef_Max 500000 #define NP_Max 500000 #define W_Nmax (POLY_Dmax+1) #define MAXSTRING 100 #undef WRITE_CWS #define WRITE_CWS #define Pos_Max (POLY_Dmax + 2) #define FIB_POINT_Nmax VERT_Nmax typedef struct { Long W[FIB_Nmax][FIB_POINT_Nmax]; Long VM[FIB_POINT_Nmax][POLY_Dmax]; int nw; int nv; int d; int Wmax; } LInfo; struct Poset_Element { int num, dim; }; struct Interval { int min, max; }; typedef struct Interval Interval; typedef struct { struct Interval *L; int n; } Interval_List; typedef struct Poset_Element Poset_Element; typedef struct { struct Poset_Element x, y; } Poset; typedef struct { struct Poset_Element *L; int n; } Poset_Element_List; typedef struct { int nface[Pos_Max]; int dim; INCI edge[Pos_Max][FACE_Nmax]; } Cone; typedef struct { Long S[2*Pos_Max]; } SPoly; typedef struct { Long B[Pos_Max][Pos_Max]; } BPoly; typedef struct { int E[4*(Pos_Max)][4*(Pos_Max)]; } EPoly; typedef struct { Long x[POINT_Nmax][W_Nmax]; int N, np; } AmbiPointList; typedef struct { int n; int nv; int codim; int S[Nef_Max][VERT_Nmax]; int DirProduct[Nef_Max]; int Proj[Nef_Max]; int DProj[Nef_Max]; } PartList; typedef struct { int n; int nv; int S[Nef_Max][VERT_Nmax]; } Part; typedef struct { int n, y, w, p, t, S, Lv, Lp, N, u, d, g, VP, B, T, H, dd, gd, noconvex, Msum, Sym, V, Rv, Test, Sort, Dir, Proj, f, G; } Flags; typedef struct { int noconvex, Sym, Test, Sort; } NEF_Flags; struct Vector { Long x[POLY_Dmax]; }; typedef struct Vector Vector ; typedef struct { struct Vector *L; int n; Long np, NP_max; } DYN_PPL; void part_nef(PolyPointList *, VertexNumList *, EqList *, PartList *, int *, NEF_Flags *); void Make_E_Poly(FILE *, CWS *, PolyPointList *, VertexNumList *, EqList *, int *, Flags *, int *); void Mink_WPCICY(AmbiPointList * _AP_1, AmbiPointList * _AP_2, AmbiPointList * _AP); int IsDigit(char); int IntSqrt(int q); void Die(char *); void Print_CWS_Zinfo(CWS *); void AnalyseGorensteinCone(CWS *_CW, PolyPointList *_P, VertexNumList *_V, EqList *_E, int *_codim, Flags * _F); palp-2.21/Mori.h0000664000177600017760000001224614572603263013032 0ustar skarkeskarke/* =========================================================== */ /* === === */ /* === M o r i . h === */ /* === === */ /* === Authors: Maximilian Kreuzer, Nils-Ole Walliser === */ /* === Last update: 19/03/12 === */ /* === === */ /* =========================================================== */ /* ======================================================== */ /* ========= D E F I N I T I O N s ========= */ /*** local for Moricone.c ***/ #define Inci64 unsigned long long /* ====================================================== */ /* ========= T Y P E D E F s ========= */ /*** from mori.c ***/ typedef struct { int FilterFlag, g, m, P, K, i, t, c, d, a, b, D, H, I, M, Read_HyperSurfCounter; } MORI_Flags; /* List of flags that correspond to the options of mori.x -h for more info plus Read_HyperSurfCounter. The latter controls if an hypersurface class has been inserted (option -H). Avoids to type the hyper class each time that HyperSurfSingula() is called. HyperSurfSingular() is called for each triangulation of the polytope. */ /*** from Moricone.c ***/ typedef struct { int d, v, n, nmax; Inci64 *I; } triang; /* INCIDENCE structure needed for Triangulation and SR-ideal data d: dimension of the lattice polytope v: number of digits in an INCIDENCE n: number of INCIDENCES nmax: max number of n I: INCIDENCE, (Inci64: unsigned long long) */ /* ====================================================== */ /* ========= P R O T O T Y P E s ========= */ /*** from MoriCone.c ***/ void TriList_to_MoriList(PolyPointList *_P, FibW *F, MORI_Flags * _Flag); /* Having read the Polytope matrix, asks for the triangulation and computes SR-Ideal and Mori cone of the ambient space. The user has to specify the number of triangulations, the number of simplices and insert the simplices in INCI format. */ void HyperSurfDivisorsQ(PolyPointList *_P,VertexNumList*V,EqList *E, MORI_Flags *Flag); /* Hypersurface divisors Q(charges) permutes the N-lattice points of non-intersecting divisors to the end of the PPL *_P, calls IP_Simplex_Fiber and then prints the charges = linear relations. */ void Subdivide(PolyPointList *P,int v,Inci64 I[],int p,Inci64 *T,int *t, MORI_Flags *_Flag, FibW *F); /* Triangulate and call InterSectionRing. Incidences of ni=*t bounding equations on I[]; subdivide -> T[*t]; assuming 4 dimensions and at most 3 non-vertices, etc.; triangulate and call InterSectionRing(T,t,P,p...). For each T[] if simplicial add <=3 pts by hand else use GKZ for <= 3d secondary fan. */ void GKZsubdivide(Inci64 *F,int f,PolyPointList *P,int p,int *Tp,int *ntp, int nPS, MORI_Flags *_Flag, FibW *_F ); /* List maximal 2ndary fans of facets with descending dimensions for all compatible max triangulations make (induced) triangulation of facets. Depending in dim of the 2ndary fan triangulates circuits calling either Triang1dSFan(), Triang2dSFan() or Triang2dSFan(). If dim (2ndary fan) > 3 then exit(0); */ void InterSectionRing(Inci64 *Tri,int *t,PolyPointList *P, int p, MORI_Flags *_Flag, FibW *F); /* Print triangulation and call StanleyReisner(SR,T). Call HyperSurfaceSingular(P,T,SR...). Call Print_Mori(P,p,t,Tri). */ void StanleyReisner(triang *SR,triang *T); /* Determine and print the SR ideal. */ void DivClassBasis(int SF,PolyPointList *P,int v,char *D,char *B); /* Find basis for divisor classes, i.e. integral basis of intersection ring. Simply trying to find toric divisors that span the lattice of DivClasses i.e. find subdeterminants=volumes=1 for elimination. */ /* ====== typedefs and functions related to INCIDENCEs ====== */ Inci64 makeN(int N); void putN(int N,Inci64 *I); /* make INCIDENCE */ void setN(int N,Inci64 *I); /* make INCIDENCE */ int getN(int N,Inci64 I); /* read INCIDENCE */ void prnI(int N,Inci64 I); /* print INCIDENCE */ void fprI(int N,Inci64 I); /* print INCIDENCE to file */ int Inci64_LE(Inci64 A,Inci64 B); int Inci64_LT(Inci64 A,Inci64 B); void PRNtriang(triang *SR,const char *c); /* print (Inci64) triangulation */ /*** from SingularInput.c ***/ void HyperSurfSingular(PolyPointList *P,triang *T, triang *SR ,MORI_Flags *_Flag , FibW *F, int *cp); /* Interface between the Mori and SINGULAR. Given the polytope P and the linear relations among their points, the triangulation T and the SR ideal it generates the the input for SINGULAR. */ /*======== dependences from other modules ======== */ /*** from Polynf.c ***/ void IP_Simplex_Fiber(Long PM[][POLY_Dmax], int p, int d, /* need PM[i]!=0 */ FibW *F, int Wmax, int CD); /* It analyzes the IP simplices among (1 <= codim <= CD) points of P*. Given the matrix CM of coordinates of p points in Z^d, the list W[i] of *nw weight systems corresponding to IP-simplices spanned by the points in CM is created. If codim!=0 only the IP-simplices with dimension > 1 and codimension between 1 and codim are computed. It is assumed that p<=VERT_Nmax and that W can hold at least Wmax sets of coefficients. */ Long SimplexVolume(Long *V[POLY_Dmax+1],int d); palp-2.21/poly.c0000664000177600017760000002314314572603263013100 0ustar skarkeskarke/* ====================================================================== */ /* ========== ========== */ /* ========== P O L Y . C ========== */ /* ========== ========== */ /* ====================================================================== */ /* * Coord get coordinates by reading them or converting weight input * Rat rational functions * Vertex computes Vertices and Faces * Polynf normal form and symmetries */ #include "Global.h" #include "LG.h" #define OSL (42) /* opt_string's length */ FILE *inFILE, *outFILE; void PrintUsage(char *c){ int i; char *opt_string[OSL]={ "h print this information ", "f use as filter ", "g general output: ", " P reflexive: numbers of (dual) points/vertices, Hodge numbers ", " P not reflexive: numbers of points, vertices, equations ", "p points of P ", "v vertices of P ", "e equations of P/vertices of P-dual", "m pairing matrix between vertices and equations ", "d points of P-dual (only if P reflexive) ", "a all of the above except h,f ", "l LG-`Hodge numbers' from single weight input ", "r ignore non-reflexive input ", "o ignore non-IP input ", "q quick version of og, incompatible with other options", "Q like 'q', with statistics on weights for 5d classification", "D dual polytope as input (ref only)", "n do not complete polytope or calculate Hodge numbers ", "i incidence information ", "s check for span property (only if P from CWS) ", "I check for IP property ", "S number of symmetries ", "T upper triangular form ", "N normal form ", "t traced normal form computation ", "V IP simplices among vertices of P*", "P IP simplices among points of P* (with 1<=codim<=# when # is set)", "Z lattice quotients for IP simplices", "# #=1,2,3 fibers spanned by IP simplices with codim<=# ", "## ##=11,22,33,(12,23): all (fibered) fibers with specified codim(s) ", " when combined: ### = (##)# ", "A affine normal form", "B Barycenter and lattice volume [# ... points at deg #]", "F print all facets", "G Gorenstein: divisible by I>1", "L like 'l' with Hodge data for twisted sectors", "U simplicial facets in N-lattice", "U1 Fano (simplicial and unimodular facets in N-lattice)", "U5 5d fano from reflexive 4d projections (M lattice)", "C1 conifold CY (unimodular or square 2-faces)", "C2 conifold FANO (divisible by 2 & basic 2 faces)", "E symmetries related to Einstein-Kaehler Metrics"}; puts(""); printf("This is '%s': computing data of a polytope P\n",c); printf("Usage: %s [-] [in-file [out-file]]\n", c); puts(""); printf("Options (concatenate any number of them into ):\n"); for (i=0;inw=0; while(narg > ++n) { if(fn[n][0]!='-') break; k=0; while ((c=fn[n][++k])!='\0'){ if(c=='A') A=1; else if(c=='B') B=1; else if(c=='F') F=1; else if(c=='G') G=1; else if(c=='L') lg=2; else if(c=='U') U=1; else if(c=='C') U=2; else if(c=='E') Einstein=1; else if(c=='h') { PrintUsage(fn[0]); exit(0);} else if(c=='f') FilterFlag=1; else if(c=='g') g=1; else if(c=='l') lg=1; else if(c=='s') s=1; else if(c=='i') i=1; else if(c=='I') I=1; else if(c=='m') m=1; else if(c=='p') p=1; else if(c=='v') v=1; else if(c=='e') e=1; else if(c=='d') d=1; else if(c=='t') t=1; else if(c=='S') S=1; else if(c=='N') N=1; else if(c=='T') T=1; else if(c=='r') r=1; else if(c=='o') o=1; else if(c=='q') q=1; else if(c=='Q') Q=1; else if(c=='n') nc=1; else if(c=='P') PS=1; else if(c=='V') VS=1; else if(c=='Z') ZS=-1; else if(c=='z') z=1; else if(c=='D') D=1; else if(('0'<=c)&&(c<='9')) CD=10*CD+c-'0'; else if(c=='a') {g=1; m=1; p=1; v=1; e=1; d=1; } else {printf("Unknown option '-%c'; use -h for help\n",c); exit(0);}}} n--; if(s+i+I+m+p+v+e+d+t+S+N+T+PS+VS+CD+G+A+B+F+z==0) g=1; VH.sts=(lg==2); if ((U==1)&&(CD==1)&&(s+i+I+m+p+v+e+d+t+S+N+T+PS+VS+G+A+B+F+z==0)) g=1; if(g+lg+p+d+PS+CD==0) nc=1; /* don't need completion of points */ if((T==1)&&(B+U+lg+g+s+i+I+m+p+v+e+d+t+S+N+PS+VS+(1-ZS)==0)){ puts( "\n-T: Please specify desired output, e.g. via -v or -p \n");exit(0);} if(FilterFlag) {inFILE=NULL; outFILE=stdout;} else { if (narg > ++n) inFILE=fopen(fn[n],"r"); else inFILE=stdin; if (inFILE==NULL){printf("Input file %s not found!\n",fn[n]);exit(0);} if (narg > ++n) outFILE=fopen(fn[n],"w"); else outFILE=stdout; } if(U) {dd=CD; CD=0; if((U==2)||(dd==5)) nc=0;} if(i){ FI=(FaceInfo *) malloc(sizeof(FaceInfo)); if (FI==NULL) {puts("Unable to allocate space for FaceInfo FI"); exit(0);}} if(Q) Initialize_C5S(&C5S, POLY_Dmax); // Initialize statistics if(Einstein) Einstein_Metric(CW,_P,&V,E); while(lg ? Read_W_PP(&W,_P) : Read_CWS_PP(CW,_P)) { if(q||Q) { FaceInfo FI; if(!QuickAnalysis(_P, &BH, &FI)) {if(Q) C5S.n_nonIP++; continue;} //non-IP Print_CWH(CW, &BH); if(Q) Update_C5S(&BH, FI.nf, CW->W[0], &C5S); continue;} if(T) { if (CW->nw) { puts("Please do not use weight input with the -T option"); continue;} else Make_Poly_UTriang(_P);} R=0; if ((IP=Find_Equations(_P,&V,E))){ if (D){ int k; *_DP=*_P; R=EL_to_PPL(E, _P, &_P->n); VNL_to_DEL(_DP, &V, E); for (k=0;k<_P->np;k++) V.v[k]=k; V.nv=_P->np; } else R=EL_to_PPL(E, _DP, &_P->n);} else if (o&&!IP) continue; if (D&&!R) {fprintf(outFILE,"Input not reflexive!\n"); continue;} if (r&&!R) continue; Sort_VL(&V); Make_VEPM(_P,&V,E,*PM); if(!nc) { if(D||!(lg||CW->nw)) Complete_Poly(*PM,E,V.nv,_P); if(R&&!(D&&(lg||CW->nw))) { if(0==Transpose_PM(*PM, *DPM, V.nv, E->ne)) { fprintf(stderr,"Transpose_PM failed because #eq=%d > VERT_Nmax\n", E->ne);exit(0);} VNL_to_DEL(_P, &V, DE); Complete_Poly(*DPM,DE,E->ne,_DP);}} if (U==1) { if(dd==5) {if(!Fano5d(_P,&V,E)) continue;} else if(!SimpUnimod(_P,&V,E,dd)) continue; } if (U==2) { VNL_to_DEL(_P,&V,DE); if(!ConifoldSing(_P,&V,E,_DP,DE,dd)) continue;} if(g){ if(!R||nc) {BH.mp=_P->np; BH.mv=V.nv; BH.np=0; BH.nv=E->ne;} else RC_Calc_BaHo(_P,&V,E,_DP,&BH); if(lg) { if ((Tr=Trans_Check(W))) LGO_VaHo(&W,&VH); Write_WH(&W, &BH, &VH, R, Tr, _P, &V, E); } else Print_CWH(CW, &BH); } if(s&&CW->nw) if(!Span_Check(E,&(CW->B),&_P->n)) fprintf(outFILE,"No Span\n"); if(I && !IP) fprintf(outFILE,"No IP\n"); if(p) Print_PPL(_P,"Points of P"); if(v) Print_VL(_P, &V, "Vertices of P"); if(e) Print_EL(E, &_P->n, R, (R ? "Vertices of P-dual <-> Equations of P" : "Equations of P")); if(i){Make_Incidence(_P,&V,E,FI); Print_FaceInfo(_P->n,FI);} if(m) Print_Matrix(*PM, E->ne, V.nv, "Pairing matrix of vertices and equations of P"); if(d&&(_DP->np>E->ne)) Print_PPL(_DP, "Points of P-dual"); if(S||N||t){ int SymNum /*, VPMSymNum*/; Long NF[POLY_Dmax][VERT_Nmax]; VPermList *VP = (VPermList*) malloc(sizeof(VPermList)); assert(VP!=NULL); /* VPMSymNum=*/ Make_Poly_Sym_NF(_P, &V, E, &SymNum, VP->p, NF, t, S, N); free(VP);} if(R&&(PS||VS||CD)) IP_Simplices(_DP, (!D)*E->ne, PS*ZS, VS*ZS, CD); if(G) { char divi[99]; Long g=Divisibility_Index(_P,&V); if(g>1){sprintf(divi,"divisible by factor=%ld",g); Print_VL(_P,&V,divi);}} if(B) { Long vB[POLY_Dmax],Z; int j; Long vol=LatVol_Barycent(_P,&V,vB,&Z); printf("vol=%ld, baricent=(",vol); for(j=0;j<_P->n;j++) printf("%s%ld",j?",":"",vB[j]); printf(")/%ld\n",Z); if(CD) IPs_degD(_P,&V,E,CD);} if(F) { int j, cc; Long VM[POLY_Dmax][VERT_Nmax]; for (j=0; jne; j++){ Make_Facet(_P, &V, E, j, VM, &cc); Print_Matrix(VM,_P->n-1,cc,"");} } if(A) { Long ANF[POLY_Dmax][VERT_Nmax]; Make_ANF(_P,&V,E,ANF); Print_Matrix(ANF, _P->n, V.nv,"Affine normal form");} fflush(outFILE); } if(Q) Print_C5S(&C5S); return 0; } palp-2.21/Coord.c0000664000177600017760000010034514572603263013163 0ustar skarkeskarke#include "Global.h" #include "Rat.h" #undef TEST_Wbase #undef USE_Old_Wbase #define NO_COORD_IMPROVEMENT /* switch off weight permutation */ typedef struct {Long x[AMBI_Dmax][AMBI_Dmax]; int n, N;} CWLatticeBasis; void Make_CWS_Points(CWS *_C, PolyPointList *_P); void Make_RGC_Points(CWS *Cin, PolyPointList *_P); void CWS_to_PermCWS(CWS *Cin, CWS *C, int *pi); /* ========== I/O functions: ========== */ int IsNextDigit(void){ char c; c=fgetc(inFILE); ungetc(c,inFILE); if(c=='0') return -1; if((c<'0') || ('9'np>20){ fprintf(outFILE,"%d %d %s\n",_P->np,_P->n,comment); for(i=0;i<_P->np;i++) { for(j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) _P->x[i][j]); fprintf(outFILE,"\n");}} else { fprintf(outFILE,"%d %d %s\n",_P->n,_P->np,comment); for(i=0;i<_P->n;i++) { for(j=0;j<_P->np;j++) fprintf(outFILE," %4d",(int) _P->x[j][i]); fprintf(outFILE,"\n");}} } void Print_VL(PolyPointList *_P, VertexNumList *_V, const char *comment){ int i,j; if(_V->nv>20){ fprintf(outFILE,"%d %d %s\n",_V->nv,_P->n,comment); for(i=0;i<_V->nv;i++) { for(j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) _P->x[_V->v[i]][j]); fprintf(outFILE,"\n");}} else { fprintf(outFILE,"%d %d %s\n",_P->n,_V->nv,comment); for(i=0;i<_P->n;i++) { for(j=0;j<_V->nv;j++) fprintf(outFILE," %4d",(int) _P->x[_V->v[j]][i]); fprintf(outFILE,"\n");}} } void Print_EL(EqList *_E, int *n, int suppress_c, const char *comment){ int i,j; fprintf(outFILE,"%d %d %s\n",_E->ne,*n,comment); for(i=0;i<_E->ne;i++) { for(j=0;j<*n;j++) fprintf(outFILE," %3d",(int) _E->e[i].a[j]); if (!suppress_c) fprintf(outFILE," %5d",(int) _E->e[i].c); fprintf(outFILE,"\n");} } void Print_Matrix(Long Matrix[][VERT_Nmax], int n_lines, int n_columns, const char *comment){ int i,j; fprintf(outFILE,"%d %d %s\n",n_lines, n_columns, comment); for(i=0;inw) for(i=0;inz;i++) { fprintf(outFILE,"/Z%d: ",CW->m[i]); for(j=0;jN;j++) fprintf(outFILE,"%d ",CW->z[i][j]); } } int Read_CWS_Zinfo(FILE *inFILE,CWS *CW) /* return !EOF */ { int *nz=&CW->nz; int i=0,n; char c[999],b=' '; *nz=0; for(n=0;n<999;n++) { c[n]=fgetc(inFILE); if(feof(inFILE)) return 0; if(c[n]=='\n') break; } if(n==999) {puts("Out of space in Read_CWS_Zinfo");exit(0);} while(c[i]==b)i++; if((c[i]=='=')&&(c[i+1]=='d'))i+=2; while(c[i]==b)i++; /* printf("Read_CWS_Zinfo n=%d -> ",n); {int I; for(I=0;Im[*nz]))) { if(c[i+j]!=':') CWSZerror(":"); else {i+=j+1; while(c[i]==b)i++;} for(k=0;kN;k++) { if((j=auxString2Int(&c[i],&CW->z[*nz][k]))) {if((j)) i+=j; else CWSZerror("missing");} /* ????? */ } s=0; for(k=0;kN;k++) s+=CW->z[*nz][k]; /* if(s % CW->m[*nz]) CWSZerror("det!=1"); */ (CW->nz)++; } else CWSZerror("Order"); } return 1; } void checkDimension(int polyDim, int codim, int index){ if (index == 1){ if (POLY_Dmax < (polyDim + codim - 1)){ if (codim > 1){ printf("Please increase POLY_Dmax to at least %d = %d + %d - 1\n", (polyDim + codim - 1), polyDim, codim); printf("(POLY_Dmax >= dim N + codim - 1 is required)\n");} else printf("Please increase POLY_Dmax to at least %d\n", polyDim); exit(0); }} else if (POLY_Dmax < polyDim +1){ printf("Please increase POLY_Dmax to at least %d = %d + 1\n", (polyDim + 1), polyDim); printf("(option -G requires POLY_Dmax >= dim(cone) = dim(support) + 1)\n" ); exit(0);} } int ReadCwsPp(CWS *_CW, PolyPointList *_P, int codim, int index) /* _P is always an M-lattice polytope codim = 1, index = 1: CY hypersurface codim > 1, index = 1: _P reflexive, CICY with codimension codim codim = 1, index > 1: _P a Gorenstein polytope with index index, determines a reflexive Gorenstein cone */ { int i, j, FilterFlag=(inFILE==NULL); int IN[AMBI_Dmax*(AMBI_Dmax+1)], S; static int InputOK; _CW->nw=_CW->N=_CW->nz=0; _CW->index = index; if(FilterFlag) inFILE=stdin; else if(inFILE==stdin) { puts("Degrees and weights `d1 w11 w12 ... d2 w21 w22 ...'"); puts(" or `#lines #columns' (= `PolyDim #Points' or `#Points PolyDim'):");} for(i=0;iIN[1]) {tr=IN[0];IN[0]=IN[1];IN[1]=tr;} tr=!tr; checkDimension(IN[0], codim, index); if(IN[1]>POINT_Nmax) {puts("Please increase POINT_Nmax"); exit(0);} if((inFILE==stdin)&&!FilterFlag) printf("Type the %d coordinates as %s=%d lines with %s=%d columns:\n", IN[0]*IN[1], tr ? "dim" : "#pts", tr ? IN[0] : IN[1], tr ? "#pts" : "dim", tr ? IN[1] : IN[0]); _P->n=IN[0]; _P->np=IN[1]; /* allow all numbers in one string (distributed over lines) or * matrix blocks with trailing comments */ if(tr) for(i=0;ix[j][i]=X; } else for(i=0;ix[i][j]=X; } /* Finish_Poly_Points(_P); */ while(fgetc(inFILE )-'\n') if(feof(inFILE)) return 0;/* read to EOL */ if(FilterFlag) inFILE=NULL; return 1; } /* End of reading PolyPointList */ assert(i!=3); S=IN[i-1]; for(j=0;jnw=1; _CW->d[0]=S; _CW->N=i-1; assert(_CW->N <= POLY_Dmax+1); /* Increase POLY_Dmax */ for(j=0;j<_CW->N;j++) {_CW->W[0][j]=IN[j]; assert(IN[j]>0);} goto MAP; } _CW->d[0] = IN[0]; /* ASSIGN (COMBINED) WEIGHTS */ S = IN[0] * index; for(j=1; jd[++(_CW->nw)]=IN[j]; S = IN[j] * index; if(1==_CW->nw) { if(i%(1+_CW->N)) {puts("INPUT error: numbers?"); exit(0);} } if(j%(1+_CW->N)) {puts("INPUT error: degrees?"); exit(0);} } } else { _CW->W[_CW->nw][j - 1 - (1 + _CW->N)*_CW->nw] = IN[j]; S-=IN[j]; if(0==_CW->nw) if(++(_CW->N)>AMBI_Dmax) { puts("Increase AMBI_Dmax!"); exit(0); } } } ++(_CW->nw); checkDimension(_CW->N - _CW->nw, codim, index); MAP: for(i=0;i<_CW->nw;i++) /* check consistency of CWS */ { Long sum = _CW->d[i] * index, *w = _CW->W[i]; for(j=0;j<_CW->N;j++) { assert(w[j]>=0); sum-=w[j]; } if((sum)&&(index==1)){ printf("Use option -l for (single) WeightSystems with "); printf("d!=\\sum(w)\n(only Read_Weight makes the correct "); puts("PolyPointList in that case)"); exit(0);} } _CW->nz=0; if(!Read_CWS_Zinfo(inFILE,_CW)) /* read Z to EOL */ { if(!InputOK) puts("-h gives you help\n"); return 0;} Make_CWS_Points(_CW, _P); if(FilterFlag) inFILE=NULL; return 1; } int Read_CWS_PP(CWS *_CW, PolyPointList *_P){ return ReadCwsPp(_CW, _P, 1, 1); } int Read_PP(PolyPointList *_P) { int i, j, FilterFlag=(inFILE==NULL); int IN[AMBI_Dmax*(AMBI_Dmax+1)]; static int InputOK; /* _CW->nw=_CW->N=_CW->nz=0; */ if(FilterFlag) inFILE=stdin; else if(inFILE==stdin) { printf("`#lines #columns' (= `PolyDim #Points' or `#Points PolyDim'):\n"); }; for(i=0;iIN[1]) {tr=IN[0];IN[0]=IN[1];IN[1]=tr;} tr=!tr; if(IN[0]>POLY_Dmax) {puts("increase POLY_Dmax!"); exit(0);} if(IN[1]>POINT_Nmax) {puts("increase POINT_Nmax!"); exit(0);} if((inFILE==stdin)&&!FilterFlag) printf("Type the %d coordinates as %s=%d lines with %s=%d columns:\n", IN[0]*IN[1], tr ? "dim" : "#pts", tr ? IN[0] : IN[1], tr ? "#pts" : "dim", tr ? IN[1] : IN[0]); _P->n=IN[0]; _P->np=IN[1]; /* allow all numbers in one string (distributed over lines) or * matrix blocks with trailing comments */ if(tr) for(i=0;ix[j][i]=X; } else for(i=0;ix[i][j]=X; } /* Finish_Poly_Points(_P); */ while(fgetc(inFILE )-'\n') if(feof(inFILE)) return 0;/* read to EOL */ if(FilterFlag) inFILE=NULL; return 1; } if(i>2){puts("Error: expected input format is matrix of polytope points!");exit(0);} if(FilterFlag) inFILE=NULL; return 1; } int Read_CWS(CWS *_CW, PolyPointList *_P) { int i, j, FilterFlag=(inFILE==NULL); int IN[AMBI_Dmax*(AMBI_Dmax+1)], S; static int InputOK; _CW->nw=_CW->N=_CW->nz=0; _CW->index = 1; if(FilterFlag) inFILE=stdin; else if(inFILE==stdin) { printf("Degrees and weights `d1 w11 w12 ... d2 w21 w22 ...':\n"); }; for(i=0;inw=1; _CW->d[0]=S; _CW->N=i-1; assert(_CW->N <= POLY_Dmax+1); /* Increase POLY_Dmax */ for(j=0;j<_CW->N;j++) {_CW->W[0][j]=IN[j]; assert(IN[j]>0);} goto MAP; } S=_CW->d[_CW->nw]=IN[0]; /* ASSIGN WEIGHTS */ for(j=1; jd[++(_CW->nw)]=IN[j]; if(1==_CW->nw) { if(i%(1+_CW->N)) {puts("INPUT error: numbers?"); exit(0);} } if(j%(1+_CW->N)) {puts("INPUT error: degrees?"); exit(0);} } } else { _CW->W[_CW->nw][j - 1 - (1 + _CW->N)*_CW->nw] = IN[j]; S-=IN[j]; if(0==_CW->nw) if(++(_CW->N)>AMBI_Dmax) { puts("Increase AMBI_Dmax!"); exit(0); } } } ++(_CW->nw); if(_CW->N-_CW->nw > POLY_Dmax){ printf("Please increase POLY_Dmax to at least %d\n", _CW->N-_CW->nw); exit(0);} /* increase POLY_Dmax */ MAP: for(i=0;i<_CW->nw;i++) /* check consistency of CWS */ { Long sum=_CW->d[i], *w=_CW->W[i]; for(j=0;j<_CW->N;j++) { assert(w[j]>=0); sum-=w[j]; } if(sum){ /*printf("Use poly.x -w for (single) WeightSystems with "); printf("d!=\\sum(w)\n(only Read_Weight makes the correct "); puts("PolyPointList in that case)"); exit(0);*/ printf("cannot handle (single) WeightSystems with "); printf("d!=\\sum(w)\n"); exit(0);}} _CW->nz=0; if(!Read_CWS_Zinfo(inFILE,_CW)) /* read Z to EOL */ { if(!InputOK) puts("-h gives you help\n"); return 0;} Make_CWS_Points(_CW, _P); /* now make POLY */ if(FilterFlag) inFILE=NULL; return 1; } void Print_CWH(CWS *_W, BaHo *_BH){ int i, j; for(i=0;i<_W->nw;i++) { fprintf(outFILE,"%d ",(int) _W->d[i]); for(j=0;j<_W->N;j++) fprintf(outFILE,"%d ",(int) _W->W[i][j]); if(i+1<_W->nw) fprintf(outFILE," "); } Print_CWS_Zinfo(_W); if(_BH->np) { fprintf(outFILE,"M:%d %d N:%d %d",_BH->mp,_BH->mv,_BH->np,_BH->nv); if (_BH->n == 3) fprintf(outFILE," Pic:%d Cor:%d",_BH->pic, _BH->cor); if (_BH->n > 3) { fprintf(outFILE," H:%d",_BH->h1[1]); for(i=2;i<_BH->n-1;i++) fprintf(outFILE,",%d",_BH->h1[i]); if(_BH->n==4) fprintf(outFILE," [%d]",2*(_BH->h1[1]-_BH->h1[2])); if(_BH->n==5) fprintf(outFILE," [%d]",48+6*(_BH->h1[1]-_BH->h1[2]+_BH->h1[3]));}} else if(_BH->mp) fprintf(outFILE,"M:%d %d F:%d",_BH->mp,_BH->mv,_BH->nv); else fprintf(outFILE,"V:%d F:%d",_BH->mv,_BH->nv); fprintf(outFILE,"\n"); } /* ========== END of I/O functions ========== */ /* ========== Solve W-Eq. -> triangular LatticeBasis * * B[0]:= (-n1, n0, 0, ...) / GCD(n0,n1); * B[i]:= (0,...,0,g/G,0,...)- (ni/G) * ExtGCD.K(n0,...,n(i-1),0,...); * with g=GCD(n0,...,n[i-1]); G=GCD(g,ni); * * CWS by iteration: NextWeight=W[]*B; NewB=Basis(NextW); B[i+1]=B[i]*NewB; * */ void PrintBasis(CWLatticeBasis *_B) { int i,j; puts("Basis:"); for(i=0;i<_B->n;i++) { for(j=0;j<_B->N;j++) fprintf(outFILE,"%6d ",(int) _B->x[i][j]); puts(""); } puts("End of Basis - -"); } void Orig_Solve_Next_WEq(Long *NW, CWLatticeBasis *_B) { int i, j, P=0, p[AMBI_Dmax]; Long W[AMBI_Dmax], G; _B->n=_B->N-1; for(i=0;i<_B->N;i++) { for(j=0;j<_B->n;j++) _B->x[j][i]=0; /* init B.x=0 */ if(NW[i]) {p[P]=i; W[P++]=NW[i];} /* non-zero weights */ } if(P<2) puts("need two non-zero weights in >>Solve_Next_WEq<<"); for(i=0;ix[i][i]=1; while((++i)x[i-1][i]=1; G=Fgcd(W[0],W[1]); if(W[0]/G<0) G=-G; _B->x[i-1][p[0]]=-W[1]/G; _B->x[i-1][p[1]]=W[0]/G; j=2; while(++i<_B->N) { if(NW[i]) { int k; Long *X=_B->x[i-1], K[AMBI_Dmax], g=REgcd(W, &j, K); G=Fgcd(g,NW[i]); if(g/G<0) G=-G; X[i]= g/G; g=W[j]/G; for(k=0;kx[i-1][i]=1; } } void Solve_Next_WEq(Long *NW, CWLatticeBasis *_B) { Long W[AMBI_Dmax], *X[AMBI_Dmax], GLZ[AMBI_Dmax][AMBI_Dmax]; int i, j, P=0, p[AMBI_Dmax]; _B->n=_B->N-1; #ifdef TEST_Wbase Orig_Solve_Next_WEq(NW,_B); PrintBasis(_B); #endif for(i=0;i<_B->N;i++) { for(j=0;j<_B->n;j++) _B->x[j][i]=0; /* init B.x=0 */ if(NW[i]) {p[P]=i; X[P]=GLZ[P]; W[P++]=NW[i];} /* non-zero weights */ } if(P>1) W_to_GLZ(W,&P,X); /* P>1, compute GLZ */ else {/* printf("P=%d W[0]=%d for W_to_GLZ\n",P,W[0]);exit(0);*/assert(P); for(i=0;ix[i][i]=1; while((++i)<_B->N)_B->x[i-1][i]=1; return; } for(i=1;ix[i][i]=1; while((++i)x[i-1][i]=1; _B->x[i-1][p[0]]=X[1][0]; _B->x[i-1][p[1]]=X[1][1]; j=2; while(++i<_B->N) { if(NW[i]) { int k; Long *B=_B->x[i-1]; for(k=0;k<=j;k++) B[p[k]]=X[j][k]; j++; } else _B->x[i-1][i]=1; } #ifdef TEST_Wbase /* for(i=0;i<_B->N;i++)printf("%d ",NW[i]);puts("=NW");for(i=0;iN=_C->N; Solve_Next_WEq(_C->W[0],_B); for(i=1;i<_C->nw;i++){ for(j=0;j<_B->n;j++){ W[j]=0; for(k=0;k<_B->N;k++) W[j]+=_C->W[i][k]*_B->x[j][k]; } NB.N=_B->n; Solve_Next_WEq(W,&NB); AuxB.n=NB.n; for(j=0;jx[l][j]; } *_B=AuxB; } /* init coordinate hyperplanes */ _C->B.ne=_B->N; /* == transposed of Basis */ for(i=0;i<_B->N;i++) { for(j=0;j<_B->n;j++) _C->B.e[i].a[j]=_B->x[j][i]; _C->B.e[i].c=1;} } void Poly_To_Ambi(CWLatticeBasis *_B, Long *x, Long *X) { int i, j; for(i=0;i<_B->N;i++) { X[i]=1; for(j=0;j<_B->n;j++) X[i] += _B->x[j][i] * x[j]; } } /* B.x[i][A] is lower triangular: zero for i

N-C->nw; Long Z[POLY_Dmax][VERT_Nmax]; *m=C->nz; for(i=0;inz;i++){ M[i]=C->m[i]; for(j=0;jN;k++) Z[i][j]+=C->z[i][k]*B->x[j][k];} } /* PrintBasis(B); */ QuotZ_2_SublatG(Z,m,M,&d,G); } void Reduce_PPL_2_Sublat(PolyPointList *P,int *nm,Long *M,Long G[][POLY_Dmax]) { int i,j,n=0,N; for(N=0;Nnp;N++) { Long X[POLY_Dmax]; for(i=0;in;i++) { X[i]=0; for(j=0;jn;j++) X[i]+=G[i][j]*P->x[N][j]; } for(i=0;i<*nm;i++) if(X[i]%M[i]) break; if(i<*nm) continue; for(i=0;i<*nm;i++) P->x[n][i]=X[i]/M[i]; for(i=*nm;in;i++) P->x[n][i]=X[i]; n++; } P->np=n; /* Print_PPL(P,"");printf("nm=%d\n",*nm); */ } Long PD_Floor(Long N,Long D) /* assuming PosDenom D>0: F <= N/D < F+1 */ { Long F=N/D; return (F*D>N) ? F-1 : F; } void Old_Make_CWS_Points(CWS *Cin, PolyPointList *_P) { int i, j, Amin[POLY_Dmax+1]; Long *x=_P->x[_P->np=0], xmin[POLY_Dmax], xmax[POLY_Dmax], Xmax[AMBI_Dmax], xaux[POLY_Dmax], L, R; CWS *_C=Cin; CWLatticeBasis B; Long G[POLY_Dmax][POLY_Dmax],M[POLY_Dmax];int m=Cin->nz; #ifndef NO_COORD_IMPROVEMENT /* ==== Perm Coord Improvement ==== */ int pi[AMBI_Dmax]; CWS Caux; _C=&Caux; CWS_to_PermCWS(Cin,_C, pi); #endif /* = End of Perm Coord Improvement = */ Make_CWS_Basis(_C, &B); /* make `triangular' Basis */ #ifndef NO_COORD_IMPROVEMENT /* ==== Perm Coord Improvement ==== */ assert(_C->N==_C->B.ne); for(i=0;iN;i++) Cin->B.e[i]=_C->B.e[pi[i]]; Cin->B.ne=_C->N; #endif /* = End of Perm Coord Improvement = */ i=_P->n=B.n; Amin[0]=0; Amin[B.n]=j=B.N; /* inversion structure */ while(--i) {while(!B.x[i-1][--j]); Amin[i]=++j;} for(i=0;inw;j++) if(_C->W[j][i]) { L=_C->d[j]/_C->W[j][i]; if(Xmax[i]) {if(L 0 */ /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ while((i--)>Amin[j]) /* if(R=B.x[B.n-1][i]): R!=0 => new limits */ { Long Low=-1, Upp=Low+Xmax[i]; R=B.x[B.n-1][i]; if(R>0) {if(xmax[j]>(L=PD_Floor(Upp,R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(-Low,R))) xmin[j]=L;} else {if(xmax[j]>(L=PD_Floor(-Low,-R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(Upp,-R))) xmin[j]=L;} /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ } /* this completes the limits for x[B.n-1] */ x[j]=xmin[j]; while(jxmax[j]) {if(B.n==(++j)) break; else x[j]++;} else /* compute limits[j-1] and initialize x[j-1] */ { Long Low=-1, Upp=Xmax[i=Amin[j--]-1]; int RangeFlag=0; for(k=j+1;kAmin[j]) if((R=B.x[j][i])) /* R!=0 => new limits */ { Low=-1; Upp=Xmax[i]; for(k=j+1;k0) {if(xmax[j]>(L=PD_Floor(Upp,R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(-Low,R))) xmin[j]=L;} else {if(xmax[j]>(L=PD_Floor(-Low,-R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(Upp,-R))) xmin[j]=L;} /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ } /* completes limits for x[] except */ else /* when R=0 and X out of Range: */ { Long X=1; for(k=j+1;kXmax[i])) RangeFlag=1; } if(RangeFlag) ++x[++j]; else x[j]=xmin[j]; if(j==0) { while(x[0]<=xmax[0]) { Long *y; if((++_P->np) < POINT_Nmax) { y=(_P->x[_P->np]); for(k=0;knp == POINT_Nmax) { y=xaux; for(k=0;knw;j++) if(_C->W[j][0]){ if (_C->d[j]%_C->W[j][N]) return 0; if(Xmax) {if (Xmax != _C->d[j]/_C->W[j][N]) return 0;} else Xmax = _C->d[j]/_C->W[j][N]; } else if(_C->d[j]) return 0; X0[0] = Xmax; return 1;} for(j=0;j<_C->nw;j++) if(_C->W[j][N]!=0){ Long L=_C->d[j]/_C->W[j][N]; if(Xmax) {if(Lnw; j++) _C->d[j] += X0[N] * _C->W[j][N]; /* reset Cin*/ return 1;} for(j=0; j<_C->nw; j++) _C->d[j] -= _C->W[j][N];} for(j=0; j<_C->nw; j++) _C->d[j] += (Xmax + 1) * _C->W[j][N]; /* reset Cin */ return 0; } void Make_CWS_Points(CWS *Cin, PolyPointList *_P) { int i, j, Amin[POLY_Dmax+1], m=Cin->nz; Long *x=_P->x[_P->np=0], xmin[POLY_Dmax], xmax[POLY_Dmax], Xmax[AMBI_Dmax], X0[AMBI_Dmax], xaux[POLY_Dmax], L, R; CWS *_C=Cin; CWLatticeBasis B; Long G[POLY_Dmax][POLY_Dmax],M[POLY_Dmax]; #ifndef NO_COORD_IMPROVEMENT /* ==== Perm Coord Improvement ==== */ int pi[AMBI_Dmax]; CWS Caux; _C=&Caux; CWS_to_PermCWS(Cin,_C, pi); #endif /* = End of Perm Coord Improvement = */ Make_CWS_Basis(_C, &B); /* make `triangular' Basis */ #ifndef NO_COORD_IMPROVEMENT /* ==== Perm Coord Improvement ==== */ assert(_C->N==_C->B.ne); for(i=0;iN;i++) Cin->B.e[i]=_C->B.e[pi[i]]; Cin->B.ne=_C->N; #endif /* = End of Perm Coord Improvement = */ if (Cin->index == 1) for (i=0; i< Cin->N; i++) X0[i] = 1; else if(!Compute_X0(Cin->N - 1, Cin, X0)){_P->n=0; puts("no X0!");return;} /* X0 is the reference point in X-space that is transformed to the origin of x-space for _P */ /*printf("\nX0: ");for (i=0;iN;i++) printf("%ld ", X0[i]);puts(""); for(i=0;inw;i++) { fprintf(outFILE,"%d ",(int) Cin->d[i]); for(j=0;jN;j++) fprintf(outFILE,"%d ",(int) Cin->W[i][j]); if(i+1nw) fprintf(outFILE," "); }*/ i=_P->n=B.n; Amin[0]=0; Amin[B.n]=j=B.N; /* inversion structure */ while(--i) {while(!B.x[i-1][--j]); Amin[i]=++j;} for(i=0;inw;j++) if(_C->W[j][i]) { L=_C->d[j]/_C->W[j][i]; if(Xmax[i]) {if(L 0 */ /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ while((i--)>Amin[j]) /* if(R=B.x[B.n-1][i]): R!=0 => new limits */ { Long Low=-X0[i], Upp=Low+Xmax[i]; R=B.x[B.n-1][i]; if(R>0) {if(xmax[j]>(L=PD_Floor(Upp,R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(-Low,R))) xmin[j]=L;} else {if(xmax[j]>(L=PD_Floor(-Low,-R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(Upp,-R))) xmin[j]=L;} /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ } /* this completes the limits for x[B.n-1] */ x[j]=xmin[j]; while(jxmax[j]) {if(B.n==(++j)) break; else x[j]++;} else /* compute limits[j-1] and initialize x[j-1] */ { Long Upp=Xmax[i=Amin[j--]-1], Low=-X0[i]; int RangeFlag=0; for(k=j+1;kAmin[j]) if((R=B.x[j][i])) /* R!=0 => new limits */ { Low=-X0[i]; Upp=Xmax[i]; for(k=j+1;k0) {if(xmax[j]>(L=PD_Floor(Upp,R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(-Low,R))) xmin[j]=L;} else {if(xmax[j]>(L=PD_Floor(-Low,-R))) xmax[j]=L; if(xmin[j]<(L=-PD_Floor(Upp,-R))) xmin[j]=L;} /** /printf("R=%2d: %2d <= x[%d=&%d] <= %2d\n",R,xmin[j],j,i,xmax[j]);/ **/ } /* completes limits for x[] except */ else /* when R=0 and X out of Range: */ { Long X=1; for(k=j+1;kXmax[i])) RangeFlag=1; } if(RangeFlag) ++x[++j]; else x[j]=xmin[j]; if(j==0) { while(x[0]<=xmax[0]) { Long *y; if((++_P->np) < POINT_Nmax) { y=(_P->x[_P->np]); for(k=0;knp == POINT_Nmax) { y=xaux; for(k=0;knorm) norm=x; } return norm; #else /* sum(|*|) */ { Long x=S[i][j]; norm += (x>0) ? x : -x ; } return norm; #endif } void Tri_GLZ_Basis_Perm(int *d,int *pi, /* int *pinv, */ Tri_GLZ_MPaux * AP) { Long g, norm, N[AMBI_Dmax], M[AMBI_Dmax][AMBI_Dmax], *S[AMBI_Dmax]; int i, j; /* if(pi[0]>pi[1]) return; *//* eliminate equiv. permut. */ for(i=0;i<*d;i++) { N[i]=AP->N[pi[i]]; S[i]=M[i];} g=W_to_GLZ(N,d,S); norm=Tri_GLZ_Norm(d,S); if(AP->s) assert(g==AP->g); else AP->g=g; #ifdef TEST_MIN_GLZ { Long err=0, max=0, tsum=0, pos; for(i=0;i<*d;i++) { for(j=0;j<*d;j++) {pos=S[i][j]; if(pos<0)pos=-pos; tsum+=pos; if(maxs) || (norm < AP->s)) /* init or improve AP->G */ { for(i=0;i<*d;i++)for(j=0;j<*d;j++)AP->G[i][pi[j]]=S[i][j]; AP->s=norm; for(i=0;i<*d;i++) AP->p[i]=pi[i]; } } #ifndef NO_COORD_IMPROVEMENT /* improved by permutation pi=pinv^-1 */ Long Wperm_to_GLZ(Long *W, int *d, Long **G, int *P) { Tri_GLZ_MPaux AS; int i, j, pi[AMBI_Dmax], pinv[AMBI_Dmax]; AS.s=0; AS.N=W; AS.G=G; AS.p=P; Map_Permut(d,pi, /* pinv,*/ (Tri_GLZ_Basis_Perm),(void *) &AS); for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=AS.G[i][j]; #ifdef TEST_MIN_GLZ for(i=0;i<*d;i++){printf(" G[%d]=",i);for(j=0;j<*d;j++)printf(" %5d", G[i][j]);if(!i)printf(" g=%d norm=%d",(int)AS.g,(int)AS.s);puts("");} #endif return AS.g; } void CWS_to_PermCWS(CWS *Cin, CWS *C, int *pi) { int i, j, N=C->N=Cin->N, n=C->nw=Cin->nw, l=0, A[AMBI_Dmax]; Long *X, *G[AMBI_Dmax], M[AMBI_Dmax][AMBI_Dmax], W[AMBI_Dmax]; for(j=1;jd[j]>Cin->d[l]) l=j; X=Cin->W[l]; j=0; for(i=0;id[0]=Cin->d[l]; for(i=0;iW[0][i]=Cin->W[l][pi[i]]; for(j=1;jd[j]=Cin->d[L]; for(i=0;iW[j][i]=Cin->W[L][pi[i]];} C->nz=Cin->nz; for(j=0;jnz;j++){C->m[j]=Cin->m[j]; for(i=0;iz[j][i]=Cin->z[j][pi[i]];} } #endif /* ========== For WS for 5d-polytopes, Sep 2017 ========== */ int int_ld(Long w){int i=-1; while (w) {w /= 2; i++;} return i;} void Initialize_C5S(C5stats *_C5S, int n){ int k; if (n < 5) {puts("Option '-Q' requires POLY_Dmax > 4!"); exit(0);}; _C5S->n_nonIP = 0; _C5S->n_IP_nonRef = 0; _C5S->n_ref = 0; _C5S->nr_max_mp = 0; _C5S->nr_max_mv = 0; _C5S->nr_max_nv = 0; _C5S->nr_max_w = 0; for (k=0; kn_w[k] = 0; _C5S->nr_n_w[k] = 0;} _C5S->max_mp = 0; _C5S->max_mv = 0; _C5S->max_np = 0; _C5S->max_nv = 0; _C5S->max_h22 = 0; _C5S->max_w = 0; for (k=1; kmax_h1[k] = 0; for (k=0; k<=n; k++) _C5S->max_nf[k] = 0; _C5S->max_chi = -100000000; _C5S->min_chi = 100000000; } void Update_C5S(BaHo *_BH, int *nf, Long *W, C5stats *_C5S){ assert(POLY_Dmax>4); if (_BH->np) { // reflexive case int i, chi = 48+6*(_BH->h1[1]-_BH->h1[2]+_BH->h1[3]), ld = int_ld(W[5]); assert(0<=ld); assert(ldmp > _C5S->max_mp) _C5S->max_mp = _BH->mp; if (_BH->mv > _C5S->max_mv) _C5S->max_mv = _BH->mv; if (_BH->np > _C5S->max_np) _C5S->max_np = _BH->np; if (_BH->nv > _C5S->max_nv) _C5S->max_nv = _BH->nv; if (_BH->h22 > _C5S->max_h22) _C5S->max_h22 = _BH->h22; for (i=1; i<_BH->n-1; i++) if (_BH->h1[i] > _C5S->max_h1[i]) _C5S->max_h1[i] = _BH->h1[i]; for (i=0; i<=_BH->n; i++) if (nf[i] > _C5S->max_nf[i]) _C5S->max_nf[i] = nf[i]; if (chi > _C5S->max_chi) _C5S->max_chi = chi; if (chi < _C5S->min_chi) _C5S->min_chi = chi; _C5S->n_ref++; _C5S->n_w[ld]++; if(W[5] > _C5S->max_w) _C5S->max_w = W[5];} else { // IP but non-reflexive case if (_BH->mp > _C5S->nr_max_mp) _C5S->nr_max_mp = _BH->mp; if (_BH->mv > _C5S->nr_max_mv) _C5S->nr_max_mv = _BH->mv; if (_BH->nv > _C5S->nr_max_nv) _C5S->nr_max_nv = _BH->nv; _C5S->n_IP_nonRef++; _C5S->nr_n_w[int_ld(W[5])]++; if(W[5] > _C5S->nr_max_w) _C5S->nr_max_w = W[5];} } void Print_C5S(C5stats *_C5S){ int i; assert(POLY_Dmax>4); printf("non-IP: #=%ld\n", _C5S->n_nonIP); printf("IP, non-reflexive: #=%ld, max_mp=%d, max_mv=%d, max_nv=%d, max_w=%ld\n", _C5S->n_IP_nonRef, _C5S->nr_max_mp, _C5S->nr_max_mv, _C5S->nr_max_nv, _C5S->nr_max_w); printf(" #(w5) of given ld: "); for (i=0; inr_n_w[i]); puts(""); printf("reflexive: #=%ld, max_mp=%d, max_mv=%d, max_np=%d, max_nv=%d, max_w=%ld\n", _C5S->n_ref, _C5S->max_mp, _C5S->max_mv, _C5S->max_np, _C5S->max_nv, _C5S->max_w); printf(" #(w5) of given ld: "); for (i=0; in_w[i]); puts(""); printf(" max #(faces): %d %d %d %d %d\n", _C5S->max_nf[0], _C5S->max_nf[1], _C5S->max_nf[2], _C5S->max_nf[3], _C5S->max_nf[4]); printf(" h11<=%d, h12<=%d, h13<=%d, h22<=%d, %d<=chi<=%d\n", _C5S->max_h1[1], _C5S->max_h1[2], _C5S->max_h1[3], _C5S->max_h22, _C5S->min_chi, _C5S->max_chi); } palp-2.21/nef.c0000664000177600017760000003674514572603263012701 0ustar skarkeskarke/* ====================================================================== */ /* ========== ========== */ /* ========== test- N E F . C ========== */ /* ========== ========== */ /* ========== Modules: IO, Rat, Points, Vertex, Convex, Hodge ========== */ /* ========== ========== */ /* ====================================================================== */ #include "Global.h" #include "Nef.h" #include "LG.h" /* ========== l o c a l T Y P E D E F s ========== */ typedef struct { Long x[POLY_Dmax][W_Nmax]; int N, n; } AmbiLatticeBasis; typedef struct { Long x[AMBI_Dmax][AMBI_Dmax]; int n, N; } CWLatticeBasis; typedef struct { Long P[POINT_Nmax]; Long n; } Pstat; /* ========== l o c a l P R O T O T Y P E s ========== */ int ReadCwsPp(CWS *_CW, PolyPointList *_P, int codim, int index); void Compute_E_Poly(EPoly *_EP, PolyPointList * _P_D, VertexNumList * _V_D, EqList * _E_D, PolyPointList * _P_N, VertexNumList * _V_N, EqList * _E_N, int *_codim, Flags * _F, time_t *_Tstart, clock_t *_Cstart); void Sort_PPL(PolyPointList *_P, VertexNumList *_V); void NormTriangularBasis(AmbiLatticeBasis * _B); void WeightLatticeBasis(Weight * _w, AmbiLatticeBasis * _B); void WeightMakePoints(Weight * _W, AmbiPointList * _P); void MakeRefWeights(int N, int from_d, int to_d); void ChangeToTrianBasis(AmbiPointList *, AmbiLatticeBasis *, PolyPointList *); int IN_WEIGHT(Weight *, CWS *, int *, PolyPointList *, Flags *, int); void OUT_CWS(CWS *, int *, int *); void Print_VP(PolyPointList *, VertexNumList *, int, int, Pstat *); void Print_Pstat(Pstat *, int, int, int); void Die(char *); //=== NOW INIZIO ===// void Print_Nefinfo(PartList *_PTL, /* Flags *_F,*/ time_t *_Tstart, clock_t *_Cstart); //=== NOW FINE ===// FILE *inFILE, *outFILE; #define OSL (31) /* opt_string's length */ void PrintNefUsage(char *c){ int i; char *opt_string[OSL]={ "Options: -h prints this information", " -f or - use as filter; otherwise parameters denote I/O files", " -N input is in N-lattice (default is M)", " -H gives full list of Hodge numbers", " -Lv prints L vector of Vertices (in N-lattice)", " -Lp prints L vector of Points (in N-lattice)", " -p prints only partitions, no Hodge numbers", " -D calculates also direct products", " -P calculates also projections", " -t full time info", " -cCODIM codimension (default = 2)", " -Fcodim fibrations up to codim (default = 2)", " -y prints poly/CWS in M lattice if it has nef-partitions", " -S information about #points calculated in S-Poly", " -T checks Serre-duality ", " -s don't remove symmetric nef-partitions ", " -n prints polytope only if it has nef-partitions", " -v prints vertices and #points of input polytope in one", " line; with -u, -l the output is limited by #points:", " -uPOINTS ... upper limit of #points (default = POINT_Nmax)", " -lPOINTS ... lower limit of #points (default = 0)", " -m starts with [d w1 w2 ... wk d=d_1 d_2 (Minkowski sum)", " -R prints vertices of input if not reflexive", " -V prints vertices of N-lattice polytope", " -Q only direct products (up to lattice Quotient)", " -gNUMBER prints points of Gorenstein polytope in N-lattice", " -dNUMBER prints points of Gorenstein polytope in M-lattice", " if NUMBER = 0 ... no 0/1 info", " if NUMBER = 1 ... no redundant 0/1 info (=default)", " if NUMBER = 2 ... full 0/1 info", " -G Gorenstein cone: input <-> support polytope" }; puts(""); printf("This is '%s': calculate Hodge numbers of nef-partitions\n",c); printf("Usage: %s \n", c); puts(""); for (i=0;i*n+1)) a=fn[++*n]; else a=&fn[*n][2]; if(*a == 0) PrintNefUsage(fn[0]); if(!IsDigit(*a)){ printf("after %s there must be digit(s)!\n",s); exit(0);} return atoi(a); } int Make_Mirror(EPoly *_EP, int h[][POLY_Dmax], int D, int dim); int main(int narg, char *fn[]) { Flags F; int N = 0, n = 0, FilterFlag = 0, VPmax = POINT_Nmax-1, VPmin = 0; CWS CW; Weight W; int D[2], codim=2; Pstat *_PS; VertexNumList *_V; EqList *_E; PolyPointList *_P; _P = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P == NULL) Die("Unable to allocate space for _P"); _V = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V == NULL) Die("Unable to alloc space for VertexNumList _V"); _E = (EqList *) malloc(sizeof(EqList)); if (_E == NULL) Die("Unable to alloc space for EqList _E"); _PS = (Pstat *) malloc(sizeof(Pstat)); if (_PS == NULL) Die("Unable to alloc space for Pstat _PS"); F.p = 0; F.Lv = 0; F.Lp = 0; F.t = 0; F.S = 0; F.T = 0; F.N = 0; F.H = 0; F.Msum = 0; F.Sym = 1; F.Rv = 0; F.V = 0; F.Test = 0; F.Sort = 1; F.Dir = 0; F.B = 1; F.VP = 0; F.Proj = 0; F.w = 0; F.f = 0; F.n = 0; F.g = 0; F.gd=1; F.d = 0; F.dd=1; F.noconvex=0; F.y=0; F.G = 0; while (narg > ++n) if (fn[n][0] != '-') break; else { if ((fn[n][1] == '?') || (fn[n][1] == 'h')) { PrintNefUsage(fn[0]); return 0; } else if (fn[n][1] == 'x'){ PrintNefUsage(fn[0]); return 0; } else if ((fn[n][1] == 'f') || (fn[n][1] == 0)) FilterFlag = 1; else if (fn[n][1] == 'S') F.S = 1; else if (fn[n][1] == 'H') F.H = 1; else if (fn[n][1] == 't') F.t = 1; else if (fn[n][1] == 'W') F.w = 1; else if (fn[n][1] == 's') F.Sym = 0; else if (fn[n][1] == 'T') F.T = 1; else if (fn[n][1] == 'N') F.N = 1; else if (fn[n][1] == 'v') F.VP = 1; else if (fn[n][1] == 'n'){ F.n = 1; F.p = 1; } else if (fn[n][1] == 'u') VPmax = READ_INT(&n, narg, fn, "u"); else if (fn[n][1] == 'l') VPmin = READ_INT(&n, narg, fn, "l"); else if (fn[n][1] == 'm') F.Msum = 1; else if (fn[n][1] == 'g'){ F.p = 1; F.g = 1; if(IsDigit(fn[n][2])) F.gd = atoi(&fn[n][2]); } else if (fn[n][1] == 'd'){ F.d = 1; F.p = 1; if(IsDigit(fn[n][2])) F.dd = atoi(&fn[n][2]); } else if (fn[n][1] == 'R') F.Rv = 1; else if (fn[n][1] == 'V') F.V = 1; else if (fn[n][1] == 'L'){ if (fn[n][2] == 'p') F.Lp = 1; if (fn[n][2] == 'v') F.Lv = 1; } else if (fn[n][1] == 'k') F.noconvex=1; else if (fn[n][1] == 'p') F.p = 1; else if (fn[n][1] == 'y') F.y = 1; else if (fn[n][1] == 'D') F.Dir = 1; else if (fn[n][1] == 'Q') F.Dir = 2; else if (fn[n][1] == 'P') F.Proj = 1; else if (fn[n][1] == 'c') codim = READ_INT(&n, narg, fn, "c"); else if (fn[n][1] == 'F'){ F.f = 2; if(fn[n][2]!=0) F.f = READ_INT(&n, narg, fn, "F"); } else if (fn[n][1] == 'G') F.G = 1; else { printf("Unknown option '-%c'; use -h for help\n",fn[n][1]); exit(0);} } n--; if (FilterFlag) { inFILE = NULL; outFILE = stdout; } else { if (narg > ++n) inFILE = fopen(fn[n], "r"); else inFILE = stdin; if (inFILE == NULL) { printf("Input file %s not found!\n", fn[n]); exit(0); } if (narg > ++n) outFILE = fopen(fn[n], "w"); else outFILE = stdout; } while (IN_WEIGHT(&W, &CW, D, _P, &F, codim)) { /* _P is the M-lattice polytope */ if (F.G) AnalyseGorensteinCone(&CW,_P,_V,_E,&codim,&F); else if (Ref_Check(_P, _V, _E)){ int nv=_V->nv, ne=_E->ne; Long PM[EQUA_Nmax][VERT_Nmax]; Make_VEPM(_P,_V,_E, PM); Complete_Poly(PM,_E,_V->nv,_P); Find_Equations(_P,_V,_E); /*Print_PPL(_P,"vorher");*/ Sort_VL(_V); Sort_PPL(_P, _V); /*Print_PPL(_P,"nachher");*/ assert(nv==_V->nv && ne==_E->ne); if (!F.VP){ #ifdef WRITE_CWS OUT_CWS(&CW, D, &F.Msum); #endif if (POLY_Dmax < (_P->n + codim - 1)){ printf("Please increase POLY_Dmax to at least %d = %d + %d - 1\n", (_P->n + codim - 1), _P->n, codim); printf("(%s requires POLY_Dmax >= dim N + codim - 1)\n", fn[0]); exit(0); } Make_E_Poly(outFILE, &CW, _P, _V, _E, &codim, &F, &D[0]); } else{ N++; Print_VP(_P, _V, VPmax, VPmin, _PS); } } else{ if ((F.Rv == 1) || ((F.V == 1)&&(F.N == 1))){ Find_Equations(_P,_V,_E); Print_VL(_P, _V, "Vertices of input polytope:"); } }} if (F.VP){ assert(VPmax < POINT_Nmax); assert(VPmax >= VPmin); Print_Pstat(_PS, N, VPmax, VPmin); } free(_E); free(_V); free(_P); free(_PS); return 0; } void Print_Pstat(Pstat *_PS, int N, int VPmax, int VPmin){ int i; fprintf(outFILE,"\n\n%d of %d\n\n",(int) _PS->n,(int) N); for(i=VPmin; i<=VPmax; i++) if (_PS->P[i] != 0) fprintf(outFILE,"%4d# %4d\n",(int) i, (int) _PS->P[i]); } void Print_VP(PolyPointList *_P, VertexNumList *_V, int VPmax, int VPmin, Pstat *_PS){ int i,j; if((_P->np <= VPmax) && (_P->np >= VPmin)){ _PS->P[_P->np] ++; _PS->n ++; if(_V->nv>20){ fprintf(outFILE,"%d %d P:%d E",_V->nv,_P->n,_P->np); for(i=0;i<_V->nv;i++) { for(j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) _P->x[_V->v[i]][j]); if(i!=(_V->nv-1)) fprintf(outFILE,"E");}} else { fprintf(outFILE,"%d %d P:%d E",_P->n,_V->nv,_P->np); for(i=0;i<_P->n;i++) { for(j=0;j<_V->nv;j++) fprintf(outFILE," %4d",(int) _P->x[_V->v[j]][i]); if(i!=(_P->n-1)) fprintf(outFILE,"E");}} fprintf(outFILE,"\n"); } } void Make_Sort(Long * _N, Long * _n, Long * _B_num, Long * _c_num, Long * _c_less) { Long N, n; n = *_n; N = *_N; while (n != 0) { if (_c_less[n - 1] == N) { _B_num[N + n - 1] = _c_num[n - 1]; n--; } else { _B_num[N + n - 1] = _B_num[N - 1]; N--; } } *_N += *_n; *_n = 0; } Long Make_Bi_section(DYN_PPL *_MP, Long *_N_List, Long *_N, Long *x) { Long max_pos, min_pos, pos, diff; int d; max_pos = *_N; min_pos = -1; while ((max_pos - min_pos) > 1) { pos = (max_pos + min_pos) / 2; diff = 0; d = _MP->n; while ((d != 0) && (diff == 0)) { diff = (x[d - 1] - _MP->L[_N_List[pos]].x[d - 1]); d--; } if (diff > 0) min_pos = pos; else if (diff < 0) max_pos = pos; else max_pos = -1; } return max_pos; } void Mink_WPCICY(AmbiPointList * _AP_1, AmbiPointList * _AP_2, AmbiPointList * _AP) { int l; Long *_x, *_B_num, *_c_num, *_c_less, n = 0, N = 0, Num, num, P_max, p_max, j, k, m; DYN_PPL B; P_max = _AP_1->np * _AP_2->np; p_max = ((Long) IntSqrt(P_max)); _x = (Long *) calloc(_AP_1->N, sizeof(Long)); B.L = (Vector *) calloc(P_max, sizeof(Vector)); _B_num = (Long *) calloc(P_max, sizeof(Long)); _c_num = (Long *) calloc(p_max, sizeof(Long)); _c_less = (Long *) calloc(p_max, sizeof(Long)); assert((B.L != NULL) && (_B_num != NULL) && (_c_num != NULL) && (_c_less != NULL) && (_x != NULL)); B.n = _AP_1->N; B.NP_max = P_max; for (j = 0; j < _AP_1->np; j++) for (k = 0; k < _AP_2->np; k++) { if (n == p_max) Make_Sort(&N, &n, _B_num, _c_num, _c_less); for (l = 0; l < _AP_1->N; l++) _x[l] = _AP_1->x[j][l] + _AP_2->x[k][l]; Num = Make_Bi_section(&B, _B_num, &N, _x); if (Num >= 0) { num = Make_Bi_section(&B, _c_num, &n, _x); if (num >= 0) { assert((n + N) < P_max); for (l = 0; l < _AP_1->N; l++) B.L[(n + N)].x[l] = _x[l]; for (m = n; m > num; m--) { _c_num[m] = _c_num[m - 1]; _c_less[m] = _c_less[m - 1]; } _c_num[num] = N + n; _c_less[num] = Num; n++; } } } assert((n + N) <= POINT_Nmax); B.np = n + N; _AP->np = B.np; _AP->N = _AP_1->N; for (j = 0; j < (N + n); j++) for (l = 0; l < _AP_1->N; l++) _AP->x[j][l] = B.L[j].x[l]; free(_x); free(B.L); free(_B_num); free(_c_num); free(_c_less); } void Make_Poly_WPCICY(Weight * _W, int *_D, PolyPointList * _PP) { AmbiLatticeBasis B; AmbiPointList *_AP_1 = (AmbiPointList *) malloc(sizeof(AmbiPointList)); AmbiPointList *_AP_2 = (AmbiPointList *) malloc(sizeof(AmbiPointList)); AmbiPointList *_AP = (AmbiPointList *) malloc(sizeof(AmbiPointList)); assert((_AP_1 != NULL) && (_AP_2 != NULL) && (_AP != NULL)); WeightLatticeBasis(_W, &B); _W->d = _D[0]; WeightMakePoints(_W, _AP_1); assert(POINT_Nmax >= _AP_1->np); _W->d = _D[1]; WeightMakePoints(_W, _AP_2); assert(POINT_Nmax >= _AP_2->np); _W->d += _D[0]; Mink_WPCICY(_AP_1, _AP_2, _AP); ChangeToTrianBasis(_AP, &B, _PP); free(_AP); free(_AP_1); free(_AP_2); return; } void Make_CW_WPCICY(Weight * _W, CWS * _CW) { int i; _CW->nw = 1; _CW->N = _W->N; _CW->d[0] = _W->d; for (i = 0; i < _CW->N; i++) _CW->W[0][i] = _W->w[i]; _CW->nz = 0; } int Read_WPCICY(Weight * _W, int *_D) /* read "d" and "w_i" till sum=d or non-digit */ { char c; int long nl, sum, FilterFlag = (inFILE == NULL); if (inFILE == stdin) printf("type degrees and weights [d w1 w2 ... wk d=d_1 d_2]: "); else if (FilterFlag) inFILE = stdin; c = fgetc(inFILE); if (!IsDigit(c)) return 0; ungetc(c, inFILE); fscanf(inFILE, "%ld", &nl); _W->d = nl; sum = nl; for (_W->N = 0; _W->N < W_Nmax; sum -= nl) { assert(_W->N < W_Nmax); while (' ' == (c = fgetc(inFILE))); ungetc(c, inFILE); if (IsDigit(c)) { fscanf(inFILE, "%ld", &nl); _W->w[(_W->N)++] = nl; } else break; } while (!IsDigit(c = fgetc(inFILE))); ungetc(c, inFILE); fscanf(inFILE, "%d", &_D[1]); while (' ' == (c = fgetc(inFILE))); ungetc(c, inFILE); fscanf(inFILE, "%d", &_D[0]); while (fgetc(inFILE) - '\n') if (feof(inFILE)) return 0; /* read to EOL */ if (_W->N > POLY_Dmax) { printf("Please increase POLY_Dmax "); printf("(POLY_Dmax >= number of weights is required)\n"); exit(0);} assert((_D[0] + _D[1]) == _W->d); if (_W->N < 2) { puts("I need at least 2 weights!"); exit(0); } if (FilterFlag) inFILE = NULL; return 1; } int Make_WPCICY(Weight * _W, CWS * _CW, int *_D, PolyPointList * _P) { int r = Read_WPCICY(_W, _D); Make_Poly_WPCICY(_W, _D, _P); Make_CW_WPCICY(_W, _CW); return r; } void Make_RGC_Points(CWS *Cin, PolyPointList *_P); int IN_WEIGHT(Weight * _W, CWS * _CW, int *_D, PolyPointList * _P, Flags *_F, int codim){ if (_F->Msum) return Make_WPCICY(_W, _CW, _D, _P); if (_F->G) return ReadCwsPp(_CW, _P , 1, codim); return ReadCwsPp(_CW, _P, codim, 1); } void OUT_CWS(CWS * _W, int *_D, int *_M_Flag) { int i, j; for (i = 0; i < _W->nw; i++) { fprintf(outFILE, "%d ", (int) _W->d[i]); for (j = 0; j < _W->N; j++) fprintf(outFILE, "%d ", (int) _W->W[i][j]); if (i + 1 < _W->nw) fprintf(outFILE, " "); } if (*_M_Flag) fprintf(outFILE, "d=%d %d ", (int) _D[1], _D[0]); Print_CWS_Zinfo(_W); } palp-2.21/SingularInput.c0000664000177600017760000004636214572603263014731 0ustar skarkeskarke/* ======================================================== */ /* === === */ /* === S i n g u l a r I n p u t . c === */ /* === === */ /* === Authors: Maximilian Kreuzer, Nils-Ole Walliser === */ /* === Emanuel Scheidegger === */ /* === Last update: 05/04/12 === */ /* === === */ /* ======================================================== */ /* ======================================================== */ /* ========= H E A D E R s ========= */ #include /* close */ #include "Global.h" #include "Mori.h" /* ======================================================== */ /* ========= D E F I N I T I O N s ========= */ /*** local for Singularinput.c ***/ #define DijkEQ "->" /* Useful for Mathematica rules: "->" */ #define T_DIV "d" /* Toric divisors */ #define DIVclassBase "J" /* Basis of the divisor classes */ /* diagnostic stuff */ #define TEST_PRINT_SINGULAR_IO (0) /* IO of SINGULAR */ #define NORM_SIMP_NUM (0) /*=========================================================*/ #if (TEST_PRINT_SINGULAR_IO) void CatFile(char *fn){ char* CAT = (char*)malloc(30 + strlen(fn)); strcpy(CAT,"cat "); strcat(CAT,fn); printf("======= FILE content of %s:\n",fn); fflush(0); assert(0==system(CAT)); printf("====== End of FILE content of %s\n\n",fn); fflush(0); free(CAT); } #endif int Read_HyperSurf(int *he, int divclassnr, int maxline, char filename[20], MORI_Flags *_Flag){ FILE *stream; int i; char string[maxline]; char delims[] = " "; char *result = NULL; if(_Flag->Read_HyperSurfCounter==0){ if( (stream = fopen(filename, "w")) == NULL) { printf("Error: cannot open file!\n"); exit(1); } fgets(string, sizeof string, stdin); fprintf(stream, "%s\n", string); } if(_Flag->Read_HyperSurfCounter != 0){ if( (stream = fopen(filename,"r")) == NULL) { printf("Error: cannot read file!\n"); exit(1); } fgets(string, maxline ,stream); } i=0; result = strtok( string, delims ); while( result != NULL ) { he[i] = atoi(result); i++; if(i == divclassnr) break; result = strtok( NULL, delims ); } fclose(stream); return i; } void HyperSurfSingular(PolyPointList *P,triang *T, triang *SR ,MORI_Flags *_Flag , FibW *F,int *cp){ int p=SR->v,d=SR->d,i,j,r, N=0;/* N=not(0th)=offset(IP) */ int divclassnr = *cp; int TORDIM=P->n; int CODIM=1; int DIM=TORDIM-CODIM; char *D=T_DIV,*B=DIVclassBase; /* Put temporary files in $TMPDIR if it is set */ char* tmpdir = getenv("TMPDIR"); if (tmpdir == NULL) { tmpdir = "/tmp"; } /* Add one to ensure room for the null byte at the end */ size_t template_size = strlen(tmpdir) + strlen("/SFnameXXXXXX") + 1; char* SFname = (char*)malloc(template_size); snprintf(SFname, template_size, "%s/SFnameXXXXXX", tmpdir); int SF = mkstemp(SFname); assert(-1 != SF); /* Construct the singular command. In this case, template_size is already padded by 1 byte (see above). */ size_t singular_cmd_size = strlen("Singular -q < ") + template_size; char* SingularCall = (char*)malloc(singular_cmd_size); snprintf(SingularCall, singular_cmd_size, "Singular -q < %s", SFname); dprintf(SF,"LIB \"general.lib\";\n"); dprintf(SF,"option(noredefine);\n"); dprintf(SF,"ring r=0,(t,%s%d",D,N+1); // ring r=0,(t,D1,...,Dp,B1,...,Bp-d),ds; for(i=N+2;i<=p;i++) dprintf(SF,",%s%d",D,i); for(i=1;i<=p-d;i++) dprintf(SF,",%s%d",B,i); dprintf(SF,"),(ds,dp(%d));\n",2*p-d); /*LINEAR EQUIVALENCES*/ dprintf(SF,"ideal lin="); for(r=0;rx[j][r]; if((X>0)) dprintf(SF,"+"); if(X) dprintf(SF,"%d*%s%d",X,D,j+1); } } dprintf(SF,";"); DivClassBasis(SF,P,p,D,B); /* STANLEY REISNER */ dprintf(SF,"ideal sr="); for(r=0;rn;r++){ int f=1; if(r) dprintf(SF,","); for(j=0;jI[r])){ if(f) f=0; else dprintf(SF,"*"); dprintf(SF,"%s%d",D,j+1); } } /* CHOW RING */ dprintf(SF,";\nideal chow=std(lin+sr+DCbase);\n"); /*reads input for the hyper surface * creates HEInput.txt * reads HEInput.txt * and defines poly cy as H*/ if(_Flag->H==1){ if(!(_Flag->FilterFlag) && _Flag->Read_HyperSurfCounter == 0) printf("Type the %d (integer) entries for the hypersurface class:\n", divclassnr); int *he, i; he=malloc(divclassnr*sizeof(int)); for(i=0;iRead_HyperSurfCounter==0){ if(control != divclassnr) printf("Warning: %d entries for the hypersurface class were expected\n" " (i.e. as many entries as toric divisor classes) \n",divclassnr ); dprintf(SF,"\"Hypersurface class: "); for(i=0; inw; int DegreeVec[dim]; for(i=0;inw;i++){ DegreeVec[i]=0; } for(i=0;inw;i++){ for(j=0;jW[i][j]); } } if(_Flag->Read_HyperSurfCounter==0){ fprintf(outFILE,"Hypersurface degrees: ("); for(i=0;inw;i++){ fprintf(outFILE," %d ",DegreeVec[i]); } fprintf(outFILE,")\n"); } // _Flag->Read_HyperSurfCounter++; free(he); fflush(0); } else { dprintf(SF,"poly HySurf=(%s%d",D,N+1); for(i=N+1;ii || _Flag->c){ dprintf(SF,"\"SINGULAR -> divisor classes (integral basis %s1",B); if(p-d>1) dprintf(SF," ... %s%d",B,p-d); dprintf(SF,"):\";\n"); dprintf(SF,"string LR=string(%s1)+\"=\"+string(reduce(%s1,chow));\n",D,D); for(j=2;j<=p;j++){ dprintf(SF,"LR=LR+\", \"+string(%s%d)+\"=\"+",D,j); dprintf(SF,"string(reduce(%s%d,chow));\n ",D,j); } dprintf(SF,"LR;\n"); } dprintf(SF, "list dli=d1"); for(j=2;j<=p;j++) dprintf(SF,",d%d",j); dprintf(SF,";\n"); dprintf(SF, "list Jli=J1"); for(j=2;j<=p-d;j++) dprintf(SF,",J%d",j); dprintf(SF,";\n"); dprintf(SF,"int i,j,k;\n"); /*linear basis ideal*/ dprintf(SF,"ideal lb=std(lin+DCbase);\n"); /* Test for nonintersecting divisors */ dprintf(SF,"ideal hypideal = quotient(chow,HySurf);\n"); if(_Flag->t || _Flag->d){ dprintf(SF,"list nonintersectingd = list();\n"); dprintf(SF,"for(i=1;i<=%d;i++){\n",p); dprintf(SF," if(reduce(dli[i],std(hypideal))==0){\n"); dprintf(SF," nonintersectingd=nonintersectingd+list(dli[i]);\n"); dprintf(SF," }\n"); dprintf(SF,"}\n"); dprintf(SF,"if(size(nonintersectingd)>0){\n"); dprintf(SF," \"SINGULAR -> nonintersecting divisor classes : \";\n"); dprintf(SF," string nd=string(nonintersectingd[1]);\n"); dprintf(SF," for(i=2;i<=size(nonintersectingd);i++){\n"); dprintf(SF," nd=nd+\", \"+string(nonintersectingd[i]);\n"); dprintf(SF," }\n"); dprintf(SF,"nd;}\n"); } if(_Flag->i || _Flag->c){ dprintf(SF,"list nonintersectingJ = list();\n"); dprintf(SF,"for(i=1;i<=%d;i++){\n",p-d); dprintf(SF,"if(reduce(Jli[i],std(hypideal))==0){nonintersectingJ=nonintersectingJ+list(Jli[i]);}\n"); dprintf(SF,"}\n"); dprintf(SF,"if(size(nonintersectingJ)>0){\n"); dprintf(SF," \"SINGULAR -> nonintersecting divisor classes (integral basis): \";\n"); dprintf(SF," string nJ=string(nonintersectingJ[1]);\n"); dprintf(SF," for(i=2;i<=size(nonintersectingJ);i++){\n"); dprintf(SF," nJ=nJ+\", \"+string(nonintersectingJ[i]);\n"); dprintf(SF," }\n"); dprintf(SF,"nJ;}\n"); } /* Singular procedure to compute the Todd class of a vector bundle given by its Chern character */ dprintf(SF,"proc Todd(poly ch, int Dim) {\n"); dprintf(SF," poly ToddD = 1;\n"); dprintf(SF," for(i=2;i<=Dim+1;i++){ToddD=ToddD+(-dli[1]*t)^(i-1)/factorial(i);}\n"); dprintf(SF," ToddD = jet(1,ToddD,2*Dim);\n"); dprintf(SF," matrix c=coeffs(ToddD,t);\n"); dprintf(SF," matrix p[Dim][1] = c[2..Dim+1,1];\n"); dprintf(SF," for(i=1;i<=Dim;i++){\n"); dprintf(SF," p[i,1]=-i*p[i,1];\n"); dprintf(SF," for(j=1;j<=i-1;j++){\n"); dprintf(SF," p[i,1]=p[i,1]-p[j,1]*c[i-j+1,1];\n"); dprintf(SF," };\n"); dprintf(SF," };\n"); dprintf(SF," poly tmp=0;\n"); dprintf(SF," for(i=1;i<=Dim;i++){\n"); dprintf(SF," tmp = tmp+p[i,1]/factorial(i)*(-t)^i;\n"); dprintf(SF," };\n"); dprintf(SF," matrix ctmp=coeffs(tmp,dli[1]);\n"); dprintf(SF," matrix cch=coeffs(ch,t);\n"); dprintf(SF," int m=nrows(ctmp);\n"); dprintf(SF," if(nrows(cch) < m){m=nrows(cch)};\n"); dprintf(SF," tmp=0;\n"); dprintf(SF," for(i=0;i<=m-1;i++){\n"); dprintf(SF," tmp=tmp+ctmp[i+1,1]*cch[i+1,1]*factorial(i);\n"); dprintf(SF," }\n"); dprintf(SF," p=coeffs(tmp,t);\n"); dprintf(SF," for(i=1;i<=nrows(p)-1;i++){\n"); dprintf(SF," p[i+1,1]=p[i+1,1]*(-1)^(i)*factorial(i);\n"); dprintf(SF," }\n"); dprintf(SF," c[1,1]=1;\n"); dprintf(SF," for(i=1;i<=Dim;i++){\n"); dprintf(SF," c[i+1,1]=0;\n"); dprintf(SF," m=i;\n"); dprintf(SF," if(nrows(p) < i+1){m=nrows(p)-1};\n"); dprintf(SF," for(j=1;j<=m;j++){\n"); dprintf(SF," c[i+1,1]=c[i+1,1]-p[j+1,1]*c[i+1-j,1];\n"); dprintf(SF," };\n"); dprintf(SF," c[i+1,1]=c[i+1,1]/(i);\n"); dprintf(SF," };\n"); dprintf(SF," tmp=0;\n"); dprintf(SF," for(i=0;i<=Dim;i++){\n"); dprintf(SF," tmp=tmp+c[i+1,1]*t^i;\n"); dprintf(SF," }\n"); dprintf(SF," return(tmp);\n"); dprintf(SF,"};\n"); /*####### Chern classes of CY/H ################*/ dprintf(SF,"poly ChernUp=1;\n"); dprintf(SF,"for(i=1;i<=%d;i++){ChernUp=ChernUp*(1+dli[i]);}\n",p); dprintf(SF,"poly ChernBottomHypersurface=1;\n"); dprintf(SF,"for(i=1;i<=%d;i++){ChernBottomHypersurface=ChernBottomHypersurface+(-1)^i*HySurf^i;}\n",DIM); dprintf(SF,"poly ChernHySurf=ChernUp*ChernBottomHypersurface;\n"); for (j=0;jb){ if(_Flag->H !=1){dprintf(SF,"\"SINGULAR -> Arithmetic genera and Euler number of the CY:\";\n");} else if (_Flag->H ==1){dprintf(SF,"\"SINGULAR -> Arithmetic genera and Euler number of H:\";\n");} /* Chern character and the Todd class of the tangent bundle */ dprintf(SF,"matrix ch[%d][1] = 1",DIM+1); for(i=2;i<=DIM+1;i++){ dprintf(SF,",c%dHySurf",i-1); }; dprintf(SF,";\n"); dprintf(SF,"matrix pp[%d][1] = -ch[2,1]",DIM); for(i=2;i<=DIM;i++){ dprintf(SF,",-%d*ch[%d,1]",i,i+1); }; dprintf(SF,";\n"); dprintf(SF,"for(i=1;i<=%d;i++){\n",DIM); dprintf(SF," for(j=1;j<=i-1;j++){\n"); dprintf(SF," pp[i,1]=pp[i,1]-pp[j,1]*ch[i-j+1,1];\n"); dprintf(SF," };\n"); dprintf(SF,"};\n"); dprintf(SF,"poly tmp=%d;\n",DIM); dprintf(SF,"for(i=1;i<=%d;i++){\n",DIM); dprintf(SF," tmp = tmp+pp[i,1]/factorial(i)*(-t)^i;\n"); dprintf(SF,"};\n"); dprintf(SF,"poly ToddHySurf=subst(Todd(tmp,%d),t,1);\n",DIM); dprintf(SF,"tmp=%d;\n",DIM); dprintf(SF,"for(i=1;i<=%d;i++){\n",DIM); dprintf(SF," tmp = tmp+pp[i,1]/factorial(i)*(t)^i;\n"); dprintf(SF,"};\n"); dprintf(SF,"tmp=subst(tmp,t,1);\n"); dprintf(SF,"\"chi_0: \","); dprintf(SF,"reduce(ToddHySurf*HySurf,chow)/norm,"); dprintf(SF,"\",\", ""\"chi_1:\","); dprintf(SF,"reduce(tmp*ToddHySurf*HySurf,chow)/norm,"); dprintf(SF,"\" [\","); dprintf(SF,"reduce(c%dHySurf*HySurf,chow)/norm,",DIM); dprintf(SF,"\"]\";\n"); } /*#############################################*/ /*####### Intersection Polynomial #############*/ if(_Flag->i){ dprintf(SF,"\"SINGULAR -> intersection polynomial:\";\n"); dprintf(SF,"poly f=1-t*(reduce(%s%d,std(hypideal))",B,1); for (j=2; j<=p-d; j++) { dprintf(SF,"+reduce(%s%d,std(hypideal))",B,j); } dprintf(SF,");\n"); dprintf(SF,"poly m=jet(1,f,%d)-jet(1,f,%d);\n",2*DIM,2*DIM-2); dprintf(SF,"matrix M=coef(m,%s%d",B,1); for (j=2; j<=p-d; j++) { dprintf(SF,"*%s%d",B,j); } dprintf(SF,");\n"); dprintf(SF,"for(i=1;i<=ncols(M);i++){\n"); dprintf(SF," M[2,i]=reduce(M[1,i]*HySurf,chow)/norm;\n"); dprintf(SF,"}\n"); dprintf(SF,"poly p=M[2,1]*M[1,1];\n"); dprintf(SF,"for(i=2;i<=ncols(M);i++){\n"); dprintf(SF," p=p+M[2,i]*M[1,i];\n"); dprintf(SF,"}\n"); dprintf(SF,"p;\n"); } //PRINT Chern classes of CY/H if(_Flag->H !=1 && _Flag->c){ dprintf(SF,"\"SINGULAR -> Chern classes of the CY-hypersurface:\";\n"); for(i=1;i<=DIM-1;i++){ dprintf(SF,"\"c%d(CY)= \",reduce(c%dHySurf,chow);\n",i,i); } dprintf(SF,"\"c%d(CY)= \",reduce(c%dHySurf*HySurf,chow)/norm,\"*[pt]\";\n",DIM,DIM); } if(_Flag->H==1 && _Flag->c){ dprintf(SF,"\"SINGULAR -> Chern classes of the hypersurface H:\";\n"); for(i=1;i<=DIM-1;i++){ dprintf(SF,"\"c%d(H)= \",reduce(c%dHySurf,chow);\n",i,i); } dprintf(SF,"\"c%d(H)= \",reduce(c%dHySurf*HySurf,chow)/norm,\"*[pt]\";\n",DIM,DIM); } /*####### triple intersection numbers #########*/ if(_Flag->t){ dprintf(SF,"\"SINGULAR -> triple intersection numbers:\";\n"); dprintf(SF,"poly f=1;\n"); dprintf(SF,"for(i=1;i<=%d;i++){\n",p); dprintf(SF," k=1;\n"); dprintf(SF," for(j=1;j<=size(nonintersectingd);j++){\n"); dprintf(SF," if(dli[i]==nonintersectingd[j]){k=0;}\n"); dprintf(SF," }\n"); dprintf(SF," f=f-t*k*dli[i];\n"); dprintf(SF,"}\n"); dprintf(SF,"poly m=jet(1,f,%d)-jet(1,f,%d);\n",2*DIM,2*DIM-2); dprintf(SF,"matrix M=coef(m,dli[%d]",1); for (j=2; j<=p; j++) { dprintf(SF,"*dli[%d]",j); } dprintf(SF,");\n"); dprintf(SF,"for(i=1;i<=ncols(M);i++){\n"); dprintf(SF," M[2,i]=reduce(M[1,i]*HySurf,chow)/norm;\n"); dprintf(SF,"}\n"); dprintf(SF,"string colon=\",\";\n"); dprintf(SF,"string arrow=\"->\";\n"); dprintf(SF,"for(i=1;i<=ncols(M);i++){\n"); dprintf(SF," string(M[1,i],arrow,M[2,i],colon);}\n"); } /*####### Top. quant'ies of the divisors '#######*/ if(_Flag->d && DIM>1){ dprintf(SF,"\"SINGULAR -> topological quantities of the toric divisors:\";\n"); for(i=1; i<=p; i++){ dprintf(SF,"k=1;\n"); dprintf(SF,"for(j=1;j<=size(nonintersectingd);j++){\n"); dprintf(SF," if(dli[%d]==nonintersectingd[j]){k=0;}\n",i); dprintf(SF,"}\n"); dprintf(SF,"if(k==1){\n"); dprintf(SF,"poly ChernBottomD%d=1;\n",i); dprintf(SF,"for(i=1;i<=%d;i++){ChernBottomD%d=ChernBottomD%d+(-1)^i*(dli[%d])^i;}\n",DIM-1,i,i,i); dprintf(SF,"poly ChernD%d=ChernUp*ChernBottomD%d*ChernBottomHypersurface;\n",i,i); /*Chern classes of divisors*/ for (j=0;j=3 && eulerD[i]<=11 && reduce(c1D[i]^2*dli[i]*HySurf,chow)/norm >=1 && reduce(c1D[i]^2*dli[i]*HySurf,chow)/norm <= 9){" "for(j=1;j<=size(dli);j++){" "if(dli[j] != dli[i]){" "for(k=1;k<=size(dli);k++){" "v++;" "if(reduce(dli[i]*dli[j]*dli[k]*HySurf,chow)/norm == 0){u++;}" "}" "if(u < v){" "if(reduce(dli[j]*dli[i]*c1D[i]*HySurf,chow)/norm <= 0){" "p++;" "}" "} u=0; v=0;" "}" "}" "if(p==0){" "s++;" "dP[s]=dli[i];" "N[s]=eulerD[i]-3;" "}" "}" "}" "p=0;" "t=0;" /* index for no repetitions of div. classes */ "} "); dprintf(SF,"string DelPezzo;for(i=1;i<=size(dP);i++){DelPezzo=DelPezzo+string(dP[i])+\"(\"+string(N[i])+\")\"+\" \";};"); dprintf(SF,"list nonintDP; int g=0; int f=0; if(size(dP)>0){if(size(dP)>1){for(i=1;i<=size(dP);i++){for(j=1;j<=size(dP);j++){if(dP[j]!=dP[i]){for(k=1;k<=size(dli);k++){if(reduce(dP[i]*dP[j]*dli[k]*HySurf,chow)/norm!=0){g++;} ;};};}; if(g==0){f++; nonintDP[f]=dP[i];}; g=0;};} else {nonintDP[1]=dP[1];};};"); dprintf(SF,"string niDP;for(i=1;i<=size(nonintDP);i++){niDP=niDP+string(nonintDP[i])+\" \";};"); dprintf(SF, "\"dPs:\",size(dP),\";\",DelPezzo,\"nonint:\",size(nonintDP),\";\",niDP;"); } /*#############################################*/ } dprintf(SF,"quit;\n"); close(SF); #if (TEST_PRINT_SINGULAR_IO) CatFile(SFname); #endif if( system(SingularCall) ) {puts("Check Singular installation");exit(1);} remove(SFname); free(SFname); free(SingularCall); } palp-2.21/E_Poly.c0000664000177600017760000013422214572603263013305 0ustar skarkeskarke#include "Global.h" #include "Nef.h" #include "Rat.h" /* =============== Typedefs and Headers =================== */ #define min(a,b) (((a)<(b)) ? (a):(b)) #define max(a,b) (((a)>(b)) ? (a):(b)) void Sort_PPL(PolyPointList *_P, VertexNumList *_V); void part_nef(PolyPointList *, VertexNumList *, EqList *, PartList *, int *, NEF_Flags *); void IP_Fiber_Data(PolyPointList *, PolyPointList *,int nv, Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax],int fd[VERT_Nmax], int *nf,int CD); /* =============== End of Typedefs and Headers =================== */ /* =============== Begin of DYNamical Complete =================== */ void Print_DYN_PPL( DYN_PPL *_MP, const char *comment){ int i,j; if(_MP->np > 20){ fprintf(outFILE,"%d %d %s\n", (int) _MP->np,_MP->n, comment); for(i = 0; i < _MP->np; i++) { for(j = 0; j < _MP->n; j++) fprintf(outFILE,"%d ",(int) _MP->L[i].x[j]); fprintf(outFILE,"\n"); } } else { fprintf(outFILE,"%d %d %s\n",_MP->n, (int)_MP->np, comment); for(i = 0;i < _MP->n; i++) { for(j = 0; j < _MP->np; j++) fprintf(outFILE," %4d",(int) _MP->L[j].x[i]); fprintf(outFILE,"\n"); } } } void DYNadd_for_completion(Long *yDen, Long Den, EqList *_E, DYN_PPL *_CP){ int i,n=_CP->n; Long yold[POLY_Dmax]; if(Den>1) for(i=0;ine;i++) if (Eval_Eq_on_V(&(_E->e[i]), yold, n) < 0) return; if(!(_CP->np < _CP->NP_max)){ _CP->NP_max += 1000000; if((_CP->L=(Vector *)realloc(_CP->L,_CP->NP_max * sizeof(Vector))) == NULL) Die("Unable to realloc space for _CP->L"); } for(i=0;iL[_CP->np].x[i]=yold[i]; _CP->np++; } void DYNComplete_Poly(Long VPM[][VERT_Nmax], EqList *_E, int nv, DYN_PPL *_CP){ int i,j,k,l,InsPoint,rank=0,n=_CP->n; Long MaxDist[EQUA_Nmax], InvMat[POLY_Dmax][POLY_Dmax], Den=1; Long yDen[POLY_Dmax]; int OrdFac[VERT_Nmax], BasFac[POLY_Dmax], one[POLY_Dmax], position[POLY_Dmax]; LRat ind[POLY_Dmax][POLY_Dmax], x[POLY_Dmax], y[POLY_Dmax], f, PInvMat[POLY_Dmax][POLY_Dmax]; _CP->np=0; /* Calculate maximal distances from facets of Delta^* (Vertices of Delta) */ for (i=0;i<_E->ne;i++) { MaxDist[i]=0; for (j=0;jne;i++){ InsPoint=i; while (InsPoint&&(MaxDist[i]InsPoint;j--) OrdFac[j]=OrdFac[j-1]; OrdFac[InsPoint]=i; } /* Find first POLY_Dmax linearly independent facets + Inverse Matrix */ for (i=0;ie[OrdFac[i]].a[j]); for (j=0;j-1){ for (k=0;ke[BasFac[j]].a[k])); if (s!=Den*(i==j)) { puts("something wrong in Make_Dual_Poly"); exit(0);}}} /* Examine all integer points of parallelogram: */ /* The basic structure of the algorithm is: for (k=0;k=0){ position[k]++; DO AT position; for(k=n-1;((position[k]==MaxDist[BasFac[k]]-1)&&(k>=0));k--) position[k]=-1; } / * sets k to the highest value where pos.[k] wasn't the max value; resets the following max values to min values */ /* Quantities linear in position can be changed with every change of position (here: yDen) */ for(i=0;ie[BasFac[k]].c; for(i=0;ie[BasFac[k]].c*InvMat[i][k]; } position[n-1]=-_E->e[BasFac[n-1]].c-1; for(i=0;ie[BasFac[k]].c+1)*InvMat[i][n-1]; while(k>=0){ position[k]++; for(i=0;i=0);k--){ if (position[k]!=MaxDist[BasFac[k]]-_E->e[BasFac[k]].c) break; position[k]=-_E->e[BasFac[k]].c; for (i=0;ine;i++) for (j=0;j<_V->nv;j++) PM[i][j]=Eval_Eq_on_V(&_E->e[i],_P->L[_V->v[j]].x,_P->n); } /* =============== End of DYNamical Complete =================== */ /* =============== Begin of FIBRATIONS =================== */ void PRINT_APL(AmbiPointList *_AP, const char *comment){ int i,j; fprintf(outFILE,"%d %d %s\n", _AP->N, _AP->np, comment); for(i = 0; i < _AP->N; i++){ for(j = 0; j < _AP->np; j++) fprintf(outFILE,(_AP->np>20) ? " %2d" : " %4d", (int) _AP->x[j][i]); fprintf(outFILE,"\n"); } } void PRINT_MATRIX(Long *M, int l, int c, int C){ int i,j; for(j = 0; j < l; j++){ for(i = 0; i < c; i++) fprintf(outFILE,(c>20) ? " %3d" : " %4d", (int) *(M+i+C*j)); fprintf(outFILE,"\n"); } } void PRINT_TMATRIX(Long *M, int l, int c, int C){ int i,j; for(i = 0; i < c; i++){ for(j = 0; j < l; j++) fprintf(outFILE,(l>20) ? " %3d" : " %4d", (int) *(M+i+C*j)); fprintf(outFILE,"\n"); } } void PRINT_PL(PolyPointList *_P, const char *comment){ fprintf(outFILE,"%d %d %s\n", _P->n, _P->np, comment); PRINT_TMATRIX(&_P->x[0][0], _P->np, _P->n, POLY_Dmax); } void PRINT_GORE(PolyPointList *_P, int codim, int n, const char *comment){ PolyPointList *_P_AUX; VertexNumList *_V_AUX; EqList *_E_AUX; int i, j, Z=0; _P_AUX = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P_AUX == NULL) Die("Unable to alloc space for PolyPointLis _P_AUX"); _V_AUX = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V_AUX == NULL) Die("Unable to alloc space for VertexNumList _V_AUX"); _E_AUX = (EqList *) malloc(sizeof(EqList)); if (_E_AUX == NULL) Die("Unable to alloc space for EqList _E_AUX"); _P_AUX->n = _P->n - codim + 1; /* troubles if IP==0 not in last position: _P_AUX->np = _P->np - codim + 1; for(i = 0; i < _P_AUX->np; i++) for(j = 0; j < _P_AUX->n; j++) _P_AUX->x[i][j] = _P->x[i][j + codim - 1]; ** replaced by: */ _P_AUX->np = _P->np - codim; for(i = 0; i < _P->np; i++){ int z=0; j=0; while((j < _P_AUX->n)&&(!z)) {if(_P->x[i][j + codim - 1]) z=1; j++;}; if(z){ for(j = 0; j < _P_AUX->n; j++) _P_AUX->x[i-Z][j] = _P->x[i][j + codim - 1]; } else Z++;} for(j = 0; j < _P_AUX->n; j++) _P_AUX->x[_P_AUX->np][j] = 0; _P_AUX->np++; /* Print_PPL(_P_AUX,"Ref_Check input"); */ assert(Ref_Check(_P_AUX, _V_AUX, _E_AUX)); /* Find_Equations(_P_AUX, _V_AUX, _E_AUX); ... redundant */ if(n == 0){ Sort_PPL(_P_AUX, _V_AUX); fprintf(outFILE,"%d %d %s (nv=%d)\n",_P_AUX->n,_P_AUX->np,comment,_V_AUX->nv); for(i = 0; i < _P_AUX->n; i++){ for(j = 0; j < _P_AUX->np; j++) fprintf(outFILE,(_P_AUX->np>20) ? " %3d" : " %4d", (int) _P_AUX->x[j][i]); fprintf(outFILE,"\n"); } /*PRINT_PL(_P_AUX, comment);*/ } else{ Sort_VL(_V_AUX); Sort_PPL(_P, _V_AUX); if(n == 1) fprintf(outFILE,"%d %d %s (nv=%d)\n",_P->n,_P->np,comment,_V_AUX->nv ); if(n == 2){ int o; fprintf(outFILE,"%d %d %s (nv=%d)\n",_P->n+1,_P->np,comment,_V_AUX->nv ); for(j = 0; j < _P->np; j++){ o = 1; i = 0; while(o && (i < codim - 1)){ if(_P->x[j][i] == 1) o = 0; i++; } fprintf(outFILE,(_P->np>20) ? " %3d" : " %4d", o); } fprintf(outFILE,"\n"); } for(i = 0; i < _P->n; i++){ for(j = 0; j < _P->np; j++) fprintf(outFILE,(_P->np>20) ? " %3d" : " %4d", (int) _P->x[j][i]); fprintf(outFILE,"\n"); } } free(_P_AUX);free(_V_AUX);free(_E_AUX); } Long G_x_P(Long *Gi, Long *V, int *d){ Long x=0; int j; for(j=0;j<*d;j++) x+=Gi[j]*V[j]; return x; } void PRINT_Fibrations(VertexNumList *_V, PolyPointList *_P, Flags *_F /* ,PartList *_PTL */ ){ Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax]; int s[VERT_Nmax], CD=_F->f, n, c, i, j, fib, nf, nv, np, dim[VERT_Nmax]; PolyPointList *_P_AUX; VertexNumList *_V_AUX; EqList *_E_AUX; char C[VERT_Nmax]; _P_AUX = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P_AUX == NULL) Die("Unable to alloc space for PolyPointLis _P_AUX"); _V_AUX = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V_AUX == NULL) Die("Unable to alloc space for VertexNumList _V_AUX"); _E_AUX = (EqList *) malloc(sizeof(EqList)); if (_E_AUX == NULL) Die("Unable to alloc space for EqList _E_AUX"); if (_P->np >= VERT_Nmax) Die("Need _P->np < VERT_Nmax in PRINT_Fibrations"); IP_Fiber_Data(_P, _P_AUX, _V->nv, G, dim, &nf, CD); if (nf >= VERT_Nmax) Die("Need nf < VERT_Nmax in PRINT_Fibrations"); if(nf){ for(j = 0; j < _P->np - 1; j++) fprintf(outFILE,(_P->np > 20) ? "----" :"-----"); fprintf(outFILE," #fibrations=%d\n",nf); } for(n = 0; n < nf; n++){ c = 0; for(i = 0; i < (_P->np - 1) ; i++){ j = dim[n]; fib = 1; while((j < _P->n) && fib){ if (G_x_P(G[n][j], _P->x[i], &_P->n)) fib = 0; j++; } if(fib){ for(j = 0; j < dim[n]; j++) _P_AUX->x[c][j] = G_x_P(G[n][j], _P->x[i], &_P->n); s[c++] = i; } } _P_AUX->np = c; _P_AUX->n = dim[n]; assert(Ref_Check(_P_AUX, _V_AUX, _E_AUX)); for(i = 0; i < (_P->np-1); i++) C[i]='_'; for(i = 0; i < c; i++) C[s[i]] = 'p'; for(i = 0; i < _V_AUX->nv; i++) C[s[_V_AUX->v[i]]] = 'v'; for(i = 0; i < _P->np-1; i++) fprintf(outFILE,"%s%c", (_P->np > 20) ? " " : " ",C[i]); nv = _V_AUX->nv; np = (_P_AUX->np + 1); EL_to_PPL(_E_AUX, _P_AUX, &dim[n]); assert(Ref_Check(_P_AUX, _V_AUX, _E_AUX)); { Long X[VERT_Nmax][VERT_Nmax]; Make_VEPM(_P_AUX, _V_AUX, _E_AUX, X); Complete_Poly(X, _E_AUX, _V_AUX->nv, _P_AUX); /*Dim_Fib_CI(dim, n, _PTL, C);*/ fprintf(outFILE," cd=%d m:%3d %2d n:%2d %d\n",(_P->n - dim[n]), _P_AUX->np, _V_AUX->nv, np, nv); } } free(_P_AUX);free(_V_AUX);free(_E_AUX); } /* =============== End of FIBRATIONS =================== */ void Die(char *comment){ printf("\n%s\n",comment); exit(0); } void Time_Info(time_t *_Tstart, clock_t *_Cstart, const char *comment){ fprintf(outFILE, "%s %dsec %dcpu\n", comment, (int) /* CLOCKS_PER_SEC::10^6 */ difftime(time(NULL), *_Tstart), (int) ((((long long) clock() - *_Cstart) / (long long) CLOCKS_PER_SEC))); fflush(0); } void Print_Nefinfo(PartList *_PTL, /* Flags *_F,*/ time_t *_Tstart, clock_t *_Cstart){ int i, d = 0, p = 0; for(i = 0; i < _PTL->n; i++){ if(_PTL->DirProduct[i]) d++; } for(i = 0; i < _PTL->n; i++){ if(_PTL->Proj[i]) p++; } fprintf(outFILE, "np=%d d:%d p:%d %4dsec %4dcpu\n", _PTL->n-d-p, d, p, /* CLOCKS_PER_SEC::10^6 */ (int) difftime(time(NULL), *_Tstart), (int) ((((long long) clock() - *_Cstart) / (long long) CLOCKS_PER_SEC))); fflush(0); } int N_Part(PartList *_PTL){ int i; for(i = 0; i < _PTL->n; i++) if((!_PTL->DirProduct[i]) && (!_PTL->Proj[i])) return 1; return 0; } void Print_L(LInfo *_L, int p, int v) { int codim, D, i, j, N; if(v && p) Die("only -Lp OR -Lv !"); N = (v ? _L->nv : (_L->nv + 1)); if(v){ assert(FIB_POINT_Nmax >= N); fprintf(outFILE,"%d %d Vertices in N-lattice:\n",_L->d, N); for(j = 0; j < _L->d; j++){ for(i = 0; i < N; i++) fprintf(outFILE,(_L->nv > 20) ? " %3d" : " %4d", (int) _L->VM[i][j]); fprintf(outFILE,"\n"); } } for(j = 0; j < N; j++) fprintf(outFILE,(_L->nv > 20) ? "----" :"-----"); fprintf(outFILE,"\n"); assert(FIB_Nmax >= _L->nw); assert(FIB_POINT_Nmax >= _L->nv); for(i = 0; i < _L->nw; i++){ D = 0; codim = 0; for(j = 0; j < _L->nv; j++){ D += _L->W[i][j]; if(_L->W[i][j] == 0) codim++; } for(j = 0; j < _L->nv; j++) fprintf(outFILE,(N > 20) ? " %3d" : " %4d",(int) _L->W[i][j]); fprintf(outFILE," d=%d ",D); fprintf(outFILE,"codim=%d\n",codim+_L->d-_L->nv+1); } } void Make_L(PolyPointList *_P, VertexNumList *_V, LInfo *_L , int p, int v){ int i,j; if(v){ for(i = 0; i < _V->nv; i++) for(j = 0; j < _P->n; j++) _L->VM[i][j] = _P->x[_V->v[i]][j]; _L->nv = _V->nv; } if(p){ assert(_P->np <= VERT_Nmax); for(i = 0; i < _P->np; i++) for(j = 0; j < _P->n; j++) _L->VM[i][j] = _P->x[i][j]; _L->nv = (_P->np-1); } _L->Wmax = FIB_Nmax; _L->nw = 0; _L->d = _P->n; IP_Simplex_Decomp(_L->VM, _L->nv, _P->n, &_L->nw, _L->W, _L->Wmax,0); } int IntSqrt(int q) { /* sqrt(q) => r=1; r'=(q+r*r)/(2r); */ if (q == 0) return 0; if (q < 4) return 1; else { /* troubles: e.g. 9408 */ long long r = (q + 1) / 2, n; while (r > (n = (q + r * r) / (2 * r))) r = n; if (q < r * r) r--; if ((r * r <= q) && (q < (r + 1) * (r + 1))) return (int) r; else{ printf("Error in sqrt(%d)=%d\n", q, (int) n); exit(0); } } return 0; }void INCI_TO(int I[], INCI * _X, int *_n) { /* INCI X -> (0,0,1,0,.....,0,1,0);*/ int i; INCI Y = *_X; for (i = 0; i < *_n; i++) { if (INCI_M2(Y)) I[i] = 1; else I[i] = 0; Y = INCI_D2(Y); } } int Num_Pos(Cone *_C){ int d, n=2; for (d = 1; d < _C->dim; d++) n += _C->nface[d]; return n; } void Make_PosetList(Cone *_C, Poset_Element_List *_PEL){ int n = 0, d, i; for (d = 0; d <= _C->dim; d++) for (i = 0; i < _C->nface[d]; i++) { _PEL->L[n].dim = d; _PEL->L[n].num = i; n++; } } int Interval_Check(int rank, Poset_Element * _x, Poset_Element * _y, Cone * _C) { int flag = 0; if (_x->dim == (_y->dim - rank)) if (INCI_LE(_C->edge[_x->dim][_x->num], _C->edge[_y->dim][_y->num])) flag = 1; return flag; } void Make_Intervallist(Interval_List *_IL, Poset_Element_List *_PEL, Cone *_C){ int d, i, j; _IL->n = 0; for (d = 0; d <= _C->dim; d++) for (i = 0; i < _PEL->n; i++) for (j = 0; j <= i; j++) if (Interval_Check(d, &_PEL->L[j], &_PEL->L[i], _C) == 1) { _IL->L[_IL->n].min = j; _IL->L[_IL->n].max = i; _IL->n++; } } int Make_Mirror(EPoly *_EP, int h[][POLY_Dmax], int D, int dim) { int i, j, k, u, v, chi = 0, H; for (u = 0; u < 4*(Pos_Max); u++) for (v = 0; v < 3*(Pos_Max); v++){ if(((-2 * D + u) > dim) || ((-2 * D + u) < 0) || ((-2 * D + v) > dim) || ((-2 * D + v) < 0)){ if (_EP->E[u][v] != 0) Die("Something wrong with E poly"); } else { h[dim - (u - 2*D)][v - 2*D] = _EP->E[u][v]; chi += _EP->E[u][v]; if(((u - 2*D + v - 2*D) %2 ) != 0) h[dim - (u - 2*D)][v - 2*D] *= -1; } } if((dim %2) != 0) chi = chi*(-1); H = - dim*chi; for (i = 0; i <= dim; i++) for (j = 0; j <= dim; j++){ if(((i+j) %2) == 0) k = 1; else k = -1; H += 3*k*(2*i - dim)*(2*i - dim)*h[i][j]; } if (H != 0) Die("paper: CY 4-folds and toric fibrations; equation (8) don't hold"); if (dim == 4){ if((-h[2][2] + 44*h[0][0] + 4 * h[1][1] - 2 * h[1][2] + 4 * h[1][3] + 20 * h[0][2] - 52 * h[0][1]) != 0) Die("paper: CY 4-folds and toric fibrations; equation (9) don't hold"); } return chi; } int Max_S(PartList * _PTL, int *_n) { int i, k, m = 0, nv, Nv = 0; for (i = 0; i < _PTL->codim; i++) { nv = 0; for (k = 0; k < _PTL->nv; k++) if (_PTL->S[*_n][k] == i) nv++; if (Nv < nv) { Nv = nv; m = i; } } return m; } void PrintDegrees( /*Flags *_F,*/ LInfo *_L, PartList *_PTL, int m, /*int n, */ int S[VERT_Nmax]) { int d[POLY_Dmax], i, j; for (i = 0; i < _L->nw; i++){ fprintf(outFILE," ("); for (j = 0; j < _PTL->codim; j++) d[j] = 0; for (j = 0; j < _L->nv; j++) d[S[j]] += _L->W[i][j]; for (j = 0; j < _PTL->codim; j++) if(j != m) fprintf(outFILE,"%d ",d[j]); fprintf(outFILE,"%d",d[m]); fprintf(outFILE,")"); } } void PrintWeights(CWS * _W) { int i,j; for (i = 0; i < _W->nw; i++) { fprintf(outFILE, "%ld", (long) _W->d[i]); for (j = 0; j < _W->N; j++) fprintf(outFILE, " %ld", (long) _W->W[i][j]); if (i != (_W->nw - 1)) fprintf(outFILE, " "); } } void PrintDiamond(int h[][POLY_Dmax], int dim) { int i,j; fprintf(outFILE, "\n\n"); fflush(0); for (i = 0; i <= dim; i++) { fprintf(outFILE, " "); for (j = 0; j <= (dim - i); j++) fprintf(outFILE, " "); for (j = 0; j <= i; j++) fprintf(outFILE, " h%2d%2d ", i - j, j); fprintf(outFILE, "\n\n"); fflush(0); } for (i = 1; i <= dim; i++) { fprintf(outFILE, " "); for (j = 0; j <= i; j++) fprintf(outFILE, " "); for (j = i; j <= dim; j++) fprintf(outFILE, " h%2d%2d ", dim - j + i, j); fprintf(outFILE, "\n\n"); fflush(0); } fprintf(outFILE, "\n\n");fflush(0); for (i = 0; i <= dim; i++) { fprintf(outFILE, " "); for (j = 0; j <= (dim - i); j++) fprintf(outFILE, " "); for (j = 0; j <= i; j++) fprintf(outFILE, "%10d", h[i - j][j]); fprintf(outFILE, "\n\n"); } for (i = 1; i <= dim; i++) { fprintf(outFILE, " "); for (j = 0; j <= i; j++) fprintf(outFILE, " "); for (j = i; j <= dim; j++) fprintf(outFILE, "%10d", h[dim - j + i][j]); fprintf(outFILE, "\n\n"); } fflush(0); } void Print_Points(PolyPointList *_P, int c, int nv, int S[VERT_Nmax]){ int i, P=0; for(i = nv; i < (_P->np - 1); i++) if(S[i] == c){ fprintf(outFILE,"%d ",i); P=1; } if(P) fprintf(outFILE," "); } void Output(PolyPointList * _P, /* PolyPointList * _DP,*/ PolyPointList * _P_D, CWS * _W, EPoly *_EP, /* EqList * _E,*/ VertexNumList * _V, int *_n, PartList *_PTL, int *_codim, FILE *outFILE, Flags * _F, int *_D, LInfo *_L) { int i, j, k, m, chi = 0, D = (_P_D->n + 1), dim = (_P->n - *_codim); int h[POLY_Dmax][POLY_Dmax] = {{0}, {0}}, S[VERT_Nmax]; m = Max_S(_PTL, _n); if (((!_PTL->DirProduct[*_n]) || _F->Dir) && ((!_PTL->Proj[*_n]) || _F->Proj)) { if (_F->H == 0){ if (_F->w){ PrintWeights(_W); fprintf(outFILE, " "); } #ifdef WRITE_CWS if (_F->Msum == 1) fprintf(outFILE, " d=%d %d", (int) _D[0], (int) _D[1]); #endif if (!_F->p){ chi = Make_Mirror(_EP, h, D, dim); fprintf(outFILE, "H:"); for (i = 1; i < dim; i++) fprintf(outFILE, "%d ", h[1][i]); fprintf(outFILE, "[%d]", chi); for (i = 1; i <= dim/2; i++) if (h[0][i] != 0) fprintf(outFILE, " h%d=%d", i, h[0][i]); if(h[0][0] != 1){ if (_PTL->DirProduct[*_n]) fprintf(outFILE, " h%d=%d", 0, h[0][0]); else Die("\nh00 not 1 !!!\n"); } } if((_P_D->np - *_codim) <= VERT_Nmax) for(i = 0; i < (_P_D->np - *_codim); i++){ S[i] = 0; for(j = 0; j < (*_codim - 1); j++) if(_P_D->x[i][j]) S[i] = (j+1); } if (*_codim == 2) { fprintf(outFILE, " P:%d V:", *_n); i = 0; if (m == 0) i = 1; for (j = 0; j < _PTL->nv; j++) if (_PTL->S[*_n][j] == i) fprintf(outFILE, "%d ", j); fprintf(outFILE," "); if((_P_D->np - *_codim) <= VERT_Nmax) Print_Points(_P, i, _V->nv, S); else fprintf(outFILE, " _P->np > VERT_Nmax! "); } else { fprintf(outFILE, " P:%d ", *_n); j = 0; for (i = 0; i < *_codim; i++) if (i != m) { fprintf(outFILE, "V%d:", j); for (k = 0; k < _PTL->nv; k++) if (_PTL->S[*_n][k] == i) fprintf(outFILE, "%d ", k); fprintf(outFILE," "); j++; if((_P_D->np - *_codim) <= VERT_Nmax) Print_Points(_P, i, _V->nv, S); else fprintf(outFILE, " _P->np > VERT_Nmax! "); } } if(_PTL->DProj[*_n]) fprintf(outFILE, "DP "); if(_PTL->DirProduct[*_n]) fprintf(outFILE, " D"); if(_F->Lv || (_F->Lp && (_P_D->np - *_codim) <= VERT_Nmax)) PrintDegrees(/*_F,*/ _L, _PTL, m, /* *_n,*/ S); fflush(0); } else{ chi = Make_Mirror(_EP, h, D, dim); PrintDiamond(h, dim); } } } int Min_Dim(int n, int T_flag) { if (!T_flag){ int i; i = n / 2; if((n % 2) != 0) i += 1; return i; } else return n; } void Init_ST(SPoly *_S, SPoly *_T, Poset_Element_List *_PEL) { int i, d; for(i = 0; i < _PEL->n; i++){ for(d = 1; d <= _PEL->L[i].dim; d++){ _S[i].S[d] = 0; _T[i].S[d] = 0; } _S[i].S[0] = 1; _T[i].S[0] = 0; } } Long Eval_Eq_on_x(Long *_x, Equation *_E, int dim){ Long c = _E->c; int d; for(d = 0; d < dim; d++) c += _x[d] * _E->a[d]; return c; } INCI INCI_to_x(int n, DYN_PPL *_P, EqList *_E){ INCI X = INCI_0(); int i; for(i = 0; i < _E->ne; i++) X = INCI_PN(X,Eval_Eq_on_x(_P->L[n].x, &_E->e[i], _P->n)); return X; } void Poly_To_ST(DYN_PPL *_P, EqList *_E, Cone *_C, SPoly *_S, SPoly *_T, Poset_Element_List *_PEL, int l, int T_flag) { int min, i, dim_flag, in_flag, n, dim, num; INCI X; min = Min_Dim(l, T_flag); for(i = 0; i < _P->np; i++){ dim_flag = 1; in_flag = 0; n = (_PEL->n - 1); X = INCI_to_x(i, _P, _E); while(dim_flag && !in_flag){ dim = (_C->dim - _PEL->L[n].dim); num = (_C->nface[dim] - _PEL->L[n].num -1); if (INCI_LE(_C->edge[dim][num], X)){ _S[n].S[l] += 1; if (INCI_LE(X, _C->edge[dim][num])){ _T[n].S[l] += 1; in_flag = 1; } } n--; if (_PEL->L[n].dim < min) dim_flag = 0; } } } void New_CPVE(PolyPointList *_P, DYN_PPL *_CP, VertexNumList *_V, VertexNumList *_CV, EqList *_E, EqList *_CE, int n) { int j, d, nv = 0; for(j = 0; j < _E->ne; j++){ _CE->e[j].c = n*(_E->e[j].c); for(d = 0; d < _P->n; d++) _CE->e[j].a[d] = _E->e[j].a[d]; } for(j = 0; j < _V->nv; j++){ for(d = 0; d < _P->n; d++) _CP->L[nv].x[d] = n*(_P->x[_V->v[j]][d]); _CV->v[nv] = nv; nv++; } _CV->nv = _V->nv; _CP->np = _V->nv; _CP->n = _P->n; _CE->ne = _E->ne; } void Poly_To_DYNPoly(DYN_PPL *_CP, PolyPointList *_P){ int i, d; assert(_P->np <= _CP->NP_max); for(i = 0; i < _P->np; i++) for(d = 0; d < _P->n; d++) _CP->L[i].x[d] = _P->x[i][d]; _CP->n = _P->n; _CP->np = _P->np; } void Make_S_Poly(Cone *_C, VertexNumList *_V, EqList *_E, PolyPointList *_P, Poset_Element_List *_PEL, SPoly *_S, int SINFO, int CHECK_SERRE) { Long PM[EQUA_Nmax][VERT_Nmax]; DYN_PPL CP; VertexNumList *_CV; EqList *_CE; SPoly *_T; int i=1, j, d, min; CP.NP_max = NP_Max; min = Min_Dim(_C->dim,CHECK_SERRE); CP.L = (Vector *) calloc(CP.NP_max, sizeof(Vector)); if (CP.L == NULL) Die("Unable to alloc space for PolyPointList _CP.L"); _CV = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_CV == NULL) Die("Unable to alloc space for VertexNumList _CV"); _CE = (EqList *) malloc(sizeof(EqList)); if (_CE == NULL) Die("Unable to alloc space for EqList _CE"); _T = (SPoly *) calloc(_PEL->n, sizeof(SPoly )); if (_T == NULL) Die("Unable to alloc space for SPoly _T"); Poly_To_DYNPoly(&CP, _P); Init_ST(_S, _T, _PEL); Poly_To_ST(&CP, _E, _C, _S, _T, _PEL, i, CHECK_SERRE); if(SINFO){ printf("\n\n#points in largest cone:\n"); printf("layer: %2d #p: %8d #ip: %8d\n", i=1, (int) _S[_PEL->n-1].S[1], (int)_T[_PEL->n-1].S[1]); } for (i = 2; i <= min; i++) { New_CPVE(_P, &CP, _V, _CV, _E, _CE, i); DYNMake_VEPM(&CP,_CV,_CE, PM); DYNComplete_Poly(PM, _CE, _V->nv, &CP); Poly_To_ST(&CP, _CE, _C, _S, _T, _PEL, i, CHECK_SERRE); if(SINFO) printf("layer: %2d #p: %8d #ip: %8d\n",i, (int)_S[_PEL->n-1].S[i], (int) _T[_PEL->n-1].S[i]); } for(i = 0; i < _PEL->n; i++){ for (j = 0; j < _PEL->L[i].dim; j++){ min = Min_Dim(_PEL->L[i].dim, CHECK_SERRE); for (d = min; d > 0; d--) { _S[i].S[d] += -_S[i].S[d - 1]; _T[i].S[d] += -_T[i].S[d - 1]; } } if(CHECK_SERRE){ for (d = 1; d < _PEL->L[i].dim; d++) if(_S[i].S[d] != _T[i].S[_PEL->L[i].dim - d]){ puts("No Serre Duality!"); for(d = 1; d < _PEL->L[i].dim; d++) printf("S[%d]: %3d T[%d]: %3d\n",d, (int) _S[i].S[d], (_PEL->L[i].dim - d), (int) _T[i].S[_PEL->L[i].dim - d]); exit(0); } } if (!CHECK_SERRE){ for (d = 1; d < _PEL->L[i].dim / 2; d++) _S[i].S[_PEL->L[i].dim - d] = _T[i].S[d]; if (_PEL->L[i].dim != 0) _S[i].S[_PEL->L[i].dim] = 0; } } free(_T);free(_CV);free(_CE);free(CP.L); } void SB_To_E(EPoly *_EP, Cone *_C, Poset_Element_List *_PEL, BPoly * _BL, Interval_List * _IL, SPoly *_S_D, SPoly *_S_N, int *_codim){ /* E[0][0] = E[2*_C->dim][2*_C->dim] */ int i, j, x, y, u, v, s, dim, dmax, dmin; for (u = 0; u < 4*(Pos_Max); u++) for (v = 0; v < 4*(Pos_Max); v++) _EP->E[u][v] = 0; for (i = 0; i < _IL->n; i++) { dmin = _PEL->L[_IL->L[i].min].dim; dmax = _PEL->L[_IL->L[i].max].dim; dim = dmax - dmin; s = 1; for (j = 0; j < dmin; j++) s *= -1; for (y = 0; y < (_C->dim - dmax + 1); y++) for (x = 0; x < (dmin + 1); x++) for (u = 0; u < (dim + 1); u++) for (v = 0;v <= (dim / 2); v++) _EP->E[2*_C->dim - x + y + dmax - u - *_codim] [2*_C->dim + y + x + v - *_codim] += _S_D[_IL->L[i].min].S[x] * _S_N[_PEL->n - _IL->L[i].max - 1].S[y] * _BL[i].B[u][v] * s; } } void Make_Cone(Cone * _C_D, Cone * _C_N, FaceInfo * _I, PolyPointList * _P) { int d, i; _C_D->dim = (_P->n + 1); _C_N->dim = (_P->n + 1); _C_D->nface[0] = 1; _C_N->nface[0] = 1; _C_D->nface[_P->n + 1] = 1; _C_N->nface[_P->n + 1] = 1; _C_D->edge[0][0] = INCI_0(); _C_N->edge[0][0] = INCI_0(); _C_D->edge[_C_D->dim][0] = INCI_0(); for (i = 0; i < _I->nf[0]; i++) _C_D->edge[_C_D->dim][0] = INCI_OR(_C_D->edge[_C_D->dim][0], _I->v[0][i]); _C_N->edge[_C_N->dim][0] = INCI_0(); for (i = 0; i < _I->nf[_P->n - 1]; i++) _C_N->edge[_C_N->dim][0] = INCI_OR(_C_N->edge[_C_N->dim][0], _I->f[_P->n - 1][i]); for (d = 0; d < _P->n; d++) { _C_D->nface[d + 1] = _I->nf[d]; _C_N->nface[_C_D->dim - d -1] = _I->nf[d]; for (i = 0; i < _I->nf[d]; i++) { _C_D->edge[d + 1][i] = _I->v[d][i]; _C_N->edge[_C_D->dim - d -1][_I->nf[d] - i -1] = _I->f[d][i]; } } } void Make_EN(PolyPointList * _P, VertexNumList * _V, EqList * _EN, int *_codim) { int x, i, j; _EN->ne = _V->nv; for (i = 0; i < _V->nv; i++) { x = 1; j = 0; while((x == 1) && (j < (*_codim - 1))){ if(_P->x[_V->v[i]][j] == 1) x = 0; j++; } _EN->e[i].c = x; for (j = 0; j < _P->n; j++){ if(j < *_codim - 1) _EN->e[i].a[j] = _P->x[_V->v[i]][j] - x; else _EN->e[i].a[j] = _P->x[_V->v[i]][j]; } } } int Remove_Proj(PolyPointList * _P, /* int *_n,*/ int *_codim) { int nv, Nv=0, j, i = 0, proj_flag = 0; while (!proj_flag && (i < *_codim - 1)) { nv=0; for(j = 0; j < _P->np; j++) if(_P->x[j][i] == 1) nv++; Nv += nv; if(nv == 2) proj_flag = 1; i++; } if((_P->np - Nv) == 2) proj_flag = 1; return proj_flag; } void Make_Gore_Poly(PolyPointList * _P, PolyPointList * _DP, PolyPointList * _P_D, PolyPointList * _P_N, VertexNumList * _V, PartList * _PTL, int *_codim, int *_n) { /*_P_N from _DP (in M-lattice), _P_D from _P (in N-lattice) */ int i, l, k, d, sum, ip, c; if(*_codim <= 0) Die("Need Codim > 0"); _P_N->n = _DP->n + *_codim - 1; _P_N->np = 0; for (l = 0; l < _DP->np; l++) { for (i = 0; i < *_codim; i++) { ip = 1; k = 0; while (ip && (k < _PTL->nv)) { sum = 0; for (d = 0; d < _DP->n; d++) sum += _DP->x[l][d] * _P->x[_V->v[k]][d]; if (((_PTL->S[*_n][k] == i) && (sum < -1)) || ((_PTL->S[*_n][k] != i) && (sum < 0))) ip = 0; k++; } if (ip == 1) { assert(_P_N->np < POINT_Nmax); for (d = 0; d < _DP->n; d++) _P_N->x[_P_N->np][d + *_codim - 1] = _DP->x[l][d]; for (d = 1; d < *_codim; d++) { if (d == i) _P_N->x[_P_N->np][d - 1] = 1; else _P_N->x[_P_N->np][d - 1] = 0; } _P_N->np++; } } } _P_D->n = _P->n + *_codim - 1; _P_D->np = 0; for (l = 0; l < _P->np; l++) { for (i = 0; i < *_codim; i++) { ip = 1; k = 0; while (ip && (k < _P_N->np)) { sum = 0; for (d = 0; d < _P->n; d++) sum += _P->x[l][d] * _P_N->x[k][d + *_codim - 1]; if (i > 0) { if (((_P_N->x[k][i - 1] == 1) && (sum < -1)) || ((_P_N->x[k][i - 1] == 0) && (sum < 0))) ip = 0; } else { c = -1; for (d = 0; d < *_codim - 1; d++) if (_P_N->x[k][d] == 1) c = 0; if (sum < c) ip = 0; } k++; } if (ip == 1) { assert(_P_D->np < POINT_Nmax); for (d = 0; d < _P->n; d++) _P_D->x[_P_D->np][d + *_codim - 1] = _P->x[l][d]; for (d = 1; d < *_codim; d++) { if (d == i) _P_D->x[_P_D->np][d - 1] = 1; else _P_D->x[_P_D->np][d - 1] = 0; } _P_D->np++; } } } } Poset Int_Pos(int i, Interval_List * _IL, Poset_Element_List * _PEL) { Poset P; P.x = _PEL->L[_IL->L[i].min]; P.y = _PEL->L[_IL->L[i].max]; return P; } void M_To_B(BPoly *_BP, BPoly *_MP, int d, int rho){ int M[Pos_Max][Pos_Max] = {{0}, {0}}, i, u, v; if(rho == 0) M[0][0] = 1; else for(u = 0; u <= rho; u++) for(v = 0; v < rho/2 + (rho % 2); v++) M[rho - u][rho - v] = _MP->B[u][v]; for(i = 1; i <= d - rho; i++){ for(u = rho + i; u > 0; u--) /* (u degree != 0) && (v degree != 0) */ for(v = rho + i; v > 0; v--) M[u][v] = - M[u-1][v] + M[u][v-1]; for(v = rho + i; v > 0; v--) /* (u degree == 0) && (v degree != 0) */ M[0][v] = M[0][v-1]; for(u = rho + i; u > 0; u--) /* (u degree != 0) && (v degree == 0) */ M[u][0] = - M[u-1][0]; M[0][0] = 0; /* (u degree == 0) && (v degree == 0) */ } for(u = 0; u <= d; u++) for(v = 0; v < d/2 + (d % 2); v++) _BP->B[u][v] += M[u][v]; } void N_To_B(BPoly *_BP, BPoly *_NP, int d, int rho){ int N[Pos_Max][Pos_Max] = {{0}, {0}}, i, u, v; if(rho == 0) N[0][0] = 1; else for(u = 0; u <= rho; u++) for(v = 0; v < rho/2 + (rho % 2); v++) N[u][v] = _NP->B[u][v]; for(i = 1; i <= d - rho; i++){ for(u = rho + i; u > 0; u--) /* (u degree != 0) && (v degree != 0) */ for(v = rho / 2 + i; v > 0; v--) N[u][v] = N[u-1][v-1] - N[u][v]; for(v = rho/2 + i; v > 0; v--) /* (u degree == 0) && (v degree != 0) */ N[0][v] *= -1; for(u = rho + i; u >= 0; u--) /* (u degree >= 0) && (v degree == 0) */ N[u][0] *= -1; } for(u = 0; u <= d; u++) for(v = 0; v < d/2 + (d % 2); v++) _BP->B[u][v] -= N[u][v]; } void Make_B_Poly(Cone * _C, Poset_Element_List * _PEL, Interval_List * _IL, BPoly *_BL) { int D, i, j, k, d, n, n_; Poset Pos, pos; for (i = 0; i < _IL->n; i++) { Pos = Int_Pos(i, _IL, _PEL); d = (Pos.y.dim - Pos.x.dim); for (j = 0; j <= d; j++) for (k = 0; k <= d / 2; k++) _BL[i].B[j][k] = 0; if (d == 0) _BL[i].B[0][0] = 1; } for (D = 1; D <= _C->dim; D++) for (n = 0; n < _IL->n; n++) { Pos = Int_Pos(n, _IL, _PEL); if ((Pos.y.dim - Pos.x.dim) == D) { for (d = 0; d < D; d++) for (n_ = 0; n_ < n; n_++) { pos = Int_Pos(n_, _IL, _PEL); if (Interval_Check(0, &pos.x, &Pos.x, _C)) if (Interval_Check((D - d), &pos.y, &Pos.y, _C)) M_To_B(&_BL[n], &_BL[n_], D, d); if (Interval_Check(0, &pos.y, &Pos.y, _C)) if (Interval_Check((D - d), &Pos.x, &pos.x, _C)) N_To_B(&_BL[n], &_BL[n_], D, d); } } } } void Compute_E_Poly(EPoly *_EP, PolyPointList * _P_D, VertexNumList * _V_D, EqList * _E_D, PolyPointList * _P_N, VertexNumList * _V_N, EqList * _E_N, int *_codim, Flags * _F, time_t *_Tstart, clock_t *_Cstart){ /* Should compute _EP from the rest. Probably requires alignment of _E_D with _V_N and of _V_D with _E_N */ Interval_List IL; SPoly *_S_D = NULL, *_S_N = NULL; BPoly *_BL = NULL; Poset_Element_List PEL_D, PEL_N; FaceInfo *_I_D; Cone *_C_D, *_C_N; _I_D = (FaceInfo *) malloc(sizeof(FaceInfo)); if (_I_D == NULL) Die("Unable to alloc space for FaceInfo _I_D"); _C_D = (Cone *) malloc(sizeof(Cone)); if (_C_D == NULL) Die("Unable to alloc space for Cone _C_D"); _C_N = (Cone *) malloc(sizeof(Cone)); if (_C_N == NULL) Die("Unable to alloc space for Cone _C_N"); Make_Incidence(_P_D, _V_D, _E_D, _I_D); Make_Cone(_C_D, _C_N, _I_D, _P_D); PEL_D.n = Num_Pos(_C_D); PEL_N.n = Num_Pos(_C_N); PEL_D.L = (Poset_Element *) calloc(PEL_D.n, sizeof(Poset_Element)); if (PEL_D.L == NULL) Die("Unable to alloc space for PEL_D.L"); PEL_N.L = (Poset_Element *) calloc(PEL_D.n, sizeof(Poset_Element)); if (PEL_N.L == NULL) Die("Unable to alloc space for PEL_N.L"); Make_PosetList(_C_D, &PEL_D); Make_PosetList(_C_N, &PEL_N); if(_F->t) Time_Info(_Tstart, _Cstart, " BEGIN S-Poly"); _S_D = (SPoly *) calloc(PEL_D.n, sizeof(SPoly )); if (_S_D == NULL) Die("Unable to alloc space for SPoly _S_D"); _S_N = (SPoly *) calloc(PEL_D.n, sizeof(SPoly )); if (_S_N == NULL) Die("Unable to alloc space for SPoly _S_N"); Make_S_Poly(_C_N, _V_D, _E_D, _P_D, &PEL_D, _S_D, _F->S, _F->T); Make_S_Poly(_C_D, _V_N, _E_N, _P_N, &PEL_N, _S_N, _F->S, _F->T); if(_F->t) Time_Info(_Tstart, _Cstart, " BEGIN B-Poly"); IL.L = (Interval *) calloc(((1 + PEL_D.n)/2 + 1)*PEL_D.n, sizeof(Interval)); if (IL.L == NULL) Die("Unable to alloc space for IL.L"); Make_Intervallist(&IL, &PEL_D, _C_D); _BL = (BPoly *) calloc(IL.n, sizeof(BPoly)); if (_BL == NULL) Die("Unable to alloc space for _BL"); Make_B_Poly(_C_D, &PEL_D, &IL, _BL); if(_F->t) Time_Info(_Tstart, _Cstart, " BEGIN E-Poly"); SB_To_E(_EP, _C_D, &PEL_D, _BL, &IL, _S_D, _S_N, _codim); free(PEL_D.L); free(PEL_N.L); free(_S_D); free(_S_N); free(IL.L); free(_BL); free(_I_D); free(_C_D); free(_C_N); } void Make_E_Poly(FILE * outFILE, CWS * _W, PolyPointList * _CP, VertexNumList * _CV, EqList * _CE, int *_codim, Flags * _F, int *_D) { time_t Tstart; clock_t Cstart; int n; /* Interval_List IL; SPoly *_S_D = NULL, *_S_N = NULL; BPoly *_BL = NULL; */ EPoly EP; /* Poset_Element_List PEL_D, PEL_N;*/ PartList *_PTL; PolyPointList *_P = NULL, *_DP = NULL, *_P_D, *_P_N; VertexNumList *_V = NULL, *_DV = NULL, *_V_D, *_V_N; EqList *_E = NULL, *_DE = NULL, *_E_D, *_E_N; /*FaceInfo *_I_D; Cone *_C_D, *_C_N;*/ LInfo *_L = NULL; /* =============== Begin of Static Allocation =================== */ _PTL = (PartList *) malloc(sizeof(PartList)); if (_PTL == NULL) Die("Unable to alloc space for PartList _PTL"); _P_D = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P_D == NULL) Die("Unable to alloc space for PolyPointLis _P_D"); _P_N = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P_N == NULL) Die("Unable to alloc space for PolyPointLis _P_N"); _V_D = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V_D == NULL) Die("Unable to alloc space for VertexNumList _V_D"); _V_N = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V_N == NULL) Die("Unable to alloc space for VertexNumList _V_N"); _E_D = (EqList *) malloc(sizeof(EqList)); if (_E_D == NULL) Die("Unable to alloc space for EqList _E_D"); _E_N = (EqList *) malloc(sizeof(EqList)); if (_E_N == NULL) Die("Unable to alloc space for EqList _E_N"); if (_F->Lv || _F->Lp){ _L = (LInfo *) malloc(sizeof(LInfo)); if (_L == NULL) Die("Unable to alloc space for LInfo _L"); } if(_F->N){ _DP = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_DP == NULL) Die("Unable to alloc space for PolyPointLis _DP"); _DV = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_DV == NULL) Die("Unable to alloc space for VertexNumList _DV"); _DE = (EqList *) malloc(sizeof(EqList)); if (_DE == NULL) Die("Unable to alloc space for EqList _DE"); } else{ _P = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P == NULL) Die("Unable to alloc space for PolyPointLis _P"); _V = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V == NULL) Die("Unable to alloc space for VertexNumList _V"); _E = (EqList *) malloc(sizeof(EqList)); if (_E == NULL) Die("Unable to alloc space for EqList _E"); } /* =============== End of Static Allocation =================== */ if(_F->N){ _P=_CP; _E=_CE; _V=_CV; Make_Dual_Poly(_P, _V, _E, _DP); Find_Equations(_DP, _DV, _DE); Sort_PPL(_DP, _DV); } else{ _DP=_CP; _DE=_CE; _DV=_CV; Make_Dual_Poly(_DP, _DV, _DE, _P); Find_Equations(_P, _V, _E); Sort_PPL(_P, _V); } Tstart = time(NULL); Cstart = clock(); _F->Test = 0;fflush(0); { NEF_Flags NF; NF.Sym=_F->Sym; NF.noconvex=_F->noconvex; NF.Test=0; NF.Sort=_F->Sort; part_nef(_P, _V, _E, _PTL, _codim, &NF); if(_F->y && (_PTL->n != 0) && (_W->nw == 0)) fprintf(outFILE, "%d %d Vertices of Poly in M-lattice: ", _DP->n, _DV->nv); if(!(_F->y && (_PTL->n==0))){ fprintf(outFILE, "M:%d %d N:%d %d ", _DP->np, _E->ne, _P->np, _V->nv); fprintf(outFILE, " codim=%d", *_codim); fprintf(outFILE, " #part="); fflush(0); fprintf(outFILE, "%d\n",_PTL->n);fflush(0); } } if(_F->y && (_W->nw == 0) && (_PTL->n != 0)) PRINT_TMATRIX(&_DP->x[0][0], _DV->nv, _DP->n, POLY_Dmax); if(_F->V) Print_VL(_P, _V, "Vertices of P:"); if((!_F->Lv) && (!_F->n) && _F->Lp) PRINT_PL(_P, "Points of Poly in N-Lattice:"); if(_F->Lv || _F->Lp){ Make_L(_P, _V, _L ,_F->Lp,_F->Lv); Print_L(_L,_F->Lp,_F->Lv); } if(_F->f){ if(_F->Lv) PRINT_PL(_P, "Points of Poly in N-Lattice:"); PRINT_Fibrations(_V, _P, _F /*, _PTL*/ ); } for (n = 0; n < _PTL->n; n++) { /*if ((!_PTL->DirProduct[n]) || _F->Dir){*/ if(_F->Dir==2) if(!_PTL->DirProduct[n]) continue ; Tstart = time(NULL); Cstart = clock(); Make_Gore_Poly(_P, _DP, _P_D, _P_N, _V, _PTL, _codim, &n); _PTL->Proj[n] = Remove_Proj(_P_D, /*&n,*/ _codim); _PTL->DProj[n] = Remove_Proj(_P_N, /*&n,*/ _codim); Find_Equations(_P_D, _V_D, _E_D); Find_Equations(_P_N, _V_N, _E_N); Sort_PPL(_P_N, _V_N); if (((!_PTL->Proj[n]) || _F->Proj) && ((!_PTL->DirProduct[n]) || _F->Dir) && !_F->p && !_F->y) { Make_EN(_P_D, _V_D, _E_N, _codim); Compute_E_Poly(&EP, _P_D, _V_D, _E_D, _P_N, _V_N, _E_N, _codim, _F, &Tstart, &Cstart);} /*for (i=0;i<=10;i++){ for (j=0;j<=10;j++) fprintf(outFILE,"%d ",EP.E[i][j]); fprintf(outFILE,"\n");}*/ if(!_F->n && !_F->g && !_F->d && !_F->y){ Output( _P, /*_DP,*/ _P_D, _W, &EP, /*_E,*/ _V, &n, _PTL, _codim, outFILE, _F, _D, _L); if (((!_PTL->Proj[n]) || _F->Proj) && ((!_PTL->DirProduct[n]) || _F->Dir)) Time_Info(&Tstart, &Cstart, ""); } if (((!_PTL->Proj[n]) || _F->Proj) && ((!_PTL->DirProduct[n]) || _F->Dir)){ if(_F->g) PRINT_GORE(_P_D, *_codim, _F->gd, "Points of PG:"); if(_F->d) PRINT_GORE(_P_N, *_codim, _F->dd, "Points of dual PG:"); } } if(!_F->n && !_F->g && !_F->d && !_F->y) Print_Nefinfo(_PTL, /* _F,*/ &Tstart, &Cstart); if(_F->n && N_Part(_PTL)) PRINT_PL(_P, "Points of Poly in N-Lattice:"); /* =============== Begin of FREE Static Allocation =================== */ free(_PTL);free(_P_D); free(_P_N); free(_V_D); free(_V_N); free(_E_D); free(_E_N); free(_L); if(_F->N){free(_DP); free(_DE); free(_DV); } else{free(_P); free(_E); free(_V); } /* =============== End of FREE Static Allocation =================== */ } void SL2Z_Make_Poly_UTriang(PolyPointList *P); void AnalyseGorensteinCone(CWS *_CW, PolyPointList *_P, VertexNumList *_V, EqList *_E, int *_codim, Flags * _F){ /* _P should be the Gorenstein-polytope in M - what is called _P_N in certain other parts of the program */ time_t Tstart; clock_t Cstart; EPoly EP; int i, j, k, dim = _P->n - (*_codim * 2) + 1, chi, r=1; int h[POLY_Dmax][POLY_Dmax] = {{0}, {0}}; PolyPointList *_P_D = (PolyPointList *) malloc(sizeof(PolyPointList)); VertexNumList *_V_D = (VertexNumList *) malloc(sizeof(VertexNumList)); EqList *_E_D = (EqList *) malloc(sizeof(EqList)); /* the Gorenstein-polytope in N-lattice and its vertices and equations */ EqList *_new_E_D = (EqList *) malloc(sizeof(EqList)); /* the equations of _P_D in an order corresponding to the vertices of _P */ PairMat VPM, VPM_D; if ((_P_D == NULL)||(_V_D == NULL)||(_E_D == NULL)||(_new_E_D == NULL)) Die("Unable to allocate space for _P_D in AnalyseGorensteinCone"); if (POLY_Dmax < _P->n + 1){/* only relevant if index == 1 */ printf("Please increase POLY_Dmax to at least %d = %d + 1\n", (_P->n + 1), _P->n); printf("(POLY_Dmax >= dim(cone) = dim(support) + 1 required)\n"); assert(*_codim == 1); exit(0);} /* Print_PPL(_P, "_P before sorting");fflush(0); */ Find_Equations(_P,_V,_E); Make_VEPM(_P, _V, _E, VPM); Complete_Poly(VPM, _E, _V->nv, _P); Sort_PPL(_P,_V); /* Print_PPL(_P, "_P after sorting"); */ /* Print_VL(_P,_V, "_V"); */ /* Print_EL(_E, &_P->n, 0, "_E"); */ /* Create _P_D from the equations of _P: _P_D is the hull of the generators of the cone dual to the one over _P, Gorenstein <-> _P_D lies in a plane at distance 1 from the origin, index = modulus of the last component of the equation of this plane */ _P_D->n = _P->n + 1; _P_D->np = _E->ne; for (i=0; i<_P_D->np; i++){ for (j=0; j<_P_D->n; j++) _P_D->x[i][j] = _E->e[i].a[j]; _P_D->x[i][_P->n] = _E->e[i].c;} /* Print_PPL(_P_D, "_P_D "); */ Find_Equations(_P_D,_V_D,_E_D); /* Print_EL(_E_D, &_P_D->n, 0, "_E_D"); */ if (_E_D->ne == 1){ if ((_E_D->e[0].c != 1)&&(_E_D->e[0].c != -1)) r = 0; else if (abs((int) _E_D->e[0].a[_P->n]) != *_codim){ printf("Warning: Input has index %d, should be %d! ", abs(_E_D->e[0].a[_P->n]), *_codim); r = 0;}} else {assert(_E_D->ne > _P_D->n); r = 0;} Tstart = time(NULL); Cstart = clock(); _F->Test = 0; for (i = 0; i < _CW->nw; i++) { fprintf(outFILE, "%d ", (int) _CW->d[i]); for (j = 0; j < _CW->N; j++) fprintf(outFILE, "%d ", (int) _CW->W[i][j]); if (i + 1 < _CW->nw) fprintf(outFILE, " "); } fflush(0); if (r) { /* shift _P_D into a plane through the origin: */ for (i=0; i<_P_D->np; i++){ for (j=0; j<_P_D->n; j++) _P_D->x[i][j] -= _P_D->x[_P_D->np-1][j];} /* Print_PPL(_P_D, "_P_D before Make_Poly_UTriang"); */ SL2Z_Make_Poly_UTriang(_P_D); /* Print_PPL(_P_D, "_P_D after Make_Poly_UTriang"); */ _P_D->n--; for (i=0; i<_P_D->np; i++) assert(_P_D->x[i][_P->n] == 0); /* Print_PPL(_P_D, "_P_D after reduction"); */ Find_Equations(_P_D,_V_D,_E_D); /* Print_EL(_E_D, &_P_D->n, 0, "_E_D"); */ Sort_VL(_V_D); /* Make_VEPM(_P, _V, _E, VPM); */ /* Print_Matrix(VPM, _E->ne, _V->nv, "VPM"); */ Make_VEPM(_P_D, _V_D, _E_D, VPM_D); /* Print_Matrix(VPM_D, _E_D->ne, _V_D->nv, "VPM_D"); */ Complete_Poly(VPM_D, _E_D, _V_D->nv, _P_D); /* Print_PPL(_P_D, "_P_D after Complete_Poly"); */ assert(_E_D->ne == _V->nv); assert(_E->ne == _V_D->nv); /* Compute _new_E_D->ne by comparing VPM and VPM_D: if (VPM[j][i] == VPM_D[k][j]) for all j then _new_E_D->e[i] = _E_D[k] */ _new_E_D->ne = _E_D->ne; for (i=0;i<_V->nv;i++){ for(k=0;k<_V->nv;k++){ for (j=0;j<_V_D->nv;j++) if (VPM[j][i] != VPM_D[k][j]) break; if (j==_V_D->nv) {_new_E_D->e[i] = _E_D->e[k]; break;} } if (k >= _V->nv){ printf("k = %d, _V->nv = %d\n", k, _V->nv); Print_Matrix(VPM, _E->ne, _V->nv, "VPM"); Print_Matrix(VPM_D, _E_D->ne, _V_D->nv, "VPM_D");} assert(k<_V->nv);} /* Print_EL(_new_E_D, &_P_D->n, 0, "_new_E_D"); Make_VEPM(_P_D, _V_D, _new_E_D, VPM_D); Print_Matrix(VPM_D, _E_D->ne, _V_D->nv, "VPM_D"); */ if (_F->N){ /* swap M and N */ PolyPointList *_auxP = _P_D; VertexNumList *_auxV = _V_D; EqList *_auxE = _new_E_D; _P_D = _P; _V_D = _V; _new_E_D = _E; _P = _auxP; _V = _auxV; _E = _auxE;} fprintf(outFILE,"M:%d %d ",_P->np,_V->nv); fprintf(outFILE,"N:%d %d ",_P_D->np,_V_D->nv); if (!_F->g && !_F->d){ Compute_E_Poly(&EP, _P_D, _V_D, _new_E_D, _P, _V, _E, _codim, _F, &Tstart, &Cstart); chi = Make_Mirror(&EP, h, _P_D->n + 1, dim); fprintf(outFILE, "H:"); for (i = 1; i < dim; i++) fprintf(outFILE, "%d ", h[1][i]); fprintf(outFILE, "[%d]", chi); for (i = 1; i <= dim/2; i++) if (h[0][i] != 0) fprintf(outFILE, " h%d=%d", i, h[0][i]); if(h[0][0] != 1) fprintf(outFILE, " h%d=%d", 0, h[0][0]); puts(""); if (_F->H) PrintDiamond(h, dim);} else puts(""); if(_F->V) Print_VL(_P_D, _V_D, "Vertices of support in N:"); if (_F->g) Print_PPL(_P_D, "Points of support in N:"); if (_F->d) Print_PPL(_P, "Points of support in M:"); if (_F->t) Time_Info(&Tstart, &Cstart, ""); if (_F->N){ /* revert M-N-swap (necessary because of alloc/free) */ PolyPointList *_auxP = _P_D; VertexNumList *_auxV = _V_D; EqList *_auxE = _new_E_D; _P_D = _P; _V_D = _V; _new_E_D = _E; _P = _auxP; _V = _auxV; _E = _auxE;}} else{ if (_F->N) fprintf(outFILE,"N:%d %d ",_P->np,_V->nv); else fprintf(outFILE,"M:%d %d ",_P->np,_V->nv); fprintf(outFILE,"F:%d ",_E->ne); puts(""); if ((_F->Rv) || ((_F->V)&&(_F->N))) Print_VL(_P, _V, "Vertices of input polytope:");} free(_P_D); free(_E_D); free(_V_D); free(_new_E_D); } palp-2.21/Global.h~0000664000177600017760000005231514572603263013523 0ustar skarkeskarke#include #include #include #include #include /* These are include files that should exist in your C library. */ /* ============ basic choice of PARAMETERS ============ */ #define Long long #define LLong long long /* For reflexive polytopes in 4 or less dimensions, everything should work with Long set to 32-bit-integer and LLong set to 64 bits. Many applications will even work with LLong at 32 bits. For higher dimensional or complicated non-reflexive polytopes it may be necessary to set even Long to 64 bits. */ #ifndef POLY_Dmax /* You can set POLY_Dmax at compilation: use -D POLY_Dmax= in the C flags */ #define POLY_Dmax 6 /* max dim of polytope */ #endif /* POLY_Dmax should be set to the dimension of the polytopes that are analysed. While the programs still work if POLY_Dmax is set to a higher value, they may be considerably slowed down. */ #if (POLY_Dmax <= 3) #define POINT_Nmax 40 /* max number of points */ #define VERT_Nmax 16 /* max number of vertices */ #define FACE_Nmax 30 /* max number of faces */ #define SYM_Nmax 88 /* cube: 2^D*D! plus extra */ #elif (POLY_Dmax == 4) #define POINT_Nmax 700 /* max number of points */ #define VERT_Nmax 64 /* max number of vertices */ #define FACE_Nmax 824 /* max number of faces */ #define SYM_Nmax 1200 #else #define POINT_Nmax 2000000 #define VERT_Nmax 64 /* !! use optimal value !! */ #define FACE_Nmax 10000 /* max number of faces */ #define SYM_Nmax 46080 /* symmetry (P_1)^6: 2^6*6! */ #define EQUA_Nmax 1280 /* up to 20000 without alloc */ #endif #ifndef EQUA_Nmax /* default setting */ #define EQUA_Nmax VERT_Nmax #endif /* POINT_Nmax, VERT_Nmax and FACE_Nmax denote the maximal numbers of points, vertices and faces, respectively. SYM_Nmax is the maximal number of symmetries of a polytope, i.e. the order of the finite subgroup S of the group GL(n,Z) of lattice automorphisms that leaves a polytope invariant. EQUA_Nmax denotes the maximal number of facets (given by equations) of a polytope. By duality this is just the number of vertices of the dual polytope, so it makes sense to have the default setting EQUA_Nmax = VERT_Nmax. In applications not related to reflexive polytopes or in large dimensions a larger value may be useful. While CPU-time is almost independent of EQUA_Nmax, it strongly depends on VERT_Nmax/32 (i.e. use 32, 64, 96, ...). Our settings for dimensions less than or equal to 4 are such that they work for any reflexive polytope. */ #define AMBI_Dmax (5 * POLY_Dmax) /* default setting */ /* If a polytope is determined by a combined weight system it is first realised by an embeddeding in an ambient space of dimension (Poly-dim + number of weight systems). AMBI_Dmax is the maximal dimension of this ambient space. */ #define FIB_Nmax 3000 /*NOW: 27/5/11 default setting*/ /* Given a polytope P* it is possible to analyze the IP simplices among its points. These simplices are given in terms of weight relations among points of P*. FIB_Nmax is the maximal number of allowed relations. */ #define CD2F_Nmax FACE_Nmax /* Max number of codimension 2 faces. */ #define GL_Long Long /* Uses W_to_GLZ like in Rat.c */ #define MAXLD (26) /* Used in the handling of large lists of weight systems (cf. C5stats) */ extern FILE *inFILE, *outFILE; /* Ascii-files for input and output. If not given in the parameter list they default to stdin and stdout, respectively. */ /* ========== Global typedefs ========== */ typedef struct {int n, np; Long x[POINT_Nmax][POLY_Dmax];} PolyPointList; /* A list (not necessarily complete) of lattice points of a polytope. P.x[i][j] is the j'th coordinate of the i'th lattice point. P.n is the dimension of the polytope and P.np the number of points in the list. */ typedef struct {int v[VERT_Nmax]; int nv;} VertexNumList; /* The list of vertices of a polytope, referring to some PolyPointList P. The j'th coordinate of the i'th vertex is then given by P.x[V.v[i]][j]. V.nv is the number of vertices of P. */ typedef struct {Long a[POLY_Dmax], c;} Equation; /* This structure determines an equation of the type ax+c=0, explicitly: sum_{i=1}^n E.a[i] x_i + E.c = 0. */ typedef struct {int ne; Equation e[EQUA_Nmax];} EqList; /* A list of equations; EL.ne is the number of equations in the list. */ typedef struct {EqList B; Long W[AMBI_Dmax][AMBI_Dmax], d[AMBI_Dmax]; int nw, N, z[POLY_Dmax][AMBI_Dmax], m[POLY_Dmax], nz, index;} CWS; /* Combined weight system: W[i][j] and d[i] are the j'th weight and the "degree" of the i'th weight system, respectively; nw is the number of weight systems, N is the dimension of the ambient space. z[i][j]/m[i] are the phases of nz symmetries for polytopes on sublattices. B describes the ambient space coordinate hyperplanes in terms of the new (non-redundant) coordinates. */ typedef Long PairMat[EQUA_Nmax][VERT_Nmax]; /* The matrix whose entries are the pairings av+c between the vertices v and the equations (a,c). */ typedef struct {int mp, mv, np, nv, n, pic, cor, h22, h1[POLY_Dmax-1];} BaHo; /* This structure is related to Batyrev's formulas for Hodge numbers. n ... dimension of the polytope pic ... Picard number cor ... sum of correction terms h1[i] ... Hodge number h_{1i} h22 ... Hodge number h_{22} (if n = 5) mp, mv, np, nv denote the numbers of points/vertices in the M and N lattices, repectively. */ typedef struct { Long W[FIB_Nmax][VERT_Nmax]; int nw, PS, ZS, nv, f[VERT_Nmax],r[VERT_Nmax],nf,nz[FIB_Nmax], n0[FIB_Nmax], Z[FIB_Nmax][VERT_Nmax], M[FIB_Nmax]; GL_Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax]; PolyPointList *P; } FibW; /* This list is an extension of the PolyPointList with the combined weight system. W[i][j] is the j'th weight; nw is the number of weight systems. */ typedef struct{ long n_nonIP, n_IP_nonRef, n_ref, // numbers of WS of certain types max_w, nr_max_w, //maximum weight in the reflexive/non-reflexive cases nr_n_w[MAXLD], n_w[MAXLD]; //numbers of weights of given [ld] int nr_max_mp, nr_max_mv, nr_max_nv, max_mp, max_mv, max_np, max_nv, max_h22, max_h1[POLY_Dmax-1], //max values of certain entries of BH min_chi, max_chi, max_nf[POLY_Dmax+1]; //range for chi, max facet numbers } C5stats; /* statistics on large lists of weight systems, cf. classification of 4fold weights */ /* ========== I/O functions (from Coord.c) ========== */ int Read_CWS_PP(CWS *C, PolyPointList *P); /* Reads either a CWS or a PolyPointList. If *C is read, the PolyPointList *P determined by *C is calculated, otherwise C->nw is set to 0 to indicate that no weight has been read. CWS-input consists of a single line of the form d1 w11 w12 ... d2 w21 w22 ..., whereas PolyPointList-input begins with a line #columns #lines followed by #lines further lines. It reads P->x as a matrix such that either P->n = #columns and P->np = #lines or vice versa (the result is unique because of P->np > P->n). */ int Read_CWS(CWS *_CW, PolyPointList *_P); /* Reads CWS input *C, the PolyPointList *P determined by *C is calculated. */ int Read_PP(PolyPointList *_P); /* Reads the PolyPointList input *P */ void Print_PPL(PolyPointList *P, const char *comment); void Print_VL(PolyPointList *P, VertexNumList *V, const char *comment); void Print_EL(EqList *EL, int *n, int suppress_c, const char *comment); void Print_Matrix(Long Matrix[][VERT_Nmax], int n_lines, int n_columns, const char *comment); /* Each of these routines prints a matrix in the format #columns #lines *comment line_0 ... line_{#lines-1}. With Print_PPL and Print_VL, points/vertices are displayed as column vectors if there's enough space and as row vectors otherwise. Print_EL always displays equations in line format. If *suppress_c is zero line_i reads EL->e[i].a[0] ... EL->e[i].a[*n-1] EL->e[i].c, otherwise the last entry EL->e[i].c is suppressed so that the resulting output can be used as input for Read_CWS_PP. */ void Print_CWH(CWS *C, BaHo *BH); /* Writes a single line that reproduces *C (if C->nw isn't 0, i.e. if the input was of CWS type), information on the numbers of points and vertices of the polytope and its dual, and the Hodge numbers of the corresponding Calabi-Yau variety. *C is reproduced in the format d1 w11 w12 ... d2 w21 w22 ... Information on the polytope is given in the form M:mp mv N:np nv for reflexive polytopes. Here mp and mv are the numbers of lattice points and vertices of the polytope, respectively, and np and nv denote the corresponding numbers for the dual polytope. If a polytope is not reflexive, "N:np nv" is replaced by "F:ne" (the number of facets/equations). Hodge number information is given in the format H: h11 h12 ... h1(n-2) [chi], where the h1i are the corresponding Hodge numbers and chi is the Euler number. This output is suppressed for polytopes that are not reflexive. As an example, the complete output for the quintic threefold reads 5 1 1 1 1 1 M:126 5 N:6 5 H:1,101 [-200]. */ void Initialize_C5S(C5stats *_C5S, int n); void Update_C5S(BaHo *_BH, int *nf, Long *W, C5stats *_C5S); void Print_C5S(C5stats *_C5S); /* Routines for handling the structure C5stats */ /* ========== From Polynf.c ========== */ int Make_Poly_Sym_NF(PolyPointList *P, VertexNumList *VNL, EqList *EL, int *SymNum, int V_perm[][VERT_Nmax], Long NF[POLY_Dmax][VERT_Nmax], int t, int S, int N); /* Given *P, *VNL and *EL, the following objects are determined: the number *SymNum of GL(n,Z)-symmetries of the polytope, the *SymNum vertex permutations V_perm realising these symmetries, the normal form coordinates NF of the vertices, the number of symmetries of the vertex pairing matrix (this number is the return value of Make_Poly_Sym_NF). If t/S/N are non-zero, the output of the corresponding options of poly.x is displayed. */ void IP_Simplex_Decomp(Long CM[][POLY_Dmax], int p, int d, int *nw, Long W[][VERT_Nmax], int Wmax, int codim); /* Given the matrix CM of coordinates of p points in Z^d, the list W[i] of *nw weight systems corresponding to IP-simplices spanned by the points in CM is created. If codim!=0 only the IP-simplices with dimension > 1 and codimension between 1 and codim are computed. It is assumed that p<=VERT_Nmax and that W can hold at least Wmax sets of coefficients. */ void IP_Simplices(PolyPointList *P, int nv, int PS, int VS, int CD); /* Realizes the -P,-V,-Z, and fibration options of poly (the results of this routine are displayed as output; *P is not modified). */ int Sublattice_Basis(int d, int p, Long *P[], /* return index=det(D) */ Long Z[][VERT_Nmax], Long *M, int *r, Long G[][POLY_Dmax], Long *D); /* Given a vector P[] of pointers at p points in N=Z^d that generate a (sub)lattice N' of the same dimension d, the following data are determined: D[i] with 0 <= i < d such that the lattice quotient N/N' is the product of cyclic groups Z_{D[i]} with D[i] dividing D[i+1], and a GL(d,Z) matrix G corresponding to a base change P->GxP such that the i'th new coordinate of each of the lattice points is divisible by D[i]. If p<=VERT_Nmax the program also computes *r coefficient vectors Z[i] for linear combinations of the points on P that are M[i]-fold multiples of primitive lattice vectors, where M[i]=D[d-i] for i<*r. If p>VERT_Nmax it is asserted that the index of the lattice quotient is 1. */ void Make_Poly_UTriang(PolyPointList *P); /* A coordinate change is performed that makes the matrix P->x upper triangular, with minimal entries above the diagonal. */ void Make_ANF(PolyPointList *P, VertexNumList *V, EqList*E, Long ANF[][VERT_Nmax]); /* Given *P, *V and *E, the affine normal form ANF (i.e., a normal form that also works for non-reflexive polytopes), is computed. */ int SimpUnimod(PolyPointList *P, VertexNumList *V, EqList *E, int vol); /* If vol is 0, the return value is 1 if all facets are simplicial, 0 otherwise If vol is not 0, the return value is 1 if all facets are unimoular (i.e. of volume 1) and 0 otherwise. */ int ConifoldSing(PolyPointList *P, VertexNumList *V, EqList *E, PolyPointList *dP, EqList *dE, int CYorFANO); /* Realizes the -C1 or -C2 options of poly for CYorFANO being 1 or 2, respectively. */ int Fano5d(PolyPointList *, VertexNumList *, EqList *); /* Realizes the -U5 option of poly. */ void Einstein_Metric(CWS *CW,PolyPointList *P,VertexNumList *V,EqList *E); /* Realizes the -E option of poly. */ int Divisibility_Index(PolyPointList *P, VertexNumList *V); /* Returns the largest integer g for which *P is a g-fold multiple of some other polytope. */ Long LatVol_Barycent(PolyPointList *P, VertexNumList *V, Long *B, Long *N); /* Given *P and *V, the coordinates of the barycenter of *P are computed (with the i'th coordinate as B[i] / *N) and the lattice volume of *P is returned. */ void IPs_degD(PolyPointList *P, VertexNumList *V, EqList *E, int l); /* *P is interpreted as the origin and the first level of a Gorenstein cone. The points of the cone up to level l are computed and displayed together with information on the type of face of the cone they represent (option -B# of poly). */ void Make_Facet(PolyPointList *P, VertexNumList *V, EqList *E, int e, Long vertices_of_facet[POLY_Dmax][VERT_Nmax], int *nv_of_facet); /* The e'th facet of *P is determined as a (P->n-1)-dimensional polytope: *nv_of_facet vertices represented by vertices_of_facet. */ /* ========== General purpose functions from Vertex.c ========== */ void swap(int *i,int *j); /* Swaps *i and *j. */ void Sort_VL(VertexNumList *V); /* Sorts the entries _V->v[i] in ascending order. */ Long Eval_Eq_on_V(Equation *E, Long *V, int n); /* Evaluates E on V, i.e. calculates \sum_{i=0}^{n-1} E->a[i] * V[i] + E->c. */ int Span_Check(EqList *EL, EqList *HL, int *n); /* Returns 1 if every equation of *HL is contained in *EL and 0 otherwise. *n is the dimension. */ int Vec_Greater_Than(Long *X, Long *Y, int n); /* Returns 1 if *X > *Y in the sense that X[i] > Y[i] for the first i where X[i] and Y[i] differ, returns 0 if *X < *Y and gives an error message if X[i] equals Y[i] for all i in {0,...n-1}. */ int Vec_is_zero(Long *X, int n); /* Returns 1 if X[i]==0 for 0<=inv exceeds EQUA_Nmax and 1 otherwise. */ int Transpose_PM(PairMat PM, PairMat DPM, int nv, int ne); /* Transposes PM into DPM; returns 1 if the dimensions nv, ne are within their limits and 0 otherwise. */ /* ========== Polytope analysis functions (from Vertex.c) ========== */ int Find_Equations(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* For the polytope determined by P, *VNL and *EL are calculated. *VNL is the complete list of vertices of P. *EL is the complete list of equations determining the facets of P. Find_Equations returns 1 if P has IP property (i.e., it has the origin in its interior) and 0 otherwise. */ int IP_Check(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* Same as Find_Equations, but returns immediately without calculating *VNL and *EL if P does not have the IP property. */ int Ref_Check(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* Returns 1 if P is reflexive and 0 otherwise. Only in the reflexive case *VNL and *EL are calculated. */ void Make_Dual_Poly(PolyPointList *P, VertexNumList *VNL, EqList *EL, PolyPointList *DP); /* Given P, VNL and EL for a reflexive polytope, the complete list *DP of lattice points of the dual polytope is determined. */ void Complete_Poly(Long VPM[][VERT_Nmax],EqList *E,int nv,PolyPointList *P); /* Given the vertex pairing matrix VPM, the EqList *E and the number nv of vertices, the complete list of lattice points *P is determined. */ void RC_Calc_BaHo(PolyPointList *P, VertexNumList *VNL, EqList *EL, PolyPointList *DP, BaHo *BH); /* Given *P, *VNL, *EL and *DP (points of dual polytope) as input, the elements of *BH are calculated. *P must be reflexive; *P and *DP must be complete. */ /* ====== typedefs and functions (from Vertex.c) related to INCIs ==== */ #define INT_Nbits 32 #define LONG_LONG_Nbits 64 /* These numbers should be set to the actual numbers of bits occupied by the structures "unsigned int" and "unsigned long long" in your version of C. If they are set to lower values, everything still works but may be considerably slowed down. */ #if (VERT_Nmax <= INT_Nbits) typedef unsigned int INCI; #elif (VERT_Nmax <= LONG_LONG_Nbits) typedef unsigned long long INCI; #else #define I_NUI ((VERT_Nmax-1)/INT_Nbits+1) typedef struct {unsigned int ui[I_NUI];} INCI; #endif /* An INCI encodes the incidence relations between a face and a list of vertices as a bit pattern (1 if a vertex lies on the face, 0 otherwise). Depending on the allowed number VERT_Nmax of vertices, a single "unsigned int" or "unsigned long long" may be sufficient. If VERT_Nmax is larger than the number of bits in a "long long integer", an array of unsigned integers is used to simulate an integer type of the required size. */ typedef struct {int nf[POLY_Dmax+1]; /* #(faces)[dim] */ INCI v[POLY_Dmax+1][FACE_Nmax]; /* vertex info */ INCI f[POLY_Dmax+1][FACE_Nmax]; /* V-on-dual info */ Long nip[POLY_Dmax+1][FACE_Nmax]; /* #IPs on face */ Long dip[POLY_Dmax+1][FACE_Nmax];} FaceInfo; /* #IPs on dual */ /* nf[i] denotes the number of faces of dimension i (the number of faces of dimension n-i-1 of the dual polytope). v[i][j] encodes the incidence relation of the j'th dim-i face with the vertices nip[i][j] is the number of interior points of the j'th dim-i face. f[i][j] and dip[i][j] give the same informations for the dual (n-i-1 dimensional) faces, with f[i][j] referring to the dual vertices. */ #if (VERT_Nmax <= LONG_LONG_Nbits) #define INCI_M2(x) ((x) % 2) /* value of first bit */ #define INCI_AND(x,y) ((x) & (y)) /* bitwise logical and */ #define INCI_OR(x,y) ((x) | (y)) /* bitwise logical or */ #define INCI_XOR(x,y) ((x) ^ (y)) /* bitwise exclusive or */ #define INCI_EQ(x,y) ((x) == (y)) /* check on equality */ #define INCI_LE(x,y) INCI_EQ(INCI_OR(x,y),y)/* bitwise less or equal */ #define INCI_EQ_0(x) INCI_EQ(x,INCI_0()) /* check if all bits = 0 */ #define INCI_0() (0) /* set all bits to 0 */ #define INCI_1() (1) /* set only first bit to 1 */ #define INCI_D2(x) ((x) / 2) /* shift by one bit */ #define INCI_PN(x,y) (2 * (x) + !(y)) /* shift and set first bit */ /* For an INCI defined as a single unsigned (long long) integer whose bits are regarded as representing incidences, these are useful definitions. INCI_PN is particularly useful when a new vertex is added: if x represents an equation E w.r.t. some vertex list and y is the result of evaluating E on some new vertex V, then INCI_PN(x,y) represents x w.r.t. the vertex list enhanced by V. */ #else #define INCI_M2(x) ((x).ui[0] % 2) INCI INCI_AND(INCI x, INCI y); INCI INCI_OR(INCI x, INCI y); INCI INCI_XOR(INCI x, INCI y); int INCI_EQ(INCI x, INCI y); int INCI_LE(INCI x, INCI y); int INCI_EQ_0(INCI x); INCI INCI_0(); INCI INCI_1(); INCI INCI_D2(INCI x); INCI INCI_PN(INCI x, Long y); #endif /* If we need more bits than can be represented by a single unsigned long long, these routines are designed to simulate the above definitions. */ int INCI_abs(INCI X); /* Returns the number of bits of X whose value is 1. */ int Print_INCI(INCI X); /* Prints X as a pattern of 0's and 1's, omitting the 0's after the last 1. */ INCI Eq_To_INCI(Equation *E, PolyPointList *P, VertexNumList *VNL); /* Converts *E to an INCI. */ void Make_Incidence(PolyPointList *P, VertexNumList *VNL, EqList *EL, FaceInfo *FI); /* Creates the structure FaceInfo *FI from *P, *VNL and *EL. */ void Print_FaceInfo(int n, FaceInfo *FI); /* Displays the information contained in the FaceInfo *FI. */ int QuickAnalysis(PolyPointList *_P, BaHo *_BH, FaceInfo *_FI); /* Fast computation of FaceInfo and Hodge numbers. */ palp-2.21/Subdb.c0000664000177600017760000023266714572603263013171 0ustar skarkeskarke#include "Global.h" #include "Subpoly.h" #include "Rat.h" /* NB mod 2^32, works for #poly<2^32 */ /* #include -> defines _ILP32 (32-bit programs) [ -> isa_defs.h ] or _LP64 (long and pointer 64 bits) #include (on Linux systems?) ... uintptr_t */ /* #include LONG_MAX = 2147483647 vs. 2^63-1 */ /* L->dbname points at constant string => don't change, use: * dbname, which has "File_Ext_NCmax" extra characters allocated !!! */ /* uchar=unsigned char uint=unsigned int * NP=#Polys NB=#Bytes #files=#nv's with NP>0 #lists=#(nv,nuc) with NP>0 * * uchar rd k_1 ... k_rd // ... not in data base !! * * uchar dim #files nv_max nuc_max * uint #lists hNF hSM hNM hNB slNF slSM slNM slNB * uchar v1 #nuc's with v1 * uchar nuc1 uint #NF(v1,nuc1) uchar nuc2 uint #NV(v1,nuc2) ... * uchar v2 #nuc's with v2 * uchar nuc1 uint #NF(v2,nuc1) uchar nuc2 uint #NV(v2,nuc2) ... * uchar "all hNF honest nf's" * uchar "all slNF sublattice {nv nuc nf[]}'s" */ void Small_Make_Dual(PolyPointList *_P, VertexNumList *_V, EqList *_E){ int i; EqList AE=*_E; VNL_to_DEL(_P, _V, _E); assert(EL_to_PPL(&AE, _P, &_P->n)); _V->nv=_P->np; for (i=0;i<_P->np;i++) _V->v[i]=i; } void Polyi_2_DBo(char *polyi,char *dbo) { char *dbnames = (char *) malloc(1+strlen(dbo)+File_Ext_NCmax), *fx; FILE *F=fopen(polyi,"rb"), *Finfo, *Fv, *Fsl; time_t Tstart=time(NULL); FInfoList L; UPint tNF=0; int d, v, nu, i, j, list_num, sl_nNF, sl_SM, sl_NM, sl_NB; Along tNB=0; if (!*polyi) {puts("With -do you require -pi or -di and -pa"); exit(0);} if(F==NULL) {printf("Input file %s not found\n",polyi); exit(0);} strcpy(dbnames,dbo); fx=&dbnames[strlen(dbo)+1]; strcat(dbnames,".info"); Finfo=fopen(dbnames,"w"); assert(Finfo!=NULL); printf("Read %s (",polyi); fflush(stdout); Init_FInfoList(&L); /* start reading the file */ d=fgetc(F); assert(d==0); /* for(i=0;i0)); fflush(stdout); fprintf(Finfo, /* write Finfo */ "%d %d %d %d %d %lld %d %lld %lld %d %d %d %d\n\n", d, L.nV, L.nVmax, L.NUCmax,list_num, L.nNF,L.nSM,L.nNM,L.NB, sl_nNF, sl_SM, sl_NM, sl_NB); for(v=d+1;v<=L.nVmax;v++) if(L.nNUC[v]) /* honest info */ { i=0; fprintf(Finfo,"%d %d\n",v,L.nNUC[v]); /* v #nuc's */ for(nu=1;nu<=L.NUCmax;nu++) if(L.NFnum[v][nu]) { fprintf(Finfo,"%d %d%s",nu,L.NFnum[v][nu], /* nuc #NF(v,nuc) */ (++iFv_pos[v][nuc] and DB->RAM_pos[v][nuc], respectively; each entry |x| corresponds to nuc unsigned characters) */ time_t Tstart=time(NULL); char *dbname = (char *) malloc(1+strlen(_NFL->dbname)+File_Ext_NCmax), *fx; DataBase *DB=&_NFL->DB; int d, v, nu, i, j, list_num, sl_nNF, sl_SM, sl_NM, sl_NB, RAM_pos=0; Along RAM_size=0; strcpy(dbname,_NFL->dbname); printf("Reading data-base %s: ",dbname); strcat(dbname,".info"); fx=&dbname[strlen(_NFL->dbname)+1]; /* read the info-file: */ DB->Finfo=fopen(dbname,"r"); assert(DB->Finfo!=NULL); fscanf(DB->Finfo, "%d %d %d %d %d %lld %d %lld %lld %d %d %d %d", &d, &DB->nV, &DB->nVmax, &DB->NUCmax, &list_num, &DB->nNF, &DB->nSM, &DB->nNM, &DB->NB, &sl_nNF, &sl_SM, &sl_NM, &sl_NB); printf("%lld+%dsl %lldnf %lldb", 2*(DB->nNF)-DB->nSM-DB->nNM, 2*sl_nNF-sl_SM-sl_NM, DB->nNF+sl_nNF, DB->NB+sl_NB); /* if( _FILE_OFFSET_BITS < 64 ) assert(DB->NB <= LONG_MAX); Along */ if(_NFL->d) assert(d==_NFL->d); else _NFL->d=d; for (v=1;vnNUC[v]=0; for(nu=0; nuNFnum[v][nu]=0;} for(i=0; inV; i++){ fscanf(DB->Finfo,"%d",&v); fscanf(DB->Finfo,"%d",&(DB->nNUC[v])); for(j=0;jnNUC[v];j++){ fscanf(DB->Finfo,"%d", &nu); fscanf(DB->Finfo,"%d", &(DB->NFnum[v][nu])); RAM_size+=nu*((DB->NFnum[v][nu]-1)/BLOCK_LENGTH); } } if(ferror(DB->Finfo)) {printf("File error in %s\n",dbname); exit(0);} fclose(DB->Finfo); fflush(stdout); assert(RAM_size<=INT_MAX); DB->RAM_NF=(unsigned char *) malloc(RAM_size); assert(DB->RAM_NF!=NULL); /* read the DB-files and create RAM_NF: */ for (v=2;v<=DB->nVmax;v++) if(DB->nNUC[v]){ char ext[4]={'v',0,0,0}; ext[1]='0' + v / 10; ext[2]='0' + v % 10; strcpy(fx,ext); DB->Fv[v]=fopen(dbname,"rb"); assert(DB->Fv[v]!=NULL); FSEEK(DB->Fv[v],0,SEEK_END); DB->Fv_pos[v][0]=0; for (nu=0;nu<=DB->NUCmax;nu++){ DB->RAM_pos[v][nu]=RAM_pos; for (i=0; i<(DB->NFnum[v][nu]-1)/BLOCK_LENGTH; i++){ FSEEK(DB->Fv[v], DB->Fv_pos[v][nu]+(i+1)*BLOCK_LENGTH*nu, SEEK_SET); for (j=0; jRAM_NF[RAM_pos++]=fgetc(DB->Fv[v]); } DB->Fv_pos[v][nu+1]=DB->Fv_pos[v][nu]+DB->NFnum[v][nu]*nu; } } printf(" done (%ds)\n",(int) difftime(time(NULL),Tstart)); fflush(stdout); } char Compare_Poly(int *nuc, unsigned char *uc1, unsigned char *uc2){ /* uc1 always encodes a single poly, uc2 might encode a single poly or a mirror pair; returns: 'm': if uc1 isn't in uc2, but its mirror is; 'i': if uc1 is in uc2; 'l': if uc1 is less than uc2; 'g': if uc1 is greater than uc2; */ switch (RIGHTminusLEFT(uc1,uc2,nuc)){ case -1: return 'g'; case 1: return 'l'; case 0: {if ((*uc1 + *uc2) % 4 == 3) return 'm'; else return 'i';} default: puts("Sth. wrong in Compare_Poly!!!"); exit(0);} return 0; } int Is_in_DB(int *nv, int *nuc, unsigned char *uc, NF_List *_NFL){ /* Uses the following basic strategy for identifying the position of some object x w.r.t. entries of a list l of length n: min_pos=-1; max_pos=n; while (max_pos-min_pos>1){ int pos=(max_pos+min_pos)/2; switch (Compare(x,l[pos]){ case 'equal': return sth.; case 'less': {max_pos=pos; continue:} case 'greater': min_pos=pos;}} results in a return or l[min_pos] < x < l[max_pos=min_pos+1] Applied here to locate x=uc=encoded polyhedron first w.r.t. RAM_poly and then w.r.t. the location in the database */ int pos, min_pos=-1, max_RAM_pos, i, max_Fv_piece; Along Fv_pos; unsigned char Aux_poly[BLOCK_LENGTH*NUC_Nmax]; DataBase *DB=&_NFL->DB; if (!DB->NFnum[*nv][*nuc]) return 0; /* Analyse the position of uc w.r.t. DB->RAM_NF */ max_RAM_pos=(DB->NFnum[*nv][*nuc]-1)/BLOCK_LENGTH; while (max_RAM_pos-min_pos>1){ pos=(max_RAM_pos+min_pos)/2; switch (Compare_Poly(nuc, uc, &(DB->RAM_NF[DB->RAM_pos[*nv][*nuc]+(*nuc)*pos]))){ case 'm': return 0; case 'i': return 1; case 'l': {max_RAM_pos=pos; continue;} case 'g': min_pos=pos;}} /* Look for uc in the database: */ Fv_pos=max_RAM_pos; if (Fv_pos==(DB->NFnum[*nv][*nuc]-1)/BLOCK_LENGTH) max_Fv_piece=DB->NFnum[*nv][*nuc]-Fv_pos*BLOCK_LENGTH; else max_Fv_piece=BLOCK_LENGTH; min_pos=-1; if (FSEEK(DB->Fv[*nv], DB->Fv_pos[*nv][*nuc]+Fv_pos* (Along) ( (*nuc)*BLOCK_LENGTH) , SEEK_SET)){ printf("Error in fseek in Is_in_DB!"); exit(0);} for (i=0;i<(*nuc)*(max_Fv_piece);i++) Aux_poly[i]=fgetc(DB->Fv[*nv]); while (max_Fv_piece-min_pos>1){ pos=(max_Fv_piece+min_pos)/2; switch(Compare_Poly(nuc, uc, &(Aux_poly[(*nuc)*pos]))){ case 'm': {return 0;} case 'i': {return 1;} case 'l': {max_Fv_piece=pos; continue;} case 'g': {min_pos=pos;} } } return 0; } void Add_Polya_2_DBi(char *dbi,char *polya,char *dbo) { FInfoList FIi, FIa, FIo; Along Apos, HIpos, HApos, Inp, tnb=0, tNF=0; unsigned char ucI[NUC_Nmax],ucA[NUC_Nmax],*ucSL=NULL,*uc;int SLp[SL_Nmax]; int d, vI, nuI, IslNF, IslSM, IslNM, nu; unsigned Ili, u, Oli=0, IslNB; int v, vA, nuA, AslNF, AslSM, AslNM, i; unsigned Ali, a; Along AslNB; int s, slNF=0, slSM=0, slNM=0, slNB=0, slNP=0; UPint Anp; int AmI=00,ms, newout=strcmp(dbi,dbo) && (*dbo),j=1+strlen(SAVE_FILE_EXT); char *Ifx, *Ifn = (char *) malloc(j+strlen(dbi)+File_Ext_NCmax), *Ofx, *Ofn = (char *) malloc(j+strlen(newout ? dbo : dbi)+File_Ext_NCmax); FILE *FI, *FA, *FO; if(*polya==0) {puts("-pa file required"); exit(0);} Init_FInfoList(&FIi); Init_FInfoList(&FIa); strcpy(Ifn,dbi); Ifx=&Ifn[strlen(dbi)]; strcpy(Ifx,".info"); if(*dbo==0)dbo=dbi; strcpy(Ofn,dbo); Ofx=&Ofn[strlen(dbo)]; if(NULL==(FI=fopen(Ifn,"r"))) {printf("Cannot open %s",Ifn);exit(0);} if(NULL==(FA=fopen(polya,"rb"))){printf("Cannot open %s",polya);exit(0);} fscanf(FI,"%d%d%d%d%d%lld%d%lld %lld %d%d%d%d",&d,&i,&j,&nu,&Ili, &FIi.nNF,&FIi.nSM,&FIi.nNM,&FIi.NB,&IslNF,&IslSM,&IslNM,&IslNB); FIi.nV=i; FIi.nVmax=j; FIi.NUCmax=nu; /* printf("%d %d %d %d %d %d %d %d %lld %d %d %d %d\n", d,FIi.nV,FIi.nVmax,FIi.NUCmax,Ili,FIi.nNF,FIi.nSM, FIi.nNM,FIi.NB,IslNF,IslSM,IslNM,IslNB); */ for(i=0;i ",slNF,slSM,slNM,slNB); if(IslNF) { HIpos=FTELL(FI); assert(HIpos==IslNB); assert(!ferror(FI)); fclose(FI); if(!newout) remove(Ifn); } /* SL file done */ FSEEK(FA,HApos,SEEK_SET); Init_FInfoList(&FIo); FIo.nVmax=max(FIi.nVmax,FIa.nVmax); FIo.NUCmax=max(FIi.NUCmax,FIa.NUCmax); /* Tnb=0; */ for(v=d+1;v<=FIo.nVmax;v++) for(nu=1;nu<=FIo.NUCmax;nu++) if( (FIo.NFnum[v][nu]=FIi.NFnum[v][nu]+FIa.NFnum[v][nu]) ) { FIo.nNUC[v]++; Oli++; /* Tnb+=FIo.NFnum[v][nu]; */ } FIo.nV=0; for(v=d+1;v<=FIo.nVmax;v++) if(FIo.nNUC[v]) FIo.nV++; for(v=d+1;v<=FIo.nVmax;v++) if(FIo.nNUC[v]) { char vxt[5]; strcpy(vxt,".v"); vxt[2]=v/10+'0'; vxt[3]=v%10+'0'; vxt[4]=0; strcpy(Ofx,vxt); strcpy(Ifx,vxt); if(FIi.nNUC[v]) { if(!newout) {strcat(Ifx,SAVE_FILE_EXT); assert(!rename(Ofn,Ifn));} if(NULL==(FI=fopen(Ifn,"rb"))){printf("Ifn %s failed",Ifn);exit(0);} } if(NULL==(FO=fopen(Ofn,"wb"))){printf("Ofn %s failed",Ofn);exit(0);} for(nu=1;nu<=FIo.NUCmax;nu++) if(FIo.NFnum[v][nu]) { unsigned int I_NF=FIi.NFnum[v][nu], A_NF=FIa.NFnum[v][nu], O_NF=0; UPint neq=0, peq=0, pa=0; Along pi=0, po=0; a=0; if(099) { long long tnp=(2*FIo.nNF-FIo.nNM-FIo.nSM)/10; tnp*=tnp; tnp/=20; tnp/=Tnb; printf(" [p^2/2m=%ldk]",tnp); } */ Print_Expect(&FIo); puts(""); assert(ferror(FA)==0); fclose(FA); assert(ferror(FO)==0); fclose(FO); } int Check_sl_order(int *v, int *nu, unsigned char *uc) { static int n, V, NU; static unsigned char UC[NUC_Nmax]; if(n) { if(V>(*v)) return 0; if((V==(*v))&&(NU>(*nu))) return 0; if((V==(*v))&&(NU==(*nu))&&(RIGHTminusLEFT(UC,uc,&NU)<=0)) return 0; } V=*v; NU=*nu; for(n=0;n(*v)) return 0; if((V==(*v))&&(NU>(*nu))) return 0; if((V==(*v))&&(NU==(*nu))&&(RIGHTminusLEFT(UC,uc,&NU)<=0)) return 0; } V=*v; NU=*nu; for(n=0;nn=*d; _P->np=*v; for(I=0;I<*v;I++) for(J=0;J<*d;J++) _P->x[I][J]=NF[J][I]; if(MS==2) Print_NF(outFILE,d,v,NF); else if(MS==1) { IP_Check(_P,&V,&E); Small_Make_Dual(_P,&V,&E); Make_Poly_NF(_P,&V,&E,NF); Print_NF(outFILE,d,&(V.nv),NF); } else {puts("Only use Print_Missing_Mirror for MM!");exit(0);} } /* cF->{1::c 2::C (extended output)} cF->{-1::M (missing mirrors)} */ void Check_NF_Order(char *polyi,char *dbi, int cF, PolyPointList *_P)/* 1=MM */ { FILE *F=NULL; FInfoList L; /* time_t Tstart=time(NULL); */ unsigned int rd, i, j, list_num, tln=0, tSM=0; int d, nu, v, si; int sl_nNF, sl_SM, sl_NM, sl_NB; Along tNF=0, tNB=0, tNM=0, SLpos, Hpos=0; char *Ifx=NULL, *Ifn = (char *) malloc(1+strlen(dbi)+File_Ext_NCmax); if((*polyi)&&(*dbi)) puts("only give one of -pi FILE or -di FILE"); if((*polyi==0)&&(*dbi==0)) puts("I need one of: -pi FILE or -di FILE"); if((*polyi==0)+(*dbi==0)!=1) exit(0); if(*polyi) /* read INFO PART */ { printf("Checking consistency of Aux/InFile %s\n",polyi); F=fopen(polyi,"rb"); if(F==NULL) {puts("File not found");exit(0);} Init_FInfoList(&L); /* start reading the file */ rd=fgetc(F); if(rd>127) rd=128*(rd-128)+fgetc(F); assert(rd <= MAX_REC_DEPTH); printf("rd=%d: ",rd); for(i=0;i0)); if(cF==2) printf("%lldnf %dsm %lldnm %lldb sl: %d %d %d %d\n", L.nNF,L.nSM,L.nNM,L.NB,sl_nNF,sl_SM,sl_NM,sl_NB); fflush(stdout); } if(*dbi) { printf("Checking consistency of DataBase %s:\n",dbi); strcpy(Ifn,dbi); Ifx=&Ifn[strlen(dbi)]; strcpy(Ifx,".info"); F=fopen(Ifn,"r"); if(F==NULL) {puts("Info File not found");exit(0);} Init_FInfoList(&L); /* start reading the file */ fscanf(F,"%d%d%d%d%d%lld%d%lld %lld %d%d%d%d", &d,&i,&j,&nu,&list_num,&L.nNF,&L.nSM,&L.nNM,&L.NB, &sl_nNF,&sl_SM,&sl_NM,&sl_NB); L.nV=i; L.nVmax=j; L.NUCmax=nu; printf("d=%d nV=%d nVmax=%d NUCmax=%d #lists=%d ", d,L.nV,L.nVmax,L.NUCmax,list_num); printf("np=%lld+%dsl %lldb %d files\n",2*L.nNF-L.nSM-L.nNM, 2*sl_nNF-sl_SM-sl_NM,L.NB+sl_NB,L.nV+1+(sl_nNF>0)); printf("%lldnf %dsm %lldnm %lldb sl: %d %d %d %d\n", L.nNF,L.nSM,L.nNM,L.NB,sl_nNF,sl_SM,sl_NM,sl_NB); fflush(stdout); for(i=0;i1)printf(" p^2/2m=%ldkCY",tln); */ Print_Expect(&L); printf("\nv:"); if(*polyi) FSEEK(F,Hpos,SEEK_SET); /* check h-order */ if(cF<0) puts(""); for(v=d+1;v<=L.nVmax;v++) /* if(cF) */ if(L.nNUC[v]) { Along nbsum=0; if(cF>0){printf(" %d",v);fflush(stdout);} if(*dbi) { char vxt[5]; strcpy(vxt,".v"); vxt[2]=v/10+'0'; vxt[3]=v%10+'0'; vxt[4]=0; strcpy(Ifx,vxt); fclose(F); if(NULL==(F=fopen(Ifn,"rb"))){printf("Ifn %s failed",Ifn);exit(0);} } for(nu=1;nu<=L.NUCmax;nu++) if(L.NFnum[v][nu]) { unsigned char uc[NUC_Nmax]; for(i=0;i127) d=128*(d-128)+fgetc(FI); Init_FInfoList(&FIi); if(d) printf("RecursionDepth=%d on %s\n",d,polyi); if(d < 128) fputc(d,FO); else {fputc(128+(d)/128,FO); fputc(d%128,FO);} for(i=0;i ",slNF,slSM,slNM,slNB); tnb=0; fflush(stdout); if(!db) FSEEK(FS,HSpos,SEEK_SET); FSEEK(FI,HIpos,SEEK_SET); Opos=HIpos; for(v=d+1;v<=FIi.nVmax;v++) if(FIi.nNUC[v]) /* init HIPli */ for(nu=1;nu<=FIi.NUCmax;nu++) if(FIi.NFnum[v][nu]) { HIPli[v][nu]=Opos; Opos+=nu*FIi.NFnum[v][nu]; } assert(Opos==HIpos+FIi.NB); Opos=HSpos; for(v=d+1;v<=FIs.nVmax;v++) if(FIs.nNUC[v]) /* init HSPli */ for(nu=1;nu<=FIs.NUCmax;nu++) if(FIs.NFnum[v][nu]) { if(db) if(v>dv) {Opos=0; dv=v;} HSPli[v][nu]=Opos; Opos+=nu*FIs.NFnum[v][nu]; } if(!db) assert(Opos==HSpos+FIs.NB); dv=0; Init_FInfoList(&FIo); for(v=d+1;v<=FIi.nVmax;v++) if(FIi.nNUC[v]) /* FIo.NFnum[v][nu]?=0 */ for(nu=1;nu<=FIi.NUCmax;nu++) if(FIi.NFnum[v][nu]) { if(FIs.NFnum[v][nu]) /* check for add polys */ { volatile unsigned int *_nf=&FIo.NFnum[v][nu]; /* (*_nf)=#NFnum(v,n) ?= 0 */ unsigned int n, I_NF=FIi.NFnum[v][nu], S_NF=FIs.NFnum[v][nu]; if(db) if(v>dv) { char vxt[5]; strcpy(vxt,".v"); vxt[2]=v/10+'0'; vxt[3]=v%10+'0'; vxt[4]=0; strcpy(Sfx,vxt); assert(!ferror(FS));fclose(FS); if(NULL==(FS=fopen(Sfn,"rb"))) {printf("%s open failed",Sfn);exit(0);} dv=v; } FSEEK(FI,HIPli[v][nu],SEEK_SET); FSEEK(FS,HSPli[v][nu],SEEK_SET); u=0; if(0tnb) { printf(" %d",v); tnb=v; fflush(stdout); if(FIs.nNUC[v]) if(db) { char vxt[5]; strcpy(vxt,".v"); vxt[2]=v/10+'0'; vxt[3]=v%10+'0'; vxt[4]=0; strcpy(Sfx,vxt); assert(!ferror(FS));fclose(FS); if(NULL==(FS=fopen(Sfn,"rb"))) {printf("%s open failed",Sfn);exit(0);} } } FSEEK(FI,HIPli[v][nu],SEEK_SET); FSEEK(FS,HSPli[v][nu],SEEK_SET); u=0; if(u=slNF) goto END_SL; } /* go up to (v,nu) in SL-list */ if(db) if(v>dv) { char vxt[5]; strcpy(vxt,".v"); vxt[2]=v/10+'0'; vxt[3]=v%10+'0'; vxt[4]=0; strcpy(Sfx,vxt); assert(!ferror(FS));fclose(FS); if(NULL==(FS=fopen(Sfn,"rb"))) {printf("%s open failed",Sfn);exit(0);} dv=v; } if((uc[0]==v)&&(uc[1]==nu)) /* read from file and sort out */ { FSEEK(FS,HSPli[v][nu],SEEK_SET); for(u=0;u=slNF) goto END_SL; if((uc[0]!=v)||(uc[1]!=nu)) goto END_VN; } if(HmSL==0) /* remove SL */ { int k, sms=uc[2]%4, hms=(*ucS)%4; switch(10*hms + sms){ case 31: case 32: case 00: case 11: case 22: case 33: for(k=i+1;k=slNF) goto END_SL; uc = & (ucSL[SLp[i]]); if((uc[0]!=v)||(uc[1]!=nu)) goto END_VN; break; case 12: case 21: break; case 13: case 23: ++slNM; uc[2]-=hms; break; default: puts("inconsistent MS flags in SL-H"); exit(0);} } /* else (SL>H): hence next H */ } assert(!ferror(FS)); } else END_VN: assert( (uc[0]>v) || ((uc[0]==v)&&(uc[1]>nu)) ); } END_SL: ; #endif for(i=0;i99) { long long tnp=(2*FIo.nNF-FIo.nNM-FIo.nSM)/1000; tnp*=tnp; tnp/=(2*tnb); printf(" [p^2/2m=%ldM]",tnp); } */ Print_Expect(&FIo); puts(""); assert(ferror(FI)==0); fclose(FI); assert(ferror(FS)==0); fclose(FS); assert(HOpos==FTELL(FO)); assert(ferror(FO)==0); fclose(FO); } void Bin2a(char *polyi, int max, PolyPointList *_P) { FILE *F=fopen(polyi,"rb"); FInfoList L; UPint list_num,tNF=0; Along tNB=0; int d, v, s, sl_nNF, sl_SM, sl_NM, sl_NB, mc=0, MS, nu; unsigned i, j; unsigned char uc[POLY_Dmax*VERT_Nmax]; VertexNumList V; EqList E; Long NF[POLY_Dmax][VERT_Nmax]; Init_FInfoList(&L); if(F==NULL) {printf("Input file %s not found\n",polyi); exit(0);} d=fgetc(F); assert(d==0); /* for(i=0;in=d; _P->np=v; for(I=0;Ix[I][J]=NF[J][I]; assert(Ref_Check(_P,&V,&E)); if(MS!=2) /* if(MS!=2) print NF */ if(!max || Poly_Max_check(_P,&V,&E)) { mc++; Print_NF(outFILE,&d,&v,NF);} if(MS>1) /* if(MS>1); print Mirror */ if(!max || Poly_Min_check(_P,&V,&E)) { mc++; Small_Make_Dual(_P,&V,&E); Make_Poly_NF(_P,&V,&E,NF); Print_NF(outFILE,&d,&(V.nv),NF); } } } printf("np=%lld+%dsl ",2*L.nNF-L.nSM-L.nNM,2*sl_nNF-sl_SM-sl_NM); printf( /* write Finfo */ "%dd %dv<=%d n<=%d %dnv %lld %d %lld %lld %d %d %d %d", d, L.nV, L.nVmax, L.NUCmax,list_num, L.nNF,L.nSM,L.nNM,L.NB, sl_nNF, sl_SM, sl_NM, sl_NB); if(max) printf(" r-max=%d",mc); puts(""); } void DB_fromVF_toVT(DataBase *DB,int vf,int vt) { int v,n; DB->nNF=0; for(v=vf;v<=vt;v++) for(n=0;nnNF+=DB->NFnum[v][n]; if(!DB->nNF){fprintf(stderr,"No NF with %d<=v<=%d\n",vf,vt);exit(0);} while(0==DB->nNUC[vt]) {vt--;assert(vf<=vt);} DB->v=vf; DB->nVmax=vt; } void Bin2aDBsl(char *dbi, int max, int vf, int vt, PolyPointList *_P) { FILE *F; FInfoList L; int d, v, nu, i, j, list_num, mc=0, MS, sl_nNF, sl_SM, sl_NM, sl_NB, tSM=0, tNM=0; char *Ifx, *Ifn = (char *) malloc(1+strlen(dbi)+File_Ext_NCmax); Long NF[POLY_Dmax][VERT_Nmax]; VertexNumList V;EqList E; strcpy(Ifn,dbi); Ifx=&Ifn[strlen(dbi)]; strcpy(Ifx,".info"); F=fopen(Ifn,"r"); if(F==NULL) {puts("Info File not found");exit(0);} Init_FInfoList(&L); /* start reading the file */ fscanf(F,"%d%d%d%d%d%lld%d%lld %lld %d%d%d%d", &d,&i,&j,&nu,&list_num,&L.nNF,&L.nSM,&L.nNM,&L.NB, &sl_nNF,&sl_SM,&sl_NM,&sl_NB); L.nV=i; L.nVmax=j; L.NUCmax=nu; if(sl_NB && (vf==2)&&(vt==VERT_Nmax-1)) { strcpy(Ifx,".sl"); fclose(F); if(NULL==(F=fopen(Ifn,"rb"))){printf("Open %s failed",Ifn);exit(0);} } else /* puts("no .sl file"); */ { DataBase *DB; Open_DB(dbi, &DB, 0); if((DB->vnVmax>vt)) DB_fromVF_toVT(DB,vf,vt); /* read only vf <= v <= vt :: */ for(i=0; Read_H_poly_from_DB(DB,_P); i++) Print_PPL(_P,""); printf("#poly=%d\n",i); Close_DB(DB); } for(i=0;in=d; _P->np=v; for(I=0;Ix[I][J]=NF[J][I]; assert(Ref_Check(_P,&V,&E)); if(MS!=2) /* if(MS!=2) print NF */ if(!max || Poly_Max_check(_P,&V,&E)) { mc++; Print_NF(outFILE,&d,&v,NF);} if(MS>1) /* if(MS>1); print Mirror */ if(!max || Poly_Min_check(_P,&V,&E)) { mc++; Small_Make_Dual(_P,&V,&E); Make_Poly_NF(_P,&V,&E,NF); Print_NF(outFILE,&d,&(V.nv),NF); } } printf("np=%lld+%dsl ",2*L.nNF-L.nSM-L.nNM,2*sl_nNF-sl_SM-sl_NM); printf( /* write Finfo */ "%dd %dv<=%d n<=%d %dnv ... %d %d %d %d", /* %d %d %d %lld */ d, L.nV, L.nVmax, L.NUCmax,list_num, /* L.nNF,L.nSM,L.nNM,L.NB, */ sl_nNF, sl_SM, sl_NM, sl_NB); if(max) printf(" r-max=%d",mc); puts(""); } void Bin_2_ascii(char *polyi,char *dbin,int max,int vf,int vt,PolyPointList *P) { if(*polyi) Bin2a(polyi, max, P); else if(*dbin) Bin2aDBsl(dbin, max, vf, vt, P); else puts("With -b[2a] you have to specify input via -pi or -di"); } /* ====================================================================== */ /* ========== ========== */ /* ========== Hodge-database routines ========== */ /* ========== ========== */ /* ====================================================================== */ #define Hod_Dif_max 480 #define Hod_Min_max 251 #if (POLY_Dmax < 6) void DB_to_Hodge(char *dbin, char *dbout, int vfrom, int vto, PolyPointList *_P){ /* Read the database, write the Hodge numbers */ DataBase DB; VertexNumList V; Long VPM[EQUA_Nmax][VERT_Nmax]; static EqList E; time_t Tstart; char *dbname = (char *) malloc(1+strlen(dbin)+File_Ext_NCmax), *fx; char *dbhname = (char *) malloc(6+strlen(dbout)+File_Ext_NCmax), *fhx; unsigned char uc_poly[NUC_Nmax]; int d, v, nu, i, j, list_num, sl_nNF, sl_SM, sl_NM, sl_NB, dh, nnf_vd[VERT_Nmax][Hod_Dif_max+1], nnf_v[VERT_Nmax]; BaHo BH; FILE *Faux[Hod_Dif_max+1]; FILE *Fvinfo; PolyPointList *_PD = (PolyPointList *) malloc(sizeof(PolyPointList)); assert(_PD!=NULL); if (!*dbin||!*dbout){ puts("You have to specify I/O database names via -di and -do"); exit(0);} for(i=0;i<=Hod_Dif_max;i++) for(j=0;j250)){ aext[4]='0'+dh/100; aext[5]='0'+(dh/10)%10; aext[6]='0'+dh%10; strcpy(fhx,aext); Faux[dh]=fopen(dbhname,"ab"); } if (!nnf_vd[v][dh]) nd++; c=BH.h1[2-mirror]; fputc(c,Faux[dh]); c=BH.mp/256+4*BH.mv; fputc(c,Faux[dh]); c=BH.mp%256; fputc(c,Faux[dh]); c=BH.np/256+4*BH.nv; fputc(c,Faux[dh]); c=BH.np%256; fputc(c,Faux[dh]); c=nu+64*mirror; fputc(c,Faux[dh]); for (j=0;j250) fclose(Faux[dh]); (nnf_vd[v][dh])++; (nnf_v[v])++; } if(ferror(DB.Fv[v])) {printf("File error in %s\n",dbname); exit(0);} fclose(DB.Fv[v]); for (dh=0;dh<=250;dh++) if (nnf_vd[v][dh]) { if(ferror(Faux[dh])) {printf("File error at dh=%d\n",dh); exit(0);} fclose(Faux[dh]);} fprintf(Fvinfo, "%d %d %d\n", v, nd, nnf_v[v]); for (dh=0;dh<=Hod_Dif_max;dh++) if (nnf_vd[v][dh]) fprintf(Fvinfo, "%d %d ", dh, nnf_vd[v][dh]); fprintf(Fvinfo, "\n"); printf(" %d NF (%ds)\n", nnf_v[v], (int) difftime(time(NULL),Tstart)); fflush(0); } free(_PD); fclose(Fvinfo); } void Sort_Hodge(char *dbaux, char *dbout){ /* Sort from v-chi-format to chi-h12-format */ time_t Tstart; char *dbaname = (char *) malloc(6+strlen(dbaux)+File_Ext_NCmax), *fax; char *dbhname = (char *) malloc(6+strlen(*dbout ? dbout : dbaux)+File_Ext_NCmax), *fhx; int v, i, j, dh, nd, nnf_d[Hod_Dif_max+1], nnf_vd[VERT_Nmax][Hod_Dif_max+1], nnf_h[Hod_Min_max+1], nnf_v[VERT_Nmax]; FILE *Fh[Hod_Min_max+1]; FILE *Fchia, *Fvinfo, *Fhinfo; for(i=0;i<=Hod_Dif_max;i++){ nnf_d[i]=0; for(j=0;j=0)&&(c-'0'<=9)) E=0; while((c-'0'>=0)&&(c-'0'<=9)) {E=10*E+c-'0'; c=x_string[++i];} if(E%2) {puts("The Euler number E number must be even!"); return;} if(neg) E*=-1;} else if(c=='H'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {H1=10*H1+c-'0'; c=x_string[++i];}} else if(c==':'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {H2=10*H2+c-'0'; c=x_string[++i];}} else if(c=='M'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {M=10*M+c-'0'; c=x_string[++i];}} else if(c=='V'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {V=10*V+c-'0'; c=x_string[++i];}} else if(c=='N'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {N=10*N+c-'0'; c=x_string[++i];}} else if(c=='F'){ c=x_string[++i]; while((c-'0'>=0)&&(c-'0'<=9)) {F=10*F+c-'0'; c=x_string[++i];}} else if(c=='L'){ c=x_string[++i]; L=0; while((c-'0'>=0)&&(c-'0'<=9)) {L=10*L+c-'0'; c=x_string[++i];}} else {printf("`%c' is not valid input", c); return;}} if(H1&&H2){E=2*(H1-H2);} else if(H1&&(E!=998)) H2=H1-E/2; else if(H2&&(E!=998)) H1=H2+E/2; if( H1>491 || H2>491 || H1+H2>502 || (abs(E)!=998 && abs(E)>960) ){ puts("#NF: 0 Note the range for Hodge numbers:"); puts(" h11,h12<=491, h11+h12<=502, |E|<=960."); return;} if( (V&&(V<5||V>33)) || (F&&(F<5||F>33))){ puts("#NF: 0 Note the range [5,33] for vertex/facet numbers!"); return;} if( (M&&(M<6||M>680)) || (N&&(N<6||N>680)) ){ puts("#NF: 0 Note the range [6,680] for point numbers!"); return;} if(V&&(Vmax_mv) break; c2=fgetc(Fh); mp=(c1%4)*256+c2; c1=fgetc(Fh); c2=fgetc(Fh); nv=c1/4; np=(c1%4)*256+c2; c1=fgetc(Fh); mirror=c1/64; nuc=c1%64; for (j=0;jL) {printf("Exceeded limit of %d\n",L); return;} sprintf(com,"M:%d %d N:%d %d H:%d,%d [%d]", mp,mv,np,nv,true_H1,true_H2,2*(true_H1-true_H2)); Print_PPL(_P,com); } if (is_dual&&MS){ VertexNumList VNL; EqList EL; Long NF[POLY_Dmax][VERT_Nmax]; if (++nnf_sum>L) {printf("Exceeded limit of %d\n",L); return;} sprintf(com,"M:%d %d N:%d %d H:%d,%d [%d]", np,nv,mp,mv,true_H2,true_H1,2*(true_H2-true_H1)); Find_Equations(_P,&VNL,&EL); Small_Make_Dual(_P, &VNL, &EL); Make_Poly_NF(_P, &VNL, &EL, NF); Print_Matrix(NF, _P->n, VNL.nv, com); } } if(ferror(Fh)) { printf("File error in Fh at dh=%d h12=%d\n",dh,h12); exit(0);} fclose(Fh); } } printf("#NF: %d\n",nnf_sum); printf(" done (%ds)\n",(int) difftime(time(NULL),Tstart)); fflush(stdout); } void Test_Hodge_file(char *filename, PolyPointList *_P){ FILE *Ft=fopen(filename,"rb"); unsigned char uc_poly[NUC_Nmax]; int nuc, mirror, nv, np, mv, mp, j, c1, c2, d=4, MS; assert (Ft!=0); while((c1=fgetc(Ft))!=EOF){ c2=fgetc(Ft); mv=c1/4; mp=(c1%4)*256+c2; c1=fgetc(Ft); c2=fgetc(Ft); nv=c1/4; np=(c1%4)*256+c2; c1=fgetc(Ft); mirror=c1/64; nuc=c1%64; for (j=0;jFinfo=fopen(dbname,"r"); assert(DB->Finfo!=NULL); fscanf(DB->Finfo, "%d %d %d %d %d %lld %d %lld %lld %d %d %d %d", &DB->d,&DB->nV,&DB->nVmax,&DB->NUCmax,&DB->list_num, &DB->nNF,&DB->nSM, &DB->nNM, &DB->NB, &DB->sl_nNF, &DB->sl_SM, &DB->sl_NM, &DB->sl_NB); if(info) printf("%lldp (%dsl) %lldnf %lldb\n", 2*(DB->nNF)-DB->nSM-DB->nNM+2*DB->sl_nNF-DB->sl_SM-DB->sl_NM, 2* DB->sl_nNF-DB->sl_SM-DB->sl_NM, DB->nNF+DB->sl_nNF,DB->NB+DB->sl_NB); for (v=1;vnNUC[v]=0; for(nu=0; nuNFnum[v][nu]=0;} for(i=0; inV; i++){ fscanf(DB->Finfo,"%d",&v); fscanf(DB->Finfo,"%d",&(DB->nNUC[v])); for(j=0;jnNUC[v];j++){ fscanf(DB->Finfo,"%d", &nu); fscanf(DB->Finfo,"%d", &(DB->NFnum[v][nu])); } } if(ferror(DB->Finfo)) {printf("File error in %s\n",dbname); exit(0);} fclose(DB->Finfo); ext[0]='v'; ext[3]=0; DB->v=DB->p=DB->nu=0; for(v=DB->d+1; v<=DB->nVmax; v++) if(DB->nNUC[v]) { ext[1]='0' + v / 10; ext[2]='0' + v % 10; strcpy(fx,ext); DB->Fv[v]=fopen(dbname,"rb"); assert(DB->Fv[v]!=NULL); if(0==DB->v) {DB->v=v; while(0==DB->NFnum[v][DB->nu]) (DB->nu)++;} } } void Close_DB(DataBase *DB) { int v; if(DB==NULL) return; for(v=1+DB->d; v<=DB->nVmax; v++) if(DB->nNUC[v]) { if(ferror(DB->Fv[v])) {printf("File error at v=%d\n",v); exit(0);} fclose(DB->Fv[v]);} free(DB); } #undef TEST int Read_H_ucNF_from_DB(DataBase *DB, unsigned char *uc)/* p=next read pos */ { static Along totNF; int rest; assert(DB!=NULL); rest = DB->NFnum[DB->v][DB->nu] - DB->p; #ifdef TEST {static int vNF, xvNF, nuNF=DB->NFnum[DB->v][DB->nu]; if(totNF==0){int i,j;for(i=1;i<=DB->NUCmax;i++)vNF+=DB->NFnum[DB->v][i]; for(i=DB->v;i<=DB->nVmax;i++) for(j=1;j<=DB->NUCmax;j++) xvNF+=DB->NFnum[i][j]; if(xvNF!=DB->nNF) {printf("xvNF=%d nNF=%d",xvNF,DB->nNF);exit(0);} xvNF=vNF; }} #endif assert(0<=rest); if(rest==0) /* search next v/nu */ { int v=DB->v, nu=DB->nu; /* search nu(v): */ while(DB->nu < DB->NUCmax) if(DB->NFnum[DB->v][++(DB->nu)]) break; if((nu==DB->nu)||(DB->NFnum[DB->v][DB->nu]==0)) /* search v: */ { if(DB->v < DB->nVmax) { while(0==DB->nNUC[++DB->v]) assert(DB->v < DB->nVmax); DB->nu=0; while(DB->nu < DB->NUCmax) if(DB->NFnum[DB->v][++(DB->nu)]) break; } else { assert(totNF==DB->nNF); return 0; } } if((vv)||(nunu)) {rest=DB->NFnum[DB->v][DB->nu]; DB->p=0;} #ifdef TEST if((vv)||(nunu)){assert(totNF==nuNF);nuNF+=DB->NFnum[DB->v][DB->nu];} if(vv) { if(vNF){printf("vNF[%d]=%d was=%d v_new=%d\n",v,xvNF,vNF,DB->v);exit(0);} for(i=1;i<=DB->NUCmax;i++) vNF+=DB->NFnum[DB->v][i];} #endif } assert(DB->p<=DB->NFnum[DB->v][DB->nu]); assert(rest); assert(totNF < DB->nNF); #ifdef TEST printf("return 1 at totNF=%d v=%d nu=%d p=%d\n", totNF,DB->v,DB->nu,DB->p); assert(0Fv[DB->v],&DB->nu,uc); ++DB->p; totNF++; return 1; } int Read_SLucNF_from_DB(void) { puts("Read_SLucNF_from_DB: to be implemented"); exit(0); return 0; } int Read_SLpoly_from_DB(void) { puts("Read_SLpoly_from_DB: to be implemented"); exit(0); return 0; } int Read_H_poly_from_DB(DataBase *DB,PolyPointList *P) { static unsigned char uc[NUC_Nmax]; static int ms3; int i,j, MS; Long NF[POLY_Dmax][VERT_Nmax]; VertexNumList V; EqList E; if(0==ms3) { if(0==Read_H_ucNF_from_DB(DB,uc)) return 0;} else --uc[0]; UCnf2vNF(&DB->d,&DB->v,&DB->nu,uc,NF,&MS); P->n=DB->d; P->np=DB->v; for(i=0;inp;i++) for(j=0;jn;j++) P->x[i][j]=NF[j][i]; MS%=4; ms3=(MS==3); if(MS==2) { assert(Ref_Check(P,&V,&E)); P->np=E.ne; for(i=0;inp;i++)for(j=0;jn;j++) P->x[i][j]=E.e[i].a[j]; } return 1; } int Read_H_poly_from_DB_or_inFILE(DataBase *DB,PolyPointList *P) { if((DB==NULL)||(inFILE==NULL)) {CWS cws; return Read_CWS_PP(&cws,P);} else return Read_H_poly_from_DB(DB,P); } /* ===================================================================== */ /* ===================================================================== */ /* ============== from Subpoly.c: ============= */ /* void Make_All_Sublat(NF_List *_L, int n, int v, subl_int diag[POLY_Dmax], subl_int u[][VERT_Nmax], char *mFlag) */ /* create all inequivalent decompositions diag=s*t into upper triangular matrices s,t; t*(first lines of u) becomes the poly P; choose the elements of t (columns rising, line # falling), calculate corresponding element of s at the same time; finally calculate P and add to list */ /* void MakePolyOnSublat(NF_List *_L, subl_int x[VERT_Nmax][VERT_Nmax], int v, int f, int *max_order, char *mFlag) */ /* Decompose the VPM x as x=w*diag*u, where w and u are SL(Z); the first lines of u are the coordinates on the coarsest lattices */ /* ============== End of "from Subpoly.c" ============= */ /* =================== Sublattice: phv =================== */ Long AuxGxP(Long *Gi,Long *V,int *d) { Long x=0; int j; for(j=0;j<*d;j++) x+=Gi[j]*V[j]; return x; } /* Glz x (lincomb(Points)) -> Diag: if(index>1) print vertices of G*P & D */ #define TEST #define TEST_OUT void Aux_Print_CoverPoly(int *I,int *d, int *N,Long *X[POLY_Dmax], Long G[][POLY_Dmax],Long *D,int *x,Long Z[][VERT_Nmax],Long *M,int r) { int i,j,dia=1, err=0; fprintf(outFILE,"%d %d index=%d D=%ld",*d,*N, *I,D[0]); for(i=1;i<*d;i++) printf(" %ld",D[i]); for(i=0;in, e=E->ne, v=V->nv; assert(e<=VERT_Nmax); P->np=V->nv=e; E->ne=v; for(i=0;ix[V->v[i]][j]; for(i=0;ix[i][j]=E->e[i].a[j]; V->v[i]=i;} for(i=0;ie[i].a[j]=VM[i][j]; E->e[i].c=1;} assert(Ref_Check(P,V,E)); } void PrintVPHMusage(void); int Make_Lattice_Basis(int d, int p, Long *P[POLY_Dmax], /* index=det(D) */ Long G[][POLY_Dmax], Long *D);/* G x P generates diagonal lattice D */ void PH_Sublat_Polys(char *dbin, int omitFIP, PolyPointList *_P, char sF) { static EqList E; VertexNumList V; int x=0, K, B, I=1; /* index>I only */ Long *RelPts[POINT_Nmax];DataBase *DB=NULL; if(*dbin)Open_DB(dbin,&DB,0); K=((sF!='P')&&(sF!='H')&&(sF!='Q')&&(sF!='B')); /* K=='CoverPoly' */ if(('1'I */ while(Read_H_poly_from_DB_or_inFILE(DB,_P)) { Long D[POLY_Dmax],G[POLY_Dmax][POLY_Dmax],PM[VERT_Nmax][VERT_Nmax]; int index, N=0; /* if(!Ref_Check(_P,&V,&E)) Print_PPL(_P,""); */ if(B)assert(_P->n==4);/* b:Brower group only for CY hypersurface d=4 */ assert(Ref_Check(_P,&V,&E)); /* Aux_Make_Dual(_P,&V,&E); */ /* don't dualize: take M-lattice poly */ Make_VEPM(_P,&V,&E,PM); _P->np=V.nv; Complete_Poly(PM,&E,V.nv,_P); ++x; if(omitFIP==0) for(N=0;N<_P->np;N++) RelPts[N]=_P->x[N]; else if(omitFIP<3 ) /* Omit facet-IPs */ { int p; for(p=0;p<_P->np;p++) { int e, z=0; for(e=0;ex[p],_P->n)) z++; if(z>omitFIP) RelPts[N++]=_P->x[p]; } assert(V.nv<=N); /* count =0; if(n>1) add_to_RelPts; */ } else if(omitFIP==3) /* Omit all non-vertices */ { for(N=0;Nx[N]; /* { int tnv=V.nv; Find_Equations(_P,&V,&E);assert(V.nv==tnv); for(tnv=0;tnvn,N,RelPts,Z,M,&r,G,D); if(B)if(D[2]==1)continue; if(omitFIP==3)if(D[1]==1)continue; assert(index>0); if(index<=I)continue; assert(Ref_Check(_P,&V,&E)); Aux_Print_CoverPoly(&index,&_P->n,&N,RelPts,G,D,&x,Z,M,r); } else { index=Make_Lattice_Basis(_P->n,N,RelPts,G,D); if(1==index)continue; if(B)if(D[2]==1)continue; if(omitFIP==3)if(D[1]==1)continue; assert(index>0); assert(Ref_Check(_P,&V,&E)); Print_VL(_P,&V,""); Aux_Print_SLpoly(&index,&_P->n,&N,RelPts,G,D,&x); } } if(*dbin) Close_DB(DB); } #undef TEST /* Lattice generated by vertices; UT-decomp of diag */ void V_Sublat_Polys(char mr,char *dbin,char *polyi,char *polyo, PolyPointList *_P) { NF_List *_L=(NF_List *) malloc(sizeof(NF_List)); int max_order=1; static EqList E; VertexNumList V; int x=0; Long *RelPts[VERT_Nmax];DataBase *DB=NULL; if(*dbin)Open_DB(dbin,&DB,0); assert(_L!=NULL); if(!(*polyo)) { puts("You have to specify an output file via -po in -sv-mode."); printf("For more help use option `-h'\n"); exit(0);} _L->of=0; _L->rf=0; _L->iname=polyi; _L->oname=polyo; _L->dbname=dbin; Init_NF_List(_L); _L->SL=0; while(Read_H_poly_from_DB_or_inFILE(DB,_P)) { Long D[POLY_Dmax],G[POLY_Dmax][POLY_Dmax]; int index, N; assert(Ref_Check(_P,&V,&E)); for(N=0;Nx[V.v[N]]; ++x; index=Make_Lattice_Basis(_P->n,N,RelPts,G,D); if(1==index) continue; assert(index>0); if(index>max_order) max_order=index; #ifdef TEST Aux_Print_SLpoly(&index,&_P->n, &N,RelPts,G,D,&x); #endif { int i,j; subl_int diag[POLY_Dmax], U[POLY_Dmax][VERT_Nmax]; for(i=0;i<_P->n;i++){diag[i]=D[i]; for(j=0;jn;k++) U[i][j]+=G[i][k]*RelPts[j][k]; assert(0==(U[i][j]%D[i])); U[i][j]/=D[i];}} Make_All_Sublat(_L, _P->n, V.nv, diag, U, &mr, _P); } } if(*dbin) Close_DB(DB); printf("max_order=%d\n", max_order); Write_List_2_File(polyo,_L); _L->TIME=time(NULL); fputs(ctime(&_L->TIME),stdout); free(_L); } void VPHM_Sublat_Polys(char sFlag,char mr,char *dbin,char *polyi,char *polyo, PolyPointList *_P) { switch(sFlag){ /* if(dbin=0) read from inFILE; */ case 'p': case 'P': PH_Sublat_Polys(dbin,0,_P,sFlag); break ; case 'h': case 'H': PH_Sublat_Polys(dbin,1,_P,sFlag); break ; case 'b': case 'B': PH_Sublat_Polys(dbin,2,_P,sFlag); break ; case 'q': case 'Q': PH_Sublat_Polys(dbin,3,_P,sFlag); break ; case 'v': case 'V': V_Sublat_Polys(mr,dbin,polyi,polyo,_P); break ; case 'm': case 'M': Find_Sublat_Polys(mr,dbin,polyi,polyo,_P); break ; default:if(('1'1 points (omit IPs of facets)"); puts(" -sp ... gen by all points"); puts(" -sb ... generated by dim<=1 (edges), print if rank=2 "); puts(" -sq ... generated by vertices, print if rank=3 "); puts(" q,b currently assume that dim=4"); exit(0); } void Bin_2_ANF(char *polyi, int max, PolyPointList *_P) { FILE *F=fopen(polyi,"rb"); FInfoList L; UPint list_num,tNF=0; Along tNB=0; int d, v, s, sl_nNF, sl_SM, sl_NM, sl_NB, mc=0, MS, nu; unsigned i, j; unsigned char uc[POLY_Dmax*VERT_Nmax]; VertexNumList V; EqList E; Long NF[POLY_Dmax][VERT_Nmax]; Init_FInfoList(&L); if(F==NULL) {printf("Input file %s not found\n",polyi); exit(0);} d=fgetc(F); assert(d==0); /* for(i=0;in=d; _P->np=v; for(I=0;Ix[I][J]=NF[J][I]; /* assert(Ref_Check(_P,&V,&E)); */ assert(MS==1); if(MS!=2) /* if(MS!=2) print NF */ if(!max || Poly_Max_check(_P,&V,&E)) { mc++; Print_NF(outFILE,&d,&v,NF);} if(MS>1) /* if(MS>1); print Mirror */ if(!max || Poly_Min_check(_P,&V,&E)) { mc++; Small_Make_Dual(_P,&V,&E); Make_Poly_NF(_P,&V,&E,NF); Print_NF(outFILE,&d,&(V.nv),NF); } } } printf("np=%lld+%dsl ",2*L.nNF-L.nSM-L.nNM,2*sl_nNF-sl_SM-sl_NM); printf( /* write Finfo */ "%dd %dv<=%d n<=%d %dnv %lld %d %lld %lld %d %d %d %d", d, L.nV, L.nVmax, L.NUCmax,list_num, L.nNF,L.nSM,L.nNM,L.NB, sl_nNF, sl_SM, sl_NM, sl_NB); if(max) printf(" r-max=%d",mc); puts(""); } void Bin_2_ANF_DBsl(char *dbi, int max, int vf, int vt, PolyPointList *_P) { FILE *F; FInfoList L; int d, v, nu, i, j, list_num, mc=0, MS, sl_nNF, sl_SM, sl_NM, sl_NB, tSM=0, tNM=0; char *Ifx, *Ifn = (char *) malloc(1+strlen(dbi)+File_Ext_NCmax); Long NF[POLY_Dmax][VERT_Nmax]; VertexNumList V;EqList E; strcpy(Ifn,dbi); Ifx=&Ifn[strlen(dbi)]; strcpy(Ifx,".info"); F=fopen(Ifn,"r"); if(F==NULL) {puts("Info File not found");exit(0);} Init_FInfoList(&L); /* start reading the file */ fscanf(F,"%d%d%d%d%d%lld%d%lld %lld %d%d%d%d", &d,&i,&j,&nu,&list_num,&L.nNF,&L.nSM,&L.nNM,&L.NB, &sl_nNF,&sl_SM,&sl_NM,&sl_NB); L.nV=i; L.nVmax=j; L.NUCmax=nu; if(sl_NB && (vf==2)&&(vt==VERT_Nmax-1)) { strcpy(Ifx,".sl"); fclose(F); if(NULL==(F=fopen(Ifn,"rb"))){printf("Open %s failed",Ifn);exit(0);} } else /* puts("no .sl file"); */ { DataBase *DB; Open_DB(dbi, &DB, 0); if((DB->vnVmax>vt)) DB_fromVF_toVT(DB,vf,vt); /* read only vf <= v <= vt :: */ for(i=0; Read_H_poly_from_DB(DB,_P); i++) { int c, l, p=_P->np-1, off=_P->x[p][0]; if(off) for(l=0;lx[c][l]-=off; /* if(off) Print_PPL(_P,"off"); else */ Print_PPL(_P,""); } printf("#poly=%d\n",i); Close_DB(DB); } for(i=0;in=d; _P->np=v; for(I=0;Ix[I][J]=NF[J][I]; if(MS!=2) /* if(MS!=2) print NF */ if(!max || Poly_Max_check(_P,&V,&E)) { mc++; Print_NF(outFILE,&d,&v,NF);} if(MS>1) /* if(MS>1); print Mirror */ if(!max || Poly_Min_check(_P,&V,&E)) { mc++; Small_Make_Dual(_P,&V,&E); Make_Poly_NF(_P,&V,&E,NF); Print_NF(outFILE,&d,&(V.nv),NF); } } printf("np=%lld+%dsl ",2*L.nNF-L.nSM-L.nNM,2*sl_nNF-sl_SM-sl_NM); printf( /* write Finfo */ "%dd %dv<=%d n<=%d %dnv ... %d %d %d %d", /* %d %d %d %lld */ d, L.nV, L.nVmax, L.NUCmax,list_num, /* L.nNF,L.nSM,L.nNM,L.NB, */ sl_nNF, sl_SM, sl_NM, sl_NB); if(max) printf(" r-max=%d",mc); puts(""); } void Gen_Bin_2_ascii(char *pi,char *dbi,int max,int vf,int vt,PolyPointList *P) { if(*pi) Bin_2_ANF(pi, max, P); else if(*dbi) Bin_2_ANF_DBsl(dbi, max, vf, vt, P); else puts("With -B[2A] you have to specify input via -pi or -di"); } palp-2.21/Makefile0000664000177600017760000000373714572603263013420 0ustar skarkeskarke# M A K E F I L E # main programs: class.c cws.c poly.c nef.c mori.c SOURCES= Coord.c Rat.c Vertex.c Polynf.c OBJECTS= $(SOURCES:.c=.o) CLASS_SRC= Subpoly.c Subadd.c Subdb.c CLASS_OBJ= $(CLASS_SRC:.c=.o) NEF_SRC= E_Poly.c Nefpart.c LG.c NEF_OBJ= $(NEF_SRC:.c=.o) MORI_SRC= Moricone.c MORI_OBJ= $(MORI_SRC:.c=.o) CC=cc CFLAGS=-O3 -fast # CFLAGS=-O3 -g # add -g for GNU debugger gdb # CFLAGS=-Ofast -O3 -mips4 -n32 # SGI / 32 bit # CFLAGS=-Ofast -O3 -mips4 -64 # SGI / 64 bit # CFLAGS=-O3 -fast -non_shared -arch pca56 # statically linked for alpha_PC # targets : dependencies ; command # command # ... all: poly class cws nef clean: ; rm -f *.o cleanall: ; rm -f *.o *.x core poly: poly.o $(OBJECTS) LG.o Global.h LG.h $(CC) $(CFLAGS) -o poly.x poly.o $(OBJECTS) LG.o class: class.o $(OBJECTS) $(CLASS_OBJ) Global.h Subpoly.h $(CC) $(CFLAGS) -o class.x class.o $(OBJECTS) $(CLASS_OBJ) cws: cws.o $(OBJECTS) LG.o Global.h LG.h $(CC) $(CFLAGS) -o cws.x cws.o $(OBJECTS) LG.o nef: nef.o $(OBJECTS) $(NEF_OBJ) Global.h $(CC) $(CFLAGS) -o nef.x nef.o $(OBJECTS) $(NEF_OBJ) mori: mori.o $(OBJECTS) $(MORI_OBJ) Global.h $(CC) $(CFLAGS) -o mori.x mori.o $(OBJECTS) $(MORI_OBJ) # D E P E N D E N C I E S Coord.o: Global.h Rat.h Polynf.o: Global.h Rat.h Rat.o: Global.h Rat.h Subpoly.o: Global.h Rat.h Subpoly.h Subadd.o: Global.h Subpoly.h Vertex.o: Global.h Rat.h Subdb.o: Global.h Subpoly.h LG.o: Global.h Rat.h LG.h E_Poly.o: Global.h Nef.h Rat.h Nefpart.o: Global.h Nef.h poly.o: Global.h LG.h class.o: Global.h Subpoly.h cws.o: Global.h LG.h Rat.h nef.o: Global.h Nef.h LG.h mori.o: Global.h Rat.h LG.h # experimental stuff ... #mori: mori.o $(OBJECTS) Global.h # $(CC) $(CFLAGS) -o mori.x mori.o $(OBJECTS) # #mori.o: mori.c Global.h # #lgo: lgotwist.c # $(CC) $(CFLAGS) -o lgo.x lgotwist.c palp-2.21/Global.h0000664000177600017760000005231514572606000013315 0ustar skarkeskarke#include #include #include #include #include /* These are include files that should exist in your C library. */ /* ============ basic choice of PARAMETERS ============ */ #define Long long #define LLong long long /* For reflexive polytopes in 4 or less dimensions, everything should work with Long set to 32-bit-integer and LLong set to 64 bits. Many applications will even work with LLong at 32 bits. For higher dimensional or complicated non-reflexive polytopes it may be necessary to set even Long to 64 bits. */ #ifndef POLY_Dmax /* You can set POLY_Dmax at compilation: use -D POLY_Dmax= in the C flags */ #define POLY_Dmax 6 /* max dim of polytope */ #endif /* POLY_Dmax should be set to the dimension of the polytopes that are analysed. While the programs still work if POLY_Dmax is set to a higher value, they may be considerably slowed down. */ #if (POLY_Dmax <= 3) #define POINT_Nmax 40 /* max number of points */ #define VERT_Nmax 16 /* max number of vertices */ #define FACE_Nmax 30 /* max number of faces */ #define SYM_Nmax 88 /* cube: 2^D*D! plus extra */ #elif (POLY_Dmax == 4) #define POINT_Nmax 700 /* max number of points */ #define VERT_Nmax 64 /* max number of vertices */ #define FACE_Nmax 824 /* max number of faces */ #define SYM_Nmax 1200 #else #define POINT_Nmax 2000000 #define VERT_Nmax 64 /* !! use optimal value !! */ #define FACE_Nmax 10000 /* max number of faces */ #define SYM_Nmax 46080 /* symmetry (P_1)^6: 2^6*6! */ #define EQUA_Nmax 1280 /* up to 20000 without alloc */ #endif #ifndef EQUA_Nmax /* default setting */ #define EQUA_Nmax VERT_Nmax #endif /* POINT_Nmax, VERT_Nmax and FACE_Nmax denote the maximal numbers of points, vertices and faces, respectively. SYM_Nmax is the maximal number of symmetries of a polytope, i.e. the order of the finite subgroup S of the group GL(n,Z) of lattice automorphisms that leaves a polytope invariant. EQUA_Nmax denotes the maximal number of facets (given by equations) of a polytope. By duality this is just the number of vertices of the dual polytope, so it makes sense to have the default setting EQUA_Nmax = VERT_Nmax. In applications not related to reflexive polytopes or in large dimensions a larger value may be useful. While CPU-time is almost independent of EQUA_Nmax, it strongly depends on VERT_Nmax/32 (i.e. use 32, 64, 96, ...). Our settings for dimensions less than or equal to 4 are such that they work for any reflexive polytope. */ #define AMBI_Dmax (5 * POLY_Dmax) /* default setting */ /* If a polytope is determined by a combined weight system it is first realised by an embeddeding in an ambient space of dimension (Poly-dim + number of weight systems). AMBI_Dmax is the maximal dimension of this ambient space. */ #define FIB_Nmax 3000 /*NOW: 27/5/11 default setting*/ /* Given a polytope P* it is possible to analyze the IP simplices among its points. These simplices are given in terms of weight relations among points of P*. FIB_Nmax is the maximal number of allowed relations. */ #define CD2F_Nmax FACE_Nmax /* Max number of codimension 2 faces. */ #define GL_Long Long /* Uses W_to_GLZ like in Rat.c */ #define MAXLD (26) /* Used in the handling of large lists of weight systems (cf. C5stats) */ extern FILE *inFILE, *outFILE; /* Ascii-files for input and output. If not given in the parameter list they default to stdin and stdout, respectively. */ /* ========== Global typedefs ========== */ typedef struct {int n, np; Long x[POINT_Nmax][POLY_Dmax];} PolyPointList; /* A list (not necessarily complete) of lattice points of a polytope. P.x[i][j] is the j'th coordinate of the i'th lattice point. P.n is the dimension of the polytope and P.np the number of points in the list. */ typedef struct {int v[VERT_Nmax]; int nv;} VertexNumList; /* The list of vertices of a polytope, referring to some PolyPointList P. The j'th coordinate of the i'th vertex is then given by P.x[V.v[i]][j]. V.nv is the number of vertices of P. */ typedef struct {Long a[POLY_Dmax], c;} Equation; /* This structure determines an equation of the type ax+c=0, explicitly: sum_{i=1}^n E.a[i] x_i + E.c = 0. */ typedef struct {int ne; Equation e[EQUA_Nmax];} EqList; /* A list of equations; EL.ne is the number of equations in the list. */ typedef struct {EqList B; Long W[AMBI_Dmax][AMBI_Dmax], d[AMBI_Dmax]; int nw, N, z[POLY_Dmax][AMBI_Dmax], m[POLY_Dmax], nz, index;} CWS; /* Combined weight system: W[i][j] and d[i] are the j'th weight and the "degree" of the i'th weight system, respectively; nw is the number of weight systems, N is the dimension of the ambient space. z[i][j]/m[i] are the phases of nz symmetries for polytopes on sublattices. B describes the ambient space coordinate hyperplanes in terms of the new (non-redundant) coordinates. */ typedef Long PairMat[EQUA_Nmax][VERT_Nmax]; /* The matrix whose entries are the pairings av+c between the vertices v and the equations (a,c). */ typedef struct {int mp, mv, np, nv, n, pic, cor, h22, h1[POLY_Dmax-1];} BaHo; /* This structure is related to Batyrev's formulas for Hodge numbers. n ... dimension of the polytope pic ... Picard number cor ... sum of correction terms h1[i] ... Hodge number h_{1i} h22 ... Hodge number h_{22} (if n = 5) mp, mv, np, nv denote the numbers of points/vertices in the M and N lattices, repectively. */ typedef struct { Long W[FIB_Nmax][VERT_Nmax]; int nw, PS, ZS, nv, f[VERT_Nmax],r[VERT_Nmax],nf,nz[FIB_Nmax], n0[FIB_Nmax], Z[FIB_Nmax][VERT_Nmax], M[FIB_Nmax]; GL_Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax]; PolyPointList *P; } FibW; /* This list is an extension of the PolyPointList with the combined weight system. W[i][j] is the j'th weight; nw is the number of weight systems. */ typedef struct{ long n_nonIP, n_IP_nonRef, n_ref, // numbers of WS of certain types max_w, nr_max_w, //maximum weight in the reflexive/non-reflexive cases nr_n_w[MAXLD], n_w[MAXLD]; //numbers of weights of given [ld] int nr_max_mp, nr_max_mv, nr_max_nv, max_mp, max_mv, max_np, max_nv, max_h22, max_h1[POLY_Dmax-1], //max values of certain entries of BH min_chi, max_chi, max_nf[POLY_Dmax+1]; //range for chi, max facet numbers } C5stats; /* statistics on large lists of weight systems, cf. classification of 4fold weights */ /* ========== I/O functions (from Coord.c) ========== */ int Read_CWS_PP(CWS *C, PolyPointList *P); /* Reads either a CWS or a PolyPointList. If *C is read, the PolyPointList *P determined by *C is calculated, otherwise C->nw is set to 0 to indicate that no weight has been read. CWS-input consists of a single line of the form d1 w11 w12 ... d2 w21 w22 ..., whereas PolyPointList-input begins with a line #columns #lines followed by #lines further lines. It reads P->x as a matrix such that either P->n = #columns and P->np = #lines or vice versa (the result is unique because of P->np > P->n). */ int Read_CWS(CWS *_CW, PolyPointList *_P); /* Reads CWS input *C, the PolyPointList *P determined by *C is calculated. */ int Read_PP(PolyPointList *_P); /* Reads the PolyPointList input *P */ void Print_PPL(PolyPointList *P, const char *comment); void Print_VL(PolyPointList *P, VertexNumList *V, const char *comment); void Print_EL(EqList *EL, int *n, int suppress_c, const char *comment); void Print_Matrix(Long Matrix[][VERT_Nmax], int n_lines, int n_columns, const char *comment); /* Each of these routines prints a matrix in the format #columns #lines *comment line_0 ... line_{#lines-1}. With Print_PPL and Print_VL, points/vertices are displayed as column vectors if there's enough space and as row vectors otherwise. Print_EL always displays equations in line format. If *suppress_c is zero line_i reads EL->e[i].a[0] ... EL->e[i].a[*n-1] EL->e[i].c, otherwise the last entry EL->e[i].c is suppressed so that the resulting output can be used as input for Read_CWS_PP. */ void Print_CWH(CWS *C, BaHo *BH); /* Writes a single line that reproduces *C (if C->nw isn't 0, i.e. if the input was of CWS type), information on the numbers of points and vertices of the polytope and its dual, and the Hodge numbers of the corresponding Calabi-Yau variety. *C is reproduced in the format d1 w11 w12 ... d2 w21 w22 ... Information on the polytope is given in the form M:mp mv N:np nv for reflexive polytopes. Here mp and mv are the numbers of lattice points and vertices of the polytope, respectively, and np and nv denote the corresponding numbers for the dual polytope. If a polytope is not reflexive, "N:np nv" is replaced by "F:ne" (the number of facets/equations). Hodge number information is given in the format H: h11 h12 ... h1(n-2) [chi], where the h1i are the corresponding Hodge numbers and chi is the Euler number. This output is suppressed for polytopes that are not reflexive. As an example, the complete output for the quintic threefold reads 5 1 1 1 1 1 M:126 5 N:6 5 H:1,101 [-200]. */ void Initialize_C5S(C5stats *_C5S, int n); void Update_C5S(BaHo *_BH, int *nf, Long *W, C5stats *_C5S); void Print_C5S(C5stats *_C5S); /* Routines for handling the structure C5stats */ /* ========== From Polynf.c ========== */ int Make_Poly_Sym_NF(PolyPointList *P, VertexNumList *VNL, EqList *EL, int *SymNum, int V_perm[][VERT_Nmax], Long NF[POLY_Dmax][VERT_Nmax], int t, int S, int N); /* Given *P, *VNL and *EL, the following objects are determined: the number *SymNum of GL(n,Z)-symmetries of the polytope, the *SymNum vertex permutations V_perm realising these symmetries, the normal form coordinates NF of the vertices, the number of symmetries of the vertex pairing matrix (this number is the return value of Make_Poly_Sym_NF). If t/S/N are non-zero, the output of the corresponding options of poly.x is displayed. */ void IP_Simplex_Decomp(Long CM[][POLY_Dmax], int p, int d, int *nw, Long W[][VERT_Nmax], int Wmax, int codim); /* Given the matrix CM of coordinates of p points in Z^d, the list W[i] of *nw weight systems corresponding to IP-simplices spanned by the points in CM is created. If codim!=0 only the IP-simplices with dimension > 1 and codimension between 1 and codim are computed. It is assumed that p<=VERT_Nmax and that W can hold at least Wmax sets of coefficients. */ void IP_Simplices(PolyPointList *P, int nv, int PS, int VS, int CD); /* Realizes the -P,-V,-Z, and fibration options of poly (the results of this routine are displayed as output; *P is not modified). */ int Sublattice_Basis(int d, int p, Long *P[], /* return index=det(D) */ Long Z[][VERT_Nmax], Long *M, int *r, Long G[][POLY_Dmax], Long *D); /* Given a vector P[] of pointers at p points in N=Z^d that generate a (sub)lattice N' of the same dimension d, the following data are determined: D[i] with 0 <= i < d such that the lattice quotient N/N' is the product of cyclic groups Z_{D[i]} with D[i] dividing D[i+1], and a GL(d,Z) matrix G corresponding to a base change P->GxP such that the i'th new coordinate of each of the lattice points is divisible by D[i]. If p<=VERT_Nmax the program also computes *r coefficient vectors Z[i] for linear combinations of the points on P that are M[i]-fold multiples of primitive lattice vectors, where M[i]=D[d-i] for i<*r. If p>VERT_Nmax it is asserted that the index of the lattice quotient is 1. */ void Make_Poly_UTriang(PolyPointList *P); /* A coordinate change is performed that makes the matrix P->x upper triangular, with minimal entries above the diagonal. */ void Make_ANF(PolyPointList *P, VertexNumList *V, EqList*E, Long ANF[][VERT_Nmax]); /* Given *P, *V and *E, the affine normal form ANF (i.e., a normal form that also works for non-reflexive polytopes), is computed. */ int SimpUnimod(PolyPointList *P, VertexNumList *V, EqList *E, int vol); /* If vol is 0, the return value is 1 if all facets are simplicial, 0 otherwise If vol is not 0, the return value is 1 if all facets are unimoular (i.e. of volume 1) and 0 otherwise. */ int ConifoldSing(PolyPointList *P, VertexNumList *V, EqList *E, PolyPointList *dP, EqList *dE, int CYorFANO); /* Realizes the -C1 or -C2 options of poly for CYorFANO being 1 or 2, respectively. */ int Fano5d(PolyPointList *, VertexNumList *, EqList *); /* Realizes the -U5 option of poly. */ void Einstein_Metric(CWS *CW,PolyPointList *P,VertexNumList *V,EqList *E); /* Realizes the -E option of poly. */ int Divisibility_Index(PolyPointList *P, VertexNumList *V); /* Returns the largest integer g for which *P is a g-fold multiple of some other polytope. */ Long LatVol_Barycent(PolyPointList *P, VertexNumList *V, Long *B, Long *N); /* Given *P and *V, the coordinates of the barycenter of *P are computed (with the i'th coordinate as B[i] / *N) and the lattice volume of *P is returned. */ void IPs_degD(PolyPointList *P, VertexNumList *V, EqList *E, int l); /* *P is interpreted as the origin and the first level of a Gorenstein cone. The points of the cone up to level l are computed and displayed together with information on the type of face of the cone they represent (option -B# of poly). */ void Make_Facet(PolyPointList *P, VertexNumList *V, EqList *E, int e, Long vertices_of_facet[POLY_Dmax][VERT_Nmax], int *nv_of_facet); /* The e'th facet of *P is determined as a (P->n-1)-dimensional polytope: *nv_of_facet vertices represented by vertices_of_facet. */ /* ========== General purpose functions from Vertex.c ========== */ void swap(int *i,int *j); /* Swaps *i and *j. */ void Sort_VL(VertexNumList *V); /* Sorts the entries _V->v[i] in ascending order. */ Long Eval_Eq_on_V(Equation *E, Long *V, int n); /* Evaluates E on V, i.e. calculates \sum_{i=0}^{n-1} E->a[i] * V[i] + E->c. */ int Span_Check(EqList *EL, EqList *HL, int *n); /* Returns 1 if every equation of *HL is contained in *EL and 0 otherwise. *n is the dimension. */ int Vec_Greater_Than(Long *X, Long *Y, int n); /* Returns 1 if *X > *Y in the sense that X[i] > Y[i] for the first i where X[i] and Y[i] differ, returns 0 if *X < *Y and gives an error message if X[i] equals Y[i] for all i in {0,...n-1}. */ int Vec_is_zero(Long *X, int n); /* Returns 1 if X[i]==0 for 0<=inv exceeds EQUA_Nmax and 1 otherwise. */ int Transpose_PM(PairMat PM, PairMat DPM, int nv, int ne); /* Transposes PM into DPM; returns 1 if the dimensions nv, ne are within their limits and 0 otherwise. */ /* ========== Polytope analysis functions (from Vertex.c) ========== */ int Find_Equations(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* For the polytope determined by P, *VNL and *EL are calculated. *VNL is the complete list of vertices of P. *EL is the complete list of equations determining the facets of P. Find_Equations returns 1 if P has IP property (i.e., it has the origin in its interior) and 0 otherwise. */ int IP_Check(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* Same as Find_Equations, but returns immediately without calculating *VNL and *EL if P does not have the IP property. */ int Ref_Check(PolyPointList *P, VertexNumList *VNL, EqList *EL); /* Returns 1 if P is reflexive and 0 otherwise. Only in the reflexive case *VNL and *EL are calculated. */ void Make_Dual_Poly(PolyPointList *P, VertexNumList *VNL, EqList *EL, PolyPointList *DP); /* Given P, VNL and EL for a reflexive polytope, the complete list *DP of lattice points of the dual polytope is determined. */ void Complete_Poly(Long VPM[][VERT_Nmax],EqList *E,int nv,PolyPointList *P); /* Given the vertex pairing matrix VPM, the EqList *E and the number nv of vertices, the complete list of lattice points *P is determined. */ void RC_Calc_BaHo(PolyPointList *P, VertexNumList *VNL, EqList *EL, PolyPointList *DP, BaHo *BH); /* Given *P, *VNL, *EL and *DP (points of dual polytope) as input, the elements of *BH are calculated. *P must be reflexive; *P and *DP must be complete. */ /* ====== typedefs and functions (from Vertex.c) related to INCIs ==== */ #define INT_Nbits 32 #define LONG_LONG_Nbits 64 /* These numbers should be set to the actual numbers of bits occupied by the structures "unsigned int" and "unsigned long long" in your version of C. If they are set to lower values, everything still works but may be considerably slowed down. */ #if (VERT_Nmax <= INT_Nbits) typedef unsigned int INCI; #elif (VERT_Nmax <= LONG_LONG_Nbits) typedef unsigned long long INCI; #else #define I_NUI ((VERT_Nmax-1)/INT_Nbits+1) typedef struct {unsigned int ui[I_NUI];} INCI; #endif /* An INCI encodes the incidence relations between a face and a list of vertices as a bit pattern (1 if a vertex lies on the face, 0 otherwise). Depending on the allowed number VERT_Nmax of vertices, a single "unsigned int" or "unsigned long long" may be sufficient. If VERT_Nmax is larger than the number of bits in a "long long integer", an array of unsigned integers is used to simulate an integer type of the required size. */ typedef struct {int nf[POLY_Dmax+1]; /* #(faces)[dim] */ INCI v[POLY_Dmax+1][FACE_Nmax]; /* vertex info */ INCI f[POLY_Dmax+1][FACE_Nmax]; /* V-on-dual info */ Long nip[POLY_Dmax+1][FACE_Nmax]; /* #IPs on face */ Long dip[POLY_Dmax+1][FACE_Nmax];} FaceInfo; /* #IPs on dual */ /* nf[i] denotes the number of faces of dimension i (the number of faces of dimension n-i-1 of the dual polytope). v[i][j] encodes the incidence relation of the j'th dim-i face with the vertices nip[i][j] is the number of interior points of the j'th dim-i face. f[i][j] and dip[i][j] give the same informations for the dual (n-i-1 dimensional) faces, with f[i][j] referring to the dual vertices. */ #if (VERT_Nmax <= LONG_LONG_Nbits) #define INCI_M2(x) ((x) % 2) /* value of first bit */ #define INCI_AND(x,y) ((x) & (y)) /* bitwise logical and */ #define INCI_OR(x,y) ((x) | (y)) /* bitwise logical or */ #define INCI_XOR(x,y) ((x) ^ (y)) /* bitwise exclusive or */ #define INCI_EQ(x,y) ((x) == (y)) /* check on equality */ #define INCI_LE(x,y) INCI_EQ(INCI_OR(x,y),y)/* bitwise less or equal */ #define INCI_EQ_0(x) INCI_EQ(x,INCI_0()) /* check if all bits = 0 */ #define INCI_0() (0) /* set all bits to 0 */ #define INCI_1() (1) /* set only first bit to 1 */ #define INCI_D2(x) ((x) / 2) /* shift by one bit */ #define INCI_PN(x,y) (2 * (x) + !(y)) /* shift and set first bit */ /* For an INCI defined as a single unsigned (long long) integer whose bits are regarded as representing incidences, these are useful definitions. INCI_PN is particularly useful when a new vertex is added: if x represents an equation E w.r.t. some vertex list and y is the result of evaluating E on some new vertex V, then INCI_PN(x,y) represents x w.r.t. the vertex list enhanced by V. */ #else #define INCI_M2(x) ((x).ui[0] % 2) INCI INCI_AND(INCI x, INCI y); INCI INCI_OR(INCI x, INCI y); INCI INCI_XOR(INCI x, INCI y); int INCI_EQ(INCI x, INCI y); int INCI_LE(INCI x, INCI y); int INCI_EQ_0(INCI x); INCI INCI_0(); INCI INCI_1(); INCI INCI_D2(INCI x); INCI INCI_PN(INCI x, Long y); #endif /* If we need more bits than can be represented by a single unsigned long long, these routines are designed to simulate the above definitions. */ int INCI_abs(INCI X); /* Returns the number of bits of X whose value is 1. */ int Print_INCI(INCI X); /* Prints X as a pattern of 0's and 1's, omitting the 0's after the last 1. */ INCI Eq_To_INCI(Equation *E, PolyPointList *P, VertexNumList *VNL); /* Converts *E to an INCI. */ void Make_Incidence(PolyPointList *P, VertexNumList *VNL, EqList *EL, FaceInfo *FI); /* Creates the structure FaceInfo *FI from *P, *VNL and *EL. */ void Print_FaceInfo(int n, FaceInfo *FI); /* Displays the information contained in the FaceInfo *FI. */ int QuickAnalysis(PolyPointList *_P, BaHo *_BH, FaceInfo *_FI); /* Fast computation of FaceInfo and Hodge numbers. */ palp-2.21/class.c0000664000177600017760000004103214572603263013217 0ustar skarkeskarke/* ====================================================================== */ /* ========== ========== */ /* ========== C L A S S . C ========== */ /* ========== ========== */ /* ========== A p r i l 2 0 0 2 ========== */ /* ========== ========== */ /* ====================================================================== */ /* Coord get coordinates by reading them or converting weight input * Rat rational functions * Vertex computes Vertices and Faces * Subpoly subpolys, sublattices, minimality * Polynf normal form and symmetries * SubAdd sorting * Subdb data base */ #include "Global.h" #include "Subpoly.h" #if ( POLY_Dmax * POINT_Nmax > 83400000 ) #error decrease POLY_Dmax or/and POINT_Nmax for compiling class #endif FILE *inFILE, *outFILE; void PrintExtOptions(void){puts("Extended/experimental options:"); puts(" -d1 -d2 [-po] combined mirror info (projected"); exit(0);} void LocalPrintUsage(char *c, char hc){ printf("This is `%s', a program for classifying reflexive polytopes\n",c); while (hc!='e'){ if (hc=='g'){ printf("Usage: %s [options] [ascii-input-file [ascii-output-file]]\n",c); printf("Options: -h print this information\n "); puts("-f or - use as filter; otherwise parameters denote I/O files"); puts(" -m* various types of minimality checks (* ... lvra)"); puts(" -p* NAME specification of a binary I/O file (* ... ioas)"); puts(" -d* NAME specification of a binary I/O database (DB) (* ... ios)"); puts(" -r recover: file=po-file.aux, use same pi-file"); puts(" -o[#] original lattice [omit up to # points] only"); puts( " -s* subpolytopes on various sublattices (* ... vphmbq)"); puts(" -k keep some of the vertices"); puts(" -c, -C check consistency of binary file or DB"); puts(" -M[M] print missing mirrors to ascii-output"); puts(" -a[2b], -A create binary file from ascii-input"); puts(" -b[2a], -B ascii-output from binary file or DB"); puts(" -H* applications related to Hodge number DBs (* ...cstfe)"); } else if (hc=='m'){ printf("`%s -m*' reads a list of combined weight systems as ascii-input\n",c); puts(" and writes the sublist with a particular property, "); puts(" possibly with extra information:"); printf("`%s -ml' returns only lp-minimal CWS\n",c); printf("`%s -mv' returns only v-minimal CWS\n",c); printf("`%s -mr' returns only r-minimal CWS\n",c); printf( "`%s -ma' returns the CWS that determine reflexive polytopes, with\n",c); puts( " information on the above properties and the `span property'."); } else if (hc=='p'){ puts("With `-p*' you specify a binary I/O file that encodes a sorted list"); puts(" of normal forms of polytopes. In particular, with"); puts("-piNAME or -pi NAME input and with"); puts("-poNAME or -po NAME output is specified."); puts("-paNAME or -pa NAME specifies a list that should be added to another "); puts(" list given as a binary file (with -pi) or as a database (with -di)."); puts("-psNAME or -ps NAME specifies a list that should be subtracted from"); puts(" another list given as a binary file (with -pi) ."); puts("With -pa and -ps you have to specify output via -po or -do."); } else if (hc=='d'){ puts("With `-d*' you specify a binary I/O database that encodes a sorted"); puts(" list of normal forms of polytopes. In particular, with"); puts("-diNAME or -di NAME input and with"); puts("-doNAME or -do NAME output is specified."); puts("-dsNAME or -ds NAME specifies a list in database format that should"); puts( " be subtracted from another list given as a binary file (with -pi),"); puts(" with an output file specified via -po."); } else if (hc=='r'){ printf("As %s sometimes requires very long running times, intermediate\n",c); puts("results are regularly written to a file .aux. If such a"); printf("file exists, `%s -r -po' can be used to recover an\n",c); printf("unfinished but terminated run of `%s -po'.\n",c); puts("Possible input files or databases should be identical."); } else if (hc=='o'){ printf("In normal mode `%s' determines reflexive subpolytopes both on\n",c); printf("the original lattice and on sublattices. With `%s -o' you can\n",c); puts("restrict to polytopes on the original lattice only. If you also"); puts("specify a number # via `-o#', then only the polytopes obtained by"); puts("omitting # or less lattice points are determined."); puts("For `-o0' the recursion breaks at any reflexive polytope."); printf("For `-oc' complete (including sublattice)"); puts(" by ignoring input polytope in list."); } else if (hc=='s'){ printf("`%s -s* [-di] [-mr] -po' polytopes on ",c); puts("sublattices:"); printf("`%s -sh [-di]' finds Calabi-Yau hypersurfaces that are free" ,c); printf("\n free quotients (i.e. points on codim>1 faces of "); printf("the dual\n polytope do not span the N-lattice). Input "); printf("can be ascii or DB.\n"); printf( "`%s -sp [-di]' same as `-sh' except that it is checked whether", c); puts("\n all points of the dual span the N lattice."); printf("`%s -sv [-di] [-mr] -po' serves to determine\n",c); printf(" on which sublattices of the original lattice a given "); printf("polytope is\n still a lattice polytope. Input can be "); printf("ascii or database. In the\n former case all sublattice "); printf("polytopes are determined and in the\n latter case only "); printf("those not yet in the database. With the option\n `-mr' "); printf("the result, which is written to , is\n "); puts("restricted to r-maximal polytopes."); printf("`%s -sm [-di] [-mr] -po' same as `-sv' but ",c); printf("now all\n reflexive polytopes that have the same pairing"); puts(" matrix between\n vertices and equations are constructed"); puts( "In addition there are the somewhat experimental options -sb, -sq for dim=4."); puts("They are similar to -sh, -sp, with the relationship summarized by"); puts(" -sh ... generated by codim>1 points (omit IPs of facets)"); puts(" -sp ... generated by all points"); puts(" -sb ... generated by dim<=1 (edges), print if rank=2 "); puts(" -sq ... generated by vertices, print if rank=3 "); } else if (hc=='k'){ printf( "`%s -k* [-di] -po' gives you a list of the vertices \n", c); puts(" of the input polytope and asks which of them should be kept;"); puts( " all reflexive subpolytopes containing the kept vertices are determined.");} else if (hc=='c'){ printf( "`%s -c' (or `-C') checks the consistency of a binary file or database\n",c); puts("specified via `-pi' or `-di'."); puts("`-C' results in a more detailed output than `-c'"); } else if (hc=='M'){ printf("`%s -M[M]' looks for polytopes in a list specified by `-pi' or\n",c); puts("`-di' whose mirrors are not in the same list. The resulting `missing"); puts("mirrors' are written in ascii format."); } else if (hc=='a'){ printf( "`%s -a[2b] -po' converts ascii-input of reflexive polytopes\n",c); puts("to binary file format."); puts("If an input file or database is specified via `-pi' or `-di', only"); puts("the polytopes not in one of these lists are written to ."); puts("If an ascii output file is explicitly specified, weights corresponding"); puts("to new polytopes are written to that file."); puts("-A[2B] converts non-reflexive ascii input to binary file format."); } else if (hc=='b'){ printf("`%s -b[2a]' converts binary input to a list of normal forms in\n",c); puts("ascii format. For file input (specified via `-pi') all normal forms of"); puts("polytopes on original lattices are displayed, but for database input"); puts("(`-di') the normal forms of the sublattice polytopes in the database"); puts("are shown. If no sublattice polytopes are left, then all polytopes "); puts("in the database are displayed."); puts("For non-reflexive binary input, -B[2A] should be used for conversion"); puts("to ascii format."); } else if (hc=='H'){ puts( "Options of the type `-H*' are used for handling Hodge number databases"); puts("and work only for polytopes of dimension four. In particular,"); printf("`%s -Hc [-vf#] [-vt#] -di -do' calculates the\n",c); puts(" Hodge numbers of the polytopes in DB and creates a Hodge number"); puts(" database whose files correspond to fixed vertex numbers and Euler"); puts(" numbers. If -vf and/or -vt are specified, only the Hodge numbers"); puts(" of the polytopes whose vertex numbers are in the corresponding"); puts(" (from/to) range are determined."); printf( "`%s -Hs -di [-do]' sorts a Hodge-DB resulting\n",c); puts(" from -Hc to one consisting of files of fixed Hodge number pairs"); puts(" (with the same name if -do is omitted),"); printf("`%s -Ht -di' tests a Hodge-DB for consistency and\n",c); printf("`%s -Hf -pi' serves for testing a Hodge-DB-file.\n",c); printf("`%s -He -di' extracts data on \n",c); puts(" polytopes (in ascii) from a Hodge-DB. A search string may take"); puts(" the form `E#H#:#M#V#N#F#L#', where the #'s denote numbers:"); puts(" E...Euler characteristic, H#:#...Hodge numbers h11,h12,"); puts(" M/V/N/F...numbers of points/vertices/dual points/facets,"); puts(" L...Limit on the total number of polytopes displayed."); puts(" The ordering is inessential and if a value isn't specified the"); puts(" corresponding symbol may be omitted. For example, `-He:1'"); puts(" leads to a search for all polytopes with h12=1."); puts(" Unless at least one of h11, h12, E is specified, the search will"); puts(" take quite long."); } else if (hc=='I'){ printf("There are three basic types of I/O structures for %s:\n",c); puts("ascii files, binary files and binary databases."); puts(" Binary files and databases always encode ordered lists of normal"); puts("forms of polytopes, and any such structure created by some application"); printf("of %s may be used as input for some other application of %s.\n",c,c); puts( " A database consists of various files NAME. and is specified"); puts("via `-d* NAME'. It contains one ascii file and several binary files."); puts(" Ascii input should always correspond to a list of polytopes given"); puts("either by combined weight systems or by lists of lattice points."); puts("Weight input is specified by a single line of the form"); printf(" d1 w11 w12 ... d2 w21 w22 ... [comments ignored by %s]\n",c); puts("with sum_j wij=di for every i."); puts("Lattice point input is specified by a line of the form"); printf(" #colums #lines [comments ignored by %s]\n",c); puts("followed by (#lines) lines each of which has (#colums) integers such"); puts("that the resulting matrix encodes the coordinates of the polytope"); puts("with lattice points given either as row or as column vectors."); puts("Sometimes ascii output may also be used as input."); } puts(""); puts( "Type one of [m,p,d,r,o,s,c,M,a,b,H] for help on options,"); printf( "`g' for general help, `I' for general information on I/O or `e' to exit: "); scanf("%s",&hc); puts(""); } } int main (int narg, char* fn[]) { int n=0, FilterFlag=0, oFlag=0, cFlag=0, rFlag=0, abFlag=0, kFlag=0, vf=2, vt=VERT_Nmax-1; char Blank=0, *dbin=&Blank, *dbsub=&Blank, *dbout=dbin, *x_string=&Blank, *polyi=dbin, *polya=dbin, *polys=dbin, *polyo=dbin, mFlag=0, HFlag=0, sFlag=0; static CWS W; PolyPointList *_P; if(narg==1) { printf("For help type `%s -h'\n", fn[0]); exit(0);} _P = (PolyPointList *) malloc(sizeof (PolyPointList)); if(_P==NULL) {puts("Unable to allocate space for _P"); exit(0);} while(narg > ++n) if(fn[n][0]!='-') break; else switch(fn[n][1]) { case 'h': LocalPrintUsage(fn[0],'g'); exit(0); case 'f': case 0 : FilterFlag=1; break; case 'm': mFlag=fn[n][2]; break; case 's': sFlag=fn[n][2]; break; case 'c': cFlag=1; break; case 'C': cFlag=2; break; case 'M': cFlag=-1; break; case 'r': rFlag=1; break; case 'a': abFlag=1; break; case 'b': abFlag=-1; break; case 'A': abFlag=2; break; case 'B': abFlag=-2; break; case 'k': kFlag=1; break; case 'H': { #if (POLY_Dmax != 4) puts("For using Hodge-DB-routines set POLY_Dmax=4!"); exit(0); #endif HFlag=fn[n][2]; if(HFlag=='e') x_string = (fn[n][3]) ? &fn[n][3] : fn[++n]; } break; case 'p': { if(fn[n][2]=='i') polyi = (fn[n][3]) ? &fn[n][3] : fn[++n]; else if(fn[n][2]=='a') polya = (fn[n][3]) ? &fn[n][3] : fn[++n]; else if(fn[n][2]=='s') polys = (fn[n][3]) ? &fn[n][3] : fn[++n]; else if(fn[n][2]=='o') polyo = (fn[n][3]) ? &fn[n][3] : fn[++n]; else { LocalPrintUsage(fn[0],'g'); exit(0); } } break; case 'd': { if(fn[n][2]=='i') dbin = (fn[n][3]) ? &fn[n][3] : fn[++n]; else if(fn[n][2]=='s') dbsub = (fn[n][3]) ? &fn[n][3] : fn[++n]; else if(fn[n][2]=='o') dbout = (fn[n][3]) ? &fn[n][3] : fn[++n]; else { LocalPrintUsage(fn[0], 'g'); exit(0); } } break; case 'o': oFlag=-1; /* original lattice only */ if(fn[n][2]) if(fn[n][2]=='c'){oFlag=-3;puts("complete data");} else {assert(('0'<=fn[n][2])&&(fn[n][2]<='9')); oFlag=atoi(&fn[n][2]); if (!oFlag) {oFlag=-2; puts("break recursion at RPs");} else printf("rec-dep<=%d\n",oFlag);} else printf("original lattices only\n"); break; case 'v': { if(fn[n][2]=='f') vf=atoi((fn[n][3]) ? &fn[n][3] : fn[++n]); if(fn[n][2]=='t') vt=atoi((fn[n][3]) ? &fn[n][3] : fn[++n]);} break; case 'x': PrintExtOptions(); break; default: printf("Unknown flag %s !!\n",fn[n]); exit(0); } n--; if(FilterFlag) { inFILE=NULL; outFILE=stdout; } else { if (narg > ++n) inFILE=fopen(fn[n],"r"); else inFILE=stdin; if (inFILE==NULL){printf("Input file %s not found!\n",fn[n]);exit(0);} if (narg > ++n) outFILE=fopen(fn[n],"w"); else outFILE=stdout; } if(sFlag) VPHM_Sublat_Polys(sFlag,mFlag,dbin,polyi,polyo,_P); else if(abFlag==1) Ascii_to_Binary(&W,_P,dbin,polyi,polyo); else if(abFlag==-1) Bin_2_ascii(polyi,dbin,(mFlag=='r'),vf,vt,_P); else if(abFlag==2) Gen_Ascii_to_Binary(&W,_P,dbin,polyi,polyo); else if(abFlag==-2) Gen_Bin_2_ascii(polyi,dbin,(mFlag=='r'),vf,vt,_P); else if(cFlag) Check_NF_Order(polyi,dbin,cFlag,_P); else if(mFlag=='a') while(Read_CWS_PP(&W,_P)) Overall_check(&W,_P); else if(mFlag=='r') while(Read_CWS_PP(&W,_P)) Max_check(&W,_P); else if(mFlag=='v') while(Read_CWS_PP(&W,_P)) DPvircheck(&W,_P); else if(mFlag=='l') while(Read_CWS_PP(&W,_P)) DPircheck(&W,_P); #if (POLY_Dmax < 6) else if(HFlag=='c') DB_to_Hodge(dbin, dbout, vf, vt,_P); else if(HFlag=='s') Sort_Hodge(dbin, dbout); else if(HFlag=='f') Test_Hodge_file(polyi,_P); else if(HFlag=='t') Test_Hodge_db(dbin); else if(HFlag=='e') Extract_from_Hodge_db(dbin,x_string,_P); #endif else if(*dbin&&!*polyo) Add_Polya_2_DBi(dbin,polya,dbout); else if(*dbout) Polyi_2_DBo(polyi,dbout); else if(*polya) Add_Polya_2_Polyi(polyi,polya,polyo); else if(*polys||*dbsub) Reduce_Aux_File(polyi,polys,dbsub,polyo); else Do_the_Classification(&W,_P, /* fn[0], */ oFlag,rFlag,kFlag, polyi,polyo,dbin); return 0; } palp-2.21/.gitignore0000664000177600017760000000026114572603263013735 0ustar skarkeskarke# All PALP executables have an ".x" suffix, making it easy to # glob them here. We also ignore the object (*.o) files that # are created as intermediate build products. *.x *.o palp-2.21/cws.c0000664000177600017760000020231514572603263012711 0ustar skarkeskarke#include "Global.h" #include "LG.h" #include "Rat.h" FILE *inFILE, *outFILE; #define Only_IP_CWS 1 #define TRANS_INFO_FOR_IP_WEIGHTS 0 #define NFmax 10 /* maximal number of WS-files */ #define SIMPLEX_POINT_Nmax 50 typedef struct { int u[NFmax]; int nu; } CWS_type; #define OSL (24) /* opt_string's length */ void PrintCWSUsage(char *c){ int i; char *opt_string[OSL]={ "Options: -h print this information", " -f use as filter; otherwise parameters denote I/O files", " -w# [L H] make IP weight systems for #-dimensional polytopes.", " For #>4 the lowest and highest degrees L<=H are required.", " -r/-t make reflexive/transversal weight systems (optional).", " -m# L H make transverse weight systems for #-dimensional polytopes", " (fast). The lowest and highest degrees L<=H are required.", " -c# make combined weight systems for #-dimensional polytopes.", " For #<=4 all relevant combinations are made by default,", " otherwise the following option is required:", " -n[#] followed by the names wf_1 ... wf_# of weight files", " currently #=2,3 are implemented.", " [-t] followed by # numbers n_i specifies the CWS-type, i.e.", " the numbers n_i of weights to be selected from wf_i.", " Currently all cases with n_i<=2 are implemented.", " -i compute the polytope data M:p v [F:f] N:p [v] for all IP", " CWS, where p and v denote the numbers of lattice points", " and vertices of a dual pair of IP polytopes; an entry ", " F:f and no v for N indicates a non-reflexive `dual pair'.", " -d# compute basic IP weight systems for #-dimensional", " reflexive Gorenstein cones;", " -r# specifies the index as #/2.", " -2 adjoin a weight of 1/2 to the input weight system.", " -N make CWS for PPL in N lattice." }; printf("This is `%s': ", c); puts("create weight systems and combined weight systems."); printf("Usage: %s -; ", c); puts("the first option must be -w, -c, -i, -d or -h."); for (i=0;i count redcheck cdd)"); } int main (int narg, char* fn[]) { inFILE=stdin; outFILE=stdout; if(narg==1) {printf("\nFor help type `%s -h'\n\n",fn[0]);exit(0);} if((fn[1][0]!='-')||(fn[1][1]=='h')) PrintCWSUsage(fn[0]); else if(fn[1][1]=='w') Init_IP_Weights(narg, fn); else if(fn[1][1]=='m') Init_moon_Weights(narg, fn); else if(fn[1][1]=='c') Init_IP_CWS(narg, fn); else if(fn[1][1]=='i') IP_Poly_Data(narg, fn); else if(fn[1][1]=='N') Npoly2cws(narg, fn); else if(fn[1][1]=='p') Conv(narg, fn); else if(fn[1][1]=='x') PrintCWSextUsage(fn[0]); else if(fn[1][1]=='S') SimplexPointCount(narg, fn); else if(fn[1][1]=='L') SimplexPointCount(narg, fn); else if(fn[1][1]=='d') RgcWeights(narg, fn); else if(fn[1][1]=='2') AddHalf(); else printf("Unknown option '-%c'; use -h for help\n",fn[1][1]); return 0; } #define WDIM 800000 typedef struct { int d, r2, allow11; Long wnum, winum, candnum; Long x[POLY_Dmax+1][POLY_Dmax]; EqList q[POLY_Dmax]; INCI qI[POLY_Dmax][EQUA_Nmax]; int f0[POLY_Dmax]; Equation wli[WDIM]; } RgcClassData; int RgcWeicomp(Equation w1, Equation w2, int d) { /* w2-w1, i.e. pos for w1w2 */ int i=d-1; if (w1.c-w2.c) return w1.c-w2.c; while((i)&&(w1.a[i]==w2.a[i])) i--; return w2.a[i]-w1.a[i]; } void RgcInsertat(Equation ww, int position, RgcClassData *X){ int i; for(i=X->wnum-1; i>=position; i--) X->wli[i+1]=X->wli[i]; X->wli[position]=ww; X->wnum++; } void RgcAddweight(Equation wn, RgcClassData *X){ int i, j, p, n0, n1, k; if (X->wnum>=WDIM) { if(X->wnum>WDIM) return; else {X->wnum++; printf("WDIM too small!\n");fflush(0);return;}} for(i=0;id;i++) if (2*wn.a[i]==-wn.c) return; for(i=0;id;i++) if (wn.a[i]==-wn.c) return; if (!X->allow11) for(i=0;id-1;i++) for(j=i+1;jd;j++) if (wn.a[i]+wn.a[j]==-wn.c) return; X->candnum++; for(i=0;id-1;i++) for(p=i+1;pd;p++) if (wn.a[i]>wn.a[p]) { k=wn.a[i]; wn.a[i]=wn.a[p]; wn.a[p]=k;} /* make n0<=n1<=...<=n# */ if (X->wnum) { i = RgcWeicomp(wn,X->wli[n0=0],X->d); if (!i) return; if (i>0) {RgcInsertat(wn,0,X); return;} i = RgcWeicomp(wn,X->wli[n1=X->wnum-1],X->d); if (!i) return; if (i<0) {RgcInsertat(wn,X->wnum,X); return;} while(n1>n0+1) { p=(n0+n1)/2; i=RgcWeicomp(wn,X->wli[p],X->d); if(!i) return; if(i>0) n1=p; else n0=p;} RgcInsertat(wn,n1,X);} else RgcInsertat(wn,0,X); } void PrintPoint(int n, RgcClassData *X){ int i; assert(nd;i++) printf("%d ",(int) X->x[n][i]); printf("\n"); } void PrintQ(int n, RgcClassData *X){ int i, j; assert(nq[n].ne); for (j=0;jq[n].ne;j++){ printf("%d ", (int) X->q[n].e[j].c); for (i=0; id; i++) printf("%d ", (int) X->q[n].e[j].a[i]); printf("\n");} } void PrintEquation(Equation *q, int d/*, char *c, int j*/){ int i; printf("%d ", (int) -q->c); for (i=0;ia[i]); /*printf(" %s np=%d\n", c, j);*/ } int LastPointForbidden(int n, RgcClassData *X){ int l; Long *y = X->x[n]; Long ysum=0, ymax=0; assert(nd); for (l=0;ld;l++){ ysum += y[l]; if (y[l]>ymax) ymax=y[l];} if (ysum < 2) return 1; if (ysum == 2) if ((!X->allow11) ||(ymax == 2)) return 1; if (X->r2 == 2) if (ymax < 2) return 1; if (X->r2 == 1) if (ymax < 3) return 1; for (l=X->f0[n-1];ld-1;l++) if (y[l]q[0].ne = X->d; for (i=0; iq[0].ne; i++){ for (j=0; jd; j++) X->q[0].e[i].a[j] = 0; if (X->r2%2) {X->q[0].e[i].a[i] = X->r2; X->q[0].e[i].c = -2;} else {X->q[0].e[i].a[i] = X->r2/2; X->q[0].e[i].c = -1;}} X->f0[0] = 0; X->qI[0][0] = INCI_1(); for (i=1; iq[0].ne; i++) X->qI[0][i] = INCI_PN(X->qI[0][i-1],1); } int IsRedundant(INCI newINCI, INCI *qINew, int ne){ int i; for (i=0;ix[n]; Long yqOld[EQUA_Nmax]; EqList *qOld = &X->q[n-1], *qNew = &X->q[n]; INCI *qIOld = X->qI[n-1], *qINew = X->qI[n]; INCI newINCI; assert(nd); for (i=X->d-1;(i>=X->f0[n-1])&&(y[i]==0);i--) ; X->f0[n] = ++i; qNew->ne = 0; for (i=0;ine;i++) if (!(yqOld[i] = Eval_Eq_on_V(&(qOld->e[i]),y,X->d))){ qNew->e[qNew->ne]=qOld->e[i]; qINew[qNew->ne]=qIOld[i]; (qNew->ne)++;} for (i=0;ine-1;i++) for (j=i+1;jne;j++) if (yqOld[i]*yqOld[j]<0) if (INCI_abs(newINCI=INCI_OR(qIOld[i],qIOld[j]))<=n+1) if (!IsRedundant(newINCI, qINew, qNew->ne)){ for (k=qNew->ne-1; k>=0; k--) if (INCI_LE(newINCI,qINew[k])){ qINew[k] = qINew[qNew->ne-1]; qNew->e[k] = qNew->e[qNew->ne-1]; qNew->ne--;} assert(qNew->ne < EQUA_Nmax-1); qINew[qNew->ne] = newINCI; qNew->e[qNew->ne] = EEV_To_Equation(&qOld->e[i],&qOld->e[j],y,X->d); if (qNew->e[qNew->ne].c > 0){ for (k=0;kd;k++) qNew->e[qNew->ne].a[k] *= -1; qNew->e[qNew->ne].c *= -1;} qNew->ne++;} } Long Flcm(Long a, Long b){ return (a*b)/Fgcd(a,b); } void Cancel(Equation *q, int d){ Long gcd = -q->c; int j; for (j=0;ja[j]); if (gcd > 1){ for (j=0;ja[j] /= gcd; q->c /= gcd;} } int ComputeAndAddAverageWeight(Equation *q, int n, RgcClassData *X){ int i, j; if (X->q[n].ne < X->d - n) return 0; q->c = -1; for (i=0;iq[n].ne;i++) { if (X->q[n].e[i].c >= 0) {PrintQ(n,X); exit(0);} q->c = -Flcm(-q->c,-X->q[n].e[i].c);} for (j=0;jd;j++){ q->a[j] = 0; for (i=0;iq[n].ne;i++) q->a[j]+=X->q[n].e[i].a[j]*(q->c/X->q[n].e[i].c); if (q->a[j]<=0){ assert(q->a[j]==0); return 0;} } q->c *= X->q[n].ne; Cancel(q, X->d); RgcAddweight(*q, X); return 1; } void ComputeAndAddLastQ(RgcClassData *X){ /* q[d-1] from q[d-2], x[d-1] */ int i, d = X->d; Equation q; Equation *q0 = &X->q[d-2].e[0], *q1 = &X->q[d-2].e[1]; Long *y = X->x[d-1]; Long yq0 = Eval_Eq_on_V(q0,y,d), yq1; if (LastPointForbidden(d-1, X)) return; if (!yq0) return; yq1 = Eval_Eq_on_V(q1,y,d); if (yq0 < 0){ if (yq1 <= 0) return; yq0 *= -1;} else { if (yq1 >= 0) return; yq1 *= -1;} q.c = yq0 * q1->c + yq1 * q0->c; for (i=0;ia[i] + yq1 * q0->a[i]; Cancel(&q, d); RgcAddweight(q, X); } void RecConstructRgcWeights(int n, RgcClassData *X){ /* we have q[n-1], x[n] */ int k, l; Equation q; Long yq[POLY_Dmax]; Long *y = X->x[n+1]; if (n == 0) ComputeQ0(X); else if (LastPointForbidden(n, X)) return; else ComputeQ(n, X); if (!ComputeAndAddAverageWeight(&q, n, X)) return; if (n >= X->d-1) return; /* Examine all integer points of simplex: */ for (k=0;kd-1;k++) {y[k]=0; yq[k]=0;} /* sets k=d-1; important! */ y[k]=-1; /* starting point just outside */ yq[k]=-q.a[k]; while(k>=0){ y[k]++; yq[k]+=q.a[k]; for (l=k+1;ld;l++) yq[l]=yq[k]; if (n==X->d-2){assert(X->q[X->d-2].ne==2); ComputeAndAddLastQ(X);} else RecConstructRgcWeights(n+1, X); for(k=X->d-1;(k>=0 ? (yq[k]+q.a[k]>=-q.c) : 0);k--) y[k]=0;} /* sets k to the highest value where y[k] didn't exceed max value; resets the following max values to min values */ } void AddPointToPoly(Long *y, PolyPointList *P){ int i; for (i=0;in;i++) P->x[P->np][i] = y[i]; P->np++; } int WsIpCheck(Equation *q, int d){ int k,l; PolyPointList *P = (PolyPointList *) malloc(sizeof(PolyPointList)); assert (P != NULL); VertexNumList V; EqList E; Long y[POLY_Dmax]; Long yq[POLY_Dmax]; P->n=d; P->np=0; for (k=0;ka[k]; while(k>=0){ y[k]++; yq[k]+=q->a[k]; for (l=k+1;lc) AddPointToPoly(y, P); for(k=d-1;(k>=0 ? (yq[k]+q->a[k]>-q->c) : 0);k--) y[k]=0;} /* sets k to the highest value where y[k] didn't exceed max value; resets the following max values to min values */ if (P->np <= d) {free(P); return 0;} Find_Equations(P, &V, &E); if (E.ne < d) {free(P); return 0;} for (k=0;knp-1; free(P); return k; } void RgcWeights(int narg, char* fn[]) { int i, j, d, n=1, r2=2; char *c=&fn[1][2]; RgcClassData *X = (RgcClassData *) malloc(sizeof(RgcClassData)); if(narg>2) if(c[0]==0) c=fn[++n]; if(!IsDigit(c[0])){ puts("-d must be followed by a number");exit(0);} if(POLY_Dmax<(d=atoi(c))){printf("Increase POLY_Dmax to %d\n",d);exit(0);} if(narg>++n){ if((fn[n][0]!='-')||(fn[n][1]!='r')){ printf("the second option has to be of the type -r\n");exit(0);} c=&fn[n][2]; r2=atoi(c);} X->d=d; X->r2=r2; X->wnum=0; X->winum=0; X->candnum=0; X->allow11=0; RecConstructRgcWeights(0,X); if (X->wnum <= WDIM){ for (i=0;iwnum;i++) { j=WsIpCheck(&X->wli[i], d); if (j) { PrintEquation(&X->wli[i], X->d); printf(" np=%d\n",j); X->winum++; /*else PrintEquation(&X->wli[i], X->d, "n");*/}}} printf("#ip=%ld, #cand=%ld(%ld)\n", X->winum, X->wnum, X->candnum); } int IsNextDigit(void); void AddHalf(void) { int IN[AMBI_Dmax*(AMBI_Dmax+1)]; int i, j, n = 0; inFILE=stdin; n=0; while (1){ for(i=0;i2) if(c[0]==0) c=fn[++n]; if(!IsDigit(c[0])){ puts("-w must be followed by a number");exit(0);} if(POLY_Dmax<(d=atoi(c))){printf("Increase POLY_Dmax to %d\n",d);exit(0);} if(++n2) if(c[0]==0) c=fn[++n]; if(!IsDigit(c[0])){ puts("-m must be followed by a number");exit(0);} if(POLY_Dmax<(d=atoi(c))){printf("Increase POLY_Dmax to %d\n",d);exit(0);} if(++n2) {if(fn[2][0]=='-'){assert(fn[2][1]=='f');inFILE=NULL;} else { inFILE=fopen(fn[2],"r"); assert(NULL!=inFILE); if(narg>3) {outFILE=fopen(fn[3],"w"); assert(NULL!=outFILE);} }} OF=outFILE; while(Read_CWS_PP(&W,P)) { if(W.N) Die("Only PPL-input in Npoly2cws!"); if(!IP_Check(P,&V,&E)) Die("Not IP!"); Sort_VL(&V); for(n=0;nx[V.v[n]]; if(VP_2_CWS(X,P->n,V.nv,&W)) {Print_CWS(&W);fprintf(outFILE,"\n");} else {outFILE=stderr; Print_PPL(P,"CWS not found"); outFILE=OF;} } } void Make_IP_CWS(int narg, char* fn[]); void Make_34_CWS(int d); void Init_IP_CWS(int narg, char* fn[]) { int d,n=1,nop=0; char *c=&fn[1][2]; if(narg>2) if(c[0]==0) c=fn[++n]; if(!IsDigit(c[0])){ puts("-c must be followed by a number");exit(0);} if(POLY_Dmax<(d=atoi(c))){printf("Increase POLY_Dmax to %d\n",d);exit(0);} if(++n4"); } /* ========== ALL IP WEIGHTS in d <= 4 ========== */ #define INFO 0 #define lcm(a,b) ((a)*(b)/NNgcd((a),(b))) typedef struct {int n[W_Nmax+1];} weights; typedef Rat ratmat[W_Nmax][W_Nmax]; typedef Rat ratvec[W_Nmax]; typedef struct { int wnum, N, points[W_Nmax][W_Nmax], nsubsets[W_Nmax-1], subsets[W_Nmax-1][10][W_Nmax]; weights wli[WDIM]; } WSaux; int weicomp(weights w1,weights w2,int *_N) /* w2-w1, i.e. pos for w1w2 */ { int i=*_N; while((i)&&(w1.n[i]==w2.n[i])) i--; return w2.n[i]-w1.n[i]; } void insertat(WSaux *X,weights ww, int position) { int i, j; for(i=X->wnum-1;i>=position;i--) for(j=0;j<=X->N;j++) X->wli[i+1].n[j]=X->wli[i].n[j]; for(j=0;j<=X->N;j++) X->wli[position].n[j]=ww.n[j]; X->wnum++; } void addweight(WSaux *X,weights wn) { int i, p, n0, n1, k; if (X->wnum>=WDIM) { if(X->wnum>WDIM) return; else {X->wnum++; printf("WDIM too small!\n");fflush(0);return;}} for(i=0;iN-1;i++) for(p=i+1;pN;p++) if (wn.n[i]>wn.n[p]) {k=wn.n[i]; wn.n[i]=wn.n[p]; wn.n[p]=k;} /* make n0<=n1<=...<=n# */ if (X->wnum) {if ((i = weicomp(wn,X->wli[n0=0],&X->N))) {if (i>0) {insertat(X,wn,0); return;}} else return; if ((i = weicomp(wn,X->wli[n1=X->wnum-1],&X->N))) {if (i<0) {insertat(X,wn,X->wnum); return;}} else return; while(n1>n0+1) {p=(n0+n1)/2; i=weicomp(wn,X->wli[p],&X->N); if(i) {if(i>0) n1=p; else n0=p;} else return;} insertat(X,wn,n1);} else insertat(X,wn,0); } int checkwrite(WSaux *X,weights ws){ int i; for (i=0;iN;i++) if (!ws.n[i]) return 0; addweight(X,ws); return 1; } weights testweisys(WSaux *X,int npoints){ weights tws; ratmat rm; ratvec newboundwei, boundwei[10], rattws, rs; int i, ii, j, k, nboundwei=0, New, rankrm, one[W_Nmax]; Long minnbw, maxnbw; for (k=0;knsubsets[npoints-2];k++ /* alle 0-systeme */ ){ rankrm=0; for (i=0;ipoints[i][X->subsets[npoints-2][k][j]]);} rs[i]=rI(1); } for (i=0;i=0){ for (j=one[i]+1;jN;j++) newboundwei[j]=rI(0); if (rankrm==npoints) for (i=0;isubsets[npoints-2][k][one[i]]]=rs[i]; minnbw=0; maxnbw=0; for (j=0;jN;j++) { minnbw=min(newboundwei[j].N,minnbw); maxnbw=max(newboundwei[j].N,maxnbw); } New=((minnbw>=0)&&(maxnbw>0)); for (i=0;New&&(iN;j++) if (rD(newboundwei[j],boundwei[i][j]).N) New=1; } if (New) { for (j=0;jN;j++) boundwei[nboundwei][j]=newboundwei[j]; nboundwei++; } } for (j=0;jN;j++) { rattws[j]=rI(0); for (i=0;iN]=1; for (j=0;jN;j++) tws.n[X->N]=lcm(tws.n[X->N],rattws[j].D); for (j=0;jN;j++) tws.n[j]=rP(rI(tws.n[X->N]),rattws[j]).N; return tws; } void createweights(WSaux *X,int npoints){ int x0, x1, x2, x3, x4, sum, maxx; weights tws; tws=testweisys(X,npoints); if(checkwrite(X,tws)) if (npointsN){ for (x0=0;x0*tws.n[0]N];x0++) for (x1=0;x0*tws.n[0]+x1*tws.n[1]N];x1++) for (x2=0;x0*tws.n[0]+x1*tws.n[1]+x2*tws.n[2]N];x2++) /* #if (N>3) */ for (x3=0; (x3==0) || ((X->N>3) && (x0*tws.n[0]+x1*tws.n[1]+x2*tws.n[2]+x3*tws.n[3]N])) ;x3++) /* #if (N>4) */ for (x4=0; (x4==0) || ((X->N>4) && (x0*tws.n[0]+ x1*tws.n[1]+x2*tws.n[2]+x3*tws.n[3]+x4*tws.n[4]N]));x4++) { sum=0; maxx=0; X->points[npoints][0]=x0; sum+=x0; maxx=max(maxx,x0); X->points[npoints][1]=x1; sum+=x1; maxx=max(maxx,x1); X->points[npoints][2]=x2; sum+=x2; maxx=max(maxx,x2); if (X->N>3) {X->points[npoints][3]=x3; sum+=x3; maxx=max(maxx,x3);} if (X->N>4) {X->points[npoints][4]=x4; sum+=x4; maxx=max(maxx,x4);} if ((sum>2)&&(maxx>1)) createweights(X,npoints+1); /* if (npoints<3) {printf("%d",npoints); fflush(0);}*/} } } void makesubsets(WSaux *X){ int i, p0,p1,p2,p3,p4; for (i=0;iN-1;i++) X->nsubsets[i]=0; for (p0=0;p0N-1;p0++) for (p1=p0+1;p1N;p1++) { X->subsets[0][X->nsubsets[0]][0]=p0; X->subsets[0][X->nsubsets[0]][1]=p1; X->nsubsets[0]++; for (p2=p1+1;p2N;p2++) { X->subsets[1][X->nsubsets[1]][0]=p0; X->subsets[1][X->nsubsets[1]][1]=p1; X->subsets[1][X->nsubsets[1]][2]=p2; X->nsubsets[1]++; for (p3=p2+1;p3N;p3++) { X->subsets[2][X->nsubsets[2]][0]=p0; X->subsets[2][X->nsubsets[2]][1]=p1; X->subsets[2][X->nsubsets[2]][2]=p2; X->subsets[2][X->nsubsets[2]][3]=p3; X->nsubsets[2]++; for (p4=p3+1;p4N;p4++) { X->subsets[3][X->nsubsets[3]][0]=p0; X->subsets[3][X->nsubsets[3]][1]=p1; X->subsets[3][X->nsubsets[3]][2]=p2; X->subsets[3][X->nsubsets[3]][3]=p3; X->subsets[3][X->nsubsets[3]][4]=p4; X->nsubsets[3]++; } } } } } void WRITE_Weight(Weight *_W); void Make_34_Weights(int d, int tFlag) { int i, Info=0; WSaux *X = (WSaux *) malloc(sizeof(WSaux)); PolyPointList *P = (PolyPointList *) malloc(sizeof (PolyPointList)); assert(P!=NULL); assert(X!=NULL); X->wnum=1; X->N=d+1; assert(d<=4); makesubsets(X); for (i=0;iN;i++) X->points[0][i]=1; X->wli[0].n[X->N]=X->N; for (i=0;iN;i++) X->wli[0].n[i]=1; if (X->N>4){ X->points[1][0]=4; for (i=1;iN;i++) X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (4,0,0,0,0)\n");fflush(0);} X->points[1][0]=3; X->points[1][1]=1; for(i=2;iN;i++)X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (3,1,0,0,0)\n"); fflush(0);} X->points[1][0]=2; X->points[1][1]=2; for(i=2;iN;i++)X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (2,2,0,0,0)\n"); fflush(0);} X->points[1][0]=2; X->points[1][1]=1; X->points[1][2]=1; for (i=3;iN;i++) X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (2,1,1,0,0)\n"); fflush(0);}} if (X->N>3){ X->points[1][0]=3; for (i=1;iN;i++) X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (3,0,0,0,0)\n"); fflush(0);} X->points[1][0]=2; X->points[1][1]=1; for(i=2;iN;i++)X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (2,1,0,0,0)\n"); fflush(0);}} X->points[1][0]=2; for (i=1;iN;i++) X->points[1][i]=0; createweights(X,2); if(Info){printf("Did (2,0,0,0,0)\n"); fflush(0);} Info=0; for (i=0;iwnum;i++){ int j; Weight W; VertexNumList V; EqList E; W.d=X->wli[i].n[W.N=X->N]; for(j=0;jN;j++)W.w[j]=X->wli[i].n[j]; W.M=0; Make_Poly_Points(&W, P); if(Ref_Check(P,&V,&E)) { int t=Trans_Check(W); char c[5]=" rt"; if(t||!tFlag) {c[3]=(t)?'t':0; if(Info++) puts(""); WRITE_Weight(&W); printf("%s",c);}} } fprintf(outFILE," #=%d #cand=%d\n",Info,X->wnum); free(X); } /* ========== End of ALL IP WEIGHTS in d <= 4 ========== */ /* ========== MAKE WEIGHTS d>4: ========== */ void WRITE_Weight(Weight *_W) { int n; fprintf(outFILE,"%d ",(int) _W->d); for(n=0; n < _W->N; n++) fprintf(outFILE," %d",(int) _W->w[n]); } int IfIpWWrite(Weight *W, PolyPointList *P, int *rFlag, int *tFlag) { VertexNumList V; EqList E; int r=1,i=-1; Make_Poly_Points(W, P); if(IP_Check(P,&V,&E)){ while(r && (++i < E.ne)) if(E.e[i].c != 1) r = 0; if(*tFlag && Trans_Check(*W)){ WRITE_Weight(W); if(r) fprintf(outFILE," r"); fprintf(outFILE,"\n");fflush(stdout); return 1;} if(*rFlag && r){Write_Weight(W); fflush(stdout); return 1;} if(!*tFlag && !*rFlag) {WRITE_Weight(W); if(r) fprintf(outFILE," r"); #if(TRANS_INFO_FOR_IP_WEIGHTS) if(Trans_Check(*W)) fprintf(outFILE,"%st", r ? "" : " "); #endif fprintf(outFILE,"\n"); fflush(stdout); return 1;} return 0; } else return 0; } void Rec_IpWeights(Weight *W, PolyPointList *P, int g, int sum, int *npp, int *nrp, int n, int *rFlag, int *tFlag) { int wmax=W->d/(W->N-n+1); wmax=min(wmax,W->w[n+1]); wmax=min(wmax,sum-n); if(n) for(W->w[n]=wmax;(n+1)*W->w[n]>=sum;W->w[n]--) Rec_IpWeights(W,P,Fgcd(g,W->w[n]),sum-W->w[n],npp,nrp,n-1,rFlag,tFlag); else if(1==Fgcd(g,W->w[0]=sum)) { (*npp)++;if(IfIpWWrite(W,P,rFlag,tFlag))(*nrp)++;}; } void MakeIpWeights(int N, int from_d, int to_d, int *rFlag, int *tFlag) { int npp=0, nrp=0; Weight W; PolyPointList *P = (PolyPointList *) malloc (sizeof(PolyPointList)); assert((N<=W_Nmax)&&(Nd; D++) if (!(W->d % D)){ /* sf = Strangefun(W->d / D); */ auxrat = rR(stf[W->d / D], W->d); for(i=0; iN; i++) if (!(D * W->w[i] % W->d)) { auxrat = rP(auxrat, dmwow[i]); auxrat.N *= -1;} chi = rS(auxrat, chi);} if (chi.D != 1) return 0; /* exit if the weight doesn't satisfy certain desired criteria */ if (chi.N % 24) return 0; if (abs(chi.N) > 96) return 1; (*nsmallchi)++; WRITE_Weight(W); printf(" chi=%ld\n", chi.N); fflush(0); return 1; } int BlaRout(int quot){/* compute |{(i,j): gcd(i,j,quot)=1}| */ int sf = 0, bla, qob; int i,j; for (i=1;i<=quot;i++){ bla = Fgcd(i,quot); qob = quot/bla; for (j=1;j<=bla;j++) if (Fgcd(j,bla) == 1) sf += qob;} return sf; } #endif void RecMoonWeights(Weight *W, int g, int sum, long *npp, long *nintPP1, long *nintchi, int n, long long *PP1N, long long *PP1D #if(MOONSHINE_CRITERIA) , long *nsmallchi, Rat*dmwow, int *stf #endif ){ int wmax=W->d/(W->N-n+1); wmax=min(wmax,W->w[n+1]); wmax=min(wmax,sum-n); if(n) for(W->w[n]=wmax; (n+1)*W->w[n]>=sum; W->w[n]--){ #if(MOONSHINE_CRITERIA) dmwow[n] = rR(W->d - W->w[n], W->w[n]); #endif /*PP1[n] = rP(dmwow[n], PP1[n+1]);*/ PP1N[n] = PP1N[n+1] * (long long) (W->d - W->w[n]); assert(PP1N[n]>0); PP1D[n] = PP1D[n+1] * (long long) W->w[n]; RecMoonWeights(W, Fgcd(g,W->w[n]), sum-W->w[n], npp, nintPP1, nintchi, n-1, PP1N, PP1D #if(MOONSHINE_CRITERIA) , nsmallchi, dmwow, stf #endif );} else if (1 == Fgcd(g,sum)){ W->w[0]=sum; /*PP1[n] = rP(dmwow[n], PP1[n+1]);*/ PP1N[n] = PP1N[n+1] * (long long) (W->d - W->w[n]); PP1D[n] = PP1D[n+1] * (long long) W->w[n]; (*npp)++; /*if (PP1->D != 1) return;*/ if (PP1N[0] % PP1D[0]) return; if (PP1N[n]/PP1N[n+1] != W->d - W->w[n]) return; (*nintPP1)++; #if(MOONSHINE_CRITERIA) dmwow[n] = rR(W->d - W->w[n], W->w[n]); if(IfMoonWWrite(W, dmwow, nsmallchi, stf)) (*nintchi)++; #else if(Trans_Check(*W)){ WRITE_Weight(W); fprintf(outFILE,"\n");fflush(stdout); (*nintchi)++;} #endif } } void MakeMoonWeights(int N, int from_d, int to_d){ /* Fast routine for creating candidates for transverse weight systems; conditions: Poincare-polynomial at t=1 integer, chi integer */ long int npp=0, nintPP1=0, nintchi=0; Weight W; /* Rat PP1[W_Nmax]; */ /* Poincare polynomial evaluated at t=1 */ long long PP1N[W_Nmax], PP1D[W_Nmax]; #if(MOONSHINE_CRITERIA) long int nsmallchi=0, i; Rat dmwow[W_Nmax]; /* dmwow[i] = rR(W.d-W.w[i], W.w[i]); "d minus w over w" */ int *stf = (int *) malloc((to_d +1) * sizeof(int)); for (i=1; i<=to_d; i++) stf[i] = BlaRout(i); #endif assert((N<=W_Nmax)&&(N607) printf("d=%d\n",W.d); fflush(0); #endif for(W.w[N-1]=W.d/2; W.d <= N*W.w[N-1]; W.w[N-1]--){ /*PP1[N-1] = rR(W.d-W.w[W.N-1], W.w[W.N-1]);*/ PP1N[N-1] = W.d-W.w[W.N-1]; PP1D[N-1] = W.w[W.N-1]; #if(MOONSHINE_CRITERIA) dmwow[N-1] = rR(W.d-W.w[W.N-1], W.w[W.N-1]); #endif RecMoonWeights(&W, Fgcd(W.d, W.w[W.N-1]), W.d-W.w[W.N-1], &npp, &nintPP1, &nintchi, N-2, PP1N, PP1D #if(MOONSHINE_CRITERIA) , &nsmallchi, dmwow, stf #endif );}} #if(MOONSHINE_CRITERIA) fprintf(outFILE,"#partitions=%ld #intPP1=%ld #intchi=%ld #smallchi=%ld\n", npp, nintPP1, nintchi, nsmallchi); #else fprintf(outFILE,"#partitions=%ld #intPP1=%ld #trans=%ld\n", npp, nintPP1, nintchi); #endif exit(0); } /* ---------- LG/transversal stuff ------------ */ #define ALLOWHALF (1) /* i.e. trivial LG potentials */ #define CHAT (0) /* 3 ... for positive c_1 */ #define TWDIM 16384 /* 16384 8192 4096 dimension of weight-buffer */ #define mod(a,b) ((a)%(b)) typedef int T_weight[AMBI_Dmax+2]; /* NM::AMBI_Dmax */ typedef struct {int n,d,wnum,jmax;T_weight wei, wli[TWDIM];} T_aux; void T_Chon(int,int,int,int,T_aux*); /* i, {-fermat,0=closed,+open}, nmax, g */ void T_Addweight(T_weight,T_aux *X); int PPT_Check(T_weight nli,T_aux *X); void Make_Trans_Weights(int n,int dmin,int dmax /*,int rFlag */) { int i,j,inc=1; T_aux X; X.n=n; X.wnum=0; outFILE=stdout; assert(n<=AMBI_Dmax); X.wei[0]=n; if(CHAT){ assert(CHAT==3); if(!(n%2)) {inc++; dmin+=(dmin%2);}} for(X.d=dmin;X.d<=dmax;X.d+=inc) { X.wei[n+1]=X.d; X.wnum=0; if(ALLOWHALF) X.jmax=X.d/2; else X.jmax=(X.d-1)/2; if(CHAT) T_Chon(1,-1,(X.d*(n- CHAT))/2-n+1,X.d,&X); else T_Chon(1,-1, X.d -n+1,X.d,&X); for(i=0;i=urp */ /* let j run; check mod(d||(d-n),j); if (upr) check if upr is resolved by j;*/ void T_Chon(int i, int urp, int nm, int g,T_aux *X) { int res, j, l=0, ip=i+1, jm=min(nm,X->jmax); if (in) for(j=(i==X->n-1) ? (1+nm-jm) : 1;j<=jm;j++) {X->wei[i]=j;/*next step*/ if(urp<0) {if(X->d%j) {res=1; /* i.e. not ferm; res=0 -> resolved */ for(l=1;(ld-X->wei[l])%j; if (res) T_Chon(ip,i,nm-j+1,Fgcd(g,j),X); else T_Chon(ip,0,nm-j+1,Fgcd(g,j),X);} else{if((i==1)||(j>=X->wei[i-1])) T_Chon(ip,-1,nm-j+1,Fgcd(g,j),X);} } else /* continue;} */ if(X->d%j) { /* now there can be no more fermat */ l=max(urp,1); for(res=1;(ld-X->wei[l])%j; if(urp){if(!res){if((X->d-j)%X->wei[urp]) T_Chon(ip,urp,nm-j+1,Fgcd(g,j),X); else T_Chon(ip,0,nm-j+1,Fgcd(g,j),X);}} else {if(res) T_Chon(ip,i,nm-j+1,Fgcd(g,j),X); else T_Chon(ip,0,nm-j+1,Fgcd(g,j),X);} }} else {if(X->jmax0) if((X->d-nm)%X->wei[urp]) return; /* pointer resolved? */ if((res=(X->d%nm))||(urp<0)){ for(l=1;(ld-X->wei[l])%nm; if(!res){X->wei[i]=nm;if(Fgcd(g,nm)==1)PPT_Check(X->wei,X);}} } } /* ppcheck checks whether the formal poincare polynomial is a polynomial */ int PPT_Check(T_weight nli,T_aux *X) { int i=0, n, t, tt, j,d=X->d; assert(d==nli[nli[0]]); for (i=1;i<=nli[0];i++){ n=1; tt=nli[i]; for (j=i+1;j<=nli[0];j++) if (!(nli[j]%tt)) n++; for (j=1;j<=nli[0];j++) if (!((d-nli[j])%tt)) n--; if (n>0) return 0; for (t=2;t*t<=nli[i];t++) if (!mod(nli[i],t)) { n=1; for (j=i+1;j<=nli[0];j++) if (!mod(nli[j],t)) n++; for (j=1;j<=nli[0];j++) if (!mod(d-nli[j],t)) n--; if (n>0) return 0; n=1; tt=nli[i]/t; for (j=i+1;j<=nli[0];j++) if (!mod(nli[j],tt)) n++; for (j=1;j<=nli[0];j++) if (!mod(d-nli[j],tt)) n--; if (n>0) return 0;};}; T_Addweight(nli,X); return 1; } int T_Weicomp(T_weight w1,T_weight w2)/* w2-w1,i.e.pos if w1w2*/ { int i=1; while((i<=(*w1)) && (w1[i]==w2[i])) i++; return w2[i]-w1[i]; } void T_Insertat(T_weight ww, int position,T_aux *X) { int i, j; for(i=X->wnum-1;i>=position;i--) for(j=0;jwli[i][0]+2;j++) X->wli[i+1][j]=X->wli[i][j]; for(j=0;jwli[position][j]=ww[j]; X->wnum++; } void T_Addweight(T_weight win,T_aux *X) { int i, p, n0, n1; T_weight wn; for(i=0;i<*win+2;i++) wn[i]=win[i]; for(i=1;iwn[p]) swap(&wn[i],&wn[p]); /* make n0<=n1<=...<=n# */ if (X->wnum) {if ((i = T_Weicomp(wn,X->wli[n0=0]))) {if (i>0) {T_Insertat(wn,0,X); return;}} else return; if ((i = T_Weicomp(wn,X->wli[n1=X->wnum-1]))) {if (i<0) {T_Insertat(wn,X->wnum,X); return;}} else return; while(n1>n0+1) {p=(n0+n1)/2; i=T_Weicomp(wn,X->wli[p]); if(i) {if(i>0) n1=p; else n0=p;} else return;} T_Insertat(wn,n1,X);} else T_Insertat(wn,0,X); } /* ========== End of MAKE WEIGHTS d>4: ========== */ /* ========== ALL CWS in d <= 4 ========== */ typedef struct {int d, w[2];} wei2; typedef struct {int d, w[3];} wei3; typedef struct {int d, w[4];} wei4; const wei2 W2={2,{1,1}}; const wei3 W3[ 3]={{3,{1,1,1}}, {4,{1,1,2}}, {6,{1,2,3}}}; const wei4 W4[95]={ {4, {1,1,1,1}}, {5,{1,1,1,2}}, {6,{1,1,2,2}}, {6,{1,1,1,3}}, {7,{1,1,2,3}}, {8, {1,2,2,3}}, {8,{1,1,2,4}}, {9,{1,2,3,3}}, {9,{1,1,3,4}}, {10,{1,2,3,4}}, {10,{1,2,2,5}}, {10,{1,1,3,5}},{11,{1,2,3,5}}, {12,{2,3,3,4}}, {12,{1,3,4,4}}, {12,{2,2,3,5}}, {12,{1,2,4,5}},{12,{1,2,3,6}}, {12,{1,1,4,6}}, {13,{1,3,4,5}}, {14,{2,3,4,5}}, {14,{2,2,3,7}},{14,{1,2,4,7}}, {15,{3,3,4,5}}, {15,{2,3,5,5}}, {15,{1,3,5,6}}, {15,{1,3,4,7}},{15,{1,2,5,7}}, {16,{1,4,5,6}}, {16,{2,3,4,7}}, {16,{1,3,4,8}}, {16,{1,2,5,8}},{17,{2,3,5,7}}, {18,{3,4,5,6}}, {18,{1,4,6,7}}, {18,{2,3,5,8}}, {18,{2,3,4,9}},{18,{1,3,5,9}}, {18,{1,2,6,9}}, {19,{3,4,5,7}}, {20,{2,5,6,7}}, {20,{3,4,5,8}},{20,{2,4,5,9}}, {20,{2,3,5,10}},{20,{1,4,5,10}}, {21,{3,5,6,7}}, {21,{1,5,7,8}},{21,{2,3,7,9}}, {21,{1,3,7,10}},{22,{2,4,5,11}}, {22,{1,4,6,11}}, {22,{1,3,7,11}},{24,{3,6,7,8}},{24,{4,5,6,9}}, {24,{1,6,8,9}}, {24,{3,4,7,10}},{24,{2,3,8,11}},{24,{3,4,5,12}},{24,{2,3,7,12}},{24,{1,3,8,12}}, {25,{4,5,7,9}}, {26,{2,5,6,13}},{26,{1,5,7,13}},{26,{2,3,8,13}},{27,{5,6,7,9}}, {27,{2,5,9,11}},{28,{4,6,7,11}},{28,{3,4,7,14}},{28,{1,4,9,14}},{30,{5,6,8,11}}, {30,{3,4,10,13}}, {30,{4,5,6,15}}, {30,{2,6,7,15}}, {30,{1,6,8,15}}, {30,{2,3,10,15}}, {30,{1,4,10,15}},{32,{4,5,7,16}}, {32,{2,5,9,16}}, {33,{3,5,11,14}}, {34,{4,6,7,17}}, {34,{3,4,10,17}},{36,{7,8,9,12}}, {36,{3,4,11,18}}, {36,{1,5,12,18}},{38,{5,6,8,19}}, {38,{3,5,11,19}}, {40,{5,7,8,20}}, {42,{3,4,14,21}},{42,{2,5,14,21}},{42,{1,6,14,21}}, {44,{4,5,13,22}}, {48,{3,5,16,24}},{50,{7,8,10,25}},{54,{4,5,18,27}}, {66,{5,6,22,33}}}; void MakeSelections(FILE *, FILE *, int); void Make2CWS(FILE *, FILE *, int, int); void RW_TO_CWS(CWS *, Weight *, int, int, int, int); void W_TO_CWS(CWS *, Weight *, int, int, int, int); void PRINT_CWS(CWS *); void Make_111_CWS(FILE **, int *); void Make_nno_CWS(FILE **, int, int); void STtmp(FILE *w2FILE, FILE *w3FILE, FILE *w4FILE) { int i,j; for(i=0; i<95; i++){fprintf(w4FILE, "%d ",W4[i].d); for(j=0; j<4; j++) fprintf(w4FILE, "%d ",W4[i].w[j]); fprintf(w4FILE,"\n"); } for(i=0; i<3; i++){fprintf(w3FILE, "%d ",W3[i].d); for(j=0; j<3; j++) fprintf(w3FILE, "%d ",W3[i].w[j]); fprintf(w3FILE,"\n"); } fprintf(w2FILE, "%d ",W2.d); for(j=0;j<2;j++)fprintf(w2FILE, "%d ",W2.w[j]); fprintf(w2FILE,"\n"); rewind(w2FILE); rewind(w3FILE); rewind(w4FILE); } void mkold2(char *outfile, FILE *INFILE1, FILE *INFILE2, int u, int ef) { FILE *AUXFILE1, *AUXFILE2; if((AUXFILE1 = tmpfile()) == NULL) Die("Unable to open tmpfile for read/write"); if((AUXFILE2 = tmpfile()) == NULL) Die("Unable to open tmpfile for read/write"); MakeSelections(INFILE1, AUXFILE1, u); MakeSelections(INFILE2, AUXFILE2, u); if(strcmp(outfile,"")) if((outFILE = fopen(outfile, "w")) == NULL){ printf("\nUnable to open file %s for write\n",outfile); exit(0);} Make2CWS(AUXFILE1, AUXFILE2, u, ef); fclose(AUXFILE1); fclose(AUXFILE2); if(strcmp(outfile,"")) fclose(outFILE); } void mk2xxx(char *outfile, int n) { int i,j,d=0; CWS CW; CW.nz=0; CW.N=2*n; CW.nw=n; for(i=0; i4 ========== */ void Print_CWS_Zinfo(CWS *CW); void Print_CWS(CWS *_W) { int i, j; for (i = 0; i < _W->nw; i++) { fprintf(outFILE, "%d ", (int) _W->d[i]); for (j = 0; j < _W->N; j++) fprintf(outFILE, "%d ", (int) _W->W[i][j]); if (i + 1 < _W->nw) fprintf(outFILE, " "); } Print_CWS_Zinfo(_W); } void print_W(Weight *_s, Weight *_W, FILE *auxFILE){ int i,j=0; fprintf(auxFILE, "%d ", (int) _W->d); for(i = 0; i < _s->N; i++) fprintf(auxFILE, "%d ", (int) _W->w[_s->w[i]]); for(i = 0; i < _W->N; i++) if(i != _s->w[j]) fprintf(auxFILE, "%d ", (int) _W->w[i]); else if(j < (_s->N - 1)) j++; fprintf(auxFILE, "\n"); } void next_n(Weight *_s, Weight *_W, int *_n, FILE *auxFILE){ int i; if(_s->N == *_n) print_W(_s, _W, auxFILE); else if(_s->w[_s->N - 1] != (_W->N - 1)){ if (_W->w[_s->w[_s->N - 1] + 1] == _W->w[_s->w[_s->N - 1]]){ _s->w[_s->N] = _s->w[_s->N - 1] + 1; _s->N ++; next_n(_s, _W, _n, auxFILE); _s->N --; } for(i = _s->w[_s->N - 1] + 1; i < _W->N; i++){ if(_W->w[i] > _W->w[i - 1]){ _s->w[_s->N] = i; _s->N ++; next_n(_s, _W, _n, auxFILE); _s->N --; } } } } void Select_n_of_W(Weight *_W, int n, FILE *auxFILE){ int i; Weight s; if(n == 0){ fprintf(auxFILE, "%d ", (int) _W->d); for(i = 0; i < _W->N; i++) fprintf(auxFILE, "%d ", (int) _W->w[i]); fprintf(auxFILE, "\n"); } else{ for(i = 1; i < _W->N; i++) if(_W->w[i] < _W->w[i-1]) Die("Weights must be sortet: W_1 <= W_2 <= .... <=W_N!"); s.N = 1; s.d = _W->d; s.w[0] = 0; next_n(&s, _W, &n, auxFILE); for(i = 1; i < _W->N; i++) if(_W->w[i] > _W->w[i-1]){ s.w[0] = i; next_n(&s, _W, &n, auxFILE); } } } void PRINT_CWS(CWS *CW){ #if (!Only_IP_CWS) { Print_CWS(CW); fprintf(outFILE,"\n"); } #else { PolyPointList *P, *DP; EqList E; VertexNumList V; P = (PolyPointList *) malloc(sizeof(PolyPointList)); if (P == NULL) Die("Unable to allocate space for P"); DP = (PolyPointList *) malloc(sizeof(PolyPointList)); if (DP == NULL) Die("Unable to allocate space for DP"); CW->index = 1; Make_CWS_Points(CW, P); if (IP_Check(P,&V,&E)){ int r=1,i=-1; Print_CWS(CW); while(r && (++i < E.ne)) if(E.e[i].c != 1) r = 0; Make_Dual_Poly(P, &V, &E, DP); fprintf(outFILE," M:%d %d",P->np, V.nv); if(r) fprintf(outFILE," N:%d %d",DP->np, E.ne); else fprintf(outFILE," F:%d N:%d", E.ne,DP->np); assert(IP_Check(DP,&V,&E)); fprintf(outFILE,"\n"); } free(DP); free(P); } #endif } void W_TO_CWS(CWS *CW, Weight *_W, int Nf, int Nr, int Nb, int u) { /* d (Nf x 0) w_1 ... w_u (Nb x 0) w_(u+1) ... w_N (Nr x 0) */ int i, j, d = 0; CW->d[CW->nw]=_W->d; CW->N=(Nf+Nb+Nr+_W->N); if(CW->N > AMBI_Dmax) Die("increase AMBI_Dmax !"); for(i=0; i < Nf; i++) CW->W[CW->nw][i]=0; for(i=0; i < _W->N; i++){ CW->W[CW->nw][i+Nf+d]=_W->w[i]; if(u && (i == (u - 1))){ for(j=0; j < Nb; j++) CW->W[CW->nw][i+j+Nf+1]=0; d=Nb; } } for(i=0; i < Nr; i++) CW->W[CW->nw][Nf+d+_W->N+i]=0; CW->nw++; CW->nz=0; } void RW_TO_CWS(CWS *CW, Weight *_W, int Nf, int Nr, int Nb, int u) { /* d (Nf x 0) w_N ... w_(u+1) (Nb x 0) w_u ... w_1 (Nr x 0) */ int i, j, d = 0; CW->d[CW->nw]=_W->d; CW->N=(Nf+Nb+Nr+_W->N); if(CW->N > AMBI_Dmax) Die("increase AMBI_Dmax !"); for(i=0; i < Nf; i++) CW->W[CW->nw][i]=0; for(i=0; i < _W->N; i++){ CW->W[CW->nw][i+Nf+d]=_W->w[_W->N - i - 1]; if(u && (i == (u - 1))){ for(j=0; j < Nb; j++) CW->W[CW->nw][i+j+Nf+1]=0; d=Nb; } } for(i=0; i < Nr; i++) CW->W[CW->nw][Nf+d+_W->N+i]=0; CW->nw++; CW->nz=0; } void SWAP(Long *_A, Long *_B) { Long C; C = *_A; *_A = *_B; *_B = C; } void scan_dim(int nF, char *infile[], int D[]) { int i, j = 0; FILE *INfile[NFmax]; Weight W; for(i = 0; i < nF; i++){ if((INfile[i] = fopen(infile[i], "r"))== NULL){ printf("\nUnable to open file %s for read\n",infile[i]);exit(0);} j = 0; while(READ_Weight(&W, INfile[i]))if (j++) break; D[i] = W.N - 1; fclose(INfile[i]); } } int Wcomp(Weight *_W1, Weight *_W2){ int i,j; int A[POLY_Dmax+1], B[POLY_Dmax+1]; if (_W1->N > (POLY_Dmax+1)) Die("increase POLY_Dmax!"); if (_W1->N != _W2->N) Die("N1 != N2 in Wcomp!"); for(i = 0; i < _W1->N; i++){ A[i] = i; B[i] = i; } for(i = 0; i < _W1->N - 1; ++i) for(j = _W1->N - 1; j > i; --j){ if(_W1->w[A[j-1]] > _W1->w[A[j]]) swap(&A[j-1], &A[j]); if(_W2->w[B[j-1]] > _W2->w[B[j]]) swap(&B[j-1], &B[j]); } for(i = 0; i < _W1->N; i++){ if(_W1->w[A[i]] > _W2->w[B[i]]) return 1; if(_W1->w[A[i]] < _W2->w[B[i]]) return -1; } return 0; } void Make_nno_CWS(FILE *AUXFILE[], int u, int ef) { int n=0, l[2]; Weight W[3]; CWS CW; l[0]=0; while (READ_Weight(&W[0], AUXFILE[0])){ l[1]=0; l[0]++; while (READ_Weight(&W[1], AUXFILE[1])){ l[1]++; while (READ_Weight(&W[2], AUXFILE[2])){ if((l[0] <= l[1]) || !ef){ CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), W[2].N, n, n); W_TO_CWS(&CW, &W[2], (W[0].N + W[1].N - u), n, n, n); PRINT_CWS(&CW); if(u == 2) if((W[0].w[0] != W[0].w[1]) && (W[1].w[0] != W[1].w[1])){ SWAP(&W[1].w[0], &W[1].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), W[2].N, n, n); W_TO_CWS(&CW, &W[2], (W[0].N + W[1].N), n, n, n); PRINT_CWS(&CW); } } } rewind(AUXFILE[2]); } rewind(AUXFILE[1]); } rewind(AUXFILE[0]); } void Make_111_CWS(FILE *AUXFILE[], int ef[]) { int u = 1, n=0, l[3]; Weight W[3]; CWS CW; l[0]=0; while (READ_Weight(&W[0], AUXFILE[0])){ l[1]=0; l[0]++; while (READ_Weight(&W[1], AUXFILE[1])){ l[2]=0; l[1]++; while (READ_Weight(&W[2], AUXFILE[2])){ l[2]++; if(((l[0] <= l[1]) || !ef[0]) && ((l[1] <= l[2]) || !ef[1])){ CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - u), n, (W[1].N - u), u); PRINT_CWS(&CW); } } rewind(AUXFILE[2]); } rewind(AUXFILE[1]); } rewind(AUXFILE[0]); } void Make_222_CWS(FILE *AUXFILE[], int ef[]) { int u = 2, n=0, l[3]; Weight W[3]; CWS CW; l[0]=0; while (READ_Weight(&W[0], AUXFILE[0])){ l[1]=0; l[0]++; while (READ_Weight(&W[1], AUXFILE[1])){ l[2]=0; l[1]++; while (READ_Weight(&W[2], AUXFILE[2])){ l[2]++; if(((l[0] <= l[1]) || !ef[0]) && ((l[1] <= l[2]) || !ef[1])){ CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - u), n, (W[1].N - u), u); PRINT_CWS(&CW); if(W[0].w[0] == W[0].w[1]){ if((W[1].w[0] != W[1].w[1]) && (W[2].w[0] != W[2].w[1])){ SWAP(&W[1].w[0], &W[1].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - u), n, (W[1].N - u), u); PRINT_CWS(&CW); } } else{ if((W[1].w[0] != W[1].w[1]) || (W[2].w[0] != W[2].w[1])){ SWAP(&W[0].w[0], &W[0].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - u), n, (W[1].N - u), u); PRINT_CWS(&CW); } if((W[1].w[0] != W[1].w[1]) && (W[2].w[0] != W[2].w[1])){ SWAP(&W[1].w[0], &W[1].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - u), n, (W[1].N - u), u); PRINT_CWS(&CW); } } } } rewind(AUXFILE[2]); } rewind(AUXFILE[1]); } rewind(AUXFILE[0]); } void Make_221_CWS(FILE *AUXFILE[], int ef) { int n=0, U = 2, u = 1, i=0, l[2]; Weight W[3]; CWS CW; l[0]=0; while (READ_Weight(&W[0], AUXFILE[0])){ l[1]=0; l[0]++; while (READ_Weight(&W[1], AUXFILE[1])){ l[1]++; while (READ_Weight(&W[2], AUXFILE[2])){ if((l[0] <= l[1]) || !ef){ i=0; CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - U -u ), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - U), (W[2].N - u ), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - U + i), n, (W[1].N - U + 1 - i), u); PRINT_CWS(&CW); if((W[0].w[0] != W[0].w[1]) && (W[1].w[0] != W[1].w[1])){ SWAP(&W[1].w[0], &W[1].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - U -u ), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - U), (W[2].N - u ), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - U + i), n, (W[1].N - U + 1 - i), u); PRINT_CWS(&CW); } if((W[0].w[0] != W[0].w[1]) || (W[1].w[0] != W[1].w[1])){ i=1; CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - U -u ), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - U), (W[2].N - u ), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - U + i), n, (W[1].N - U + 1 - i), u); PRINT_CWS(&CW); if((W[0].w[0] != W[0].w[1]) && (W[1].w[0] != W[1].w[1])){ SWAP(&W[1].w[0], &W[1].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - U -u ), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - U), (W[2].N - u ), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - U + i), n,(W[1].N - U + 1 - i),u); PRINT_CWS(&CW); } } } } rewind(AUXFILE[2]); } rewind(AUXFILE[1]); } rewind(AUXFILE[0]); } void Make_211_CWS(FILE *AUXFILE[], int ef) { int u = 1, n=0, l[3]; Weight W[3]; CWS CW; while (READ_Weight(&W[0], AUXFILE[0])){ l[1]=0; while (READ_Weight(&W[1], AUXFILE[1])){ l[2]=0; l[1]++; while (READ_Weight(&W[2], AUXFILE[2])){ l[2]++; if(((l[1] <= l[2]) || !ef)){ CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - 2*u), n, W[1].N, u); PRINT_CWS(&CW); if((W[0].w[0] != W[0].w[1]) && (W[1].w[0] != W[2].w[0])){ SWAP(&W[0].w[0], &W[0].w[1]); CW.nw=0; RW_TO_CWS(&CW, &W[0], n, (W[1].N + W[2].N - 2*u), n, n); W_TO_CWS(&CW, &W[1], (W[0].N - u), (W[2].N - u), n, n); W_TO_CWS(&CW, &W[2], (W[0].N - 2*u), n, W[1].N, u); PRINT_CWS(&CW); } } } rewind(AUXFILE[2]); } rewind(AUXFILE[1]); } rewind(AUXFILE[0]); } void Make2CWS(FILE *AUXFILE1, FILE *AUXFILE2, int u, int ef){ Weight W1, W2; int n=0, l[2]; CWS CW; if (u > 2) Die("for u > 2 no support !"); l[0]=0;while (READ_Weight(&W1, AUXFILE1)){ l[1]=0; l[0]++; while (READ_Weight(&W2, AUXFILE2)){ l[1]++; if((l[1] >= l[0]) || !ef){CW.nw=0; RW_TO_CWS(&CW, &W1, n, (W2.N-u), n, n); W_TO_CWS(&CW, &W2, (W1.N - u), n, n, n); PRINT_CWS(&CW); if(u == 2) if((W1.w[0] != W1.w[1]) && (W2.w[0] != W2.w[1])){ SWAP(&W2.w[0], &W2.w[1]); CW.nw=0; RW_TO_CWS(&CW, &W1, n, (W2.N - u), n, n); W_TO_CWS(&CW, &W2, (W1.N - u), n, n, n); PRINT_CWS(&CW); } } } rewind(AUXFILE2); } rewind(AUXFILE1); } void MakeSelections(FILE *INFILE, FILE *AUXFILE, int u) { Weight W; while (READ_Weight(&W, INFILE)) Select_n_of_W(&W, u, AUXFILE); rewind(AUXFILE); rewind(INFILE); } void PrintCWSTypes(void) { const char B[]=" "; printf("\nThe following types are available:\n\n"); printf("#infiles = 2 (need no -t option):\n"); printf("%s-c# -n2 [intile1] [infile2] (-t 0 0)\n",B); printf("%s-c# -n2 [intile1] [infile2] (-t 1 1)\n",B); printf("%s-c# -n2 [intile1] [infile2] (-t 2 2)\n",B); printf("#infiles = 3:\n"); printf("%s-c# -n3 [intile1] [infile2] [infile3] -t n n 0\n",B); printf("%s-c# -n3 [intile1] [infile2] [infile3] -t 1 1 1\n",B); printf("%s-c# -n3 [intile1] [infile2] [infile3] -t 2 1 1\n",B); printf("%s-c# -n3 [intile1] [infile2] [infile3] -t 2 2 1\n",B); printf("%s-c# -n3 [intile1] [infile2] [infile3] -t 2 2 2\n",B); exit(0); } void Make_IP_CWS(int narg, char* fn[]) { FILE *INFILE[NFmax] = {NULL}, *AUXFILE[NFmax] = {NULL}; char *infile[NFmax] = {NULL}, *outfile = NULL, *a; int n = 0, d = 0, u = -1, nF = 0, i, D[NFmax]; CWS_type t; t.nu = 0; for (i=0; i ++n) { if(fn[n][0] != '-') break; if(fn[n][1] == 'c'){ if((fn[n][2]==0) && (narg>n+1)) a=fn[++n]; else a=&fn[n][2]; if(!IsDigit(*a)) Die("after -c there must be a digit!"); d = atoi(a); } if(fn[n][1] == 'n'){ if((fn[n][2]==0) && (narg>n+1)) a=fn[++n]; else a=&fn[n][2]; if(!IsDigit(*a)) Die("after -n there must be a digit!"); nF = atoi(a); n++; break; } if(fn[n][1] == 't') PrintCWSTypes(); } for(i = 0; i < nF; i++){ if((n >= narg)||(fn[n][0] == '-')) {printf("#infiles = %d < %d!\n",i,nF); exit(0);} infile[i] = fn[n]; n++; } if((narg > n) && (fn[n][0] != '-')) Die("too many infiles!"); n--; t.nu=0; while (narg > ++n) { if(fn[n][0] != '-') break; if(fn[n][1] == 't'){ if((fn[n][2]==0) && (narg>n+1)) a=fn[++n]; else a=&fn[n][2]; if(*a == 0) PrintCWSTypes(); if(!IsDigit(*a)) Die("after -t there must be digit(s)!"); t.u[0] = atoi(a); t.nu = 1; while ((narg > ++n) && (t.nu < nF)) { if(fn[n][0] == '-') break; a=fn[n]; if(!IsDigit(*a)) Die("after -t there must be digit(s)!"); assert(t.nu < NFmax); t.u[t.nu] = atoi(a); t.nu++; } n--; if(narg > ++n) outfile = fn[n]; } } if(nF == 0) Die("there is no -n#infiles!"); if(d == 0) Die("No dimensoin specified!"); if(t.nu && (t.nu != nF)) Die("if input is -nN -t k_1,...,k_n then N must be equal to n!"); if(outfile == NULL) outFILE = stdout; else if((outFILE = fopen(outfile, "w")) == NULL){ printf("\nUnable to open file %s for write\n",fn[n]); exit(0);} scan_dim(nF, infile, D); for(i = 0; i < nF; i++){ if((AUXFILE[i] = tmpfile()) == NULL) Die("Unable to open tmpfile to read/write"); if((INFILE[i] = fopen(infile[i], "r"))==NULL) Die("Unable to open infile to read"); } if(nF == 2){ if(!t.nu) assert((u = D[0] + D[1] -d) >= 0); else{ if(t.u[0] != t.u[1]) Die("if input is -n2 -t k_1 k_2 then k_1 must be equal to k_2!"); if(t.u[0] != (D[0] + D[1] - d)) Die("wrong DIM -cDIM or wrong TYPES -t TYPE1 TYPE2"); u = t.u[0]; } for(i = 0; i < nF; i++) MakeSelections(INFILE[i], AUXFILE[i], u); Make2CWS(AUXFILE[0], AUXFILE[1], u, !strcmp(infile[0], infile[1])); } if(nF == 3){ if(!t.nu) Die("with nNUMBER and NUMBER>2 I need -t TYPE1 TYPE2 TYPE3!"); if(((t.u[0] == 1) && (t.u[1] == 1) && (t.u[2] == 1)) || ((t.u[0] == 2) && (t.u[1] == 2) && (t.u[2] == 2))){ int eq[2]; if((D[0] + D[1] + D[2] -2*t.u[0] - d) != 0) Die("wrong DIM -cDIM or wrong TYPES -t TYPE1 TYPE2 TYPE3"); eq[0] = 0; eq[1] = 0; if(!strcmp(infile[0], infile[1])) eq[0] = 1; if(!strcmp(infile[1], infile[2])) eq[1] = 1; if(((!eq[0]) && (!eq[1])) && (!strcmp(infile[0], infile[2]))){ eq[0] = 1; MakeSelections(INFILE[0], AUXFILE[0], t.u[0]); MakeSelections(INFILE[2], AUXFILE[1], t.u[1]); MakeSelections(INFILE[1], AUXFILE[2], t.u[2]); } else for(i = 0; i < nF; i++) MakeSelections(INFILE[i], AUXFILE[i], t.u[i]); if(t.u[0] == 1) Make_111_CWS(AUXFILE, eq); else Make_222_CWS(AUXFILE, eq); } else if(((t.u[0] == 2) && (t.u[1] == 1) && (t.u[2] == 1)) || ((t.u[0] == 2) && (t.u[1] == 2) && (t.u[2] == 1))){ if((D[0] + D[1] + D[2] -(t.u[1] + t.u[2]) - d) != 0) Die("wrong DIM -cDIM or wrong TYPES -t TYPE1 TYPE2 TYPE3"); for(i = 0; i < nF; i++) MakeSelections(INFILE[i], AUXFILE[i], t.u[i]); if(t.u[1] == 2) Make_221_CWS(AUXFILE, !strcmp(infile[1], infile[2])); else Make_211_CWS(AUXFILE, !strcmp(infile[0], infile[1])); } else if((t.u[0] == t.u[1]) && (t.u[2] == 0)){ if((D[0] + D[1] + D[2] - t.u[0] - d) != 0) Die("wrong DIM -cDIM or wrong TYPES -t TYPE1 TYPE2 TYPE3"); for(i = 0; i < nF; i++) MakeSelections(INFILE[i], AUXFILE[i], t.u[i]); Make_nno_CWS(AUXFILE, t.u[0], !strcmp(infile[0], infile[1])); } else PrintCWSTypes(); } for(i = 0; i < nF; i++){fclose(INFILE[i]);fclose(AUXFILE[i]);} } /* ========== POLY DATA: ========== */ void FileRW(char *file, char *m, FILE *rwFILE){ if((rwFILE = fopen(file, m)) == NULL){ printf("\n\nUnable to open file %s for %s!\n\n",file,m); exit(0); } } void IP_Poly_Data(int narg, char* fn[]) { int r = 1, i, n = 0, p=0, d=0; CWS CW; PolyPointList *_P, *_DP; VertexNumList *_V; EqList *_E; inFILE=stdin; outFILE=stdout; /*puts("IP_Poly_Data: to be done");*/ _P = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_P == NULL) Die("Unable to allocate space for _P"); _DP = (PolyPointList *) malloc(sizeof(PolyPointList)); if (_DP == NULL) Die("Unable to allocate space for _DP"); _V = (VertexNumList *) malloc(sizeof(VertexNumList)); if (_V == NULL) Die("Unable to alloc space for VertexNumList _V"); _E = (EqList *) malloc(sizeof(EqList)); if (_E == NULL) Die("Unable to alloc space for EqList _E"); while ((narg > ++n) && (fn[n][0] == '-')){ if (fn[n][1] == 'i'){ if (fn[n][2] == 'p') p=1; if (fn[n][2] == 'd') d=1; } if ((fn[n][1] == 'f') || (fn[n][1] == 0)) inFILE=NULL; } n--; if (narg > ++n){ if((inFILE = fopen(fn[n], "r")) == NULL){ printf("\nUnable to open file %s for read\n",fn[n]); exit(0); } } if (narg > ++n){ if((outFILE = fopen(fn[n], "w")) == NULL){ printf("\nUnable to open file %s for write\n",fn[n]); exit(0); } } while (Read_CWS_PP(&CW, _P)) if (IP_Check(_P,_V,_E)){ r=1; i=-1; while(r && (++i < _E->ne)) if(_E->e[i].c != 1) r = 0; Make_Dual_Poly(_P, _V, _E, _DP); if((!p) && (!d)){ Print_CWS(&CW); fprintf(outFILE," M:%d %d",_P->np, _V->nv); if(r) fprintf(outFILE," N:%d %d",_DP->np, _E->ne); else fprintf(outFILE," F:%d N:%d", _E->ne,_DP->np); } if(p) Print_PPL(_P,""); if(d) Print_PPL(_DP,""); assert(IP_Check(_DP,_V,_E)); fprintf(outFILE,"\n"); } } /* ========== END POLY DATA ========== */ /* ========== Convex Hull: ========== */ int Remove_Identical_Points(PolyPointList *); int ConvHull(PolyPointList *P1, PolyPointList *P2, PolyPointList *P, VertexNumList *V1, int x) { int i, j; VertexNumList *V2; EqList *E1, *E2; E1 = (EqList *) malloc(sizeof(EqList)); if (E1 == NULL) Die("Unable to alloc space for EqList E1"); E2 = (EqList *) malloc(sizeof(EqList)); if (E2 == NULL) Die("Unable to alloc space for EqList E2"); V2 = (VertexNumList *) malloc(sizeof(VertexNumList)); if (V2 == NULL) Die("Unable to alloc space for VertexNumList V2"); Find_Equations(P1, V1, E1); Find_Equations(P2, V2, E2); if((V1->nv+V2->nv) > VERT_Nmax) Die("increase VERT_Nmax!"); if((V1->nv+V2->nv) > POINT_Nmax) Die("increase POINT_Nmax!"); if((P1->n+x) > POLY_Dmax) Die("increase POLY_Dmax!"); if(x<0) Die("if input is -p#, # must be less than dim of first poly"); P->np=V1->nv; for(i=0; inv; i++){ for(j=P1->n;j<(P2->n+x);j++)P->x[i][j]=0; for(j=0;jn;j++) P->x[i][j]=P1->x[V1->v[i]][j]; } for(i=0; inv; i++){ for(j=0;jx[P->np][j]=0; for(j=0;jn;j++) P->x[P->np][x+j]=P2->x[V2->v[i]][j]; P->np++; } P->n=P2->n+x; if(x==0) Remove_Identical_Points(P); i=Find_Equations(P, V1, E1); Sort_VL(V1); free(E1);free(E2);free(V2); return i; } void Conv(int narg, char* fn[]) { FILE *INFILE[2]; int n=0, x=0, nF=2, i; char *infile[2] = {NULL}, *outfile = NULL, *a; PolyPointList *P[2], *PP; CWS *CW[2]; VertexNumList *V; V = (VertexNumList *) malloc(sizeof(VertexNumList)); if (V == NULL) Die("Unable to alloc space for VertexNumList V"); PP = (PolyPointList *) malloc(sizeof(PolyPointList)); if (PP == NULL) Die("Unable to allocate space for PolyPointList"); for(i = 0; i < nF; i++){ P[i] = (PolyPointList *) malloc(sizeof(PolyPointList)); if (P[i] == NULL) Die("Unable to allocate space for PolyPointList"); CW[i] = (CWS *) malloc(sizeof(CWS)); if (CW[i] == NULL) Die("Unable to allocate space for CWS"); } while ((narg > ++n) && (fn[n][0] == '-')){ if(fn[n][1] == 'p'){ if(fn[n][2]!=0){ a=&fn[n][2]; if(!IsDigit(*a)) Die("after -c there must be a digit!"); x=atoi(a);} } } for(i = 0; i < nF; i++){ if((n >= narg)||(fn[n][0] == '-')) {printf("#infiles = %d < %d!\n",i,nF); exit(0);} infile[i] = fn[n]; n++; } if(narg > n) outfile = fn[n]; for(i = 0; i < nF; i++) if((INFILE[i] = fopen(infile[i], "r"))==NULL) Die("Unable to open infile to read"); if(outfile == NULL) outFILE = stdout; else if((outFILE = fopen(outfile, "w")) == NULL){ printf("\nUnable to open file %s for write\n",fn[n]); exit(0);} while(READ_CWS_PP(CW[0], P[0], INFILE[0])){ while(READ_CWS_PP(CW[1], P[1], INFILE[1])) if(ConvHull(P[0], P[1], PP, V, (P[0]->n-x))) Print_VL(PP, V, "Vertices of P"); rewind(INFILE[1]); } for(i = 0; i < nF; i++){free(P[i]); free(CW[i]);} free(PP);free(V); } /* ========== END of Convex Hull ========== */ /*uses latte instead of Aux_Complete_Poly for counting points*/ void td_Print_EL(EqList *_E, int *n, int suppress_c, const char *comment){ int i,j; char command[100]; sprintf(command,"rm zzL.tmp"); system(command); outFILE=fopen("zzL.tmp","w"); fprintf(outFILE,"%d %d %s\n",_E->ne,(*n)+1,comment); for(i=0;i<_E->ne;i++) { if (!suppress_c) fprintf(outFILE,"%d",(int) _E->e[i].c); for(j=0;j<*n;j++) fprintf(outFILE," %3d",(int) _E->e[i].a[j]); fprintf(outFILE,"\n");} fclose(outFILE); } Long NP_use_lat(EqList *_E, PolyPointList *_P) { int tmp; char command[100]; sprintf(command,"count zzL.tmp | grep '*' | awk '{print $7}' > zzL.tmp1"); td_Print_EL(_E,&_P->n,0,""); system(command);outFILE=fopen("zzL.tmp1","r"); while((fscanf(outFILE,"%d",&tmp))!=EOF); fclose(outFILE); return tmp; } Long L_Point_Count(Weight *W,PolyPointList *P,VertexNumList *V,EqList *E){ int i,j,d; Long *G[W_Nmax], GM[W_Nmax][VERT_Nmax]; d=W->N; for(i=0;iw,&d, G); P->n=d-1; P->np=d; for(i=0;ix[j][i]=GM[i+1][j]; Find_Equations(P,V,E); return NP_use_lat(E,P); } int Read_Weight(Weight *); Long Poly_Point_Count(PolyPointList *P,VertexNumList *V,EqList *E); Long W_Point_Count(Weight *W,PolyPointList *P,VertexNumList *V,EqList *E){ int i,j,d; Long *G[W_Nmax], GM[W_Nmax][VERT_Nmax]; d=W->N; for(i=0;iw,&d, G); P->n=d-1; P->np=d; for(i=0;ix[j][i]=GM[i+1][j]; return Poly_Point_Count(P,V,E); /* char c[50]="#points="; sprintf(&c[8],"%d",P->np); if(P->np<20) Print_PPL(P,c); else printf("%s\n",c); */ } void SimplexPointCount(int narg, char* fn[]) { Weight W; VertexNumList V; EqList *E = (EqList *) malloc(sizeof(EqList)); int L; PolyPointList *P = (PolyPointList *) malloc(sizeof(PolyPointList)); if ((E == NULL)||(P == NULL)) Die("Unable to allocate space for E or P"); assert(narg>1); if(fn[1][2]=='f') inFILE=NULL; W.M=0; L=(fn[1][1]=='L'); while(Read_Weight(&W)){int n; Long np= L ? L_Point_Count(&W,P,&V,E) : W_Point_Count(&W,P,&V,E); if(np<=SIMPLEX_POINT_Nmax){printf("%d",W.d); for(n=0;n #ifdef __DECC /* use local "/tmp" on clusters: */ #define USE_TMP_DIR (1) /* write aux-files to "/tmp" */ #else #define USE_TMP_DIR (0) #endif #define NUC_Nmax 256 /* on 32-bit architectures the GNU C compiler requires flags: * * -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE * * moreover, fseek and ftell have to be replaced by fseeko and ftello */ #ifdef _LARGEFILE_SOURCE #define FTELL ftello #define FSEEK fseeko #else #define FTELL ftell #define FSEEK fseek #endif /* Target dimensions: 2^32 polytopes (unsigned!) ... 80GB/DB */ /* Along=64bit for polytopes except on bin-files::unsigned */ /* SL, self-mirror, NFnum[nv][nu]<2^32, rec-depth? */ #define MAX_REC_DEPTH 16383 /* present "dirty fix" workes till 128^2-1 */ /* large files with gcc -> -D_FILE_OFFSET_BITS=64 and ftell -> ftello */ #define Along long long /* signed > addresses bytes DBpolys */ #define UPint unsigned /* unsigned > #polys in RAM & aux */ #define FORCE_SAVE_TIME (28800) /* real time for Aux-IO in seconds */ #define GOOD_SAVE_TIME (21600) /* same at multiple of 1000 polys */ #define WRITE_DIM 4 /* File IO after weight if WD<= dim */ #define MIN_NEW 1 /* write file if MIN_NEW <= #newREF */ #define MIN_W_SAVE_TIME (7200) /* min real time for IO after poly */ #if (POLY_Dmax < 5) #define WATCHREF (100000) /* print some info after X refs */ #define SAVE_INC (1000000) /* save PolyNFlist after X refs */ #define CperR_MAX (32) /* 4*9 is safe for CY (average=10) */ #define BASE_MAX (905) /* 191->317 184->338 218->464 */ #define BLOCK_LENGTH (64) /* fraction of data base stored in RAM */ #else #define WATCHREF (100000) /* print some info after X refs */ #define SAVE_INC (4000000) /* save PolyNFlist after X refs */ #define CperR_MAX (40) /* average is 35 for PolyDim=5 */ #define BASE_MAX (1631723) /* 1631721 1 903 37947 233103 543907 815860 */ #define BLOCK_LENGTH (128) /* fraction of data base stored in RAM */ #endif #define subl_int LLong #define NB_MAX POLY_Dmax*VERT_Nmax /* an uneducated guess */ #if(POLY_Dmax<5) #define SL_Nmax (65536) #else #define SL_Nmax (300000) #endif /* ==== this should be o.k. (only change if you know what you do) ==== */ #define File_Ext_NCmax 5 /* space for following FILE_EXTs */ #define SAVE_FILE_EXT ".aux" /* aux. O/I file for big allocation */ #define TEMP_FILE_EXT ".tmp" /* undefine to directly overwrite aux */ #define MOVE_SAVE_FILE ".bak" /* move SAVE-file after read */ /* undef: risk data loss -> save disk space */ #undef MOVE_SAVE_FILE /* undefine to directly overwrite SAVE file */ #undef TEMP_FILE_EXT /* undefine to directly overwrite aux file */ #ifdef MOVE_SAVE_FILE /* consistency of these options */ #if USE_TMP_DIR /* is not yet implemented: */ #error Inconsistent options USE_TMP_DIR and MOVE_SAVE_FILE !!! #endif #endif typedef struct { Along nNF, nNM; int nSM, /* #ref=2*nNF-nSelfMir.-nNoMir. */ d, v, nu, p, sl_nNF, sl_SM, sl_NM, sl_NB, list_num, nV, nNUC[VERT_Nmax], nVmax, NUCmax, NFnum[VERT_Nmax][NUC_Nmax]; Along Fv_pos[VERT_Nmax][NUC_Nmax]; UPint RAM_pos[VERT_Nmax][NUC_Nmax]; unsigned char *RAM_NF; long long NB; FILE *Finfo, *Fsl, *Fv[VERT_Nmax]; } DataBase; typedef struct { Along nNF, nNM; int nSM; /* #ref=2*nNF-nSelfMir.-nNoMir. */ unsigned char nV, nNUC[VERT_Nmax+1], nVmax, NUCmax; unsigned int NFnum[VERT_Nmax+1][NUC_Nmax]; long long NB; unsigned char *NF[VERT_Nmax+1][NUC_Nmax],*NFli;} FInfoList; typedef struct {unsigned int n, c; } /* below n in NFptr, @NewNF[c] */ PEnt; typedef struct {int n; PEnt pe; } /* below #n in PEnt[], PEnt */ PPEnt; typedef struct { /* flags and file names: */ int SL, of, rf, kf, rd, b[POINT_Nmax]; /* orig/omit-flag, recov-flag, keep-flag, rec.depth, branch */ char *iname, *oname, *dbname; /* file names : &(Constant Strings) !! */ /* Statistics: */ UPint nNF, nIP; unsigned int nSLNF, hc, con; /* #refhit #con.ref */ int V, F, VN, FN, d, Nmin, Nmax, Xdif, Xnuc; /* max values */ time_t TIME, SAVE; clock_t CLOCK; long long IP_Time, NF_Time; /* Results */ Along NP, savedNP, NC; int nSLP; /* NC = # unit-encode */ /* Lists */ DataBase DB; FInfoList Aux, In; PEnt *PE; PPEnt *PPE; unsigned char *NewNF; Along NewNB, ANB; /* allocate*/ int RemNB; /* SL-remove */ int *SLp, SLN, PEN, PPEN, peNM, peSM, slNM, slSM; /* no/self mirror's on NewNF */ } NF_List; /* NP (HP)=#(honest) refpolys NNF=#nf's, NSM=#self mirror, */ /* NP==HRP+SLRP HRP==2*HNF-HSM-HnoMirror * HNF=PEN+PPEN+Aux.nNF HSM=peSM+Aux.nSM HNM=peNM+Aux.nNM * SLRP=2*SLN-slNM-slSM */ /* watch: #R=NP (nSLP) #C=NC #IP=nIP #NF=nNF (nSLNF) Nmin..Nmax vV fF dx=dX */ /* ========== checks and warnigs ========== */ #if ( FORCE_SAVE_TIME <= MIN_W_SAVE_TIME ) #error MIN_W_SAVE_TIME should be smaller than AUX-file save_times #endif void Make_ANF(PolyPointList *P,VertexNumList *V, /* affine normal form */ EqList *E, Long ANF[POLY_Dmax][VERT_Nmax]); void Gen_Ascii_to_Binary(CWS *W, PolyPointList *P, char *dbin, char *polyi, char *polyo); void Gen_Bin_2_ascii(char *pi,char *dbi,int max,int vf,int vt,PolyPointList *); /* ========== Functions from Subpoly.c ========== */ void DPircheck(CWS *_W, PolyPointList *_P); void DPvircheck(CWS *_W, PolyPointList *_P); void Max_check(CWS *_W, PolyPointList *_P); void Overall_check(CWS *_W, PolyPointList *_P); void Do_the_Classification(CWS *W, PolyPointList *P, /* char *fn, */ int oFlag, int rFlag, int kFlag, char *polyi, char *polyo, char *dbin); void Find_Sublat_Polys(char mFlag, char *dbi, char *polyi, char *slout, PolyPointList *_P); void Ascii_to_Binary(CWS *W, PolyPointList *P, char *dbin, char *polyi, char *polyo); int Start_Find_Ref_Subpoly(PolyPointList *_P/*, NF_List *_NFL*/); void uc_nf_to_P(PolyPointList *_P, int *MS, int *d, int *v, int *nuc, unsigned char *uc); void Make_All_Sublat(NF_List *_L, int n, int v, subl_int diag[POLY_Dmax], subl_int u[][VERT_Nmax], char *mFlag, PolyPointList *P); int Poly_Max_check(PolyPointList *_P, VertexNumList *_V, EqList *_E); int Poly_Min_check(PolyPointList *_P, VertexNumList *_V, EqList *_E); /* ========== Functions from Subdb.c ========== */ void Init_DB(NF_List *_NFL); void Check_NF_Order(char *polyi,char *polyo,int cFlag, PolyPointList *P); void Add_Polya_2_DBi(char *dbi,char *polya,char *dbo); void Polyi_2_DBo(char *polyi,char *dbo); void Reduce_Aux_File(char *polyi,char *polys,char *dbsub,char *polyo); void Bin_2_ascii(char *polyi,char *dbi,int max,int vf,int vt,PolyPointList *P); int Is_in_DB(int *nv, int *nuc, unsigned char *uc, NF_List *_L); #if (POLY_Dmax <6) void DB_to_Hodge(char *dbin,char *dbout, int vfrom,int vto, PolyPointList *P); void Sort_Hodge(char *dbaux, char *dbout); void Test_Hodge_file(char *filename, PolyPointList *_P); void Test_Hodge_db(char *dbname); void Extract_from_Hodge_db(char *dname, char *x_string, PolyPointList *P); #endif void Open_DB(char *dbin, DataBase **DB, int info); int Read_H_poly_from_DB(DataBase *DB,PolyPointList *_P); void Close_DB(DataBase *DB); void VPHM_Sublat_Polys(char sFlag,char mr,char *dbin,char *polyi,char *polyo, PolyPointList *P); /* ========== Functions from Subadd.c ========== */ void Add_Polya_2_Polyi(char *polyi,char *polya,char *polyo); void Init_NF_List(NF_List *); void Init_FInfoList(FInfoList *FI); void Read_File_2_List(char *polyi,NF_List *_NFL); void Write_List_2_File(char *polyo,NF_List *_NFL); void Print_Weight_Info(CWS *_W, NF_List *_L); void fputUI(unsigned int l,FILE *F); void UCnf2vNF(int *d, int *v, int *nuc, unsigned char *uc, /* IN */ Long NF[POLY_Dmax][VERT_Nmax], int *MS); /* OUT */ int Add_NF_to_List(PolyPointList *_P, VertexNumList *_V, EqList *_F, NF_List *_NFL); /* 1 if new */ int RIGHTminusLEFT(unsigned char *ucL, unsigned char *ucR, int *nuc); unsigned int fgetUI(FILE *F); void Test_ucNF(int *d, int *tnv, int *tnuc, unsigned char *tuc, PolyPointList *P); int InfoSize(int rd, int lists, FInfoList *FI); int Make_Poly_NF(PolyPointList *_P, VertexNumList *_V, EqList *_E, Long pNF[POLY_Dmax][VERT_Nmax]); /* 1 if reflexive */ void ANF_2_ucNF(PolyPointList *P, VertexNumList *V, EqList *E, /* IN */ int *NV, int *nUC, unsigned char *UC); /* OUT */ void UCnf_2_ANF(int *d, int *v, int *nuc, unsigned char *uc, /* IN */ Long NF[POLY_Dmax][VERT_Nmax], int *MS); /* OUT */ void Print_Expect(FInfoList *L); /* ==== headers of aux-Routines for Add_Polya_2_DBi in Subadd.c ==== */ void Read_Bin_Info(FILE *F, int *d, unsigned *li, int *slNF, int *slSM, int *slNM, Along *NewNB, FInfoList *FI); void AuxGet_vn_uc(FILE *F,int *v, int *nu, unsigned char *uc); void AuxGet_uc(FILE *F,int *nu, unsigned char *uc); void AuxPut_hNF(FILE *F,int *v,int *nu,unsigned char *Huc,FInfoList *Io, int *slNF,int *slSM,int *slNM,int *slNB,unsigned char *ucSL,int *SLp); #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) palp-2.21/Vertex.c0000664000177600017760000011645714572603263013405 0ustar skarkeskarke#include "Global.h" #include "Rat.h" #define MAX_BAD_EQ (POLY_Dmax>5) /* previously 6; needed for nef !? */ #define SHOW_NEW_CEq 0 /* (POLY_Dmax>12) tracks polytope analysis */ #ifndef CEQ_Nmax #define CEQ_Nmax EQUA_Nmax #endif typedef struct {int ne; Equation e[CEQ_Nmax];} CEqList; /* ====================================================================== */ /* ========== ========== */ /* ========== I N C I D E N C E S (as bit patterns) ========== */ /* ========== ========== */ /* ====================================================================== */ #if (VERT_Nmax > LONG_LONG_Nbits) INCI INCI_AND(INCI x, INCI y){ INCI z; int i; for (i=0;i>(INT_Nbits-1)); return z;} INCI INCI_D2(INCI x){ INCI z; int i; for (i=0;i>1)|(x.ui[i+1]<<(INT_Nbits-1)); z.ui[I_NUI-1]=x.ui[I_NUI-1]>>1; return z;} int INCI_lex_GT(INCI *x, INCI *y){ int i=I_NUI; while(i--) if(x->ui[i]>y->ui[i]) return 1; else if(x->ui[i]ui[i]) return 0; return 0; } int INCI_LmR(INCI *x, INCI *y){ puts("Implement INCI_LmR"); exit(0); } #else int INCI_lex_GT(INCI *x, INCI *y){ return (*x > *y) ? 1 : 0 ; } int INCI_LmR(INCI *x, INCI *y){ return (*x>*y) ? 1 : (*x<*y) ? -1 : 0; } /* int Lead_Vert(INCI x){int i=0; while(!(x%2)) {i++; x/=2;} return i;} */ #endif int INCI_abs(INCI X){ int abs=0; while(!INCI_EQ_0(X)) {abs+=INCI_M2(X); X=INCI_D2(X);} return abs; } INCI Eq_To_INCI(Equation *_Eq, PolyPointList *_P, VertexNumList *_V){ int j; INCI X=INCI_0(); for (j=0;j<_V->nv;j++) X=INCI_PN(X,Eval_Eq_on_V(_Eq,_P->x[_V->v[j]],_P->n)); return X; } int Print_INCI(INCI X) { int i=0; while(!INCI_EQ_0(X)) {printf("%d", (int) INCI_M2(X)); X=INCI_D2(X); i++;} return i; /* number of printed bits */ } void Print_FaceInfo(int M,FaceInfo *_I){ int i,j, k, l; M--; printf("Incidences as binary numbers [F-vector=(%d",_I->nf[0]); for(i=1;i<=M;i++) printf(" %d",_I->nf[i]); puts(")]:"); puts("v[d][i]: sum_j Incidence(i'th dim-d-face, j-th vertex) x 2^j"); for(i=0;i<=M;i++) { printf("v[%d]: ",i); for(j=0;j<_I->nf[i];j++){ k=Print_INCI(_I->v[i][j]); for (l=k;l<_I->nf[0];l++) printf("0"); printf(" ");} puts(""); } puts("f[d][i]: sum_j Incidence(i'th dim-d-face, j-th facet) x 2^j"); for(i=0;i<=M;i++) { printf("f[%d]: ",i); for(j=0;j<_I->nf[i];j++){ k=Print_INCI(_I->f[i][j]); for (l=k;l<_I->nf[M];l++) printf("0"); printf(" ");} puts(""); } } void Make_CD2Faces(PolyPointList *_P, VertexNumList *_V, EqList *_E, FaceInfo *_I); void Make_Incidence(PolyPointList *_P, VertexNumList *_V, EqList *_E, FaceInfo *_I) /* The incidence relations for faces are stored on the structure FaceInfo: * * int nf[d] == #faces(dim.=d) == #dual faces[dim.=n-d-1] * INCI v[d][i] :: vertices on i-th dim=d face * INCI f[d][i] :: dual vertices on face dual to i-th dim=n-d-1 face * Long nip[d][i] :: #(IPs of i-th dim=d face) * Long dip[d][i] :: #(IPs of i-th dim=n-d-1 face on dual) * * .v: compute vertices on facets; make intersections `&' of faces with facets * while keeping only maximal intersections; * .f: take analogous union; if same intersection again make union `|' of f's */ { int i, j, M=_P->n-1, d=M, D; assert(_E->ne<=VERT_Nmax); _I->nf[M]=_E->ne; for(i=0;i<_E->ne;i++)_I->v[M][i]=Eq_To_INCI(&_E->e[i],_P,_V); /* init .v*/ assert(i>0); _I->f[M][--i]=INCI_1(); while(i--) _I->f[M][i]=INCI_PN(_I->f[M][i+1],1); /* init .f */ while((D=d--)) { int *n=&_I->nf[d]; *n=0; /* #(d-faces) */ for(i=0; i<_I->nf[D]; i++) for(j=0; j<_I->nf[M]; j++) { int k; INCI x=INCI_AND(_I->v[D][i],_I->v[M][j]); /* x=candidate */ INCI u=INCI_OR(_I->f[D][i],_I->f[M][j]); if( (!INCI_EQ(x,_I->v[D][i]))&&(INCI_abs(x)>d) )/* x!=vD & |x|>d */ { for(k=0;k<*n;k++) { INCI *y=&_I->v[d][k],*v=&_I->f[d][k]; /* (*y)==v[d][k] */ if(INCI_LE(*y,x)) { if(INCI_EQ(x,*y)) { *v=INCI_OR(*v,u); break; /* x=y :: .f&=... */ } else {int l=k; *y=x; _I->f[d][k]=u;/* x>y :: y=x;f= */ while((++l) < (*n)) if(INCI_LE(_I->v[d][l],x)) {(*n)--; if(l<(*n)){_I->v[d][l]=_I->v[d][*n]; _I->f[d][l]=_I->f[d][*n];}} else assert(!INCI_LE(x,_I->v[d][l])); /* for(k++;k<*n;k++) if(!INCI_LE(x,_I->v[d][k])&&!INCI_LE(_I->v[d][k],x)) {Print_PPL(_P,"FACE_Info trouble");assert(0);} */ break;} } else if(INCI_LE(x,*y)) break; /* x new face */ { assert(kv[d][k]=x; _I->f[d][k]=u; (*n)++; } } } } d=_P->n; M=0; for(i=0;inf[i] * (1-2*(i%2)); if(M!=2*(d%2)){for(i=0;inf[i]);puts("=F-vector"); Print_PPL(_P,"PPL for incidence error");Print_FaceInfo(_P->n,_I); printf("d=%d euler=%d\n",d,M); assert(M==2*(d%2));} } /* ====================================================================== */ /* ========== ========== */ /* ========== G E N E R A L P U R P O S E R O U T I N E S ========== */ /* ========== ========== */ /* ====================================================================== */ void swap(int* i,int* j) {register int k; k=*i; *i=*j; *j=k;} int diff(const void *a, const void *b){return *((int *) a) - *((int *) b);} void Sort_VL(VertexNumList *_V){qsort(_V->v, _V->nv, sizeof(int), &diff);} void Make_VEPM(PolyPointList *_P, VertexNumList *_V, EqList *_E, PairMat PM){ int i, j; for (i=0;i<_E->ne;i++) for (j=0;j<_V->nv;j++) PM[i][j]=Eval_Eq_on_V(&_E->e[i],_P->x[_V->v[j]],_P->n); } int Transpose_PM(PairMat PM, PairMat DPM, int nv, int ne){ int i, j; if((nv>EQUA_Nmax)||(ne>VERT_Nmax)) return 0; for (i=0;inv>EQUA_Nmax) return 0; _DE->ne=_V->nv; for (i=0;i<_V->nv;i++){ for (j=0;j<_P->n;j++) _DE->e[i].a[j]=_P->x[_V->v[i]][j]; _DE->e[i].c=1; } return 1; } #define LLong_EEV (1) /* 1 @ [4662 4 20 333 422 1554 2329] */ #define TEST_EEV (0) /* compare Long to LLong EEV */ Equation EEV_To_Equation(Equation *_E1, Equation *_E2, Long *_V, int n){ /* Calculate the equation spanned by _V and the intersection of _E1, _E2 */ int i; Long l, m, g; Equation Eq; l=Eval_Eq_on_V(_E2,_V,n); m=Eval_Eq_on_V(_E1,_V,n); g=NNgcd(l,m); assert(g); l/=g; m/=g; #if ((!(LLong_EEV))||(TEST_EEV)) /* Long version */ for(i=0;ia[i]-m*_E2->a[i]; { int gcd=Eq.c=l*_E1->c-m*_E2->c; for(i=0;ia[i])-((LLong)m)*((LLong)_E2->a[i]); G=C=((LLong) l)*((LLong)_E1->c)-((LLong)m)*((LLong)_E2->c); for(i=0;ia[i]);printf(" %d = E1\n",_E1->c); for(i=0;ia[i]);printf(" %d = E2\n",_E2->c); for(i=0;ic; while(i--) p+=V[i]*E->a[i]; return p; } Long DualBraP1(Long *X, Long *Y, int n){ Long p=1; while(n--) p+=X[n] * Y[n]; return (Long) p; } Long CompareEq(Equation *X, Equation *Y, int n) { /* return "X-Y"; */ Long d; while(n--) if((d=X->a[n]-Y->a[n])) return d; return X->c-Y->c; } int Vec_Greater_Than(Long *X, Long *Y, int i){ /* return 1 iff `X > Y' */ while(i--) {if(X[i]>Y[i]) return 1; if(X[i] Y' */ Long z; while(i--) {z=X[i]; X[i]=Y[i]; Y[i]=z;} } int Ref_Equations(EqList *_F){ int i; for (i=0;i<_F->ne;i++) if (_F->e[i].c!=1) return 0; return 1; } int Span_Check(EqList *_F, EqList *H, int *n){ int i, j; for(i=0;ine;i++){ for(j=0;j<_F->ne;j++) if (!CompareEq(&(H->e[i]),&(_F->e[j]),*n)) break; if(j==_F->ne) return 0; } /* didn't find H[i] among the F's */ return 1; } int IsGoodCEq(Equation *_E, PolyPointList *_P, VertexNumList *_V){ int i=_V->nv; Long s; while(!(s=Eval_Eq_on_V(_E, _P->x[_V->v[--i]], _P->n))); if(s < 0) { int j=_P->n; while(j--) _E->a[j]=-_E->a[j]; _E->c=-_E->c; } while(i) if(Eval_Eq_on_V(_E, _P->x[_V->v[--i]], _P->n) < 0) return 0; return 1; } int Search_New_Vertex(Equation *_E, PolyPointList *_P){ int i, v=0; Long *X=_P->x[0], x=Eval_Eq_on_V(_E,X,(_P->n)); for(i=1;i<_P->np;i++) { Long *Y=_P->x[i], y=Eval_Eq_on_V(_E,Y,(_P->n)); if(y>x) continue; if(y==x) if(Vec_Greater_Than(X,Y,_P->n)) continue; v=i; X=Y; x=y; } return v; } void Sort_PPL(PolyPointList *_P, VertexNumList *_V){ /* Vertices first, IP last */ int i,j; for (i=0;i<_V->nv;i++){ Swap_Vecs(_P->x[i], _P->x[_V->v[i]], _P->n); for (j=i+1;j<_V->nv;j++) if (_V->v[j]==i) _V->v[j]=_V->v[i]; _V->v[i]=i;} for (i=_V->nv;i<_P->np-1;i++) if(Vec_is_zero(_P->x[i], _P->n)){ Swap_Vecs(_P->x[i], _P->x[_P->np-1], _P->n); return;} } int EL_to_PPL(EqList *_E, PolyPointList *_P, int *n){ int i,j; for (i=0;i<_E->ne;i++){ if (_E->e[i].c!=1) {_P->np=0; return 0;} for (j=0;j<*n;j++) _P->x[i][j]=_E->e[i].a[j];} _P->np=_E->ne; _P->n=*n; return 1; } /* ====================================================================== */ /* ========== ========== */ /* ========== S T A R T -- S I M P L E X ========== */ /* ========== ========== */ /* ====================================================================== */ /* return 0 <=> max.dim., E.ne==P.n+1, made Simplex of Vertices of P; * * return (P.n-E.ne) == codim. > 0 <=> E.ne defining equations on E; */ /* #define NEW_START_SIMPLEX (1) 1 @ [16644 1 38 439 2315 5548 8303] */ #define VERT_WITH_MAX_DISTANCE (0) /* 0 @ [1845 2 15 97 247 610 874] */ #define LONG_EQ_FIRST (0) /* 0 @ [3425 2 7 137 429 1141 1709] */ #define TEST_GLZ_EQ (0) /* trace StartSimplex EQs */ Long VZ_to_Base(Long *V,int *d,Long M[POLY_Dmax][POLY_Dmax]) /* 0 iff V=0 */ { int p[POLY_Dmax], i, j, J=0; Long g=0, W[POLY_Dmax], *G[POLY_Dmax]; for(i=0;i<*d;i++) if(V[i]) {W[J]=V[i]; G[J]=M[i]; p[J++]=i;} else for(j=0;j<*d;j++) M[i][j]=(i==j); if(J) if(p[0]) { G[0]=M[0]; for(j=0;j<*d;j++) M[p[0]][j]=(j==0);} if(J>1) g=W_to_GLZ(W,&J,G); else if(J){g=*W; M[0][0]=0; M[0][p[0]]=1;} if(J>1) { for(i=0;i=0;j--) G[i][j] = (V[j]) ? G[i][--I] : 0; assert(I==0);} } return g; } int OrthBase_red_by_V(Long *V, int *d, Long A[][POLY_Dmax], int *r, Long B[][POLY_Dmax]) { int i, j, k; Long W[POLY_Dmax], G[POLY_Dmax][POLY_Dmax]; for(i=0;i<*r;i++) {int j; W[i]=0; for(j=0;j<*d;j++) W[i]+=A[i][j]*V[j];} assert( VZ_to_Base(W,r,G) ); for(i=0;i<*r-1;i++) for(k=0;k<*d;k++) { B[i][k]=0; for(j=0;j<*r;j++) B[i][k]+=G[i+1][j]*A[j][k]; } #if (TEST_GLZ_EQ) printf("A -> B ... V = "); for(k=0;k<*d;k++) printf(" %5d",V[k]); printf(" W=");for(k=0;k<*r;k++)printf(" %5d",W[k]);puts(""); {int a,b; for(a=0;a<*r-1;a++){for(b=0;b<*d;b++)printf(" %5d",A[a][b]); printf(" =A B= ");for(b=0;b<*d;b++)printf(" %5d",B[a][b]); puts("");}for(b=0;b<*d;b++)printf(" %5d",A[a][b]);printf(" =A\n");} #endif return (*r)--; } int New_Start_Vertex(Long *V0,Long *Ea, PolyPointList *P,int *v) /* P.x[v] */ { Equation E; int i, n=0, p=0; Long d, dn=0, dp=0, *Xn=P->x[0], *Xp=Xn; for(i=0;in;i++) E.a[i]=Ea[i]; E.c=0; E.c=-Eval_Eq_on_V(&E,V0,P->n); d=Eval_Eq_on_V(&E,P->x[0],P->n); if(d>0) dp=d; if(d<0) dn=d; for(i=1;inp;i++) { d=Eval_Eq_on_V(&E,P->x[i],P->n); if(d==0) continue; if(d==dp) if(Vec_Greater_Than(P->x[i],Xp,P->n)) Xp=P->x[p=i]; if(d>dp) {dp=d; Xp=P->x[p=i];} if(d==dn) if(Vec_Greater_Than(P->x[i],Xn,P->n)) Xn=P->x[n=i]; if(dx[n=i];} } if(dp) if(dn) /* points on both sides */ #if (VERT_WITH_MAX_DISTANCE) {if(dp+dn>0) *v=p; else *v=n;} #else {if(dp+dn>0) *v=n; else *v=p;} #endif else *v=p; /* d >=0 */ else if(dn) *v=n; /* d <=0 */ else return 0; /* for(i=0;in;i++) printf(" %d ",Xp[i]); printf(" = Xp Xn ="); for(i=0;in;i++) printf(" %d ",Xn[i]); printf(" \n"); */ return 1; } /* ========= GLZ_Start_Simplex() => return codimension ======= */ int GLZ_Start_Simplex(PolyPointList *_P, VertexNumList *_V, CEqList *_C) { int i, x=0, y=0, *VN=_V->v, *d=&_P->n, r=*d, b[POLY_Dmax]; Long *X=_P->x[x], *Y=_P->x[y], XX=0, YY=0, B[(POLY_Dmax*(POLY_Dmax+1))/2][POLY_Dmax], W[POLY_Dmax]; if(_P->np<2) { for(x=0;x<_P->n;x++) for(y=0;y<_P->n;y++) _C->e[x].a[y]=(x==y); assert(_P->np>0); for(x=0;x<_P->n;x++) _C->e[x].c=-_P->x[0][x]; return _C->ne=_P->n; } for(i=1; i<_P->np; i++) { Long *Z=_P->x[i]; if(Vec_Greater_Than(X,Z,_P->n)) X=_P->x[x=i]; /* (x_n)-max: VN[0] */ if(Vec_Greater_Than(Z,Y,_P->n)) Y=_P->x[y=i]; /* (x_n)-min: VN[1] */ } assert(x!=y); /* at this point I need two different vertices */ for(i=0;i<*d;i++) { Long Xi=(X[i]>0) ? X[i]: -X[i], Yi=(Y[i]>0) ? Y[i]: -Y[i]; if(Xi>XX)XX=Xi; if(Yi>YY)YY=Yi;} if(YYnv=2; y=VN[1]; X=_P->x[VN[0]];Y=_P->x[VN[1]]; for(i=0;i<*d;i++) b[i]=(i*(2*(*d)-i+1))/2; for(x=0;x<*d;x++) for(i=0;i<*d;i++) B[x][i]=(x==i); /* b[i+1]-b[i]=d-i */ for(x=1;x<*d;x++) { for(i=0;i<*d;i++) W[i]=_P->x[y][i]-X[i]; OrthBase_red_by_V(W,d,&B[b[x-1]],&r,&B[b[x]]); for(i=0;iv[_V->nv++]=y; /* x = dim(span) < d */ } if(x<*d) { for(y=0;ye[y]; Long *Z=B[b[x]+y]; E->c=0; for(i=0;i<*d;i++) E->a[i]=Z[i]; E->c=-Eval_Eq_on_V(E,X,_P->n); } return _C->ne=r; } else { Equation *E=_C->e; Long *Z=B[b[*d-1]]; E->c=0; _C->ne=2; for(i=0;i<*d;i++)E->a[i]=Z[i]; E->c=-Eval_Eq_on_V(E,X,_P->n); if(Eval_Eq_on_V(E,_P->x[_V->v[*d]],_P->n)<0) { for(i=0;i<*d;i++)E->a[i]=-Z[i]; E->c*=-1;} X=_P->x[_V->v[r=*d]]; for(x=1;x<*d;x++) /* now the 2nd equation */ { Y=_P->x[_V->v[x-1]]; for(i=0;i<*d;i++) W[i]=X[i]-Y[i]; OrthBase_red_by_V(W,d,&B[b[x-1]],&r,&B[b[x]]); } E=&_C->e[1]; E->c=0; for(i=0;i<*d;i++)E->a[i]=Z[i]; E->c=-Eval_Eq_on_V(E,X,_P->n); XX=Eval_Eq_on_V(E,_P->x[_V->v[*d-1]],_P->n); assert(XX); if(XX<0) {for(i=0;i<*d;i++)E->a[i]=-Z[i]; E->c*=-1;} for(x=*d-2;x>=0;x--) /* omit vertex #x */ { r=*d-x; for(y=x+1;y<*d;y++) { Y=_P->x[_V->v[y]]; for(i=0;i<*d;i++) W[i]=X[i]-Y[i]; OrthBase_red_by_V(W,d,&B[b[y-1]],&r,&B[b[y]]); } E=&_C->e[(_C->ne)++]; E->c=0; for(i=0;i<*d;i++)E->a[i]=Z[i]; E->c=-Eval_Eq_on_V(E,X,_P->n); XX=Eval_Eq_on_V(E,_P->x[_V->v[x]],_P->n); assert(XX); if(XX<0) {for(i=0;i<*d;i++)E->a[i]=-Z[i]; E->c*=-1;} } } assert(*d+1==_C->ne); for(x=0;x<_C->ne;x++) for(i=0;i<=*d;i++) assert((x==i)==(0!=Eval_Eq_on_V(&_C->e[x],_P->x[_V->v[*d-i]],_P->n))); return 0; } /* ====================================================================== */ /* ========== ========== */ /* ========== P O L Y H E D R O N A N A L Y S I S ========== */ /* ========== ========== */ /* ====================================================================== */ void Make_New_CEqs(PolyPointList *_P, VertexNumList *_V, CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I){ int i,j, Old_C_ne=_C->ne; static CEqList Bad_C; static INCI Bad_C_I[CEQ_Nmax]; #if (SHOW_NEW_CEq) static int init; static clock_t CLOCK1; static time_t DATE1; if(!init){init=1; CLOCK1=clock(); DATE1=time(NULL);} printf("V=%d F=%d: Ceq=%d",_V->nv,_F->ne,_C->ne);fflush(stdout); #endif Bad_C.ne=_C->ne=0; for (i=0;ie[i],_P->x[_V->v[_V->nv-1]],_P->n); CEq_I[i]=INCI_PN(CEq_I[i],dist); if (dist<0) {Bad_C.e[Bad_C.ne]=_C->e[i]; Bad_C_I[Bad_C.ne++]=CEq_I[i];} else {_C->e[_C->ne]=_C->e[i]; CEq_I[_C->ne++]=CEq_I[i];}} #if (SHOW_NEW_CEq) printf("=%dg+%db",_C->ne,Bad_C.ne);fflush(stdout); #endif Old_C_ne=_C->ne; for (i=0;i<_F->ne;i++) F_I[i]= INCI_PN(F_I[i],Eval_Eq_on_V(&_F->e[i],_P->x[_V->v[_V->nv-1]],_P->n)); for (j=0;j<_F->ne;j++) if (!INCI_M2(F_I[j])) for (i=0;in-1) continue; for (k=0;kne;k++) if (INCI_LE(New_Face,F_I[k])) if (k!=j) break; if (k!=_F->ne) continue; assert(_C->nene]=INCI_PN(INCI_D2(New_Face),0); _C->e[_C->ne]=EEV_To_Equation(&(Bad_C.e[i]),&(_F->e[j]), _P->x[_V->v[_V->nv-1]],_P->n); assert(IsGoodCEq(&(_C->e[_C->ne++]),_P,_V));} for (j=0;j=0;i--){ INCI New_Face=INCI_AND(Bad_C_I[i],CEq_I[j]); int k; if (INCI_abs(New_Face)<_P->n-1) continue; for (k=0;kne;k++) if (INCI_LE(New_Face,F_I[k])) break; if (k!=_F->ne) continue; assert(_C->nene]=INCI_PN(INCI_D2(New_Face),0); _C->e[_C->ne]=EEV_To_Equation(&(Bad_C.e[i]),&(_C->e[j]), _P->x[_V->v[_V->nv-1]],_P->n); assert(IsGoodCEq(&(_C->e[_C->ne++]),_P,_V));} #if (SHOW_NEW_CEq) {time_t DATE2=time(NULL); char sm[2]={'s',0}; int Rs= (int)difftime(DATE2,DATE1);if(Rs>999){Rs/=60; *sm='m';} printf(" done: C.ne=%d %d%s\n",_C->ne,Rs,sm);fflush(0);} #endif } #if MAX_BAD_EQ int IP_Search_Bad_Eq(CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I, PolyPointList *_P, int *_IP){ /* return 0 :: no bad eq. */ while(_C->ne--) { int j, M=_C->ne; /* INCI_LmR INCI_lex_GT */ for(j=0;j<_C->ne;j++) if(INCI_lex_GT(&CEq_I[j],&CEq_I[M])) M=j; for(j=0;j<_P->np;j++) if(Eval_Eq_on_V(&(_C->e[M]),_P->x[j],_P->n) < 0) { INCI AI=CEq_I[M]; Equation AE=_C->e[M]; CEq_I[M]=CEq_I[_C->ne]; _C->e[M]=_C->e[_C->ne]; CEq_I[_C->ne]=AI; _C->e[_C->ne]=AE; return ++_C->ne;} if(_C->e[M].c < 1) {*_IP=0; return 1;} assert(_F->nene,_C->ne); fflush(stdout); */ _F->e[_F->ne]=_C->e[M]; F_I[_F->ne++]=CEq_I[M]; if(M<_C->ne) {_C->e[M]=_C->e[_C->ne]; CEq_I[M]=CEq_I[_C->ne];} } return 0; } int FE_Search_Bad_Eq(CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I, PolyPointList *_P, int *_IP){ /* return 0 :: no bad eq. */ while(_C->ne--) { int j, M=_C->ne; /* INCI_LmR INCI_lex_GT */ for(j=0;j<_C->ne;j++) if(INCI_lex_GT(&CEq_I[j],&CEq_I[M])) M=j; for(j=0;j<_P->np;j++) if(Eval_Eq_on_V(&(_C->e[M]),_P->x[j],_P->n) < 0) { INCI AI=CEq_I[M]; Equation AE=_C->e[M]; CEq_I[M]=CEq_I[_C->ne]; _C->e[M]=_C->e[_C->ne]; CEq_I[_C->ne]=AI; _C->e[_C->ne]=AE; return ++_C->ne;} if(_C->e[M].c < 1) *_IP=0; assert(_F->nene,_C->ne); fflush(stdout); */ _F->e[_F->ne]=_C->e[M]; F_I[_F->ne++]=CEq_I[M]; if(M<_C->ne) {_C->e[M]=_C->e[_C->ne]; CEq_I[M]=CEq_I[_C->ne];} } return 0; } #else int IP_Search_Bad_Eq(CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I, PolyPointList *_P, int *_IP){ /* return 0 :: no bad eq. */ while(_C->ne--) { int j; for(j=0;j<_P->np;j++) if(Eval_Eq_on_V(&(_C->e[_C->ne]),_P->x[j],_P->n) < 0) return ++_C->ne; if(_C->e[_C->ne].c < 1) { *_IP=0; return 1;} assert(_F->nee[_F->ne]=_C->e[_C->ne]; F_I[_F->ne++]=CEq_I[_C->ne];} return 0; } int FE_Search_Bad_Eq(CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I, PolyPointList *_P, int *_IP){ /* return 0 :: no bad eq. */ while(_C->ne--) { int j; for(j=0;j<_P->np;j++) if(Eval_Eq_on_V(&(_C->e[_C->ne]),_P->x[j],_P->n) < 0) return ++_C->ne; if(_C->e[_C->ne].c < 1) *_IP=0; assert(_F->nee[_F->ne]=_C->e[_C->ne]; F_I[_F->ne++]=CEq_I[_C->ne];} return 0; } #endif int REF_Search_Bad_Eq(CEqList *_C, EqList *_F, INCI *CEq_I, INCI *F_I, PolyPointList *_P, int *_REF){ /* return 0 :: no bad eq. */ while(_C->ne--) { int j; for(j=0;j<_P->np;j++) if(Eval_Eq_on_V(&(_C->e[_C->ne]),_P->x[j],_P->n) < 0) return ++_C->ne; if(_C->e[_C->ne].c != 1) { *_REF=0; return 1;} assert(_F->nee[_F->ne]=_C->e[_C->ne]; F_I[_F->ne++]=CEq_I[_C->ne];} return 0; } int Finish_Find_Equations(PolyPointList *_P, VertexNumList *_V, EqList *_F, CEqList *_CEq, INCI *F_I, INCI *CEq_I){ int IP=1; while(0<=_CEq->ne) if (FE_Search_Bad_Eq(_CEq,_F,CEq_I,F_I,_P,&IP)){ assert(_V->nvv[_V->nv++]=Search_New_Vertex(&(_CEq->e[_CEq->ne-1]),_P); Make_New_CEqs(_P,_V,_CEq,_F,CEq_I,F_I); } return IP; } int Find_Equations(PolyPointList *_P, VertexNumList *_V, EqList *_F){ /* return: IP, finds Vertices and Equations for _P even if not IP */ int i; CEqList *CEq = (CEqList *) malloc(sizeof(CEqList)); INCI *CEq_I = (INCI *) malloc(sizeof(INCI)*CEQ_Nmax); INCI *F_I = (INCI *) malloc(sizeof(INCI)*EQUA_Nmax); CEq->ne=0; if((CEq==NULL)||(CEq_I==NULL)||(F_I==NULL)) { printf("Allocation failure in Find_Equations\n"); exit(0);} if (GLZ_Start_Simplex(_P, _V, CEq)) { _F->ne=CEq->ne; for(i=0;i<_F->ne;i++) _F->e[i]=CEq->e[i]; free(CEq); free(CEq_I); free(F_I); return 0;} _F->ne=0; for (i=0;ine;i++) if(INCI_abs(CEq_I[i]=Eq_To_INCI(&(CEq->e[i]),_P,_V))<_P->n) {fprintf(outFILE,"Bad CEq in Find_Equations"); exit(0);} i=Finish_Find_Equations(_P, _V, _F, CEq, F_I, CEq_I); free(CEq); free(CEq_I); free(F_I); return i; } int Finish_IP_Check(PolyPointList *_P, VertexNumList *_V, EqList *_F, CEqList *_CEq, INCI *F_I, INCI *CEq_I){ int IP=1; while(0<=_CEq->ne) if (IP_Search_Bad_Eq(_CEq,_F,CEq_I,F_I,_P,&IP)){ if(!IP) return 0; /* found d<=0 */ assert(_V->nvv[_V->nv++]=Search_New_Vertex(&(_CEq->e[_CEq->ne-1]),_P); Make_New_CEqs(_P,_V,_CEq,_F,CEq_I,F_I); } return 1; } int IP_Check(PolyPointList *_P, VertexNumList *_V, EqList *_F){ int i; CEqList *CEq = (CEqList *) malloc(sizeof(CEqList)); INCI *CEq_I = (INCI *) malloc(sizeof(INCI)*CEQ_Nmax); INCI *F_I = (INCI *) malloc(sizeof(INCI)*EQUA_Nmax); if((CEq==NULL)||(CEq_I==NULL)||(F_I==NULL)) { printf("Allocation failure in IP_Check\n"); exit(0);} if (GLZ_Start_Simplex(_P, _V, CEq)) { free(CEq); free(CEq_I); free(F_I); return 0;} for (i=0;ine;i++) if(INCI_abs(CEq_I[i]=Eq_To_INCI(&(CEq->e[i]),_P,_V))<_P->n) {fprintf(outFILE,"Bad CEq in IP_Check"); exit(0);} _F->ne=0; i=Finish_IP_Check(_P, _V, _F, CEq, F_I, CEq_I); free(CEq); free(CEq_I); free(F_I); return i; } int Finish_REF_Check(PolyPointList *_P, VertexNumList *_V, EqList *_F, CEqList *_CEq, INCI *F_I, INCI *CEq_I){ int REF=1; while(0<=_CEq->ne) if(REF_Search_Bad_Eq(_CEq,_F,CEq_I,F_I,_P,&REF)){ if(!REF) return 0; /* found d!=1 */ assert(_V->nvv[_V->nv++]=Search_New_Vertex(&(_CEq->e[_CEq->ne-1]),_P); Make_New_CEqs(_P,_V,_CEq,_F,CEq_I,F_I); } return 1; } int Ref_Check(PolyPointList *_P, VertexNumList *_V, EqList *_F){ int i; CEqList *CEq = (CEqList *) malloc(sizeof(CEqList)); INCI *CEq_I = (INCI *) malloc(sizeof(INCI)*CEQ_Nmax); INCI *F_I = (INCI *) malloc(sizeof(INCI)*EQUA_Nmax); if((CEq==NULL)||(CEq_I==NULL)||(F_I==NULL)) { printf("Allocation failure in Ref_Check\n"); exit(0);} if (GLZ_Start_Simplex(_P, _V, CEq)) { free(CEq); free(CEq_I); free(F_I); return 0;} for (i=0;ine;i++) CEq_I[i]=Eq_To_INCI(&(CEq->e[i]),_P,_V); _F->ne=0; i=Finish_REF_Check(_P, _V, _F, CEq, F_I, CEq_I); free(CEq); free(CEq_I); free(F_I); return i; } /* ====================================================================== */ /* ========== ========== */ /* ========== D U A L P O L Y & C O M P L E T I O N ========== */ /* ========== ========== */ /* ====================================================================== */ void Make_Dual_Poly(PolyPointList *_P, VertexNumList *_V, EqList *_E, PolyPointList *_DP){ EqList DE; PairMat PM, DPM; Make_VEPM(_P,_V,_E,PM); Transpose_PM(PM, DPM, _V->nv, _E->ne); VNL_to_DEL(_P,_V,&DE); _DP->n=_P->n; _DP->np=0; Complete_Poly(DPM, &DE, _E->ne, _DP); } void add_for_completion(Long *yDen, Long Den, EqList *_E, PolyPointList *_CP, int *old_np){ int i,n=_CP->n; Long yold[POLY_Dmax]; if(Den>1) for(i=0;ine;i++) if (Eval_Eq_on_V(&(_E->e[i]), yold, n) < 0) return; for (i=0;i<*old_np;i++) if (Vec_Equal(_CP->x[i],yold,n)) return; assert(_CP->npx[_CP->np][i]=yold[i]; _CP->np++; } void Compute_InvMat(int n, EqList *_E, int OrdFac[VERT_Nmax], int BasFac[POLY_Dmax], Long *Den, Long InvMat[POLY_Dmax][POLY_Dmax]){ /* Find first POLY_Dmax linearly independent facets + Inverse Matrix */ LRat ind[POLY_Dmax][POLY_Dmax], x[POLY_Dmax], y[POLY_Dmax], f, PInvMat[POLY_Dmax][POLY_Dmax]; int i, j, k, l, rank=0, one[POLY_Dmax]; for (i=0;ie[OrdFac[i]].a[j]); for (j=0;j-1){ for (k=0;ke[BasFac[j]].a[k])); if (s!=*Den*(i==j)) { puts("something wrong in Make_Dual_Poly"); exit(0);}}} } void Complete_Poly(PairMat VPM, EqList *_E, int nv, PolyPointList *_CP){ int i, j, k, InsPoint, n=_CP->n, old_np=_CP->np; Long MaxDist[EQUA_Nmax], InvMat[POLY_Dmax][POLY_Dmax], Den=1; Long yDen[POLY_Dmax]; int OrdFac[VERT_Nmax], BasFac[POLY_Dmax], position[POLY_Dmax]; /*_CP->np=0;*/ /* Calculate maximal distances from facets of Delta^* (Vertices of Delta) */ for (i=0;i<_E->ne;i++) { MaxDist[i]=0; for (j=0;jne;i++){ InsPoint=i; while (InsPoint&&(MaxDist[i]InsPoint;j--) OrdFac[j]=OrdFac[j-1]; OrdFac[InsPoint]=i; } Compute_InvMat(n, _E, OrdFac, BasFac, &Den, InvMat); /* printf("Den=%ld ", Den); mostly 1 or 2!!! */ /* Examine all integer points of parallelogram: */ /* The basic structure of the algorithm is: for (k=0;k=0){ position[k]++; DO AT position; for(k=n-1;((position[k]==MaxDist[BasFac[k]]-1)&&(k>=0));k--) position[k]=-1; } / * sets k to the highest value where pos.[k] wasn't the max value; resets the following max values to min values */ /* Quantities linear in position can be changed with every change of position (here: yDen) */ for(i=0;ie[BasFac[k]].c; for(i=0;ie[BasFac[k]].c*InvMat[i][k]; } position[n-1]=-_E->e[BasFac[n-1]].c-1; for(i=0;ie[BasFac[k]].c+1)*InvMat[i][n-1]; while(k>=0){ position[k]++; for(i=0;i=0);k--){ if (position[k]!=MaxDist[BasFac[k]]-_E->e[BasFac[k]].c) break; position[k]=-_E->e[BasFac[k]].c; for (i=0;inf[i];j++) if(INCI_EQ(x,_I->v[i][j])) {_I->dip[i][j] += mult; return;} } void RaiseNip(INCI x, FaceInfo *_I, int n){ int i, j; for(i=n-1;i>=0;i--) for(j=0;j<_I->nf[i];j++) if(INCI_EQ(x,_I->f[i][j])) {_I->nip[i][j]++; return;} } void Make_FaceIPs(PolyPointList *_P, VertexNumList *_V, EqList *_E, PolyPointList *_DP, FaceInfo *_I){ /* compute IP's of faces by computing Incidences for all points and * comparing with Incidences of dual faces */ int i, j, k; INCI x; for(i=0;i<_P->n;i++) for(j=0;j<_I->nf[i];j++) { _I->nip[i][j]=0; _I->dip[i][j]=0; } for(k=0;k<_P->np;k++){ x=INCI_0(); for(i=0;i<_E->ne;i++) x=INCI_PN(x,Eval_Eq_on_V(&(_E->e[i]),_P->x[k],_P->n)); RaiseNip(x, _I, _P->n);} for (k=0;k<_DP->np;k++){ x=INCI_0(); for(i=0;i<_V->nv;i++) x=INCI_PN(x,DualBraP1(_P->x[_V->v[i]],_DP->x[k],_P->n)); RaiseDip(x, _I, _P->n, 1);} } void PrintFaceIPs(PolyPointList *_P,FaceInfo *_I){ int i,j, M=_P->n-1; for(i=0;i<=M;i++) { printf("ip[%d]:",i); for(j=0;j<_I->nf[i];j++) printf(" %ld",(long) _I->nip[i][j]); puts(""); } for(i=0;i<=M;i++) { printf("dip[%d]:",i); for(j=0;j<_I->nf[i];j++)printf(" %ld",(long) _I->dip[i][j]); puts(""); } } void Eval_BaHo(FaceInfo *_I, BaHo *_BH){ /* Calculate Hodge/Picard numbers from FaceInfo */ int i,j, n=_BH->n; int *h1; _BH->cor=0; h1=_BH->h1; for(i=0;inp-n-1; for (i=0;i<_I->nf[0];i++) h1[1]-=_I->dip[0][i]; for (j=1;jnf[j];i++) { h1[j]+=_I->dip[j][i]*_I->nip[j][i]; _BH->cor+=_I->dip[j][i]*_I->nip[j][i];} if (n==3) _BH->pic=h1[1]; for (i=0;i<_I->nf[n-1];i++) h1[n-2]-=_I->nip[n-1][i]; h1[n-2]+=_BH->mp-n-1; if (n==5) _BH->h22=44+4*h1[1]+4*h1[3]-2*h1[2]; } void RC_Calc_BaHo(PolyPointList *_P, VertexNumList *_V, EqList *_E, PolyPointList *_DP, BaHo *_BH){ /* Needs reflexive and complete _P and _DP */ FaceInfo *_FI=(FaceInfo *) malloc(sizeof(FaceInfo)); if(_FI==NULL) {printf("RC_Calc_BaHo: Unable to allocate _FI\n"); exit(0);} _BH->mp=_P->np; _BH->mv=_V->nv; _BH->nv=_E->ne; _BH->np=_DP->np; _BH->n=_P->n; Make_Incidence(_P, _V, _E, _FI); Make_FaceIPs(_P, _V, _E, _DP, _FI); Eval_BaHo(_FI, _BH); free(_FI); } void Qadd_for_completion(Long *yDen, Long Den, int n, int *np, EqList *_E, FaceInfo *_I){ int i; Long y[POLY_Dmax]; INCI x = INCI_0(); for(i=0;ine;i++) x=INCI_PN(x,Eval_Eq_on_V(&(_E->e[i]),y,n)); RaiseDip(x, _I, n, 1); (*np)++; } void lastline(Long *EyD, Long *yDen, Long Den, EqList *_E, int n, int *np, Long MD /*MaxDist[BasFac[n-1]*/, Long IME[POLY_Dmax][EQUA_Nmax], Long InvMat[POLY_Dmax][POLY_Dmax], FaceInfo *_I){ int i, j, l, lmin=0, lmax=MD; INCI xmin, xmax; Long y[POLY_Dmax]; for (j=0;j<_E->ne;j++) if ((EyD[j]<0)&&(IME[n-1][j]<=0)) return; for (j=0;(j<_E->ne)&&(lmax >=lmin);j++) if (IME[n-1][j]<0) { l = EyD[j]/(-IME[n-1][j]); if (lmax > l) lmax = l;} else if ((IME[n-1][j]>0)&&(EyD[j]<0)){ l = 1 + (-1-EyD[j])/IME[n-1][j]; if (lmin < l) lmin = l;} if (lmax < lmin) return; if(Den>1) { for(i=0;ine;i++) xmin=INCI_PN(xmin,Eval_Eq_on_V(&(_E->e[i]),y,n)); RaiseDip(xmin, _I, n, 1); (*np)++; if (lmax == lmin) return; for(i=0;ine;i++) xmax=INCI_PN(xmax,Eval_Eq_on_V(&(_E->e[i]),y,n)); RaiseDip(xmax, _I, n, 1); (*np)++; if (lmax == lmin +1) return; RaiseDip(INCI_AND(xmin,xmax), _I, n, lmax - lmin - 1); (*np) += lmax - lmin - 1; } void QComplete_Poly(PairMat VPM, EqList *_E, int nv, int n, int *np, FaceInfo *_I){ int i, j, k, InsPoint; Long MaxDist[EQUA_Nmax], InvMat[POLY_Dmax][POLY_Dmax], Den=1; Long yDen[POLY_Dmax], EyD[EQUA_Nmax], IME[POLY_Dmax][EQUA_Nmax]; /* IME[k][j] = InvMat [k] * _E[j] */ int OrdFac[VERT_Nmax], BasFac[POLY_Dmax], position[POLY_Dmax]; for(i=0;inf[i];j++) _I->dip[i][j]=0; (*np) = 0; /* Calculate maximal distances from facets of Delta^* (Vertices of Delta) */ for (i=0;i<_E->ne;i++) { MaxDist[i]=0; for (j=0;jne;i++){ InsPoint=i; while (InsPoint&&(MaxDist[i]InsPoint;j--) OrdFac[j]=OrdFac[j-1]; OrdFac[InsPoint]=i; } Compute_InvMat(n, _E, OrdFac, BasFac, &Den, InvMat); for (k=0;kne;j++){ IME[k][j] = 0; for(i=0;ie[j].a[i];} /* Examine all integer points of parallelogram: */ /* The basic structure of the algorithm is: for (k=0;k=0){ position[k]++; DO AT position; for(k=n-1;((position[k]==MaxDist[BasFac[k]]-1)&&(k>=0));k--) position[k]=-1; } / * sets k to the highest value where pos.[k] wasn't the max value; resets the following max values to min values */ /* Quantities linear in position can be changed with every change of position (here: yDen) */ for(i=0;ie[BasFac[k]].c; for(i=0;ie[BasFac[k]].c*InvMat[i][k];} position[n-2]=-_E->e[BasFac[n-2]].c-1; for(i=0;ie[BasFac[k]].c+1)*InvMat[i][k]; yDen[i]-=_E->e[BasFac[n-1]].c*InvMat[i][n-1];} for (j=0;j<_E->ne;j++) { EyD[j]=_E->e[i].c * Den; for(i=0;ie[j].a[i]; } while(k>=0){ position[k]++; for (i=0;ine;j++) EyD[j] += IME[k][j]; lastline(EyD, yDen, Den, _E, n, np, MaxDist[BasFac[n-1]], IME, InvMat, _I); for (k=n-2;(k>=0);k--){ if (position[k]!=MaxDist[BasFac[k]]-_E->e[BasFac[k]].c) break; position[k]=-_E->e[BasFac[k]].c; for (i=0;ine;j++) EyD[j] -= MaxDist[BasFac[k]] * IME[k][j];}} } void Compute_nip(PolyPointList *_P, EqList *_E, FaceInfo *_I){ /* compute IP's of faces by computing Incidences for all points and * comparing with Incidences of dual faces */ int i, j, k; INCI x; for(i=0;i<_P->n;i++) for(j=0;j<_I->nf[i];j++) _I->nip[i][j]=0; for(k=0;k<_P->np;k++){ x=INCI_0(); for(i=0;i<_E->ne;i++) x=INCI_PN(x,Eval_Eq_on_V(&(_E->e[i]),_P->x[k],_P->n)); RaiseNip(x, _I, _P->n);} } int QuickAnalysis(PolyPointList *_P, BaHo *_BH, FaceInfo *_FI){ VertexNumList V; EqList E; EqList DE; PairMat PM; PairMat DPM; //FaceInfo FI; int i; if (!IP_Check(_P,&V,&E)) return 0; _BH->mp=_P->np; _BH->mv=V.nv; _BH->nv=E.ne; _BH->np = 0; _BH->n=_P->n; for(i = 0; i < E.ne; i++) if (E.e[i].c != 1) return 1; Make_VEPM(_P,&V,&E,PM); if (!Transpose_PM(PM, DPM, V.nv, E.ne)) { fprintf(stderr,"Transpose_PM failed because #eq=%d > VERT_Nmax\n", E.ne); exit(0);} VNL_to_DEL(_P, &V, &DE); Make_Incidence(_P, &V, &E, _FI); Compute_nip(_P, &E, _FI); QComplete_Poly(DPM, &DE, E.ne, _P->n, &_BH->np, _FI); Eval_BaHo(_FI, _BH); return 1; } palp-2.21/LG.h0000664000177600017760000000321614572603263012423 0ustar skarkeskarke#define WZinput (1) /* WZ-input (in progress) */ #define W_Nmax (POLY_Dmax+1) #define min(a,b) (((a)<(b)) ? (a) : (b)) #define max(a,b) (((a)>(b)) ? (a) : (b)) #define Pint int /* type of coefficients in PolyCoeffList */ typedef struct {int n; int *e; Pint *c; int A;} PoCoLi; /* e=exp */ void AllocPoCoLi(PoCoLi *P); /* allocate e[P.A] and c[P.A] */ void Free_PoCoLi(PoCoLi *P); /* free P.e and P.c */ void Poly_Sum(PoCoLi *A,PoCoLi *B,PoCoLi *S); /* S = A+B */ void Poly_Dif(PoCoLi *A,PoCoLi *B,PoCoLi *D); /* D = A-B */ void PolyProd(PoCoLi *A,PoCoLi *B,PoCoLi *AB); /* AB = A*B */ int BottomUpQuot(PoCoLi *N,PoCoLi *D,PoCoLi *Q,PoCoLi *R); /* Q*D = N-R */ void PolyCopy(PoCoLi *X,PoCoLi *Y); /* Y = X */ void PrintPoCoLi(PoCoLi *P); void UnitPoly(PoCoLi *P); void Init1_xN(PoCoLi *P,int N); /* 1 - x^N */ void PoincarePoly(int N,int *w,int d, PoCoLi *PP, PoCoLi *Naux, PoCoLi *Raux); int IsDigit(char c); typedef struct {int d, N, z[POLY_Dmax][W_Nmax], m[POLY_Dmax], M, r, R;/* Ref */ Long w[W_Nmax], B[W_Nmax][POLY_Dmax], A[W_Nmax], rI[POLY_Dmax]; PolyPointList *P;} /* Eq: Ei.c=Ai Ei.a[]=Bi[]} */ /* 0<=A+B*x r=sum(w)/d rI=IP(r*P) n=(r,rI) */ Weight; typedef struct {int D,E,sts; int h[POLY_Dmax][POLY_Dmax];} VaHo; int Read_W_PP(Weight *, PolyPointList *); int Trans_Check(Weight); void LGO_VaHo(Weight *,VaHo *); void Write_Weight(Weight *_W); void Write_WH(Weight *_W, BaHo *_BH, VaHo *_VH, int rc, int tc, PolyPointList *_P, VertexNumList *_V, EqList *_E); void Make_Poly_Points(Weight *_W_in, PolyPointList *_PP); Long V_to_G_GI(Long *V,int d, Long G[][POLY_Dmax],Long GI[][POLY_Dmax]); palp-2.21/Polynf.c0000664000177600017760000037675414572603263013407 0ustar skarkeskarke#include "Global.h" #include "Rat.h" #define SORT_CWS (0) #define FIB_PERM (27) /* print permutation for p<=# */ #define SMOOTH (1) /* print only regular simplicial */ #define NON_REF (1) /* allow non-reflexive input */ #define SSR_PRINT (0) /* SemiSimpleRoots, 2: also noFIPs */ #define BARY_PRINT (1) /* print if BARY_ZERO */ #define ZEROSUM_PRINT (1) /* 1::Psum 2::kPsum */ #define KP_VALUE ((P->n+1)/2) /* (P->n+1)/2 is sufficient */ #define KP_PRINT (3) /* print if sum kP !=0 at this k */ #define KP_EXIT ((P->n+1)/2) /* exit if !=0 above this k */ #undef OLD_IPS #define ALL_FANOS_BUT_INEFFICIENT (0) #define SL_Long LLong /* has same problems as REgcd */ #if (POLY_Dmax < 5) #define NFX_Limit 903 /* 138b->255 153e->279 165c->327 */ #define X_Limit 9999 /* 178c->375 218->399,462,483 */ #define VPM_Limit 9999 #else #define NFX_Limit 1631721 /* 1631721 1 903 37947 233103 543907 815860 */ #define X_Limit 3263441 /* 3263442 1 1806 75894 466206 1087814 1631721 */ #define VPM_Limit 3263442 /* 1631721 1 903 37947 233103 543907 815860 */ #endif /* ------ some flags for testing ------ */ #define TEST_GLZ_VS_SL (0) /* exit on difference: GL vs. SL */ #define SHOW_NFX_LIMIT (1) /* exit on NFX_LIMIT violation */ #undef WARN_BIG_NS /* [1152] ... 1152 = sym(24-cell) */ #undef SHOW_BIG_NS /* [1153] ... printf VPM and exit */ /* ------ local typedefs and headers ------ */ typedef struct {int C[VERT_Nmax], L[VERT_Nmax], s;} PERM; typedef struct {int nv, nf, ns;} vNF; #define Fputs(S) {fputs(S,outFILE);fputs("\n",outFILE);} /* ------ some useful routines ------ */ void NF_Coordinates(PolyPointList *_P, VertexNumList *_V, EqList *_F); int GLZ_Make_Trian_NF(Long X[][VERT_Nmax], int *n, int *nv, GL_Long G[POLY_Dmax][POLY_Dmax]); /* current=best */ int SL2Z_Make_Poly_NF(Long X[][VERT_Nmax], int *n, int *nv, SL_Long S[POLY_Dmax][POLY_Dmax]); /* previous=bad */ int Init_rVM_VPM(PolyPointList *P, VertexNumList *_V,EqList *_F,/* in */ int *d,int *v,int *f, Long VM[POLY_Dmax][VERT_Nmax], /* out */ Long VPM[VERT_Nmax][VERT_Nmax]); /* return reflexive */ void Eval_Poly_NF(int *d,int *v,int *f, Long VM[POLY_Dmax][VERT_Nmax], Long VPM[VERT_Nmax][VERT_Nmax], /* in */ Long pNF[POLY_Dmax][VERT_Nmax], int t); /* out */ void Make_VPM_NF(int *v, int *f, Long VPM[VERT_Nmax][VERT_Nmax], /* in */ PERM *CL,int *ns,Long VPM_NF[VERT_Nmax][VERT_Nmax]); /* out */ void Aux_pNF_from_vNF(PERM *CL,int *ns,int *v,int *d, Long VM[POLY_Dmax][VERT_Nmax], /* in */ Long pNF[POLY_Dmax][VERT_Nmax],int *t); /* out */ void New_pNF_Order(int *v,int *f,PERM *CL,int *ns,Long VPM_NF[][VERT_Nmax]); int Make_Poly_NF(PolyPointList *_P, VertexNumList *_V, EqList *_F, Long pNF[POLY_Dmax][VERT_Nmax]); /* 1 if reflexive */ /* ============================================================== */ int Aux_Make_Poly_NF(Long X[][VERT_Nmax], int *n, int *nv) { GL_Long G[POLY_Dmax][POLY_Dmax]; #if (TEST_GLZ_VS_SL) int i,j,x; SL_Long S[POLY_Dmax][POLY_Dmax];Long XS[POLY_Dmax][VERT_Nmax]; for(i=0;i<*n;i++)for(j=0;j<*nv;j++)XS[i][j]=X[i][j]; x=GLZ_Make_Trian_NF(X,n,nv,G); SL2Z_Make_Poly_NF(XS,n,nv,S); for(i=0;i<*n;i++)for(j=0;j<*n;j++) assert( S[i][j]==G[i][j]);} for(i=0;i<*n;i++)for(j=0;j<*nv;j++) assert(XS[i][j]==X[i][j]); return x; #else return GLZ_Make_Trian_NF(X,n,nv,G); #endif } int SL2Z_Aux_Make_Poly_NF(Long X[][VERT_Nmax], int *n, int *nv) { SL_Long S[POLY_Dmax][POLY_Dmax]; return SL2Z_Make_Poly_NF(X,n,nv,S); } void SL2Z_Make_Poly_UTriang(PolyPointList *P) { if(VERT_Nmaxnp) puts("Triang Form requires VERT_Nmax>=#Points"); else { int i,j; Long UTF[POLY_Dmax][VERT_Nmax]; for(i=0;inp;i++)for(j=0;jn;j++)UTF[j][i]=P->x[i][j]; SL2Z_Aux_Make_Poly_NF(UTF,&P->n,&P->np); for(i=0;inp;i++)for(j=0;jn;j++)P->x[i][j]=UTF[j][i]; } } void Make_Poly_UTriang(PolyPointList *P) { if(VERT_Nmaxnp) puts("Triang Form requires VERT_Nmax>=#Points"); else { int i,j; Long UTF[POLY_Dmax][VERT_Nmax]; for(i=0;inp;i++)for(j=0;jn;j++)UTF[j][i]=P->x[i][j]; Aux_Make_Poly_NF(UTF,&P->n,&P->np); for(i=0;inp;i++)for(j=0;jn;j++)P->x[i][j]=UTF[j][i]; } } /* ============================================================== */ GL_Long GL_Egcd(GL_Long A0, GL_Long A1, GL_Long *Vout0, GL_Long *Vout1) { GL_Long V0=A0, V1=A1, A2, X0=1, X1=0, X2=0; while((A2 = A0 % A1)) { X2=X0-X1*(A0/A1); A0=A1; A1=A2; X0=X1; X1=X2; } *Vout0=X1, *Vout1=(A1-(V0) * X1)/ (V1); return A1; } GL_Long GL_RoundQ(GL_Long N,GL_Long D) { GL_Long F; if(D<0) {D=-D; N=-N;} F=N/D; return F+(2*(N-F*D))/D; } GL_Long GL_W_to_GLZ(GL_Long *W, int d, GL_Long **GLZ) { int i, j; GL_Long G, *E=*GLZ, *B=GLZ[1];for(i=0;i0 non-zero entries */ { ++C; for(i=0;i<*n;i++) { for(j=0;j<*n;j++) NF[i][C]+=G[i][j]*X[j][C]; } for(i=L;i<*n;i++) if(NF[i][C]) {W[N]=NF[i][C]; p[N++]=i;} } assert(N); if(N==1) {g=W[0]; _G[0][0]=1;} else g=GL_W_to_GLZ(W,N,_G); if(g<0) { g *= -1; for(i=0;i G[p[0]] */ { GL_Long A=G[L][i]; G[L][i]=G[p[0]][i]; G[p[0]][i]=A; } for(i=0;iNFX_Limit) { fprintf(stderr, "NFX_Limit in GL -> %lld !!\n",(long long) g); return 0; } else #endif X[i][j]=NF[i][j]; } return 1; } /* ============================================================= */ void TEST_rVM_VPM(int *d,int *v,int *f, Long X[POLY_Dmax][VERT_Nmax], Long x[VERT_Nmax][VERT_Nmax]) { int i,j,err=0; for(i=0;i<*v;i++) { for(j=0;j<*d;j++) if(abs(X[j][i])>X_Limit) err=X[j][i]; for(j=0;j<*f;j++) if(abs(x[j][i])>VPM_Limit) err=x[j][i]; } if(err) { printf("TEST_VM_VPM: limits exceeded %d\n",err); printf("%d %d VM[%d][%d]:\n",*v,*d,*d,*v); for(j=0;j<*d;j++) { for(i=0;i<*v;i++)printf("%3d ",(int) X[j][i]);puts(""); } puts(""); printf("VPM[%d][%d]:\n",*f,*v); for(j=0;j<*f;j++) { for(i=0;i<*v;i++)printf("%3d ",(int) x[j][i]);puts(""); } puts(""); exit(0); } } int Init_rVM_VPM(PolyPointList *_P,VertexNumList *_V,EqList *_F,/* in */ int *d,int *v,int *f, Long X[POLY_Dmax][VERT_Nmax], /* out */ Long x[VERT_Nmax][VERT_Nmax]) /* return reflexive */ { int i,j, ref=1; *v=_V->nv; *f=_F->ne; *d=_P->n; for(j=0;j<_F->ne;j++) /* compute VPM */ { if(_F->e[j].c!=1) ref=0; for(i=0;i<_V->nv;i++) x[j][i]=Eval_Eq_on_V(&_F->e[j],_P->x[_V->v[i]],_P->n); } for(i=0;i<_V->nv;i++) { Long *pv=_P->x[_V->v[i]]; for(j=0;j<_P->n;j++) X[j][i]=pv[j]; } TEST_rVM_VPM(d,v,f,X,x); return ref; } void New_pNF_Order(int *v,int *f,PERM *CL,int *ns,Long VPM_NF[][VERT_Nmax]) { int i, j, pi[VERT_Nmax], c[VERT_Nmax]; Long maxP[VERT_Nmax], sumP[VERT_Nmax]; for(i=0;i<*v;i++) { pi[i]=i; maxP[i]=sumP[i]=0; for(j=0;j<*f;j++) { sumP[i]+=VPM_NF[j][i]; if(VPM_NF[j][i]>maxP[i])maxP[i]=VPM_NF[j][i]; } } for(i=0;i<*v-1;i++) { int n=i; for(j=i+1;j<*v;j++) { if(maxP[j]"); fflush(stdout); for(j=0;j<*v;j++)fprintf(outFILE,"%3d",(int)VPM_NF[i][j]);Fputs(""); fflush(stdout); } Fputs(""); } void Eval_Poly_NF(int *d,int *v,int *f, Long VM[POLY_Dmax][VERT_Nmax], Long VPM[VERT_Nmax][VERT_Nmax], /* in */ Long pNF[POLY_Dmax][VERT_Nmax],int t) /* out */ { PERM *CL=(PERM *) malloc((SYM_Nmax+1) * sizeof(PERM)); Long VPM_NF[VERT_Nmax][VERT_Nmax]; int ns; assert(CL!=NULL); Make_VPM_NF(v,f,VPM,CL,&ns,VPM_NF); if(t)Print_vNF(v,f,VPM,VPM_NF); New_pNF_Order(v,f,CL,&ns,VPM_NF); Aux_pNF_from_vNF(CL,&ns,v,d,VM,pNF,&t); free(CL); #ifdef WARN_BIG_NS #ifdef SHOW_BIG_NS if(SHOW_BIG_NS<=ns) {int i,j; printf("ns=%d VM:\n",ns);fflush(stdout); for(i=0;i<*d;i++){for(j=0;j<*v;j++)printf("%2d ",(int)VM[i][j]); puts("");} printf("ns=%d VPM:\n",ns);fflush(stdout); for(i=0;i<*f;i++){for(j=0;j<*v;j++)printf("%2d ",(int)VPM[i][j]); puts("");} printf("ns=%d VPM_NF:\n",ns);fflush(stdout); for(i=0;i<*f;i++){for(j=0;j<*v;j++)printf("%2d ",(int)VPM_NF[i][j]); puts("");} printf("ns=%d pNF:\n",ns);fflush(stdout); for(i=0;i<*d;i++){for(j=0;j<*v;j++)printf("%2d ",(int)pNF[i][j]); puts("");} exit(0);} #endif #endif } /* ======== tedious details of NFs ======= */ /* Make_NF(); make NormalForm of VertexPairingMatrices ====== * * To bring the VPM to normal form, NF=lexicographic if reading line by line * we need permutations Cp and Lp of columns and lines: Make Cp's respecting * rest symmetry to get maximal lines and remember them and their rest sym. * 1. Start with last permutation and append different refinements or throw * everything below away if you find a `better' NF; * 2. Remember permutation and rest symmetry if equal; replace by last one * if the `next' line is not good. * In each step, i.e. after finding n lines of NF, their {Cp,Lp}'s and sym. * s[i]=l, s[j]=i for iX[line] */ while(n--) /* go over CL (n from *_ns-1 to 0), ns_* changes! */ { PERM nP[VERT_Nmax]; int c=0, L=l-1, np=0, *C, ccf=cf; /* ccf=column compare flag */ *nP=CL[n]; while(++L<_X->nf) /* init nP (from 1st col.) */ { int j=0; C=nP[np].C; y=x[nP[np].L[L]]; while(++j<=*S) if(y[C[c]]L[l]),&(nP->L[L])); } else /* EQUAL line */ { swap(&(nP[np].L[l]),&(nP[np].L[L])); nP[++np]=CL[n]; } } else /* NEW line */ { *r=y[*C]; swap(&(nP[np].L[l]),&(nP[np].L[L])); nP[++np]=CL[n]; ccf=1; } } while(++c<_X->nv) /* check/complete nP */ { int s=S[c]; L=np; ccf=cf; if(sL) nP[L]=nP[np];} /* BAD line */ else if(d) /* BETTER line */ { r[c]=y[C[c]]; cf=0; np=L+1; *_ns=n+1; } /* else ; */ /* EQUAL line */ } else { r[c]=y[C[c]]; ccf=1; } } } cf=1; if(--(*_ns) > n) CL[n]=CL[*_ns]; /* write nP to CL */ if(SYM_Nmax < (cf=(*_ns+np))) { printf("Need SYM_Nmax > %d !!\n",cf);exit(0); } for(L=0;LL[l]]; /* compute S */ { int c=0, *C=CL->C; while(c<_X->nv) { int s=S[c]+1; S[c]=c; while(++c best; y=x[nn] -> next */ for(i=0;i<_X->nf;i++) P.L[i]=i; for(j=0;j<_X->nv;j++) P.C[j]=j; /* init P */ q=CL; *q=P; b=*x; /* P=CL[ns-1] StartPerm; maximize 0-th line */ for(j=1;j<_X->nv;j++)if(b[q->C[0]]C[j]])swap(&q->C[0],&q->C[j]); for(i=1;i<_X->nv;i++) { for(j=i+1;j<_X->nv;j++) if(b[q->C[i]]C[j]]) swap(&q->C[i],&q->C[j]); } for(nn=1;nn<_X->nf;nn++) /* maximize nn-th line */ { Long d; p=&CL[*_ns]; *p=P; y=x[nn]; /* nb=*q=*b=best, nn=*p=*y=next */ { int m=0; for(j=1;j<_X->nv;j++) if(y[p->C[m]]C[j]]) m=j; if(m) swap(&p->C[0],&p->C[m]); } if((d=y[p->C[0]]-b[q->C[0]]) < 0) continue; /* d<0 => forget this */ for(i=1;i<_X->nv;i++) { int m=i; for(j=i+1;j<_X->nv;j++) if(y[p->C[m]]C[j]]) m=j; if(m>i) swap(&p->C[i],&p->C[m]); if(d==0) if((d=y[p->C[i]]-b[q->C[i]]) <0) break; } if(d<0) continue; swap(&p->L[0],&p->L[nn]); /* p->L[nn]=0; p->L[0]=nn; */ if(d==0) (*_ns)++; else {*q=*p; *_ns=1; b=y;} /* d>0 => forget prev */ } y=x[CL->L[0]]; S[0]=0; for(i=1;i<_X->nv;i++) /* compute S */ if(y[CL->C[i]]==y[CL->C[i-1]]) ++S[ S[i]=S[i-1] ]; else S[i]=i; } int Aux_XltY_Poly_NF(Long X[][VERT_Nmax],Long Y[][VERT_Nmax], int *n,int *nv) { int i, j; Long d; /* return "X < Y" */ for(i=0;i<*n;i++)for(j=0;j<*nv;j++) if((d=X[i][j]-Y[i][j])) { if(d<0) return 1; else return 0; } return 0; } void Print_Perm(int *p,int v,const char *s); void TEST_pNF(int* C,Long V[][VERT_Nmax],Long X[][VERT_Nmax], int* n,int* nv,int* try_) { int i,j; fprintf(outFILE,"Poly NF try[%d]: C=",*try_); Print_Perm(C,*nv,"\n"); for(i=0;i<*n;i++) { for(j=0;j<*nv;j++) fprintf(outFILE," %3d",(int) V[i][j]); fprintf(outFILE," =>"); for(j=0;j<*nv;j++) fprintf(outFILE," %3d",(int) X[i][j]); Fputs(""); } } void Aux_Make_Triang(PERM *CL,int ns,Long V[][VERT_Nmax],int*n,int*nv,int *t) { int i, j, s, x=0, g=0, ps=1; /* x :: make X :: if X>Y */ Long X[POLY_Dmax][VERT_Nmax], Y[POLY_Dmax][VERT_Nmax]; for(i=0;i<*n;i++) for(j=0;j<*nv;j++) X[i][j]=V[i][CL->C[j]]; if(!Aux_Make_Poly_NF(X,n,nv)) exit(0); /* t>0: print NFs */ /* -1: calc CL.s */ if(*t) { if(*t>0) TEST_pNF(CL->C,V,X,n,nv,&g); else { CL->s=1; if(*t+1){puts("t<-1 in Aux_Make_Triang");exit(0);} } } for(s=1;s0) TEST_pNF(CL[s].C,V,X,n,nv,&s); if(x==0) { if(*t<0) { int k; for(k=g;k0) TEST_pNF(CL[s].C,V,Y,n,nv,&s); if(x==1) { if(*t<0) { int k; for(k=g;k0) fprintf(outFILE, "\nPoly NF: NormalForm=try[%d] #Sym(VPM)=%d #Sym(Poly)=%d\n",g,ns,ps); if(x) for(i=0;i<*n;i++)for(j=0;j<*nv;j++) V[i][j]=Y[i][j]; else for(i=0;i<*n;i++)for(j=0;j<*nv;j++) V[i][j]=X[i][j]; } /* ======== END of tedious details of NFs ======= * * * Make_VPM_NF uses Aux_vNF_Init, Aux_vNF_Line * * Aux_pNF_from_vNF uses Aux_Make_Triang */ void Make_VPM_NF(int *v, int *f, Long x[VERT_Nmax][VERT_Nmax], /* in */ PERM *CL,int *ns,Long VPM_NF[VERT_Nmax][VERT_Nmax]) /* out */ { int i, j, S[VERT_Nmax]; int nsF=0, nsM=0; /* make VPM NF */ volatile vNF auX; vNF *_X= (vNF*) &auX; _X->nv=*v;_X->nf=*f; /* x=VPM */ *ns=1; Aux_vNF_Init(_X, x, CL, S, ns); /* init = 1st line */ for(i=1;i<_X->nf-1;i++){Aux_vNF_Line(i,_X,x,CL,S,ns); /* lines of NF */ #ifdef WARN_BIG_NS if((WARN_BIG_NS<=(*ns))||nsF){ nsF=1;/*printf("ns[%d]=%d\n",i,*ns);*/} #endif if(*ns>nsM) nsM=*ns; } _X->ns=*ns; for(i=0;i<_X->nv;i++) /* write VPM-NF to _X */ { for(j=0;j<_X->nf;j++) /* _X->x */ VPM_NF[j][i]=x[CL->L[j]][CL->C[i]]; } if(nsF)printf("WARNing: ns_max=%d -> ns=%d\n",nsM,*ns); } void Aux_pNF_from_vNF(PERM *CL,int *ns,int *v,int *d, Long VM[POLY_Dmax][VERT_Nmax], /* in */ Long pNF[POLY_Dmax][VERT_Nmax],int *t) /* out */ { int i,j; for(i=0;i<*d;i++)for(j=0;j<*v;j++) pNF[i][j]=VM[i][j]; Aux_Make_Triang(CL,*ns,pNF,d,v,t); } int Make_Poly_NF(PolyPointList *_P, VertexNumList *_V, EqList *_F, Long pNF[POLY_Dmax][VERT_Nmax]) /* 1 if reflexive */ { int d, v, f; Long VM[POLY_Dmax][VERT_Nmax], VPM[VERT_Nmax][VERT_Nmax]; int ref=Init_rVM_VPM(_P,_V,_F,&d,&v,&f,VM,VPM); Eval_Poly_NF(&d,&v,&f,VM,VPM,pNF,0); return ref; } void Poly_Sym(PolyPointList *_P, VertexNumList *_V, EqList *_F, int *sym_num, int V_perm[][VERT_Nmax]) { Long pNF[POLY_Dmax][VERT_Nmax]; Make_Poly_Sym_NF(_P,_V,_F,sym_num,V_perm,pNF,0,0,0); } int PermChar(int n) { if(n<10) return '0'+n; else if(n<36) return 'a'+n-10; else if(n<62) return 'A'+n-36; else {puts("Printing permutations only for #Vert<=62 !!");exit(0);} return 0; } void Print_Perm(int *p,int v,const char *s) { int i; for(i=0;in, *v=&_V->nv, *f=&_F->ne, *C; PERM *CL = (PERM *) malloc ( sizeof(PERM) *(SYM_Nmax+1)); Long VM[POLY_Dmax][VERT_Nmax], VPM[VERT_Nmax][VERT_Nmax]; Long VPM_NF[VERT_Nmax][VERT_Nmax]; Init_rVM_VPM(_P,_V,_F,d,v,f,VM,VPM); if (traced) Eval_Poly_NF(&_P->n,&_V->nv,&_F->ne,VM,VPM,NF,1); Make_VPM_NF(v,f,VPM,CL,&ns,VPM_NF); New_pNF_Order(v,f,CL,&ns,VPM_NF); Aux_pNF_from_vNF(CL,&ns,v,d,VM,NF,&t); *SymNum=-t;i=0; while(0==CL[i].s) i++; C=CL[i].C; for(t=0;inv,"\n"); /*{for(j=0;j<_V->nv;j++)printf("%c",PermChar(V_perm[i][j]));puts("");}*/ } if (S) fprintf(outFILE,"#GL(Z,%d)-Symmetries=%d, #VPM-Symmetries=%d\n", _P->n, *SymNum, ns); if (N) { char c[VERT_Nmax+38]="Normal form of vertices of P"; if(*SymNumnv,&c[37])) {strcpy(&c[28]," perm");c[36]='=';} Print_Matrix(NF, _P->n, _V->nv,c);} free(CL); return ns; } void Aux_NF_Coord(PolyPointList *_P, Long VM[POLY_Dmax][VERT_Nmax], int *C, int *n, int *np, int *v) { SL_Long S[POLY_Dmax][POLY_Dmax], X[POLY_Dmax]; Long V[POLY_Dmax][VERT_Nmax]; int i, j; for(i=0;i<*n;i++) for(j=0;j<*v;j++) V[i][j]=VM[i][C[j]]; if(!SL2Z_Make_Poly_NF(V,n,v,S)) exit(0); for(j=0;j<*np;j++) { for(i=0;i<*n;i++) { int k=*n; X[i]=0; while(k--) X[i]+=_P->x[j][k]*S[i][k]; } for(i=0;i<*n;i++) _P->x[j][i]=X[i]; } } void NF_Coordinates(PolyPointList *_P, VertexNumList *_V, EqList *_F) /* needs converted EqList !! */ { PERM *CL; Long VM[POLY_Dmax][VERT_Nmax], VPM[VERT_Nmax][VERT_Nmax]; int ns; CL=(PERM*) malloc((SYM_Nmax+1)*sizeof(PERM)); assert(CL!=NULL); Init_rVM_VPM(_P,_V,_F,&_P->n,&_V->nv,&_F->ne,VM,VPM); /* make VPM */ { Long VPM_NF[VERT_Nmax][VERT_Nmax]; Make_VPM_NF(&_V->nv,&_F->ne,VPM,CL,&ns,VPM_NF); /* get PERM */ New_pNF_Order(&_V->nv,&_F->ne,CL,&ns,VPM_NF); /* improve PERM */ } Aux_NF_Coord(_P,VM,CL->C,&_P->n,&_P->np,&_V->nv); /* improve _P */ { int f=_F->ne; VertexNumList V; /* EqList in new basis */ if(!IP_Check(_P,&V,_F)){puts("IP=0 in NF_Coords"); exit(0);} if((V.nv!=_V->nv)||(f!=_F->ne)) {puts("Error in NF_Coords"); exit(0);} } free(CL); } int Improve_Coords(PolyPointList *_P,VertexNumList *_V) { SL_Long S[POLY_Dmax][POLY_Dmax], X[POLY_Dmax]; Long V[POLY_Dmax][VERT_Nmax]; int i, j; for(i=0;i<_P->n;i++) for(j=0;j<_V->nv;j++) V[i][j]=_P->x[_V->v[j]][i]; if(!SL2Z_Make_Poly_NF(V,&(_P->n),&(_V->nv),S)) return 0; for(j=0;j<_P->np;j++) { for(i=0;i<_P->n;i++) { int k=_P->n; X[i]=0; while(k--) X[i] += (long long) _P->x[j][k] * S[i][k]; } for(i=0;i<_P->n;i++) _P->x[j][i]=X[i]; } return 1; } /* ================= SL(2,Z) - Version of Trian_NF ================= */ void SL_swap(SL_Long *X, SL_Long *Y) { SL_Long A=*Y; *Y=*X; *X=A; } SL_Long SL_Egcd(SL_Long A0, SL_Long A1, SL_Long *Vout0, SL_Long *Vout1) { register SL_Long V0=A0, V1=A1, A2, X0=1, X1=0, X2=0; while((A2 = A0 % A1)) { X2=X0-X1*(A0/A1); A0=A1; A1=A2; X0=X1; X1=X2; } *Vout0=X1, *Vout1=(A1-(V0) * X1)/ (V1); return A1; } /* S * X = UpperTrian; T * S = 1 (a b) x = g (d -b)(a b)=1 * g=EGCD(x,y,&a,&b); ax+by=g => (c d) y 0 (-c a)(c d)=1 * c=-y/g, d=x/g => det(abcd)=1 */ int SL2Z_Make_Poly_NF(Long X[][VERT_Nmax], int *n, int *nv, SL_Long S[POLY_Dmax][POLY_Dmax]) { SL_Long NF[POLY_Dmax][VERT_Nmax], a, b, g; int i, j, C=-1, L; for(i=0;i<*n;i++)for(j=0;j<*n;j++)S[i][j]=(i==j); /* init S */ for(i=0;i<*n;i++)for(j=0;j<*nv;j++)NF[i][j]=0; for(L=0;L<*n-1;L++) { int N=0; while(!N) /* find column C with N>0 non-zero entries */ { ++C; for(i=0;i<*n;i++) { for(j=0;j<*n;j++) NF[i][C]+=S[i][j]*X[j][C]; } if(NF[i=L][C]) N++; while(++i<*n) if(NF[i][C]) { N++; /* make NF[i][C]=0 */ if(NF[L][C]) { SL_Long A; g=SL_Egcd(NF[L][C],NF[i][C],&a,&b); for(j=0;j<*n;j++) /* c=-N_iC/g */ { A=a*S[L][j]+b*S[i][j]; /* d= N_LC/g */ S[i][j]=(NF[L][C]/g)*S[i][j]-(NF[i][C]/g)*S[L][j]; S[L][j]=A; } NF[L][C]=g; NF[i][C]=0; } else { SL_swap(&NF[L][C],&NF[i][C]); for(j=0;j<*n;j++)SL_swap(&S[L][j],&S[i][j]); } } if(NF[L][C]<0) { NF[L][C]*=-1;for(j=0;j<*n;j++)S[L][j]*=-1; /* sign */ } if(N) for(i=0;i NFX_Limit) { fprintf(stderr,"NFX_Limit in SL: I need %ld !!\n", labs(X[i][j]));return 0; } return 1; } /* ============================================================= */ /* ================= weights, fibrations and quotients ============== */ Long GxP(GL_Long *Gi,Long *V,int *d) { Long x=0; int j; for(j=0;j<*d;j++) x+=Gi[j]*V[j]; return x; } void G_2_BxG(GL_Long **G,GL_Long **B,int *d,int *L) /* G -> B.G */ { GL_Long W[POLY_Dmax]; int l,c; for(c=0;c<*d;c++) { for(l=*L;l<*d;l++) { int j; W[l]=0; for(j=*L;j<*d;j++) W[l]+=B[l-*L][j-*L]*G[j][c]; } for(l=*L;l<*d;l++) G[l][c]=W[l]; } /* TEST_GLZmatrix(G,*d); */ } #define TEST #undef TEST_OUT void TEST_GLZmatrix(GL_Long *G[POLY_Dmax], int d) { int x,y; GL_Long Ginv[POLY_Dmax][POLY_Dmax]; Long X[POLY_Dmax][VERT_Nmax]; for(x=0;x1) { g=GL_W_to_GLZ(W,p,G); if(g<0) for(i=0;i0) ? 1 : -1;} else if(*V<0) G[0][0]=-1; g=V[P[0]]; } if(g<0) g=-g; #ifdef TEST_OUT for(i=0;i0);}} #endif return g; } Long V_to_G_GI(Long *V,int d, Long G[][POLY_Dmax],Long GI[][POLY_Dmax]) { GL_Long AV[POLY_Dmax],AG[POLY_Dmax][POLY_Dmax],AGI[POLY_Dmax][POLY_Dmax], *P[POLY_Dmax]; Long g; int i,j; for(i=0;i1) for(i=j+1;i<=r;i++) x[i]*=a; } assert((*nw)++ < *Wmax); for(i=0;i<*p;i++) X[i]=0; for(i=0;i<=r;i++) X[s[i]]=x[i]; return 1; #ifdef TEST_OUT for(i=0;inp;p++) { for(s=0;sx[p],P->x[s],P->n)) break; if(s==r) { if(rn;i++)P->x[r][i]=P->x[p][i]; r++;} } P->np=r; } int PM_to_GLZ_for_UTriang(Long M[][VERT_Nmax],int *d,int *v,/* return rank */ GL_Long G[POLY_Dmax][POLY_Dmax]) /* allows rank<*d */ { int i,j,k,r=0; GL_Long B[POLY_Dmax][POLY_Dmax],*b[POLY_Dmax], *g[POLY_Dmax]; for(i=0;i<*d;i++) {b[i]=B[i]; g[i]=G[i];} for(i=0;i<*d;i++) for(j=0;j<*d;j++) G[i][j]=(i==j); for(i=0;i<*v;i++) { GL_Long V[POLY_Dmax]; int nz=0; for(j=r;j<*d;j++) { GL_Long x=0; for(k=0;k<*d;k++)x+=G[j][k]*M[k][i];if((V[j]=x))nz=1;} if(nz) {GL_V_to_GLZ(&V[r],b,*d-r); G_2_BxG(g,b,d,&r); r++;} } return r; } typedef Long PoMat[VERT_Nmax][POLY_Dmax]; typedef Long VMat[POLY_Dmax][VERT_Nmax]; void Print2_PM(Long PM[][POLY_Dmax],int d,int p) { int i,j; for(i=0;ip,NF,0,0,0); for(v=0;vnv;v++) { Long X[POLY_Dmax], g=0; for(i=0;in;i++) { int s; X[i]=0; for(s=0;sx[V->v[VP->p[s][v]]][i]; if(X[i]) g = g ? NNgcd(g,X[i]) : X[i]; } if(g>0) { for(i=0;in;i++) {assert(0==(X[i]%g)); Inv[i][p]=X[i]/g;} p++; } } pri=p; if(p>V->nv){fprintf(outFILE,"p=%d v=%d\n",p,V->nv);exit(0);} if(pri) fprintf(outFILE,"%d %d #Sym=%d (<=%d) ",P->n,V->nv,sn,EVsn); if(p) { GL_Long G[POLY_Dmax][POLY_Dmax],B[POLY_Dmax][POLY_Dmax]; r=PM_to_GLZ_for_UTriang(Inv,&P->n,&p,G); if(pri) { VMat VM; int j; for(j=0;jn;i++) {VM[i][j]=0; for(v=0;vn;v++) VM[i][j] += G[i][v]*Inv[v][j]; if(i>=r)assert(VM[i][j]==0); } fprintf(outFILE,"InvSubspace: dim=%d <(",r); INV_GLZmatrix(G,&P->n,B); for(i=0;in;v++) fprintf(outFILE, "%ld%s",B[v][i],(vn-1) ? "," : ((i+1==r) ? "":"),(")); fprintf(outFILE,")>\n"); } } else if(pri) fprintf(outFILE,"symmetric\n"); free(VP); if(pri){for(v=0;vnv;v++)for(i=0;in;i++)Inv[i][v]=P->x[V->v[v]][i]; Print2_VM(Inv,P->n,V->nv);} if(pri)fflush(0); return r; } /* Vol = #simp = GeomVol / dim!, V=Vol(), v=Vol(F), B=barcent() * B=b+(p-b)/(D+1), V=v*n, n=dist(A,p), D=dim() */ Long Simp_Vol_Barycent(PolyPointList *A,Long VM[][VERT_Nmax],Long *B,Long *N) { int i,j; Long I=0; *N=A->np; for(i=0;in;i++) { B[i]=0; for(j=0;jn+1;j++) B[i]+=A->x[j][i]; I=NNgcd(I,B[i]);} if(I==0) *N=0; else I=Fgcd(I,*N); if(I>1) {(*N)/=I; for(i=0;in;i++) B[i]/=I;} for(i=1;inp;i++)for(j=0;jn;j++)VM[j][i-1]=A->x[i][j]-A->x[0][j]; assert(A->np==A->n+1); Aux_Make_Poly_NF(VM,&A->n,&A->n); I=1; for(i=0;in;i++) I*=VM[i][i]; assert(I>0); return I; } Long SimplexVolume(Long *V[POLY_Dmax+1],int d) { Long I=1, VM[POLY_Dmax][VERT_Nmax]; int i,p; for(i=0;i=0); return I; } void Print_GLZ(GL_Long G[][POLY_Dmax],int d,const char *c); Long Aux_Vol_Barycent(PolyPointList *A, VertexNumList *V, EqList *E, Long *_B, Long *_N) { Long P[VERT_Nmax][POLY_Dmax],F[POLY_Dmax][VERT_Nmax],B[POLY_Dmax],g, vol=0; int i,j,e,p=A->np-1,D=A->n,ne=0; Equation Eq[VERT_Nmax]; if(A->np==1+D) return Simp_Vol_Barycent(A,F,_B,_N); p=A->np-1; *_N=1; for(i=0;ix[0][i]; /* choose origin _B[] */ for(j=0;jnp;j++)A->x[j][i]-=_B[i];} Find_Equations(A,V,E); assert(A->np==V->nv); for(e=0;ex[i+1][j]; for(e=0;ene;e++) if(E->e[e].c){Eq[ne++]=E->e[e];assert(E->e[e].c>0);} for(e=0;en=D-1; A->np=f; for(i=0;inp;i++)for(j=0;jn;j++){A->x[i][j]=0; for(f=0;fx[i][j]+=G[j][f]*F[f][i];} /*j=A->n*/ for(i=0;inp;i++){A->x[i][j]=0;for(f=0;fx[i][j]+= /*test*/ G[j][f]*F[f][i];assert(A->x[i][j]==0);} INV_GLZmatrix(G,&D,GI); /* if(D==4){Print_PPL(A,"GxP");Print_GLZ(GI,D,"GI");} */ Ve=Aux_Vol_Barycent(A,V,E,Be,&Ne)*Eq[e].c; vol+=Ve; /* if(D==4){fprintf(outFILE,"%d<%d: E.c=%d V=%d ",e,ne,Eq[e].c,Ve); for(i=0;i0); Ne/=g;for(i=0;in=P->n; A->np=V->nv; for(i=0;inv;i++) for(j=0;jn;j++) A->x[i][j] = P->x[V->v[i]][j]; vol=Aux_Vol_Barycent(A,&aV,e,B,N); free(A); #ifdef TEST_OUT Print_PPL(P,"result for:"); printf("vol=%d, B=",vol); for(i=0;in;i++)printf("%d ",B[i]);printf("/ %d\n",*N); #endif for(i=0;in;i++) if(B[i]) break; if(i==P->n) (*N)=0; return vol; /* N=0 iff B=0 */ } int ZeroSum(Long *A,Long *B,int d){while(d--)if(A[d]+B[d])return 0;return 1;} int SemiSimpleRoots(PolyPointList *P,EqList *E,Long **R){ int e,p,d=P->n,N=0; for(p=0;pnp;p++){ int z=0; for(e=0;ene;e++) if(0==Eval_Eq_on_V(&E->e[e],P->x[p],P->n)) z++; if(z==1) R[N++]=P->x[p];} if(N%2) return 0; if(N==0) return -1; for(e=0;en;e++){Long s=0; for(p=0;pp+1){Long *X=R[e];R[e]=R[p+1];R[p+1]=X;} p++;} return N;} typedef struct { int v, d; Long **x;} Matrix;/* Line[v][d] */ void Init_Matrix(Matrix *M,int v, int d){ /* v=#vec, d=dim */ int i; M->x=(Long **) malloc (v*(sizeof(Long *)+d*sizeof(Long))); assert(M->x != NULL); M->d=d; M->v=v; M->x[0]=(Long *)(&(M->x[v])); for(i=1;ix[i]=&M->x[i-1][d];} void Free_Matrix(Matrix *M){free(M->x);M->v=M->d=0;} void Print_LMatrix(Matrix M, char *s){int i,j; fprintf(outFILE,"%d %d LV %s\n",M.v,M.d,s); for(i=0;i1){ g=W_to_GLZ(W,&p,G.x); if(g<0) for(i=0;i0) ? 1 : -1;} else if(*V<0) G.x[0][0]=-1; g=V[P[0]]; } if(g<0) g=-g; for(j=0;j0); for(c=0;cn; for(v=0;vnv;v++) { int e=0,i=0; Long *X=P->x[V->v[v]], *Y[POLY_Dmax+1]; for(e=0;ene;e++) if(0==Eval_Eq_on_V(&E->e[e],X,d)) { if(i==d) return 0; Y[i++]=E->e[e].a;} /* simplicial */ if(vol) if(1!=(i=SimplexVolume(Y,d))) return 0; /* unimodular */ } return 1; } /* check simplicial and (if vol) FANO for M-lattice polytope */ int SimpUnimod_M(PolyPointList *P,VertexNumList *V,EqList *E,int vol) { int e,d=P->n; for(e=0;ene;e++) { int v=0,i=0; Long *Y[POLY_Dmax+1]; for(v=0;vnv;v++) if(0==Eval_Eq_on_V(&E->e[e],P->x[V->v[v]],d)) { if(i==d) return 0; Y[i++]=P->x[V->v[v]];} /* simplicial */ if(vol) if(1!=(i=SimplexVolume(Y,d))) return 0; /* unimodular */ } return 1; } #define RelativeSimplexVolume LinRelSimplexVolume int AffRelSimplexVolume(Long *X[POLY_Dmax],int v,int d) /* S-dim=v<=dim */ { int i,j,k,r=0,det=1; GL_Long B[POLY_Dmax][POLY_Dmax], *b[POLY_Dmax], Y[POLY_Dmax][POLY_Dmax], G[POLY_Dmax][POLY_Dmax], *g[POLY_Dmax]; for(i=0;i1); for(i=0;in,E->ne, "Vertices of P* (N-lattice) ",P->np,vn,dpn,E->ne); for(j=0;jn;j++) {for(i=0;ine-1;i++)fprintf(outFILE,"%2ld ", E->e[i].a[j]); fprintf(outFILE,"%2ld\n",E->e[i].a[j]);} for(i=0;ine;i++) assert(E->e[i].c==1); } void PrintFanoVert(PolyPointList *P, VertexNumList *V) { Long *Z=P->x[0],*N[4*VERT_Nmax]; int i,j,n=0; assert(P->n==4); for(i=0;inv;i++){ if (V->v[i] >= V->nv) printf("Please do not use weight input with option '-C2'!\n"); assert(V->v[i]nv);} for(i=V->nv;inp;i++){Long *X=P->x[i]; if((X[0]-Z[0])%2==0) if((X[1]-Z[1])%2==0)if((X[2]-Z[2])%2==0)if((X[3]-Z[3])%2==0) N[n++]=X;} fprintf(outFILE,"P/2: %d points (%d vertices) of P'=P/2 (M-lattice):\n", V->nv+n,V->nv); for(j=0;jn;j++) {fprintf(outFILE,"P/2: "); for(i=0;inv;i++)fprintf(outFILE,"%2ld ",(P->x[i][j]-Z[j])/2); for(i=0;il;j--) { for(i=0;i0); A/=g; B/=g; #ifdef TEST_RK printf("reduce New with %d-th line: N= A/g*N-B/g*rel find new c:\n",l); for(j=0;jx[V->v[0]]; for(i=0;inp;i++){Long *Xi=P->x[i]; int e,eq=0; for(e=0;ene;e++){if(0==Eval_Eq_on_V(&E->e[e],Xi,P->n)) eq++;} if(eq==1) if((X[0]-Xi[0])%2==0)if((X[1]-Xi[1])%2==0) if((X[2]-Xi[2])%2==0)if((X[3]-Xi[3])%2==0) IP++; } assert(IP<2); j=0;for(i=0;inf[3];i++) if(FI->nip[3][i])j++; if(IP)assert(j); /* if(j>0){char c[2]; c[1]=0; c[0]='0'+j; Print_VL(P,V,c);exit(0);} */ return IP; } int Divisibility_Index(PolyPointList *P,VertexNumList *V) { int i,j; Long g=0,x; assert(V->nv>1); for(i=0;in;i++)if(!g) g=labs(P->x[V->v[1]][i]-P->x[V->v[0]][i]); for(j=1;jnv;j++)for(i=0;in;i++) { x=labs(P->x[V->v[j]][i]-P->x[V->v[0]][i]); if(x) g=Fgcd(g,x); if(g<2) return 1; } return g; } int Obstructed_Conifold_Deformations(int S[SQnum_Max][4], int M[SQnum_Max], int Q, int R, int v, Long rel[SQnum_Max][VERT_Nmax], int C[SQnum_Max]) { int s,bad=0; for(s=0;sn==4); if(divby==0){if(FANO_CONIFOLD) divby=2; else divby=1;} /* set default */ assert(divby/100<=2); if(divby>99) {PIC=divby%100; CF=divby/100;} else if (divby>9) {PIC=divby%10; CF=divby/10;} else {PIC=0;CF=divby;} /* * 1st criterion: points::dP->np==dV->nv::cd4+cd1+1::cd0::IPip * Fano(trian+coni::N & M::\D=2\D'): need Vol(\D')=2#(\D')-8 <=64 * doublepoints = l/2(edges(\D)) */ if(_FI==NULL) {printf("ConifoldSing: Unable to allocate _FI\n"); exit(0);} Make_Incidence(P, V, E, _FI); npol++; nf=_FI->nf[1]; FInc=_FI->f[1]; /* cd2-faces of dP :: edge of P :: */ #ifdef OLD_FACE_LIST assert(nF==nf); #endif Make_FaceIPs(P,V,E,dP,_FI); for(j=0;jn,0,"E"); Print_PPL(dP,"dP");Print_EL(dE,&dP->n,0,"dE"); printf("e<3: nf=%d I=",nf);Print_INCI(FInc[j]);} assert(f>2); if(f>4){five++; /* more than 4 vertices */ free(_FI); return 0;} i=E->ne;while(!INCI_EQ_0(I)){i--;if(INCI_M2(I))el[e++]=i;I=INCI_D2(I);} assert(e==f);for(i=0;ie[el[i]].a; if(e==4){ for(i=0;in;i++)if(X[0][i]+X[1][i]-X[2][i]-X[3][i]) break; if(i==P->n) sq=1; if(!sq){for(i=0;in;i++) if(X[0][i]+X[2][i]-X[1][i]-X[3][i]) break; if(i==P->n)sq=2;} if(!sq){for(i=0;in;i++) if(X[0][i]+X[3][i]-X[1][i]-X[2][i]) break; if(i==P->n)sq=3;} if(sq==0){nosq++; free(_FI); return 0;} /* 4 vertices: no square */ } #ifdef PRINT_COORD {int l;for(l=0;ln;i++) printf("%3ld ",X[l][i]);printf(" j=%d fn=%d\n",j, nf);}} #endif if(1n)){nonbasic++;free(_FI);return 0;} if(e==4){int mul=0,vv[2]; INCI ID=_FI->v[1][j]; i=el[3]; if(sq==2) el[3]=el[0]; else if(sq==3) {el[3]=el[1]; el[1]=el[0];} else if(sq==1) {el[3]=el[1];el[1]=el[2];el[2]=el[0];} else assert(0); el[0]=i; assert((ine,rel,C); for(i=0;i<4;i++) S[nsq][i]=el[i]; i=V->nv; while(!INCI_EQ_0(ID)){i--; if(INCI_M2(ID)) vv[mul++]=V->v[i]; ID=INCI_D2(ID);} assert(mul==2); mul=P->x[vv[1]][0]-P->x[vv[0]][0];for(i=1;in;i++){ mul=NNgcd(mul,P->x[vv[1]][i]-P->x[vv[0]][i]);} assert(mul==1+_FI->nip[1][j]); M[nsq]=mul; if(CF==2){assert(mul%2==0);mul/=2;} ndpt+=mul; nsq++;} } if(nsq) ncon++; /* doublePts=sum_sq(l(sq^*)) [over 2 for fano] */ if(CF==2) {Long xB[POLY_Dmax],xN; /* Fano case */ int py=PyramidIP(P,V,E,_FI), pic=E->ne-4-rk, /* vertices of \D^*(N) - 4 - rank(relations) */ h12=1+ndpt-rk-py, /* 1 + doublePts - rk - facetIP(\D')=pyramid */ vol=LatVol_Barycent(P,V,xB,&xN); if (0!=vol%16) printf("option '-C2' requires polytopes divisible by 2 as input!\n"); assert(0==vol%16);vol/=16; /* degree */ if((PIC==0)||(PIC==pic)) /* restrict output to PIC=pic */ { printf("pic=%d deg=%2d h12=%2d rk=%d #sq=%d ",pic,vol,h12,rk,nsq); printf("#dp=%d py=%d F=%d %d %d %d #Fano=%d\n",ndpt,py, _FI->nf[0],_FI->nf[1],_FI->nf[2],_FI->nf[3],++fano); PrettyPrintDualVert(P,V->nv,E,dP->np); PrintFanoVert(P,V);} free(_FI);return 1;} else if((ndpt==0)&&(V->nv!=P->n+1)) {free(_FI);return 0;} else { BaHo BH; /* Calabi-Yau case */ int pic, cs, Ind=Divisibility_Index(P,V), I3=Ind*Ind*Ind, sing=Obstructed_Conifold_Deformations(S,M,nsq,rk,E->ne,rel,C); Long xB[POLY_Dmax], xN, vol=LatVol_Barycent(P,V,xB,&xN), c2h=12*(P->np-1)-2*vol; /* VertexNumList dV; EqList *auxE=(EqList *) malloc(sizeof(EqList)); int volN;assert(auxE!=NULL);Find_Equations(dP,&dV,auxE);free(auxE); assert(dV.nv==E->ne); volN=LatVol_Barycent(dP,&dV,xB,&xN); */ BH.mp=P->np; BH.mv=V->nv; BH.nv=E->ne; BH.np=dP->np; BH.n=P->n; Eval_BaHo(_FI, &BH); pic=BH.h1[1]-rk; cs=BH.h1[2]+ndpt-rk; if(pic>1)if(ndpt==0) {free(_FI);return 0;} /* ndpt=0 for pic=1 */ assert(c2h%Ind==0); c2h/=Ind; assert(vol%I3==0); if((PIC==0)||(PIC==pic)) /* restrict output to PIC=pic */ {printf("pic=%d h12=%d E=%d ",pic,cs,2*(pic-cs)); if(pic==1) printf("H^3=%ld c2H=%ld ",vol/I3,c2h); printf(" sing=%d rk=%d #sq=%d #dp=%d ",sing,rk,nsq,ndpt); printf("toric=%d,%d F=%d %d %d %d #CY=%d\n",BH.h1[1],BH.h1[2], _FI->nf[0],_FI->nf[1],_FI->nf[2],_FI->nf[3],ncon); PrettyPrintDualVert(P,V->nv,E,dP->np);} free(_FI); return nsq;} } void Einstein_Metric(CWS *CW,PolyPointList *P,VertexNumList *V,EqList *E) { int i,j,tot=0,reg=0,sym=0,ksum=0,sum=0,bary=0,ssroot=0,nofip=0,NR=NON_REF; PolyPointList *A = (PolyPointList *) malloc(sizeof(PolyPointList)); Long S, **root=(Long**)malloc(POINT_Nmax*sizeof(Long**)), *d=NULL, PM[VERT_Nmax][VERT_Nmax]; assert(A!=NULL); assert(root!=NULL); while(Read_CWS_PP(CW,P))/* nis=noinvss s=sum ks=ksum bcz=bary0 ssr(oot) */ { Long C[POLY_Dmax], N; int nis,r=0,s,ks,bcz,ssr, R=KP_VALUE; char c[90]; Long kPM[VERT_Nmax][VERT_Nmax]; #if(NON_REF) Long D[EQUA_Nmax]; d=D; #endif *c=0; tot++;nis=S=0; A->np=0;A->n=P->n; if(SMOOTH) {if(!Ref_Check(P,V,E)) continue;} else if(NR) Find_Equations(P,V,E); else assert(Ref_Check(P,V,E)); #if SMOOTH if(!SimpUnimod(P,V,E,1)) continue; reg++; #endif Sort_VL(V); for(i=0;inv;i++){ if (V->v[i] >= V->nv) printf("Please do not use weight input with option '-E'!\n"); assert(V->v[i]nv);} if(NR) for(i=0;ine;i++) d[i]=E->e[i].c; LatVol_Barycent(P,V,C,&N);bcz=(N==0);if(bcz)bary++;/*BaryCenterZero*/ Make_VEPM(P,V,E,PM); Complete_Poly(PM,E,V->nv,P); ssr=SemiSimpleRoots(P,E,root); if(ssr)ssroot++; if(ssr<0)nofip++; for(j=0;jne;j++) {int x=KPF; if(NR) x*=d[j]; for(i=0;inv;i++) kPM[j][i]=x*PM[j][i]; E->e[j].c=x; } A->np=0; Complete_Poly(kPM,E,V->nv,A); if(NR) for(i=0;ine;i++) E->e[i].c=d[i]; for(i=0;in;i++) { for(j=0;jnp;j++) S+=A->x[j][i]; if(S) { /* if(bcz) Print_PPL(P,"bary=0 for Psum!=0"); */ break;} } if(S) {s=0;r=1;} else {s=1;sum++;} if(S==0) for(r=2;r<=R;r++) { for(j=0;jne;j++) {int x=r*KPF; if(NR) x*=d[j]; for(i=0;inv;i++) kPM[j][i]=x*PM[j][i]; E->e[j].c=x; } A->np=0; Complete_Poly(kPM,E,V->nv,A); S=0; if(NR) for(i=0;ine;i++) E->e[i].c=d[i]; else for(i=0;ine;i++) E->e[i].c=1; for(i=0;in;i++) { for(j=0;jnp;j++) S+=A->x[j][i]; if(S) break; } if(S!=0) break; } ks=(S==0); if(S!=0) if(r>=KP_PRINT) { fprintf(stderr,"%d %d Nonzero at r=%d P\n",P->n,V->nv,r); for(i=0;in;i++){for(j=0;jnv;j++)fprintf(stderr,"%3ld%s", P->x[V->v[j]][i], (j+1<(V->nv)) ? " " : "\n");}fflush(0); } if(S!=0) if(r>KP_EXIT) { fprintf(stderr,"%d %d Counterexample at r=%d P\n",P->n,V->nv,r); for(i=0;in;i++){for(j=0;jnv;j++)fprintf(stderr,"%3ld%s", P->x[V->v[j]][i], (j+1<(V->nv)) ? " " : "\n");}fflush(0); exit(0); } if(S==0) { int is; ksum++; for(i=0;ine;i++) E->e[i].c=1; if(bcz==0){ Print_PPL(P,"Inconsistent: bary!=0 for kPsum==0");exit(0);} is=InvariantSubspace(P,V,E); nis=!is; if(nis) sym++; assert(bcz); #ifdef PRINT_ALL_ZEROSUM if(is==0) Print_PPL(P,is ? "zerosum" : "symmetric");fflush(0); #endif } /* else if(bcz) Print_PPL(P,"bary=0 for kPsum!=0"); */ strcat(c,"PPL:"); if(nis) strcat(c," symmetric"); if(ks) strcat(c," kPsum"); else if(s) strcat(c," Psum"); if(bcz) strcat(c," bary"); if(ssr) strcat(c," semisimple"); if( ((SSR_PRINT)&&(ssr>0))||((SSR_PRINT>1)&&ssr)||((BARY_PRINT)&&bcz) ||((ZEROSUM_PRINT==1)&&s)||((ZEROSUM_PRINT==2)&&ks) ) { int nr=(ssr+1) ? ssr : 0; printf("%d %d v=%d p=%d roots=%d " ,P->n,V->nv+nr,V->nv,P->np,nr); puts(c); for(i=0;in;i++){ for(j=0;jnv;j++) printf("%2ld ",P->x[V->v[j]][i]); printf(" "); for(j=0;j0) || ((SSR_PRINT<0)&&ssr)) {int nr=(ssr+1) ? ssr : 0; printf("%d %d v=%d roots=%d p=%d " ,P->n,V->nv+nr,V->nv,nr,P->np); puts(c); for(i=0;in;i++){ for(j=0;jnv;j++)printf("%2d ",P->x[V->v[j]][i]);printf(" "); for(j=0;jr)&&(r>1)) if(TriMat_to_WeightZ(T,d,p,r,s,nw,W,Wmax,FW)) Check_New_Fiber(PM,d,s,r,FW); } /* printf("finished r=%d\n",r); */ } #ifdef CHECK_Nref_FIRST int Fiber_Ref_Check(Long PM[][POLY_Dmax], int *d, int *p, int *v, GL_Long G[POLY_Dmax][POLY_Dmax], GL_Long Ginv[][POLY_Dmax], Long X[VERT_Nmax][VERT_Nmax], PolyPointList *A, int r) { int i,j; VertexNumList V; EqList E; int l,c=0; for(i=0;i<*p;i++) { for(l=r;l<*d;l++) if(GxP(G[l],PM[i],d)) break; if(l==*d) { for(l=0;lx[c][l]=GxP(G[l],PM[i],d); c++; } } A->np=c; A->n=r; if(!Ref_Check(A,&V,&E)) return 0; /* only necessary */ #else int Fiber_Ref_Check(Long PM[][POLY_Dmax], int *d, /*int *p,*/ int *v, GL_Long G[POLY_Dmax][POLY_Dmax], /* GL_Long Ginv[][POLY_Dmax], Long X[VERT_Nmax][VERT_Nmax], */ PolyPointList *A, int r) { int i,j; VertexNumList V; EqList E; #endif A->np=*v; A->n=*d; for(i=0;i<*v;i++) for(j=0;j<*d;j++) A->x[i][j]=GxP(G[j],PM[i],d); /* reflexivity of projection */ assert(Ref_Check(A,&V,&E)); EL_to_PPL(&E,A,d); A->n=r; Remove_Identical_Points(A); return Ref_Check(A,&V,&E); } void Add_Ref_Fibers(Long PM[][POLY_Dmax], int *d, int *v, int *s, GL_Long G[][POLY_Dmax][POLY_Dmax], int *n, PolyPointList *A, int r) { int i,j,c,l; Long X[VERT_Nmax][VERT_Nmax],x; /* n==nf */ GL_Long Ginv[POLY_Dmax][POLY_Dmax]; for(i=0;in,*n=&s[r] /*,p=_P->np-1*/ ; GL_Long *X=T[r]; for(*n=s[r-1]+1; *n<_P->np-(*fdim)+r; (*n)++) { Long *P=_P->x[*n]; for(i=0;i<*d;i++) { X[i]=0; for(j=0;j<*d;j++) X[i]+=G[r-1][i][j]*P[j]; } for(j=r;j<*d;j++) if(X[j]) break; if(j<*d) /* non-zero :: rank increased */ { X[r]=GL_V_to_GLZ(&X[r],GN,*d-r); for(i=r+1;i<*d;i++) X[i]=0; for(i=r;i<*d;i++) for(j=0;j<*d;j++) { G[r][i][j]=0; for(k=0;k<*d-r;k++)G[r][i][j]+=GN[i-r][k]*G[r-1][r+k][j];} if(r<(*fdim)-1) Fiber_Rec_New_Point(_P,v,G,GI,GN,T,s,r+1,F,fdim); else Add_Ref_Fibers(_P->x,d,v,s,F->G,&F->nf,&F->F,r+1); } } } void Reflexive_Fibrations(PolyPointList *P, int nv, ek3fli *F,int fdim) { int n, i, j, d=P->n, s[POLY_Dmax]; GL_Long T[POLY_Dmax+1][POLY_Dmax],*X=T[0], **G[POLY_Dmax],*GN[POLY_Dmax], *GI[POLY_Dmax][POLY_Dmax], GX[(POLY_Dmax*(POLY_Dmax+3))/2][POLY_Dmax]; F->nf=0; for(j=0;jlines of GX */ if(inp-fdim;n++) { s[0]=n; for(i=0;ix[n][i]; GL_V_to_GLZ(X,G[0],d); for(i=0;ix[n][j];} Fiber_Rec_New_Point(P,&nv,G,GI,GN,T,s,1,F,&fdim); } } void AuxDPolyData(PolyPointList *P,PolyPointList *A,int*v,int*n,int*f) { Long X[VERT_Nmax][VERT_Nmax]; EqList E; VertexNumList V; assert(Ref_Check(P,&V,&E)); *v=V.nv; EL_to_PPL(&E,A,&P->n); assert(Ref_Check(A,&V,&E)); *f=V.nv; Make_VEPM(A,&V,&E,X); Complete_Poly(X,&E,V.nv,A); *n=A->np; } void Test_EK3_Fibration(PolyPointList *P,int edim, GL_Long G[POLY_Dmax][POLY_Dmax]) { int s[VERT_Nmax],t[VERT_Nmax],d=P->n,p=P->np-1; PolyPointList *A; assert(NULL != (A=(PolyPointList*) malloc(sizeof(PolyPointList)))); { int i,j,e,k, v,n,f; Long PM[VERT_Nmax][POLY_Dmax]; for(i=0;ix[i],&d); while(!PM[i][--j]) if(j==0) break; if(jx[i][j]=PM[s[i]][j]; A->n=edim; puts("PM"); for(j=0;jnp>20) ? fprintf(outFILE,"%2ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " ") : fprintf(outFILE,"%4ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " "); A->np=e;Print_PPL(A,"Elliptic"); A->np=e;AuxDPolyData(A,A,&v,&n,&f); printf("Em:%d %d n:%d %d\n",n,f,e+1,v); for(i=0;ix[i][j]=PM[s[i]][j]; A->n=edim+1;A->np=k;Print_PPL(A,"K3"); A->n=edim+1; A->np=k; AuxDPolyData(A,A,&v,&n,&f); printf(" K:%d %d n:%d %d ",n,f,k+1,v); AuxDPolyData(P,A,&v,&n,&f); printf("M:%d %d N:%d %d pi=",A->np,f,P->np,v); for(i=0;inp>20) ? fprintf(outFILE,"%2ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " ") : fprintf(outFILE,"%4ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " "); } free(A); } void Print_Elliptic_K3_Fibrations(PolyPointList *P,int edim, GL_Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax],int nk) { int x,s[VERT_Nmax],t[VERT_Nmax],d=P->n,p=P->np-1; PolyPointList *A=NULL; if(nk)assert(NULL != (A=(PolyPointList*) malloc(sizeof(PolyPointList)))); for(x=0;xx[i],&d); while(!PM[i][--j]) if(j==0) break; if(jx[i][j]=PM[s[i]][j]; A->n=edim; A->np=e; AuxDPolyData(A,A,&v,&n,&f); fprintf(outFILE,"Em:%d %d n:%d %d",n,f,e+1,v); for(i=0;ix[i][j]=PM[s[i]][j]; A->n=edim+1; A->np=k; AuxDPolyData(A,A,&v,&n,&f); fprintf(outFILE," Km:%d %d n:%d %d ",n,f,k+1,v); AuxDPolyData(P,A,&v,&n,&f); fprintf(outFILE,"M:%d %d N:%d %d",A->np,f,P->np,v); if(p<=FIB_PERM) { fprintf(outFILE," p="); Print_Perm(s,p,"\n"); } /*for(i=0;ix[i][j]=PM[s[i]][j]; A->n=d;A->np=p; Make_Poly_UTriang(A); for(j=0;jnp>20) ? fprintf(outFILE,"%2ld%s",A->x[i][j],(i==p-1) ? "\n" : " ") : fprintf(outFILE,"%4ld%s",A->x[i][j],(i==p-1) ? "\n" : " "); } if(nk)free(A); } void All_CDn_Fibrations(PolyPointList *P,int nv,int cd) { int x, fdim=P->n-cd; ek3fli *F = (ek3fli *) malloc ( sizeof(ek3fli) ); PolyPointList *A=&F->F;assert(F!=NULL); Reflexive_Fibrations(P,nv,F,fdim); for(x=0;xnf;x++) { int i,j,s[VERT_Nmax],t[VERT_Nmax],d=P->n,p=P->np-1,fn,v,n,f; Long PM[VERT_Nmax][POLY_Dmax]; for(i=0;iG[x][j],P->x[i],&d); while(!PM[i][--j]) if(j==0) break; if(jx[i][j]=PM[s[i]][j]; A->n=fdim; A->np=fn; AuxDPolyData(A,A,&v,&n,&f); fprintf(outFILE,"m:%d %d n:%d %d ",n,f,fn+1,v); AuxDPolyData(P,A,&v,&n,&f); fprintf(outFILE,"M:%d %d N:%d %d",A->np,f,P->np,v); if(p<=FIB_PERM){fprintf(outFILE," p="); Print_Perm(s,p,"\n"); } /* for(i=0;inp>20) ? fprintf(outFILE,"%2ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " ") : fprintf(outFILE,"%4ld%s",PM[s[i]][j],(i==p-1) ? "\n" : " "); } free(F); } void Print_GLZ(GL_Long G[][POLY_Dmax],int d,const char *c) { int i,j; for(i=0;in, /*p=P->np-1,*/ cd=P->n-edim, nb=0, nk=0; GL_Long GE[POLY_Dmax][POLY_Dmax], *ge[POLY_Dmax]; ek3fli *F = (ek3fli *) malloc ( sizeof(ek3fli) ); assert(F!=NULL); Reflexive_Fibrations(P,nv,F,edim); for(c=0;c<*d;c++) ge[c]=GE[c]; for(e=0;enf;e++) for(c=0;cnp-1;c++) { int i,j,nz=0,newf=1; GL_Long *b[POLY_Dmax], X[POLY_Dmax]; for(i=edim;in;i++) if((X[i]=GxP(F->G[e][i],P->x[c],&P->n))) nz=1; if(nz) /* find new B; compare/add B; BxG-FiberRefCheck; print */ { GL_Long Binv[POLY_Dmax][POLY_Dmax]; for(i=0;iB[nb][i]; GL_V_to_GLZ(&X[edim],b,cd); INV_GLZmatrix(F->B[nb],&cd,Binv); for(i=0;iB[i][j][l]*Binv[l][C]; if(x) {nz=1; break; } /* r->1, d->cd */ } if(nz==0) { newf=0; break; } } if(newf) { for(i=0;i<*d;i++)for(j=0;j<*d;j++) GE[i][j]=F->G[e][i][j]; G_2_BxG(ge,b,d,&edim); INV_GLZmatrix(GE,d,Binv); if(Fiber_Ref_Check(P->x,d,/*&p,*/&nv,GE,/*Binv,VV,*/ &F->F,edim+1)) {nb++; assert(nbnp,nb); */ } /* printf("e=%d c=%d nb=%d ",e,c,nb); */ if(c+2==P->np) /* finish e */ { int n; for(n=0;nGK[nk][i][j]=F->G[e][i][j]; for(i=0;i<*d;i++) { ge[i]=F->GK[nk][i]; b[i]=F->B[n][i];} G_2_BxG(ge,b,d,&edim); assert(++nk < VERT_Nmax); /* printf("\nTest_EK3: e=%d nf=%d n=%d nb=%d\n",e,F->nf,n,nb); Test_EK3_Fibration(P,edim,F->GK[nk-1]); */ } for(i=0;i<*d;i++) ge[i]=GE[i]; nb=0; } } Print_Elliptic_K3_Fibrations(P,edim,F->GK,nk); free(F); } void IP_Simplex_Fiber(Long PM[][POLY_Dmax], int p, int d, /* need PM[i]!=0 */ FibW *F, int Wmax, int CD) { int n,i,j, s[POLY_Dmax+1]; int *nw=&F->nw; /* nw=#IP_Simp <= Wmax */ GL_Long T[POLY_Dmax+1][POLY_Dmax],*X=T[0], **G[POLY_Dmax],*GN[POLY_Dmax], *GI[POLY_Dmax][POLY_Dmax], GX[(POLY_Dmax*(POLY_Dmax+3))/2][POLY_Dmax]; *nw=0; /*s[-1]=-1;*/ for(j=0;jnf=0; for(n=0;nW,&Wmax,G,GI,GN,T,s,1,F,&CD); }if(!CD)if(*nwp-d) printf("WARNING: nw=%d > #pts-dim=%d\n",*nw,p-d); */ for(i=0;i<*nw;i++)for(n=0;nW[i][j]; if(sum){printf("At line %d ERROR in W =",n); for(j=0;jW[i][j]); puts("");exit(0);}} } void IP_Simplex_Decomp(Long PM[][POLY_Dmax], int p, int d, /* need PM[i]!=0 */ int *nw,Long W[][VERT_Nmax],int Wmax,int CD) /* nw=#IP_Simp <= Wmax */ { int n,i,j, s[POLY_Dmax+1]; FibW *FW=NULL; GL_Long T[POLY_Dmax+1][POLY_Dmax],*X=T[0], **G[POLY_Dmax],*GN[POLY_Dmax], *GI[POLY_Dmax][POLY_Dmax], GX[(POLY_Dmax*(POLY_Dmax+3))/2][POLY_Dmax]; *nw=0; /*s[-1]=-1;*/ for(j=0;jp-d) printf("WARNING: nw=%d > #pts-dim=%d\n",*nw,p-d); */ for(i=0;i<*nw;i++)for(n=0;nn, e=E->ne, v=V->nv; assert(e<=VERT_Nmax); P->np=V->nv=e; E->ne=v; for(i=0;ix[V->v[i]][j]; for(i=0;ix[i][j]=E->e[i].a[j]; V->v[i]=i;} for(i=0;ie[i].a[j]=VM[i][j]; E->e[i].c=1;} assert(Ref_Check(P,V,E)); } #undef TEST #define TEST #undef TEST_OUT void Aux_IPS_Print_Poly(PolyPointList *_P, VertexNumList *_V, int np,int nw,int VS,int CD) { int j; if(VS) Print_VL(_P,_V,"vertices of P-dual and IP-simplices"); else Print_PPL(_P,"points of P-dual and IP-simplices"); for(j=0; jnp-_P->n) fprintf(outFILE," > %d=#pts-dim",np-_P->n); fputs("\n",outFILE);} } void Aux_IPS_Print_W(Long *W,int w,int cd) { int j, d=0; for(j=0;j19) ? " %2d" : " %4d", (int)W[j]);d+=W[j];} fprintf(outFILE," %3d=d codim=%d",d,cd); } void Print_Fiber_PolyData(PolyPointList *P,VertexNumList *V,Long *W,int w, int n,int nw,int VS,int CD) { int cd=0, j, Mmp, Mmv, Mnp, Mnv, Nmp, Nmv, Nnp, Nnv; static int f; for(j=0; jn-w+1; if(CD==0) Aux_IPS_Print_W(W,w,cd); else if(n==0) f=0; if(CD||((cd>0)&&(cd<3)&&((P->n)-cd>1))) { int i, s=0, p, D=P->n, d=P->n-cd, fib, ref; Long X[VERT_Nmax][VERT_Nmax]; GL_Long G[POLY_Dmax][POLY_Dmax],Ginv[POLY_Dmax][POLY_Dmax]; EqList e; VertexNumList v; PolyPointList *F = (PolyPointList *) malloc(sizeof(PolyPointList));assert(F!=NULL); for(p=0;px[p][i]; s++;} #ifdef TEST_OUT {int j; puts("");for(i=0;inv;p++) for(i=0;ix[V->v[p]][s]; F->x[p][i]=x;} F->np=P->np; F->n=D; assert(Ref_Check(F,&v,&e)); Aux_Make_Dual_Poly(F,&v,&e); Make_VEPM(F,&v,&e,X); Complete_Poly(X,&e,v.nv,F); F->n=d; Remove_Identical_Points(F); fib=Ref_Check(F,&v,&e); Mmp=F->np;Mmv=v.nv;Mnv=e.ne; if(fib){Aux_Make_Dual_Poly(F,&v,&e); Make_VEPM(F,&v,&e,X); Complete_Poly(X,&e,v.nv,F); Mnp=F->np;} else Mnp=0; if(fib&&CD) {if(f==0){f=1;Aux_IPS_Print_Poly(P,V,w,nw,VS,CD);} Aux_IPS_Print_W(W,w,cd); fprintf(outFILE, " fiber m:%d %d n:%d %d\n",Mmp,Mmv,Mnp,Mnv); return;} s=0; F->np=P->np;F->n=D; for(p=0;px[s][i]=P->x[p][i]; s++;} for(p=0;px[s][i]=P->x[p][i]; s++;} for(p=w;pnp;p++) for(i=0;ix[p][i]=P->x[p][i]; Make_Poly_UTriang(F); s=0; for(p=0;pnp;p++) { for(i=d;ix[p][i]) break; if(i==D) {if(sx[s][i]=F->x[p][i]; s++;} } F->n=d;F->np=s;ref=Ref_Check(F,&v,&e);Nmv=e.ne; Nnp=F->np;Nnv=v.nv; #ifdef TEST_OUT puts("\nFiber:");Print_PPL(F,"Fiber"); #endif if(ref) { Long PM[VERT_Nmax][VERT_Nmax]; Aux_Make_Dual_Poly(F,&v,&e); Make_VEPM(F,&v,&e,PM); Complete_Poly(PM,&e,v.nv,F); Nmp=F->np; if(fib)fprintf(outFILE," fiber m:%d %d n:%d %d",Mmp,Mmv,Mnp,Mnv); else fprintf(outFILE," m:%d %d f:%d // m:%d %d n:%d %d", Mmp,Mmv,Mnv,Nmp,Nmv,Nnp,Nnv); } else fprintf(outFILE," m:%d %d f:%d // f:%d n:%d %d", Mmp,Mmv,Mnv,Nmv,Nnp,Nnv); free(F); } fprintf(outFILE,"\n"); } #ifdef OLD_IPS /* switch of Check_New_Fiber in ... !!! */ void IP_Simplices(PolyPointList *_P, int nv, int PS,int VS,int CDin){ int i, nw, np = VS ? nv : _P->np-1; Long W[FIB_Nmax][VERT_Nmax]; VertexNumList V; V.nv=nv; for (i=0;inp-1; i++) if(Vec_is_zero(_P->x[i],_P->n)) { Swap_Vecs(_P->x[i],_P->x[_P->np-1],_P->n); break;} CD=CDin; assert(CD<4); IP_Simplex_Decomp(_P->x,np,_P->n,&nw,W,FIB_Nmax,CD); if(nw==0) return; if(CD==0) Aux_IPS_Print_Poly(_P,&V,np,nw,VS,CD); for(i=0; inf; Long X[VERT_Nmax][VERT_Nmax],x; GL_Long Ginv[POLY_Dmax][POLY_Dmax]; for(i=0;iG[*n]); INV_GLZmatrix(F->G[*n],d,Ginv); for(i=0;i<*n;i++) if(r==F->r[i]) /* check if already found */ { int newfib=0; for(j=r;j<*d;j++) for(c=0;cG[i][j][l]*Ginv[l][c]; if(x)newfib=1; } if(!newfib) {if(!F->PS) F->nw--; return;} } F->P->np=F->nv; F->P->n=*d; for(i=0;inv;i++) for(j=0;j<*d;j++) F->P->x[i][j]=GxP(F->G[*n][j],PM[i],d); /* reflexivity of projection */ { VertexNumList V; EqList E; assert(Ref_Check(F->P,&V,&E)); EL_to_PPL(&E,F->P,d); F->P->n=r; Remove_Identical_Points(F->P); if(Ref_Check(F->P,&V,&E)) { assert(*nf[*n]=F->nw-1; F->r[*n]=r; (*n)++; } else if(!F->PS) F->nw--; } } void Print_Fibrations(PolyPointList *P,FibW *F) { int n; char C[VERT_Nmax]; VertexNumList V; EqList E; for(n=0;nnf;n++) { int s[VERT_Nmax], i,r=F->r[n],*d=&P->n,l,c=0,N; for(i=0;inp-1;i++) { for(l=r;l<*d;l++) if(GxP(F->G[n][l],P->x[i],d)) break; if(l==*d){for(l=0;lP->x[c][l]=GxP(F->G[n][l],P->x[i],d); s[c++]=i;} } F->P->np=c; F->P->n=r; assert(Ref_Check(F->P,&V,&E)); for(i=0;inp-1;i++) C[i]='_'; for(i=0;inp-1;i++) fprintf(outFILE,"%s%c", (P->np>20) ? " " : " ",C[i]); N=F->P->np+1; fprintf(outFILE," cd=%d ",*d-r); EL_to_PPL(&E,F->P,&r); assert(Ref_Check(F->P,&V,&E)); { Long X[VERT_Nmax][VERT_Nmax]; Make_VEPM(F->P,&V,&E,X); Complete_Poly(X,&E,V.nv,F->P);} fprintf(outFILE,"m:%d %d n:%d %d\n",F->P->np,V.nv,N,E.ne); } } void IP_Simplices_Docu(void) { puts("Allowed fibration flags: 1 2 3 11n 22n 33n 12n 23n with n=[ 123]"); printf("1,2,3: only fibrations spanned by IP simplices with codimension"); puts(" <= 1,2,3\n11,22,33: all fibrations with codimension 1,2,3"); puts("12,23: all codim-1 fibered fibrations with codimension 1,2"); puts("NNn with n=1,2,3: same as NN and n\n"); exit(0); } void Print_QuotZ(int Z[][VERT_Nmax],int *M,int p,int n) { int i,j; for(i=0;inp-1; FibW *F = (FibW *) malloc( sizeof(FibW) ); VertexNumList V; assert(F!=NULL); F->ZS=((PS<0)||(VS<0)); for (i=nv; i<_P->np-1; i++) if(Vec_is_zero(_P->x[i],_P->n)) { Swap_Vecs(_P->x[i],_P->x[_P->np-1],_P->n); break;} if((CDin<0)||(CDin>333)) IP_Simplices_Docu(); if(CDin<10) {CD=CDin; CDin=0;} else if(CDin>99) {CD=CDin % 10; CDin/=10;} switch(CDin){ case 0: case 11: case 22: case 33: case 12: case 23: break; default: IP_Simplices_Docu(); } if(CD > 3) IP_Simplices_Docu(); if(VS||CDin) { if(nv && (!PS)) {for(i=0;iV.v[j]) swap(&V.v[i],&V.v[j]); nv=V.v[V.nv-1]+1; } } if(VS) { Print_VL(_P,&V,"vertices of P-dual and IP-simplices"); for(i=0; ix,nv,_P->n,F,FIB_Nmax,0); else { Long P[VERT_Nmax][POLY_Dmax]; for(i=0;in;j++)P[i][j]=_P->x[V.v[i]][j]; IP_Simplex_Fiber(P,V.nv,_P->n,F,FIB_Nmax,0); } fprintf(outFILE," #IP-simp=%d",F->nw); if(F->nw>V.nv-_P->n) fprintf(outFILE," > %d=#pts-dim",V.nv-_P->n); if(F->ZS) { Long *pl[VERT_Nmax]; for(i=0;ix[V.v[i]]; Print_Quotient(pl,_P->n,V.nv); } fputs("\n",outFILE); for(i=0; inw; i++) { int cd=_P->n-V.nv+1 ; for(j=0;jW[i][j]) cd++; Aux_IPS_Print_W(F->W[i],V.nv,cd); if(F->ZS) if(F->nz[i]) Print_QuotZ(&F->Z[F->n0[i]],&F->M[F->n0[i]],nv,F->nz[i]); fprintf(outFILE,"\n"); } } if(CD) { F->P=(PolyPointList *)malloc(sizeof(PolyPointList)); assert(F->P!=NULL); F->PS=PS; F->nv=nv; } if(CD||PS) { /* if(CD)*/ IP_Simplex_Fiber(_P->x,np,_P->n,F,FIB_Nmax,CD); /* else IP_Simplex_Decomp(_P->x,np,_P->n,&F->nw,F->W,FIB_Nmax,CD);*/ if(F->nw) { fprintf(outFILE,"%d %d %s\n",_P->n,_P->np, "points of P-dual and IP-simplices"); for(i=0;i<_P->n;i++) { for(j=0;j<_P->np;j++) fprintf(outFILE,(_P->np>20) ? " %2d" : " %4d", (int)_P->x[j][i]);fprintf(outFILE,"\n");}} if(PS) { for(i=0; i20) ? "---" : "-----"); fprintf(outFILE," #IP-simp=%d",F->nw); if(F->nw>np-_P->n) fprintf(outFILE," > %d=#pts-dim",np-_P->n); fputs("\n",outFILE); for(i=0; inw; i++) { int cd=_P->n-np+1 ; for(j=0;jW[i][j]) cd++; Aux_IPS_Print_WP(F->W[i],np,cd); if(F->ZS) if(F->nz[i]) Print_QuotZ(&F->Z[F->n0[i]],&F->M[F->n0[i]],np,F->nz[i]); fprintf(outFILE,"\n"); } } if(CD) { for(i=0; i20) ? "---" : "-----"); fprintf(outFILE," #fibrations=%d",F->nf); fputs("\n",outFILE); Print_Fibrations(_P,F); } } if(CDin) switch(CDin){ case 11: All_CDn_Fibrations(_P,nv,1); break; case 22: All_CDn_Fibrations(_P,nv,2); break; case 33: All_CDn_Fibrations(_P,nv,3); break; case 12: Elliptic_K3_Fibration(_P,nv,_P->n-2); break; case 23: Elliptic_K3_Fibration(_P,nv,_P->n-3); break; } if(CD) free(F->P); free(F); return; } void IP_Fiber_Data(PolyPointList *PD,PolyPointList *AuxP,int nv,/* PD::N-lat.*/ Long G[VERT_Nmax][POLY_Dmax][POLY_Dmax],int fd[VERT_Nmax],int *nf,int CD) { int i,j,k; FibW *F = (FibW *) malloc ( sizeof(FibW) ); assert(NULL != F); F->P=AuxP; F->PS=F->ZS=0; F->nv=nv; IP_Simplex_Fiber(PD->x,PD->np-1,PD->n,F,FIB_Nmax,CD); *nf=F->nf; for(i=0;i<*nf;i++) { fd[i]=F->r[i]; for(j=0;jn;j++)for(k=0;kn;k++) G[i][j][k]=F->G[i][j][k]; } free(F); } /* aux routine for nef package */ #endif /* ============================================================= */ /* ============================================================= */ /* find GLZ G such that G*P generates a diagonal basis D; basis = Ginv x D */ /* minimum of column gcd's -> basis vector -> while(line-entry%g) reduce */ Long AuxColGCD(int *d, int l, GL_Long G[][POLY_Dmax], Long *X) { Long g=labs(GxP(G[l],X,d)), x; while(++l<*d) if((x=labs(GxP(G[l],X,d)))) g=(g) ? Fgcd(g,x) : x; return g; } void Normalize_Diagonal(int *d, Long *D, GL_Long **G) { int a,b,i; for(a=0;a<*d-1;a++) for(b=a+1;b<*d;b++) if(D[b]%D[a]) { GL_Long A, B, g=GL_Egcd(D[a],D[b],&A,&B), X=-D[b]/g, Y=D[a]/g, L; D[b]*=D[a]/g; D[a]=g; for(i=0;i<*d;i++) { L=A*G[a][i]+B*G[b][i]; G[b][i]=X*G[a][i]+Y*G[b][i]; G[a][i]=L; } } for(i=1;i<*d;i++) assert((D[i]%D[i-1])==0); } int GL_Lattice_Basis(int d, int p, Long *P[POLY_Dmax], /* return index */ GL_Long GM[][POLY_Dmax], Long *D, GL_Long BM[][POLY_Dmax]) { int L,C;Long g,a,index=1;GL_Long V[POLY_Dmax],*G[POLY_Dmax],*B[POLY_Dmax]; static int x;x++; for(L=0;L B, G.B */ } else /* search best gcd */ { if((g==0)||(a B, G.B */ for(C=0;Ci;j--) /* reduce: (g1.g2) m=lcm(m1,m2) */ { int mi,mj;Long *Zi,*Zj;g=Fgcd(M[i],M[j]);/* g2^(m2/m') m'=gcd(m1,m2) */ mi=M[i]/g; mj=M[j]/g; Zi=Z[i]; Zj=Z[j]; M[i]*=mj; M[j]=g; for(k=0;k<*d;k++) { Zi[k]=mj*Zi[k]+mi*Zj[k]; if((Zi[k]%=M[i])<0) Zi[k]+=M[i]; if(M[j]>1) {if((Zj[k]%=M[j])<0) Zj[k]+=M[j];} } } while(M[*m-1]==1)(*m)--; assert(*m>0);for(i=0;i<*m;i++)assert(M[i]>1); for(i=0;i<*m;i++) {Long *Zi=Z[i]; for(j=0;j<*d;j++) { if((Zi[j]%=M[i]) < 0) Zi[j]+=M[i]; A[j][i]=Zi[j];}} r=PM_to_GLZ_for_UTriang(A,d,m,GT); INV_GLZmatrix(GT,d,Ginv); for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=Ginv[j][i];/* Z*G lower trian */ #ifdef TEST_QZ printf("rank=%d m=%d\n",r,*m); for(i=0;i<*m;i++){for(j=0;j<*d;j++)printf("%2d ",Z[i][j]); printf("/%d normalized\n",M[i]);} for(i=0;i<*m;i++){for(j=0;j<*d;j++)printf("%2d ",GxP(GT[j],Z[i],d)); printf("/%d Z*G diagonal\n",M[i]);} for(i=0;i<*d;i++){for(j=0;j<*d;j++)printf("%2d ",G[i][j]); printf("=G[%d]\n",i);} /* *m=0; for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=(i==j); */ #endif assert((*m) == r); } /* g=gcd(M1,M2), L=lcm(M1,M2)=M1.m2=m1.M2=m1.m2.g, a*m1+b*m2=1 * * G1=g1.g2 (order L), G2=g2/G1^(a*m1)=g2^b*m2/g1^a*m1 (order g). */ Long Phase(Long *Z,int p){Long s=0;while(p--)s+=Z[p];return s;} void Print_QuotientZ(int *r,int *p,Long Z[POLY_Dmax][VERT_Nmax],Long *M) { int i,j; fprintf(stderr,"Z-action:\n"); for(i=0;i<*r;i++){ for(j=0;j<*p;j++) fprintf(stderr,"%5ld ",Z[i][j]); fprintf(stderr," /Z%ld\n",M[i]);} } void Normalize_QuotientZ(int *r,int *p,Long Z[POLY_Dmax][VERT_Nmax],Long *M) { int i,j=0,k; /* for(i=0;i<*r;i++) if(Phase(Z[i],*p)%M[i]) ... don't check phase::I/O { fprintf(stderr,"\nZ%d[i=%d]:",M[i],i); for(k=0;k<*p;k++) fprintf(stderr," %d",Z[i][k]); fprintf(stderr, "\ndet!=1 in Normalize_QuotientZ\n\n");exit(0); } */ /* Print_QuotientZ(r,p,Z,M); */ for(i=0;i<*r;i++) {Long g=M[i]; assert(g>0); for(k=0;k<*p;k++) g=NNgcd(g,Z[i][k]); if(g>1){M[i]/=g; for(k=0;k<*p;k++) Z[i][k]/=g;}} for(i=0;i<*r;i++) if(M[i]>1) { if(i>j) {Long *Zi=Z[i],*Zj=Z[j]; for(k=0;k<*p;k++)Zj[k]=Zi[k]; M[j]=M[i];} j++; } else assert(M[i]==1); *r=j; /* drop trivial factors */ for(i=0;i<*r;i++) {Long *z=Z[i];j=M[i]; /* make min non-neg */ for(k=0;k<*p;k++)if((z[k]%=j)<0)z[k]+=j;} for(i=0;i<*r-1;i++)for(j=*r-1;j>i;j--)if(M[i]%M[j]) /* Mi -> L; Mj -> g */ { Long g=Fgcd(M[i],M[j]),*Zi=Z[i],*Zj=Z[j]; int mi=M[i]/g,mj=M[j]/g; M[i]*=mj; for(k=0;k<*p;k++) Zi[k] = (mj*Zi[k]+mi*Zj[k]) % M[i]; if(g>1) /* compute G2 */ { Long A,B; assert(1==Egcd(mi,mj,&A,&B)); M[j]=g; for(k=0;k<*p;k++) { Zj[k]-=A*Zi[k]; assert(0==(Zj[k]%mj)); Zj[k]/=mj; if((Zj[k]%=g)<0) Zj[k]+=g; } } else if(j==*r-1) (*r)--; /* drop G2 */ else { Zi=Z[*r-1]; for(k=0;k<*p;k++)Zj[k]=Zi[k]; M[j]=M[--(*r)]; } } /* Print_QuotientZ(r,p,Z,M); */ } void Test_Effective_Zaction(int *r,int *d,Long Z[POLY_Dmax][VERT_Nmax],Long *M) { int i,j; Long g; for(i=0;i<*r;i++) { g=labs(Z[i][0]); for(j=1;j<*d;j++)if(Z[i][j])g=Fgcd(g,labs(Z[i][j])); if(g!=1){if(Fgcd(g,M[i])==1){/*printf("g=%d M=%d\n",g,M[i]);exit(0)*/;} else {printf("Non-effective group action [%d]\n",i);exit(0);}} } } void QuotZ_2_SublatG(Long Z[][VERT_Nmax],int *m,Long *M,int *d, Long G[][POLY_Dmax]) /* normalize and diagonalize Z */ { int i,j,r;GL_Long GT[POLY_Dmax][POLY_Dmax],Ginv[POLY_Dmax][POLY_Dmax]; Long A[POLY_Dmax][VERT_Nmax]; Normalize_QuotientZ(m,d,Z,M); /* don't check determinants !!! */ Test_Effective_Zaction(m,d,Z,M); for(i=0;i<*m;i++) for(j=0;j<*d;j++) A[j][i]=Z[i][j]; r=PM_to_GLZ_for_UTriang(A,d,m,GT); INV_GLZmatrix(GT,d,Ginv); for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=Ginv[j][i];/* Z*G lower trian */ #ifdef TEST_QZ printf("rank=%d m=%d\n",r,*m); for(i=0;i<*m;i++){for(j=0;j<*d;j++)printf("%2d ",Z[i][j]); printf("/%d normalized\n",M[i]);} for(i=0;i<*m;i++){for(j=0;j<*d;j++)printf("%2d ",GxP(GT[j],Z[i],d)); printf("/%d Z*G diagonal\n",M[i]);} for(i=0;i<*d;i++){for(j=0;j<*d;j++)printf("%2d ",G[i][j]); printf("=G[%d]\n",i);} /* *m=0; for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=(i==j); */ #endif assert((*m) == r); } int GL_Lattice_Basis_QZ(int d,int p, Long *P[VERT_Nmax], Long *D, /* index */ Long Z[][VERT_Nmax], Long *M, int *r, GL_Long GM[][POLY_Dmax], GL_Long BM[][POLY_Dmax]); /* PM_2_Quotie ... general purpose making quotients from PointMatrix * Aux_Mat_2_Q ... translating triantular form on T[s[i]] ... onto FibW */ int PM_2_QuotientZ(Long PM[VERT_Nmax][POLY_Dmax], int *d, int *p, Long Z[POLY_Dmax][VERT_Nmax], Long M[POLY_Dmax], int *n) { int i,j,I,rk=0; GL_Long G[POLY_Dmax][POLY_Dmax],B[POLY_Dmax][POLY_Dmax]; Long D[POLY_Dmax],*P[VERT_Nmax];for(j=0;j<*p;j++)P[j]=PM[j]; for(i=0;i<*d;i++)for(j=0;j<*p;j++)Z[i][j]=PM[j][i]; *n=PM_to_GLZ_for_UTriang(Z,d,p,G); if(*n<*d) for(i=0;i<*n;i++)for(j=0;j<*p;j++) { PM[j][i]=0; for(I=0;I<*d;I++)PM[j][i]+=G[i][I]*Z[I][j]; } I=GL_Lattice_Basis_QZ(*n,*p,P,D,Z,M,&rk,G,B); #ifdef TEST_OUT puts("PM_2_QuotientZ:\n"); for(i=0;inw>0); #ifdef TEST_out {int i,j,dd=rk,pp=p;for(i=0;in0[F->nw-1] = (F->nw>1) ? (F->n0[F->nw-2]+F->nz[F->nw-2]) : 0; F->nz[F->nw-1] = rk; assert(F->n0[F->nw-1]+F->nz[F->nw-1] <= FIB_Nmax); j=F->n0[F->nw-1]; for(i=0;iZ[j+i]; m=&F->M[j];} /* assert(rk>=0);printf("rk=%d s[0]=%d i=%d j=%d\n",rk,s[0],i,j); */ for(i=0;inw=%d\n",F->nw); for(i=0;iZS) Aux_Mat_2_QuotientZ(T,d,p,&r,s,F); return 1; } else return 0; } Long AuxLinRelGPZ(Long *A,int *j,Long *D,int *d,Long GP[][POLY_Dmax],int *p, Long Z[][VERT_Nmax]) { Long s=0,g=0; int i,l; for(l=0;l<*p;l++){ A[l]=(l==(*j)); for(i=0;i<*d;i++) A[l]-=(GP[*j][i]/D[i])*Z[i][l]; g=(g) ? NNgcd(A[l],g) : A[l];} if(g) {for(l=0;l<*p;l++) s+=(A[l]/=g); return s;} else return 0; } void Test_Phase(int d,int p,Long *P[],Long Z[][VERT_Nmax],Long *M,int r,char*c) { int i,j; for(i=0;im){for(l=0;l<*p;l++)A[l]*=-1;s=m-s;} ms=Egcd(m,s,&a,&b); if((r=x/ms)) for(l=0;l<*p;l++) z[l]-=r*b*A[l]; #ifdef TEST_ImpPhase for(l=0;l<*p;l++)printf("%2d ",A[l]); printf("=lr[%d] s=%d\n",j,s); printf("ms=%d m=%d s=%d a=%d b=%d r=%d x=%d\n",ms,m,s,a,b,r,x); #endif x=Phase(z,*p) % m; if(x==0) return 1; if(x<0)x+=m; } return 0; } int GL_Lattice_Basis_QZ(int d,int p, Long *P[VERT_Nmax], Long *D, /* index */ Long Z[][VERT_Nmax], Long *M, int *r, GL_Long GM[][POLY_Dmax], GL_Long BM[][POLY_Dmax]) { Long g,a,index=1,*Y; GL_Long V[POLY_Dmax], *G[POLY_Dmax], *B[POLY_Dmax]; int L,C, tz=(p B, G.B */ } else /* search best gcd */ { if((g==0)||(a B, G.B */ for(C=0;C %ld /%ld\n", Phase(Z[i],p)%D[i],D[i]);} for(i=0;i1)for(c=0;c1 for p>VERT_Nmax"); exit(0);} } *r = (index==1) ? 0 : d; #ifdef TEST if(tz) for(L=0;LN,w=W->nw, nz=0,np=0, z[AMBI_Dmax], p[AMBI_Dmax], pi[AMBI_Dmax], X[AMBI_Dmax]; Long *L=W->W[0]; for(i=0;ii;j--) if(L[pi[j-1]]nw>1) { L=W->W[1]; for(i=np;ii;j--) if(L[pi[j-1]]W[j][pi[i]];for(i=0;iW[j][i]=X[i]; } for(j=0;jnz;j++) { for(i=0;iz[j][pi[i]];for(i=0;iz[j][i]=X[i]; } } Long WZ_to_GLZ(Long *W,Long *Waux,int *d,Long **G) /* allows components=0 */ { int i,j,r=0,J; Long g; for(i=0;i<*d;i++) if(W[i]) Waux[r++]=W[i]; if(r<2){for(i=0;i<*d;i++)for(j=0;j<*d;j++)G[i][j]=(i==j); if(r==1){for(i=0;i<*d;i++)if(W[i]) break; G[0][i]=G[i][0]=1; G[0][0]=G[i][i]=0; return W[i];} else return 0;} g=W_to_GLZ(Waux,&r,G); if(r<*d) { j=0; for(i=0;i<*d;i++) if(W[i]) Waux[j++]=i; J=0; while(W[J]) J++; assert(J<*d); for(j=r-1;J<=j;j--)for(i=0;iAMBI_Dmax)return 0; for(j=0;jp[R]) R=r; if(p[R]==p[r]) if(d[r]W[0][j]=W[R][j]; CW->d[0]=d[R]; CW->nw=1; for(i=0;ii;j--) wp[j]=wp[j-1]; wp[i]=r; } for(j=0;jW[0],X,&v,C); for(r=0;rnw; Long Y[AMBI_Dmax]; R=wp[r]; for(i=CW->nw;inw;iW[CW->nw][j]=W[R][j]; CW->d[CW->nw]=d[R]; #ifdef TEST_OUT for(i=0;inw],X,&cd,B); C_to_BrxC(B,C,X,&cd,&v); CW->nw++; /*Print_XXG(B,&cd,"B"); Print_xxG(C,&v,"BxC");*/ assert(CW->nw<=v-n); if(CW->nw==v-n) break; } assert(CW->nw==v-n); Sublattice_Basis(n,v,V,Z,M,&r,G,D); for(i=0;iz[i][j]=Z[i][j];CW->m[i]=M[i];} /* for(i=0;im[i]==0); */ CW->N=v; CW->nz=r; #if (SORT_CWS) Sort_CWS(CW); #endif return 1; } void Print_if_Divisible(PolyPointList *P,VertexNumList *V) { char divi[99]; Long g=Divisibility_Index(P,V); if(g<2) return; sprintf(divi,"divisible by factor=%ld",g); Print_VL(P,V,divi); } void Aux_Complete_Poly(PolyPointList *P,VertexNumList *V,EqList *E) /* ??? */ { int e,v; Long MaxDist[EQUA_Nmax][VERT_Nmax]; assert(E->ne > P->n); /* check spanning of dimension */ for(e=0;ene;e++) { MaxDist[e][0]=Eval_Eq_on_V(&E->e[e],P->x[V->v[0]],P->n); for(v=1;vnv;v++) { Long X=Eval_Eq_on_V(&E->e[e],P->x[V->v[v]],P->n); if(X>MaxDist[e][0]) MaxDist[e][0]=X; } } Complete_Poly(MaxDist,E,1,P); } /* Complete_Poly unfortunetely requires Matrix[][VERT_Nmax] */ void Make_Dilat_Poly(PolyPointList *P,VertexNumList *V,EqList *E,int k, PolyPointList *kP) { int e,v; Long MaxDist[EQUA_Nmax][VERT_Nmax]; kP->np=0; assert(E->ne > P->n); /* check spanning of dimension */ for(e=0;ene;e++) { MaxDist[e][0]=Eval_Eq_on_V(&E->e[e],P->x[V->v[0]],P->n); for(v=1;vnv;v++) { Long X=Eval_Eq_on_V(&E->e[e],P->x[V->v[v]],P->n); assert(X>=0); if(X>MaxDist[e][0]) MaxDist[e][0]=X; } MaxDist[e][0] *= k; E->e[e].c *= k; } Complete_Poly(MaxDist,E,1,kP); for(e=0;ene;e++) E->e[e].c /= k; } void LatVol_IPs_degD(PolyPointList *P,VertexNumList *V,EqList *E,int g) { Long vB[POLY_Dmax],vol,Z; int e,j; vol=LatVol_Barycent(P,V,vB,&Z); printf("vol=%ld, baricent=(",vol); for(j=0;jn;j++) printf("%s%ld",j?",":"",vB[j]); printf(")/%ld\n",Z); if(g) { PolyPointList *gP = (PolyPointList *) malloc(sizeof(PolyPointList)); j=0; for(e=0;ene;e++) if(E->e[e].c==0)j++; if(jn) { puts( "-B#: IPs at degree D is only implemented for Gorenstein cones!"); exit(0);} /* parallel-epiped ... to be done */ assert(gP!=NULL); gP->n=P->n;gP->np=0; Make_Dilat_Poly(P,V,E,g,gP); if(POLY_Dmax*VERT_Nmaxnp){puts("increase dim of IP");exit(0);} puts("IPs:"); for(j=0;jnp;j++){ int i,cd=0; for(e=0;ene;e++) if(E->e[e].c==0) if(0==Eval_Eq_on_V(&E->e[e],gP->x[j],P->n)) cd++; if((cd==0)||(E->ne==P->n+1)) { for(i=0;in;i++) printf(" %ld",gP->x[j][i]); printf(" cd=%d",cd); puts("");} } /* Print_PPL(gP,"gPoly"); */ free(gP); } if(0){puts("-B#: (I)Ps at degree D, only implemented if 0 is a vertex!"); puts("to be done");exit(0);} /* parallel-epiped */ } void IPs_degD(PolyPointList *P,VertexNumList *V,EqList *E,int g){ PolyPointList *gP = (PolyPointList *) malloc(sizeof(PolyPointList)); int e, j=0; for(e=0;ene;e++) if(E->e[e].c==0)j++; if(jn) { puts("-B#: IPs at degree D is only implemented for Gorenstein cones!"); exit(0);} /* parallel-epiped ... to be done */ assert(gP!=NULL); gP->n=P->n;gP->np=0; Make_Dilat_Poly(P,V,E,g,gP); if(POLY_Dmax*VERT_Nmaxnp){puts("increase dim of IP");exit(0);} puts("IPs:"); for(j=0;jnp;j++){ int i,cd=0; for(e=0;ene;e++) if(E->e[e].c==0) if(0==Eval_Eq_on_V(&E->e[e],gP->x[j],P->n)) cd++; if((cd==0)||(E->ne==P->n+1)){ for(i=0;in;i++) printf(" %ld",gP->x[j][i]); printf(" cd=%d",cd); puts("");} } /* Print_PPL(gP,"gPoly"); */ free(gP); } int Check_ANF_Form(Long VM[][VERT_Nmax], int d, int v) { int i, r=1, c=0; Long G[POLY_Dmax]; for(i=0;i<=d;i++) if(VM[i][0]) break; c+=(i==d+1); /* 0 == VM[0] */ for(i=1;i<=d;i++) if(VM[i][1]) break; c+=(i==d+1); c+=(VM[0][1]==1); if(c!=3) {Print_Matrix(VM, d+1, v+1,"unexpected AFF-NF"); return 1;} G[0]=1; for(c=2;c<=v;c++) { for(i=r+1;i<=d;i++)if(VM[i][c]) {Print_Matrix(VM, d+1, v+1,"rank increase>1 in AFF-NF");return 1;} if(VM[r][c]) /* rank++ => solve G.Vc==1 */ { Long g=1; for(i=0;in, v=V->nv, e=E->ne, p=P->np; assert(V->nvnnpn,0,"eq-in"); PairMat PM; Make_VEPM(P,V,E,PM); Print_Matrix(PM, E->ne, V->nv,"PM");*/ for(i=0;ix[V->v[i]][d]=1; P->n=d+1; V->nv++; for(j=0;j<=d;j++) P->x[p][j]=0; P->np=p+1; V->v[v]=p; for(i=0;ie[i].a[d]=E->e[i].c; E->e[i].c=0;} for(j=0;je[e].a[j]=0; E->e[e].a[d]=-1; E->e[e].c=1; E->ne++; /* Print_PPL(P,"AFF");Print_VL(P,V,"AFFvert");Print_EL(E,&P->n,0,"AFFeq"); Make_VEPM(P,V,E,PM); Print_Matrix(PM, E->ne, V->nv,"AFF-PM"); */ Make_Poly_NF(P,V,E,VM); if(Check_ANF_Form(VM,d,v)) {Print_PPL(P,"unexpected in ANF"); fprintf(stderr,"unexpected ANF");exit(0);} Reduce_ANF_Form(VM,d,v); for(i=0;ie[i].c=E->e[i].a[d]; /* restore original P,E,V */ P->n=d;P->np=p; V->nv=v;E->ne=e; /* Print_PPL(P,"Pout");Print_VL(P,V,"Vout");Print_EL(E,&P->n,0,"Eout");*/ } void EPrint_VL(PolyPointList *_P, VertexNumList *V,double f){ int i,j; fprintf(stderr,"%d %d fat=%f\n",_P->n,V->nv,f); for(i=0;i<_P->n;i++) { for(j=0;jnv;j++) fprintf(stderr," %3ld",_P->x[V->v[j]][i]); fprintf(stderr,"\n");} } void Print_Facets(PolyPointList *P,VertexNumList *V,EqList *E) { int e,err=0; Long VM[POLY_Dmax][VERT_Nmax]; for(e=0;ene;e++) { int c=0, v, j; for(v=0;vnv;v++) if(0==Eval_Eq_on_V(&E->e[e],P->x[V->v[v]],P->n)) { for(j=0;jn;j++) VM[j][c]=P->x[V->v[v]][j]; c++; } for(j=0;jn;j++) for(v=0;vn,c,"");*/ Aux_Make_Poly_NF(VM,&P->n,&c); /* Print_Matrix(VM,P->n,c,"");*/ for(j=0;jn-1][j]!=0) err=1; if(err){ int i; fprintf(stderr,"%d %d VM c=%d\n",P->n,V->nv,c); for(i=0;in;i++){ for(j=0;jn-1,c,""); } } void Make_Facet(PolyPointList *P,VertexNumList *V,EqList *E, int e, Long VM[POLY_Dmax][VERT_Nmax], int *cc){ /* writes the e'th facet to VM, cc... */ assert(e < E->ne); int c=0, err=0, v, j; for(v=0;vnv;v++) if(0==Eval_Eq_on_V(&E->e[e],P->x[V->v[v]],P->n)) { for(j=0;jn;j++) VM[j][c]=P->x[V->v[v]][j]; c++; } for(j=0;jn;j++) for(v=0;vn,c,"");*/ SL2Z_Aux_Make_Poly_NF(VM,&P->n,&c); /* Print_Matrix(VM,P->n,c,"");*/ for(j=0;jn-1][j]!=0) err=1; if(err){ int i; fprintf(stderr,"%d %d VM c=%d\n",P->n,V->nv,c); for(i=0;in;i++){ for(j=0;jn-1,c,""); */ } #ifdef FIND_OCTAHEDRON int FindOctahedron(PolyPointList *P,VertexNumList *V,EqList *E){Matrix M,G; int n,i, x=0, X[90*VERT_Nmax]; for(n=1;nnp;n++){int l; for(l=0;ln;i++) if(P->x[l][i]+P->x[n][i]) break; if(i==P->n) {assert(x<90*VERT_Nmax); X[x++]=n;}}} // x[l] == -x[n] Init_Matrix(&M,x,P->n); Init_Matrix(&G,P->n,P->n); for(n=0;nn;i++)M.x[n][i]=P->x[X[n]][i]; n=(M.d==Make_G_for_GxMT_UT(M,G));Free_Matrix(&M);Free_Matrix(&G); return n;} #endif int CodimTwoFaceNum(PolyPointList *P,VertexNumList *V,EqList *E) { int i, j, n=0, LiVj[FACE_Nmax]; INCI FI[FACE_Nmax], EI[ 2*VERT_Nmax ]; assert(E->ne<= 2*VERT_Nmax ); for(i=0;ine;i++) EI[i]=Eq_To_INCI(&E->e[i],P,V); /* EqInci=facet */ for(i=1;ine;i++) for(j=0; jnv;break;} /* x>y :: y=x; */ else if(INCI_LE(x,FI[k])) break; /* xnv; FI[n++]=x;} #ifdef FIND_OCTAHEDRON /* dirty for Fano-Projection */ } if(P->n!=4){int k,l; Long edge=0; for(k=0;knv; j=LiVj[k]%V->nv; for(l=0;ln;l++) x=NNgcd(x,E->e[i].a[l]-E->e[j].a[l]); if(x>edge)edge=x; } printf("|edge|<=%ld\n",edge); assert(edge>0); if(0==FindOctahedron(P,V,E)) Print_PPL(P,"contains no octahedron"); #endif } return n; /* non-comparable => new */ } /* requires E,V pre-allocation; computes E,V; completes points; returns np */ Long Poly_Point_Count(PolyPointList *P,VertexNumList *V,EqList *E) { Find_Equations(P,V,E); Aux_Complete_Poly(P,V,E); return P->np; } #define TESTfano 0 #define FanoProjNPmax 14 #define FPcirNmax 15 #define PrintFanoProjCand 1 /* */ #define INCIbits unsigned long long int getNI(int N,INCIbits I){return (I>>N)%2;} /* read INCIDENCE */ int Make_Fano5d(PolyPointList *,int *,EqList *, int symDP, int nc, int CC[FPcirNmax][FanoProjNPmax]); int Fano5d(PolyPointList *P,VertexNumList *V,EqList *E){ int e,d=P->n,np=P->np-1,z,n=V->nv,nc=0,D[VERT_Nmax],p[POLY_Dmax],symDP=1; char s[99]="FanoProjection candidate #nnn"; int CC[FPcirNmax][FanoProjNPmax]; static int FPc; INCIbits FI[VERT_Nmax],CI[FPcirNmax]; PolyPointList *Q; EqList *F; Matrix G, M; /* assert(d==4); */ if(FanoProjNPmax<=np)return 0; assert(dne<=VERT_Nmax); for(z=np;0<=z;z--){{for(n=0;nx[z][n])break;}if(n==d)break;} assert(0<=z); if(zx[z][n]=P->x[np][n];P->x[np][n]=0;} for(e=0;ene;e++) FI[e]=0; for(n=0;nne;e++){Long *Y[POLY_Dmax]; int i=0; for(n=0;ne[e],P->x[n],d)){ FI[e]+=1<d) return 0; p[i++]=n;} for(n=0;nx[p[n]]; if(i==d) {if(1!=(SimplexVolume(Y,d))) return 0;}/* simplicial unimodular */ else {int p1=0,m1=0,p2=0,m2=0,sum=0; Long C[POLY_Dmax]; assert(i==d+1); Circuit(d,Y,C); for(i=0;i<=d;i++) {sum+=C[i]; if(C[i]>0) {if(C[i]>1) p2++; else p1++;} else if(C[i]<0) {if(C[i]<-1) m2++; else m1++;}} if(sum || (m2 && p2)) return 0; /* Batyrev :: inconsistent projection */ CI[nc]=0; for(i=0;i<=d;i++) {D[p[i]]=0; if(C[i])CI[nc]+=1< change signs */ else for(i=0;i<=d;i++) CC[nc][p[i]]=C[i]; if(p2||m2) {symDP=0; CC[nc][np]=0;} /* circuits with abs(C[])>1 */ else CC[nc][np]=1; assert(++nc "); for(i=0;i<=d;i++)printf("%ld ",C[i]); puts(" [circuit]"); */ } } if(PrintFanoProjCand){int c; FILE *OF=outFILE; outFILE=stdout; n=++FPc; e=99; while(n){s[--e]='0'+(n%10);n/=10;} for(n=26;n<125-e;n++) s[n]=s[e+n-26]; s[n]=0; Print_PPL(P,s); outFILE=OF; printf("Facets[%d]:",E->ne); for(e=0;ene;e++){ printf(" "); for(n=0;nne;f++) if((FI[f]&CI[c])==CI[c]) printf(" F[%d]",f); puts("");} printf("DoublePt = "); for(n=0;nn=P->n+1; for(n=0;nx[n][z]=(n==z); for(e=0;ene;e++) {int c,x=0,X[FanoProjNPmax]; /* BEGIN go over CELLS */ for(n=0;nx[X[j]][i]; I+=1<x[X[k]][i]; if(s!=(k==l)){if(TESTfano==1) /* >> test UnitBasis << */ {Print_LMatrix(G,"G");Print_LMatrix(M,"M");exit(0);} goon = 0;}}} if (goon){ for(k=0;kx[P->np-1][k]=0; Q->x[k][d]=0;} Q->np=P->np; Q->x[np][d]=0; l=0; for(k=d;kx[k][d]=0; while(getNI(l,I)) l++; DP[k]=D[l]; if(TESTfano==1)printf("l=%d ",l); for(i=0;ix[k][i]=0; for(j=0;jx[k][i]+=G.x[i][j]*P->x[l][j]; } l++;} if(TESTfano==1){puts("");Print_PPL(Q,"fano");} else if(TESTfano==2){Q->n--;Print_PPL(Q,"fanoP");Q->n++;} else if(inFILE!=stdin)Make_Fano5d(Q,DP,F,symDP,nc,CC);}}/* ENDof base change */ else {int Y[POLY_Dmax]; assert(x==d+1); /* circuit facet case */ for(c=0;cx[Y[j]][i]; I+=1<x[Y[k]][i]; if(s!=(k==l)){if(TESTfano==1) /* >> test UnitBasis << */ {Print_LMatrix(G,"G");Print_LMatrix(M,"M");exit(0);} goon = 0;}}} if(goon){ for(k=0;kx[P->np-1][k]=0; Q->x[k][d]=0;} Q->np=P->np; Q->x[np][d]=0; l=0; for(k=d;kx[k][d]=0; while(getNI(l,I)) l++; DP[k]=D[l]; if(TESTfano==1)printf("l=%d ",l); for(i=0;ix[k][i]=0; for(j=0;jx[k][i]+=G.x[i][j]*P->x[l][j]; } l++;} if(TESTfano==1){puts("");Print_PPL(Q,"fano");} else if(TESTfano==2){Q->n--;Print_PPL(Q,"fanoP");Q->n++;} else if(inFILE!=stdin)Make_Fano5d(Q,DP,F,symDP,nc,CC);}}}/* ENDof base change */ if(TESTfano==1){for(c++;cx[p][n] = n-th coordinate of p-th point with 0 <= n < d, 0 <= p < np. * For 4d projections of 5d Fanos we have d=4 (but P->n is already set to 5). * Dpt[i] is 1 if P->x[i] may be a double point and is 0 otherwise. * The first d points on P->x[0,...,d-1] have been transformed to a standard * basis and the last point P->x[np-1] denotes the origin 0. * The subroutine "Print_Fano5d(P,Dpt)" now needs to assign the last * coordinate to the $np$ points on P and possible add further $na$ * points if there are $na$ double points. For each of the assignments * P->np has to be set to np+na and after a reflexivity check * if(Ref_Check(P,&V,F)) the polytope is printed by Print_PPL(P,"fano"); */ int TempVecUpdate0(int tempvec[], int l, int* atotal_zeiger, int limitwert, int singlelimit, int* zero_zeiger){ /*Erhoehung von tempvec und atotal*/ /* Hier ist l Laenge von tempvec, atotal_zeiger zeigt auf atotal=Summe der Eintraege, und limitwert max. Summe */ #if (ALL_FANOS_BUT_INEFFICIENT) singlelimit++; #endif int akt=l-1; /* akt. Index, der erhoeht werden soll */ while(akt >= 0){ if ((*atotal_zeiger < limitwert) && (tempvec[akt] < singlelimit)){ if (tempvec[akt] == 0) *zero_zeiger = *zero_zeiger - 1; tempvec[akt]++; *atotal_zeiger = *atotal_zeiger + 1; /* ist <=limitwert */ return 1; } if (tempvec[akt] != 0) *zero_zeiger = *zero_zeiger + 1; *atotal_zeiger -= tempvec[akt]; tempvec[akt]=0; akt=akt-1; } return 0; } int TempVecUpdate1(int tempvec[], int l, int* atotal_zeiger, int limitwert, int dpindex, int singlelimit, int* zero_zeiger){ /* Erhoehung von tempvec und atotal, wobei ein Index auf DP zeigt */ /* Hier ist l Laenge von tempvec, atotal_zeiger zeigt auf atotal=Summe der Eintraege (inkl. DP), limitwert max. Summe, dpindex Index von DP */ #if (ALL_FANOS_BUT_INEFFICIENT) singlelimit++; #endif int akt=l-1;/*akt. Index, beginnt hinten*/ while(akt >= 0){ if (akt==dpindex){ if(((*atotal_zeiger+1) < limitwert) && ((tempvec[akt]+1) < singlelimit)){ if (tempvec[akt] == 0) *zero_zeiger = *zero_zeiger - 1; tempvec[akt]++; *atotal_zeiger = *atotal_zeiger + 2; /* ist <= limitwert */ return 1; } *atotal_zeiger -= 2*tempvec[akt]; /* akt springt eine Stelle weiter nach vorne */ if (tempvec[akt] != 0) *zero_zeiger = *zero_zeiger + 1; tempvec[akt]=0; akt=akt-1; } else{ if ((*atotal_zeiger < limitwert) && (tempvec[akt] < singlelimit)){ if (tempvec[akt]==0) *zero_zeiger = *zero_zeiger - 1; tempvec[akt]++; *atotal_zeiger = *atotal_zeiger + 1; /* ist <=limitwert */ return 1; } *atotal_zeiger -= tempvec[akt]; /* akt springt eine Stelle weiter nach vorne */ if (tempvec[akt] != 0) *zero_zeiger = *zero_zeiger + 1; tempvec[akt]=0; akt=akt-1; } } return 0; } /* Falls Fano, gibt 1 zurueck */ int DisplayFano(PolyPointList *P, EqList *E){ VertexNumList V; if(Ref_Check(P,&V,E)) { if(SimpUnimod_M(P,&V,E,1)) { Print_PPL(P,"fano"); return 1; } } return 0; } int CCtest(PolyPointList *P, int d, int np, int nc, int CC[FPcirNmax][FanoProjNPmax]){ int i,j,temp; #if (ALL_FANOS_BUT_INEFFICIENT) return 1; #else for(i=0;ix[j][d]*CC[i][j]; if ((temp + P->x[np-1][d])!=0) return 0; } else/*Also vom Typ 1 -1 1 0 -1 Schluss 1*/ { /*1. Fall: 1 -1 1 0 -1 1 stimmt!*/ temp=0; for(j=0;jx[j][d]*CC[i][j]; if (temp !=0) {/*2. Fall: -1 1 -1 0 1 1 stimmt!*/ temp=0; for(j=0;j<(np-1);j++) temp -= P->x[j][d]*CC[i][j]; if ((temp + P->x[np-1][d])!=0) return 0; } } } return 1; #endif } /* Bestimmt alle Moeglichkeiten fuer Fanos, gibt Anzahl zurueck */ int CalculateFano(PolyPointList *P,EqList *E, int d, int np, int na, int aDP, int bDP, int cDP, int s[], int modeDP, int zeronumber, int nc, int CC[FPcirNmax][FanoProjNPmax]){ /*zeronumber gibt Anzahl an 0-Abstaenden an, muss <= d+1 sein*/ int nf_temp=0; int i; P->np = np+1+na; /*** Bestimmen von letzten Koordinaten von Ecken ganz oben ueber d, ..., np-2; sowie schliesslich von DPs drunter so dass Bedingung erfuellt ist, dass Summe aller Abstaende >= 1 kleiner/gleich Dimension von P = d+1 ist und einzelner Abstand (Wert) <= d. (Neuer Satz) ***/ int l=np-1-d; /* Ist immer > 0 */ int tempvec[FanoProjNPmax]; /* Hat (bis auf Faelle 5,6) Laenge l, Indizes gehen von 0, ..., l-1=np-2-d, und entsprechen d, ..., np-2 */ int atotal; /* Gibt totale Summe aller Abstaende an, von Indizes in tempvec (und DPs darunter) */ for (i=0;i mit Wert 0) **/ atotal=1; /* min. Wert */ tempvec[l-1]=1; zeronumber = zeronumber + l - 1; do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } } while(TempVecUpdate0(tempvec, l, &atotal, d+1, d, &zeronumber)); } else if (modeDP==2){ /** Fall: 0 ist DP, aber es gibt sonst keine DPs (oder nur 1 DP in 0, ..., d-1 -> mit Wert 0) **/ atotal=0; /* min. Wert */ tempvec[l-1]=0; zeronumber = zeronumber + l; do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } }while(TempVecUpdate0(tempvec, l, &atotal, d, d, &zeronumber)); } else if (modeDP==3){ /** Fall: 0 ist kein DP, aber es gibt noch einen DP, nicht in 0, ..., d-1 **/ atotal=1; /* min. Wert */ tempvec[l-1]=0; zeronumber = zeronumber + l; do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } /* Letzte Koordinate von DP ausserhalb bestimmen */ P->x[np+1][d]=P->x[aDP][d]-1; if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } }while(TempVecUpdate1(tempvec, l, &atotal, d+1, aDP-d, d, &zeronumber)); } else if (modeDP==4){ /** Fall: 0 ist DP, und es gibt noch einen DP, nicht in 0, ..., d-1 **/ atotal=1; /* min. Wert */ tempvec[l-1]=0; zeronumber = zeronumber + l; do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } /* Letzte Koordinate von DP ausserhalb bestimmen */ P->x[np+2][d]=P->x[bDP][d]-1; if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } }while(TempVecUpdate1(tempvec, l, &atotal, d, bDP-d, d, &zeronumber)); } else if (modeDP==5){ /**Fall: 0 ist kein DP, aber es gibt noch einen DP in 0, ..., d-1 und einen ausserhalb (schon bestimmt)**/ atotal=0;/*min. Wert*/ int zwstelle=bDP-d; zeronumber = zeronumber + l - 1; /* Zwei Teile von d, ..., np-2: d, ..., bDP-1, und bDP+1, ..., np-2 also: 0, ..., bDP-1-d=zwstelle-1, und bDP+1-d=zwstelle+1, ..., np-2-d=l-1 entspricht: 0, ..., zwstelle-1, und zwstelle, ..., l-2 in tempvec der Laenge l-1*/ do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } for(i=zwstelle;ix[i+d+1][d]=-s[i+d+1]-tempvec[i]; } if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } }while(TempVecUpdate0(tempvec, l-1, &atotal, d, d, &zeronumber)); } else if (modeDP==6){ /** Fall: 0 ist DP, und es gibt noch einen DP in 0, ..., d-1 und einen ausserhalb (schon bestimmt)**/ atotal=0; /* min. Wert */ int zwstelle=cDP-d; zeronumber = zeronumber + l - 1; /* Zwei Teile von d, ..., np-2: d, ..., cDP-1, und cDP+1, ..., np-2 also: 0, ..., cDP-1-d=zwstelle-1, und cDP+1-d=zwstelle+1, ..., np-2-d=l-1 entspricht: 0, ..., zwstelle-1, und zwstelle, ..., l-2 in tempvec der Laenge l-1*/ do{ if (zeronumber <= (d+1)){ for(i=0;ix[i+d][d]=-s[i+d]-tempvec[i]; } for(i=zwstelle;ix[i+d+1][d]=-s[i+d+1]-tempvec[i]; } if (CCtest(P,d,np,nc,CC) == 1) nf_temp=nf_temp+DisplayFano(P,E); } }while(TempVecUpdate0(tempvec, l-1, &atotal, d-1, d, &zeronumber)); } return nf_temp; } /* Berechnet alle moeglichen (d+1)-dim. Fanos (mit <= maxVnumber Ecken), die auf d-dim. Polytop projezieren; gibt Anzahl aus; ACHTUNG bei ALL_FANOS_BUT_INEFFICIENT=0: Es fehlen genau die eindeutigen mit d+2 Ecken (Fanosimplex) und 3*(d+1) Ecken (nur in gerader Dimension d+1) */ int Make_Fano5d(PolyPointList *P,int *Dpt,EqList *E, /* nc=#Circuits */ int symDP,int nc,int CC[FPcirNmax][FanoProjNPmax]){/* CC=CircCoeffs */ int nf=0; int d=P->n-1, np=P->np;/*Achtung, anders als oben wirklich ALLE Gitterpunkte von P*/ #if (ALL_FANOS_BUT_INEFFICIENT) int maxVnumber=3*P->n; #else int maxVnumber=3*P->n-1; /* Reicht da jede n-dim. Fano <= 3n-1 Ecken hat; mit genau einer bekannten Ausnahme mit 3n Ecken, falls n gerade ist */ #endif /*Circuits sind (bei np=6) entweder von Form 1 0 0 1 -2 Schluss 0 (np=6) oder 1 -1 1 0 -1 Schluss 1*/ int i,j,k; /*Folgende Variablen werden hier bestimmt:*/ int aDP=-1,bDP=-1,cDP=-1;/*Indizes von Doppelpunkten*/ int s[FanoProjNPmax+1];/*Summe der Koordinaten (0, ..., d-1)*/ /*Bestimmen von s*/ for(i=0;ix[i][j]; } } /* Bestimmung von letzter Koordinate von (oberen) Ecken ueber 0, ..., d-1 und ueber np-1=Proj.ecke */ for(i=0;ix[i][d]=0; } P->x[np-1][d]=1; /*0-Punkt wird eingefuegt an Stelle np*/ for(j=0;j<=d;j++){ P->x[np][j]=0; } /**Bestimmen von Doppelpunkten (werden an Stellen np+1, np+2, np+3 eingefuegt); gibt unterschiedliche Faelle (wird als letzte Variable uebergeben)**/ /*printf("\n1.Fall: Keine DPs\n");*/ nf = nf + CalculateFano(P,E,d,np,0,aDP,bDP,cDP,s,1,0,nc,CC);/*Keine DPs*/ if ((maxVnumber-np) > 0){ /*1 oder 2 DPs, aber keiner ist 0*/ for(i=0;ix[np+1][k]=P->x[aDP][k]; } P->x[np+1][d]=-1; /*printf("\n1.Fall: 1 DP am Anfang (%d)\n", aDP);*/ nf = nf + CalculateFano(P,E,d,np,1,aDP,bDP,cDP,s,1,1,nc,CC); /*1 DP in 0,...,d-1; aber nicht 0-DP*/ if ((maxVnumber-np) > 1){ /*wegen Satz von Casagrande bzw. klar: keine 2 DPs in 0, ..., d-1*/ for(j=d;jx[i],P->x[j],d))){ bDP=j; for(k=0;kx[np+2][k]=P->x[bDP][k]; } P->x[np+2][d]=0;/*Das ist Satz von Casagrande*/ P->x[bDP][d]=1; /*printf("\n5.Fall: 2 DPs, 1 am Anfang (%d,%d)\n", aDP,bDP);*/ nf = nf + CalculateFano(P,E,d,np,2,aDP,bDP,cDP,s,5,2,nc,CC); /* noch 1 DP nicht in 0, ..., d-1 */ } } } } } for(i=d;ix[np+1][k]=P->x[aDP][k]; } /*printf("\n3.Fall: 1 DP nicht am Anfang (%d)\n", aDP);*/ nf = nf + CalculateFano(P,E,d,np,1,aDP,bDP,cDP,s,3,0,nc,CC); /* 1 DP, nicht in 0, ..., d-1; aber nicht 0-DP */ } } /* Nach Satz von Casagrande und Reid nicht moeglich, dass 2 DPs, ungleich 0, gibt, die nicht in 0, ..., d-1 sind */ /*0 ist jetzt DP, Obstruktion: kein Circuit mit Koeffizient von Absolutbetrag > 1*/ if (symDP==1){ aDP = np-1; for(k=0;kx[np+1][k]=0; } P->x[np+1][d]=-1; nf = nf + CalculateFano(P,E,d,np,1,aDP,bDP,cDP,s,2,0,nc,CC); /* Ausser 0-DP keine DPs */ if ((maxVnumber-np) > 1){ for(i=0;ix[np+2][k]=P->x[bDP][k]; } P->x[np+2][d]=-1; /*printf("\n2.Fall: 0 ist DP, 1 DP am Anfang (%d,%d)\n",aDP,bDP);*/ nf = nf + CalculateFano(P,E,d,np,2,aDP,bDP,cDP,s,2,1,nc,CC); /*noch 1 DP in 0, ..., d-1 ausser 0-DP*/ if ((maxVnumber-np) > 2){ /*wegen Satz von Casagrande bzw. klar: keine 2 DPs in 0, ..., d-1*/ for(j=d;jx[i],P->x[j],d))){ cDP=j; for(k=0;kx[np+3][k]=P->x[cDP][k]; } P->x[np+3][d]=0;/*Das ist Satz von Casagrande*/ P->x[cDP][d]=1; /*printf("\n6.Fall: 0 ist DP, 2 DPs, 1 am Anfang (%d,%d,%d)\n",aDP,bDP,cDP);*/ nf = nf + CalculateFano(P,E,d,np,3,aDP,bDP,cDP,s,6,2,nc,CC); /*noch 2 DPs, einer in 0, ..., d-1, ausser 0-DP*/ } } } } } /* Nach Satz von Casagrande und Reid nicht moeglich, dass 2 DPs, ungleich 0, gibt, die nicht in 0, ..., d-1 sind */ for(i=d;ix[np+2][k]=P->x[bDP][k]; } /*printf("\n4.Fall: 0 ist DP, 1 DP nicht am Anfang (%d,%d)\n",aDP,bDP);*/ nf = nf + CalculateFano(P,E,d,np,2,aDP,bDP,cDP,s,4,0,nc,CC); /*noch 1 DP, nicht in 0, ..., d-1, ausser 0-DP*/ } } } } } /*printf("\n SCHLUSS (von 1 Zelle): nf=%d\n",nf);*/ return nf;/* nf = number of output polytopes (just for statistics) */ } palp-2.21/MoriCone.c0000664000177600017760000021524414572603263013635 0ustar skarkeskarke/* ======================================================== */ /* === === */ /* === M o r i C o n e . c === */ /* === === */ /* === Authors: Maximilian Kreuzer, Nils-Ole Walliser === */ /* === Last update: 02/05/12 === */ /* === === */ /* ======================================================== */ /* ======================================================== */ /* ========= H E A D E R s ========= */ #include "Global.h" #include "Rat.h" #include "Mori.h" #include "LG.h" /* ======================================================== */ /* ========= D E F I N I T I O N s ========= */ /*** local for Moricone.c ***/ #define Inci64 unsigned long long #define naT FACE_Nmax /* allocate: triangulation */ /* change to options */ #define NewtonMonomCOORD (1) /* (1) t_i, (2) u,v,w,x,... */ #define PRINT_MONOMIALS (0) #define EXCEPT_DIV_CLASS_BASE (1) /* try 0: D_min, 1: D_max */ /* diagnostic stuff */ #define TRACE_TRIANGULATION (0) /* detailed triangulation info */ /* ====================================================== */ /* ========= T Y P E D E F s ========= */ /*** from Polynf.c ***/ typedef struct { int v, d; Long **x; } Matrix; /* ====================================================== */ /* ========= P R O T O T Y P E s ========= */ /* from Vertex.c */ void Sort_PPL(PolyPointList *_P, VertexNumList *_V); /* from Polynf.c */ void Init_Matrix(Matrix *M,int v, int d); int Make_G_for_GxMT_UT(Matrix M,Matrix G); void Free_Matrix(Matrix *M); Long VxV(Long *X,Long *Y,int d); void Aux_IPS_Print_WP(Long *W,int w,int cd); void Print_LMatrix(Matrix M, char *s); void Print_QuotZ(int Z[][VERT_Nmax],int *M,int p,int n); /* Auxiliary print functions */ /* from LG.c */ int Init_Multiloop(int *N, int *I, int *j, int *J); int Multiloop(int *N,int *I,int *j,int *J); // =========================================================================== // // Examples of interest for the extension of the triangulation algorithm // // make poly && poly.x -gPV zfree.c // poly.x -e ~/h/pic4| cws.x -N -f| poly.x -f| grep " 5 H">pic4.v5 // make poly && tail -n11 ~/h/pic4.v5| poly.x -fgPV|grep pri // 6 2 1 1 1 1 0 0 3 1 1 0 0 0 1 0 3 0 0 1 0 0 1 1 M:74 7 N:8 7 H:3,63 [-120] // -> non-convex-triangulation :: Singular crash because of norm=0 // 7 1 2 2 0 0 1 1 9 1 3 3 1 1 0 0 15 2 5 4 1 0 0 3 M:48 10 N:9 7 H:4,37 [-66] // -> incompatible induced triangulations 11010111 & 11101011 = 11000011 // 6 1 2 1 1 0 1 12 3 4 1 0 2 2 M:59 6 N:9 6 H:4,52 [-96] // -> "triangles+squares" // 6 2 1 1 0 1 1 3 1 0 0 1 0 1 /Z3: 1 1 2 2 0 0 M:41 7 N:9 6 H:4,34 [-60] // -> non-triangular chamber in 3d 2ndary fan (double-intersecting edges) // 8 1 0 4 0 1 1 0 1 6 1 0 3 1 0 1 0 0 6 1 0 3 0 1 0 1 0 6 0 1 3 1 0 0 1 0 // M:106 8 N:10 8 H:4,82 [-156] -> coincident (triple) intersections of edges //============================================================================ // I N C I D E N C E S Inci64 makeN(int N){return ((Inci64) 1)<>N)%2;} /* read INCIDENCE */ void prnI(int N,Inci64 I){int i; for(i=0;i*B) ? 1:-1);} //int Inci64_diff(const void *A,const void *B){return Inci64_LmR(A,B);} void PRNtriang(triang *SR,const char *c){int i; printf("%d %s\n",SR->n,c); for(i=0;in;i++){if(i)printf(" ");prnI(SR->v,SR->I[i]);}puts("");} int MaxBit(Inci64 I,int p){assert(I!=0);while(0==getN(--p,I));return p;} /* do {;} while(Multiloop(N,I,j,J)); <--> do forall 0<=I[j] forall 0 <= C[0]<...0); assert(k<=n); for(i=0;i ++ and below -> min for(i=0;in, C[VERT_Nmax]; nok=Init_Choose(v,d,C); do { int c, CC[VERT_Nmax]; if(EXCEPT_DIV_CLASS_BASE) for(c=0;cx[CC[c]]; sv=SimplexVolume(X,P->n); cdiv=NNgcd(cdiv,sv); if(sv==1){int x=0; dprintf(SF,"\nideal DCbase="); Inci64 I=makeN(CC[0]); for(c=1;c1){ printf("Fundamental group = Z%d\n",(int)cdiv); nok=Init_Choose(v,d,C); do { int c, CC[VERT_Nmax]; if(EXCEPT_DIV_CLASS_BASE) for(c=0;cx[CC[c]]; sv=SimplexVolume(X,P->n); if(sv==cdiv){int x=0; dprintf(SF,"\nideal DCbase="); Inci64 I=makeN(CC[0]); for(c=1;c8) {DivClassBasis(SF,P,v,D,B);return;} if(P->n != 4) {DivClassBasis(SF,P,v,D,B);return;} for(l=3;lx[y]; assert(x==4); /*---ENDE QUICK-FIX----------------------------------------------------------*/ //printf("SimpVol[%d%d%d%d]=%ld\n",i,j,k,l,SimplexVolume(X,P->n)); sv=SimplexVolume(X,P->n); cdiv=NNgcd(cdiv,sv); if(sv==1) {x=0; dprintf(SF,"\nideal DCbase="); for(y=0;y1){printf("Fundamental group = Z%d\n",(int)cdiv);fflush(0); for(l=3;lx[y]; assert(x==4); sv=SimplexVolume(X,P->n); if(sv==cdiv) {x=0; dprintf(SF,"\nideal DCbase="); for(y=0;ynv;i++) fprintf(outFILE,"%d ",V->v[i]); fprintf(outFILE,"#=%d\n",V->nv);} int Vdiff_LmR(Long *L,Long *R,int d){ while(d--){Long D=L[d]-R[d]; if(D) return (D>0) ? 1 : -1;} return 0;} void Inci64_2_VNL(Inci64 X, VertexNumList *V, int n){int i; V->nv=0; for(i=0;iv[V->nv++]=i; //Print_VNL(V);Sort_VL(V);Print_VNL(V);exit(0); } void Print_Inci64_list(int n,Inci64 *I,int p){ printf("To be done: Print_Inci64_list n=%d p=%d I=%lld\n",n,p,*I);exit(0);} #define Inci64_AND(I,J) ((I)&(J)) int Inci64_abs(Inci64 X){int abs=X%2; while(X/=2) abs+=X%2; return abs;} void IDerr(void){puts("\n ******** INPUT DATA ERROR ********");} int Make_triCD2F(triang *T,Inci64 *cd2I){int i,j,cd2n=0; for(i=1;in;i++)for(j=0;jI[i]&T->I[j]; for(k=0;kd-1) break; if((in*T->d)){IDerr();PRNtriang(T,"Triangulation ERROR"); T->n=cd2n; T->I=cd2I; PRNtriang(T,"Codim-2 faces:");exit(0);} return cd2n;} int Check_Mori(PolyPointList *P,int p,triang *T){ // strongly convex(?) int nI=T->n; Inci64 *I=T->I, cd2F[CD2F_Nmax]; int i,j,r=0,d=P->n,ngen=0, /*ng0,*/nv,np; Long Z[POLY_Dmax+1]; VertexNumList V; // int e0=0,nm=0,m[VERT_Nmax];; Inci64 IE[VERT_Nmax]; PolyPointList *UT = (PolyPointList *) malloc(sizeof(PolyPointList)); Matrix R,VT,G; EqList *E = (EqList*)malloc(sizeof(EqList)); assert(E!=NULL); assert(UT!=NULL); for(i=1;ix[V.v[a]][b]; MoriGen(VT,Z); for(a=0;a "); Print_VNL(&V); assert(Inci64_abs(Ia)==2); assert(b0) for(a=0;a<=d;a++) R.x[r][V.v[a]]=Z[a]; else for(a=0;a<=d;a++) R.x[r][V.v[a]]=-Z[a]; //for(a=0;anp=ngen=r; r=Make_G_for_GxMT_UT(R,G); // base change -> UT if(r!=p-d) { Matrix GR; R.v=ngen; Print_LMatrix(R,"R"); Print_LMatrix(G,"GLZ"); Init_Matrix(&GR,R.v,p); for(i=0;inp>=POINT_Nmax){fprintf(outFILE,"need POINT_Nmax>=%d\n",UT->np+1); exit(0);} UT->n=r; if(r>POLY_Dmax){fprintf(outFILE,"need POLY_Dmax>=%d\n",UT->n);exit(0);} for(i=0;ix[i][j]=VxV(G.x[j],R.x[i],p); for(i=0;in;i++) UT->x[UT->np][i]=0; UT->np++; Find_Equations(UT,&V,E); np=UT->np-1; nv=V.nv-1; Sort_VL(&V); Free_Matrix(&VT); Free_Matrix(&R); Free_Matrix(&G); free(E); free(UT); if(np!=V.v[nv]) {PRNtriang(T,"Non-coherent Triangulation"); return 0;} else return 1; } void Print_Mori(PolyPointList *P,int p,int nI, Inci64 *I){ int i,j,r=0,d=P->n,ngen=0, /* ng0,*/ e0=0,nm=0,nv,np; int m[VERT_Nmax]; Long Z[POLY_Dmax+1]; VertexNumList V; Inci64 IE[VERT_Nmax]; PolyPointList *UT = (PolyPointList *) malloc(sizeof(PolyPointList)); Matrix R,VT,G; EqList *E = (EqList*)malloc(sizeof(EqList)); assert(E!=NULL); assert(UT!=NULL); for(i=1;ix[V.v[a]][b]; MoriGen(VT,Z); for(a=0;a "); Print_VNL(&V); assert(Inci64_abs(Ia)==2); assert(b0) for(a=0;a<=d;a++) R.x[r][V.v[a]]=Z[a]; else for(a=0;a<=d;a++) R.x[r][V.v[a]]=-Z[a]; //for(a=0;anp=ngen=r; r=Make_G_for_GxMT_UT(R,G); // base change -> UT if(r!=p-d) { Matrix GR; R.v=ngen;Print_LMatrix(R,"R"); Print_LMatrix(G,"GLZ"); Init_Matrix(&GR,R.v,p); for(i=0;inp>=POINT_Nmax){fprintf(outFILE,"need POINT_Nmax>=%d\n",UT->np+1); exit(0);} UT->n=r; if(r>POLY_Dmax){fprintf(outFILE,"need POLY_Dmax>=%d\n",UT->n);exit(0);} for(i=0;ix[i][j]=VxV(G.x[j],R.x[i],p); for(i=0;in;i++) UT->x[UT->np][i]=0; UT->np++; Find_Equations(UT,&V,E); np=UT->np-1; nv=V.nv-1; Sort_VL(&V); if(np!=V.v[nv]){IDerr();puts("MORI CONE not strictly convex:"); Print_Inci64_list(nI,I,p);puts("... non-convex triangulation?\n");exit(0);} /* The extremal rays of the Mori cone are those that have maximal incidences * * with faces of the cone, i.e. with equations containing the origin. */ for(i=0;ine;i++) if(Eval_Eq_on_V(&E->e[i],UT->x[np],UT->n)==0){e0++; for(j=0;je[i],UT->x[V.v[j]],r));}/* compute Eq(0)-INCIs for Vs */ if(e0>VERT_Nmax){fprintf(outFILE,"need VERT_Nmax >= %d\n",e0);exit(0);} //printf("p=%d nm=%d\n",p,nm); for(i=0;i=r); // fprintf(outFILE, // "%d MORI GENERATORS / dim(cone)=%d [#rays=%d<=%d #eq=%d<=%d #v=%d<=%d]\n", // nm,r,ngen,ng0,e0,E->ne,nm,V.nv); fprintf(outFILE, "%d MORI GENERATORS / dim(cone)=%d \n", nm,r); //printf("p=%d nm=%d\n",p,nm);fflush(0); for(i=0;i Stanley Reisner ============ // /* SR generators: G=I+2^n with I<2^n, I<=face and not G'v=SR->v, j=p/2, d=TR->d=SR->d, s=SR->n, m=0, k, l, r; Inci64 *S=SR->I,*T=TR->I, *A,*M,*N; long long binco=TR->v; /* Bino.Coeff */ assert(p<=64); if(j>d)j=d+1; while(i2999) binco=2999; A = (Inci64*) malloc(2*binco*sizeof(Inci64)); assert(A!=NULL); M=A; N=&A[binco]; for(i=1;in=m; assert(m<=TR->nmax); for(k=0;kI,*I=T->I,*A,*M,*N,U=1; long long binco=T->v; /* Binom.Coeff */ int i=1, p=T->v, j=p/2, d=T->d,nI=T->n, s=0, m=0, k, l, r; assert(p<=64); if(j>d) j=d+1; while(i2999) binco=2999; A = (Inci64*) malloc(2*binco*sizeof(Inci64));assert(A!=NULL);M=A;N=&A[binco]; for(i=1;i N[%d]=",k,x,n);prnI(p,N[n]);puts("");*/ for(l=0;lnmax);S[s++]=N[n];}} else assert(++nn=s; SR->v=T->v; SR->d=T->d; { int ok=1; triang TeST; TeST.I=A; TeST.nmax=2*binco; // Triang_from_SR(&TeST,SR); if(TeST.n!=T->n) ok=0; else #ifdef TRIANG_CHECKSUM {Inci64 sumT=0,sumC=0;for(i=0;in;i++){sumT+=TeST.I[i];sumS+>T->I[i];} if(sumT!=sumC) ok=0;} #else {for(i=0;in;i++) { int sum=0; for(j=0;jn;j++) if(TeST.I[i]==T->I[j]) sum++; if(sum!=1) break;} if(in) ok=0;} #endif if(ok)free(A); else {PRNtriang(T,"Triangulation");PRNtriang(SR,"SR-ideal"); PRNtriang(&TeST,"Tri(SR) ... test failed !!!"); assert(0);} }} // INTERSECTION RING (Singular) / MORI CONE / TRIANGULATIONS void InterSectionRing(Inci64 *Tri,int *t,PolyPointList *P, int p, MORI_Flags *_Flag, FibW *F){ triang T,SR; Inci64 srI[VERT_Nmax]; T.v=p; T.n=*t; T.I=Tri; SR.d=T.d=P->n; SR.I=srI; SR.d=P->n; SR.n=0; SR.v=p; SR.nmax=T.nmax=VERT_Nmax; if(Check_Mori(P,p,&T)){ if(_Flag->g) PRNtriang(&T,"Triangulation"); StanleyReisner(&SR,&T); if(_Flag->g) PRNtriang(&SR,"SR-ideal"); if(_Flag->i || _Flag->t || _Flag->c || _Flag->d || _Flag->a || _Flag->b || _Flag->H){ if(P->n<(POLY_Dmax+1)){ HyperSurfSingular(P,&T,&SR,_Flag,F,&p); } else{ printf("Intersection ring implemented only for polytopes up to dim=%d \n", POLY_Dmax); } } if(_Flag->m) Print_Mori(P,p,*t,Tri); } } /* ============== TRIANGULATIONS ================ */ void Transpose(Matrix M,Matrix MT){int i,j,l=M.v,c=M.d; assert((MT.v==c)&&(MT.d==l)); for(i=0;ix[i][j]=G.x[A.d+j][i];} /* GKZ: Gale transform; implement circuit and 2ndary polygon * T[] space for triangulations; t[] #simplices; nt=number of triangulations */ int AcuteAngle(Long *L,Long *R){return L[0]*R[0]+L[1]*R[1]>0;} // R.L>0 int ConeAngle(Long *L,Long *R){ Long X=L[1]*R[0]-L[0]*R[1]; // 0->0, (0,pi) ->+1 if(X>0)return 1; if(X<0)return -1; return(AcuteAngle(L,R)>0)?0:-1;}// [pi,)->-1 #define BZangle(a,b) (ConeAngle(B.x[Z[a]],B.x[Z[b]])) // Gale-points /* * 2d: secondary POLYGON: return nmt = #(maximal triangulations) * V[]=facet points; rays R [ rn,C[VERT_Nmax]; Inci64 X=0; Matrix A,B; Init_Matrix(&A,f,d); for(i=0;ix[i][j];C[k++]=i;} assert(f>d);assert(k==f);d=f-d;GaleTransform(A,&B);//Print_CMatrix(B,"Gale"); for(i=0;i0); else {puts("ZeroVectors in SameRay (forbidden)"); assert(x); return 000;}} Long XYZproduct(Long *X,Long *Y,Long *Z){return Z[2]*(X[0]*Y[1]-X[1]*Y[0]) +Z[0]*(X[1]*Y[2]-X[2]*Y[1])+Z[1]*(X[2]*Y[0]-X[0]*Y[2]);} void CROSSproduct(Long *X,Long *Y,Long *XxY){XxY[2]=X[0]*Y[1]-X[1]*Y[0]; XxY[0]=X[1]*Y[2]-X[2]*Y[1]; XxY[1]=X[2]*Y[0]-X[0]*Y[2];} Long SCALproduct(Long *X,Long *Y){return X[0]*Y[0]+X[1]*Y[1]+X[2]*Y[2];} //#define BZx(a,b,c) (XYZproduct(B.x[Z[a]],B.x[Z[b]],B.x[Z[c]])) //#define BZRx(a,b,c) (XYZproduct(B.x[Z[*R[a]]],B.x[Z[*R[b]]],B.x[Z[*R[c]]])) #define BZR(eqr) (B.x[Z[*R[eqr]]]) #define BZRx(a,b,c) (XYZproduct(BZR(a),BZR(b),BZR(c))) #define BZRE(i,j) (BZR(Eli[i][j])) void AuxPrintRays(int R[VERT_Nmax][POLY_Dmax],int nrp[VERT_Nmax],int nr){ int i,j; printf("Rays: "); for(i=0;i1) {X[0]/=g;X[1]/=g; X[2]/=g;}} void IntersectEdges(Long *X,Long *Y,Long *U,Long *V,Long *Q){ Long XY[3],UV[3]; CROSSproduct(X,Y,XY); MakeVecPrim(XY); if(SCALproduct(XY,U)<0)CROSSproduct(U,V,UV);else CROSSproduct(V,U,UV); MakeVecPrim(UV); CROSSproduct(XY,UV,Q); MakeVecPrim(Q); #if (TRACE_TRIANGULATION) printf("X=%ld %ld %ld, Y=%ld %ld %ld : ",X[0],X[1],X[2],Y[0],Y[1],Y[2]); printf("U=%ld %ld %ld, V=%ld %ld %ld -> Q=%ld %ld %ld ...\n", U[0],U[1],U[2],V[0],V[1],V[2],Q[0],Q[1],Q[2]); #endif assert((SCALproduct(X,Q)>0)||(SCALproduct(Y,Q)>0)); assert((SCALproduct(U,Q)>0)||(SCALproduct(V,Q)>0)); assert(XYZproduct(X,Y,Q)==0);assert(XYZproduct(U,V,Q)==0);} void Print_MaxTrian(Inci64 C, Inci64 *CT[ANtri], int nmt, int *nt,int p) { int i,j;for(i=0;in,i,j,k=0,tnt=0, F[POLY_Dmax+1]; Inci64 CI=0; Matrix A,B; Init_Matrix(&A,d+1,d); for(i=0;ix[i][j]; F[k++]=i;} assert(k==d+1); GaleTransform(A,&B); i=j=*nmt=0; for(k=0;k<=d;k++) if(*B.x[k]) {CI|=makeN(F[k]); if(*B.x[k]>0) i++; else j++;} #if (TRACE_TRIANGULATION) { Inci64 PC=FindPolyCircuits(P,p,I,d+1); assert(PC==CI); } prnI(p,CI); printf("=C -> "); Print_CMatrix(B,"Gale"); #endif if(i>1){ CT[*nmt]=X; nt[*nmt]=0; for(k=0;k<=d;k++) if(*B.x[k]>0) CT[*nmt][nt[*nmt]++]=CI-makeN(F[k]); tnt+=i; (*nmt)++;} if(j>1){ CT[*nmt]=X+i; nt[*nmt]=0; for(k=0;k<=d;k++) if(*B.x[k]<0) CT[*nmt][nt[*nmt]++]=CI-makeN(F[k]); tnt+=j; (*nmt)++;} #if (TRACE_TRIANGULATION) Print_MaxTrian(CI,CT,*nmt,nt,p); //printf("i=%d j=%d nmt=%d\n",i,j,*nmt); #endif assert(*nmt==(i*j+1>i+j)+1); Free_Matrix(&A); Free_Matrix(&B); return tnt;} int Triang2dSFan(PolyPointList *P,int p,Inci64 FI,Inci64 *X,Inci64 *CT[ANtri], int *nmt,int *nt) // P,p,F[c],X,CT[nmf],&nmt[nmf],nt[nmf] { int d=P->n,v=d+2,i,j,k=0,r,F[POLY_Dmax+2],Z[POLY_Dmax+2],z=0, // GKZ polygon: R[VERT_Nmax][POLY_Dmax],nrp[VERT_Nmax],nr,neg=0,tnt=0;// num.max.tri Matrix A,B; Init_Matrix(&A,v,d); Inci64 U; // P.x::F[A]::F[Z[R]] for(i=0;ix[i][j]; F[k++]=i;} assert(k==d+2); GaleTransform(A,&B); U=0; // F_ir;J--) {nrp[J]=nrp[J-1];for(L=0;L(k=BZangle(i,0))){ // points with negative angle if(neg==0) {r=neg=nr; k=1;} // init neg. else for(r=neg;r k=%d r=%d\n",i,neg,nr,k,r); { int J,L; if(k){for(J=nr++;J>r;J--) {nrp[J]=nrp[J-1];for(L=0;L rays: "); for(r=0;r0); for(j=0;j0); // if((nrp[r]>1)&&(nrp[s]>1)) // maximal triangulations only for(j=1;j0) for(a=0;a0); #if (TRACE_TRIANGULATION) Print_MaxTrian(U,CT,*nmt,nt,p); #endif return tnt;} // nmt = # maximal triangulations #ifdef OLD_code // problem: negative cone -> XYZcone int ABCline(Long *a,Long *b,Long *c){int i; // 1:: edge(abc), -1:: acb|cab Long A[3],C[3],AA=0,AC=0,CC=0; // 0:: no line or a=b or a=c for(i=0;i<3;i++){AA+=b[i]*a[i];AC+=b[i]*b[i];CC+=b[i]*c[i];} // A=ab^2-b(ab) for(i=0;i<3;i++){A[i]=a[i]*AC-b[i]*AA; C[i]=c[i]*AC-b[i]*CC;} // C=cb^2-b(cb) // printf("ABCline a=(%ld,%ld,%ld),b=(%ld,%ld,%ld),c=(%ld,%ld,%ld) ", // a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);printf( // "A=(%ld,%ld,%ld),C=(%ld,%ld,%ld)\n",A[0],A[1],A[2],C[0],C[1],C[2]); if(0==(AC=SCALproduct(A,C))) return 0; // A/b^2, C/b^2 = ortho. proj. if(!(AA=SCALproduct(A,A))) return 0; if(!(CC=SCALproduct(C,C))) return 0; if(AA*CC!=AC*AC) return 0; return (AC<0) ? 1 : -1;} // assuming a!=c #endif int XYZcone(Long *A,Long *B,Long *C){ // 1: B inside cone _+ int i,j,k; Long x,y,z; // -1: _+ is 2d strict conv. cone if(XYZproduct(A,B,C)) return 0; // 0: 3d or non strictly convex for(k=0;k<3;k++){i=(k+1)%3; j=(k+2)%3;// if((x=B[i]*C[j]-B[j]*C[i])) break;} // solve x A + y B + z C = 0 if(k==3) return 0; // coincident lines => return 0 if(!(y=C[i]*A[j]-C[j]*A[i])) return 0; if(!(z=A[i]*B[j]-A[j]*B[i])) return 0; if(x*z>0) return (x*y<0) ? 1 : 0; else return -1; } int Triang3dSFan(PolyPointList *P,int p,Inci64 FI,Inci64 *X,Inci64 *CT[ANtri], int *nmt,int *nt){Matrix A,B; Inci64 C=0; int tmt=0; // #triang in max.tri's int R[VERT_Nmax][POLY_Dmax], nrp[VERT_Nmax], r=0; // Rays, #ray-Pts, #rays int d=P->n,i,j,f=0,z=0,F[VERT_Nmax],Z[VERT_Nmax]; // P.x [ F [ Z [ R < z ]]] Inci64 Einc[VERT_Nmax]; Long CR[VERT_Nmax][3]; // chamber rays < int Tli[VERT_Nmax][3],Eli[VERT_Nmax][2],IEli[VERT_Nmax][9],ien[VERT_Nmax]; int tn=0,en=0, a,b,c, k=0,l,iem=0,ies=0,nQuad=0,chi=0,ncr=0; /* int ChamberTriangle(Long *Q,int *T){Long a,b,c; // Q in BZR(T_0,T_1,T_2) if(0<=(a=XYZproduct(BZR(T[0]),BZR(T[1]),Q))) if(0<=(b=XYZproduct(BZR(T[1]) ,BZR(T[2]),Q))) if(0<=(c=XYZproduct(BZR(T[2]),BZR(T[0]),Q))) {assert(a*b*c>0); return 1;} return 0;} // END of DECLARATIONS */ Init_Matrix(&A,Inci64_abs(FI),d); for(i=0;i<=p;i++) if(getN(i,FI)){ // GALE for(j=0;jx[i][j]; F[f++]=i;} GaleTransform(A,&B); for(i=0;i=r); #endif // 3d secondary fan A L G O R I T H M // // list triangles / edges / crossing edges; subdivide; check Euler // * no multiple crossing: crossing -> 4 chambers, removing 4 min.trian. // * multiple crossings: add crossings and split edges; then either make // *-* minimal triangles for refined edges; overlaps -> chamber=union. or: // *-* compose split edges to minimal polygons // general dim: hyperplan wedges split by intersections; combine pieces for(c=2;c0){Tli[tn][0]=a;Tli[tn][1]=b;} else {Tli[tn][0]=b;Tli[tn][1]=a;} for(k=0;k0)break; if(b eliminate #if (TRACE_TRIANGULATION) // for(l=0;l#",i,Eli[i][0],Eli[i][1]); for(l=0;l1){int OE[8*VERT_Nmax][2],noe=0,y,q=0; // orient.edges, y = #Rays+#Q's Long *Y[VERT_Nmax],YY[VERT_Nmax][3]; int nse=0;for(i=0;ii) { k=q+r; // if new add Q to YY's IntersectEdges(BZRE(i,0),BZRE(i,1),BZRE(j,0),BZRE(j,1),Y[y]); Qinc[q]=makeN(i)+makeN(j);Y[++y]=YY[++q];} // Y[r+q]::E_i & E_j else {for(k=0;ki){k=q+r;// if new add Q to YY IntersectEdges(BZRE(i,0),BZRE(i,1),BZRE(j,0),BZRE(j,1),Y[y]); Qinc[q]=makeN(i)+makeN(j);Y[++y]=YY[++q];} // Y[r+q]::E_i & E_j else {for(k=0;k0){k=OE[noe][0];f=OE[noe][1];} else {f=OE[noe][0];k=OE[noe][1];} noe+=2; // edge=(i0,k,f,i1) // printf("edge(%d)=%d %d %d %d\n",i,Eli[i][0],k,f,Eli[i][1]); assert(XYZcone(Y[f],Y[k],Y[Eli[i][0]])>0); // add end-edges OE[noe][0]=OE[noe+1][1]=Eli[i][0]; OE[noe][1]=OE[noe+1][0]=k; noe+=2; OE[noe][0]=OE[noe+1][1]=Eli[i][1]; OE[noe][1]=OE[noe+1][0]=f; noe+=2; break; default: puts("#(intersect.edges)>2 in Triang3dSFan() TO DO"); exit(0);} assert(2*nse==noe); assert(2-y+nse<=VERT_Nmax); // Euler == y-nse+ncr == 2 } #endif // => first make intersections, then split edges, then add unsplit for(i=0;ii){ // intersection points IntersectEdges(BZRE(i,0),BZRE(i,1),BZRE(j,0),BZRE(j,1),Y[y]); for(k=r;k0) break; if(k==y) Y[++y]=YY[++q];}} // Y[r+q]::Ei & Ej for(f=r;fi){ // if new add Y[k]=Q to YY's IntersectEdges(BZRE(i,0),BZRE(i,1),BZRE(j,0),BZRE(j,1),Y[y]); for(k=r;k0) break;// split OE_l by Y_k printf("OE[%d]=%d%d k=%d .. l=%d noe=%d f=%d\n",l,OE[l][0],OE[l][1],k,l,noe,f); assert(l#",i,Eli[i][0], // Eli[i][1]);for(l=0;l1); for(j=0;j<3;j++) CR[ncr][j] = Y[face[0]][j]+Y[face[2]][j]; if(f==3) for(j=0;j<3;j++) CR[ncr][j] += Y[face[1]][j]; // chamber ray CR #if (TRACE_TRIANGULATION) printf("face[i=%d]=",i); for(j=0;j<=f;j++) printf("%d ",face[j]); printf(" noe=%d CR=",noe); for(j=0;j<3;j++) printf(" %ld",CR[ncr][j]); puts(""); #endif ncr++;} //// chambers DONE assert(ncr-nse+y==2);} // check Euler number ///// ================== squares and triangles only: else {Inci64 IEI[VERT_Nmax]; int nie=0; ncr=0; // ies==#(squares) for(i=0;ii) {Long Q[3]; // make QUAD IEI[nie++]=Einc[i]; assert(Einc[i]==makeN(Eli[i][0])+makeN(Eli[i][1])); IEI[nie++]=Einc[j]; assert(Einc[j]==makeN(Eli[j][0])+makeN(Eli[j][1])); IntersectEdges(BZRE(i,0),BZRE(i,1),BZRE(j,0),BZRE(j,1),Q); for(a=0;a<2;a++)for(b=0;b<2;b++){Long *rA=BZRE(i,a),*rB=BZRE(j,b); for(c=0;c<3;c++) CR[ncr][c]=Q[c]+rA[c]+rB[c]; ncr++;} } assert(nie==2*ies); chi=r-en+3*ies; // QUAD DONE, NOW MIN.TRIANG: for(i=0;i X, *nmt=#MaxTri nt[num]=#Triang for(i=0;i0); ChamberTriangle = 1;} if(ChamberTriangle){ for(a=0;a ");prnI(p,U);printf("]:");for(a=0;a iT=");for(i=0;i=0)assert(Inci64_abs(iT[a])==d);} static int s; if(++s>13)exit(0); #endif return n; } int Compatible_Tri(Inci64 CA,Inci64 CB,int a,Inci64 *A,int b,Inci64 *B,int p){ Inci64 I=CA&CB, IA[VERT_Nmax], IB[VERT_Nmax]; int i, ia=1, ib=1; *IA=(*A)&I; for(i=1;in, d2, i,j,t=00; // d2=dim(2ndaryFan) Inci64 T[naT],*X=&T[nPS],C[ANfan],*CT[ANfan][ANtri]; // C=circuit, CT=triang int nmt[ANfan], nt[ANfan][ANtri], nmf=0; // NumMaxTri, NumTriang, NumMax2Fan Inci64 MT[VERT_Nmax*POLY_Dmax], *_CT[ANfan]; int TpMax=0, nMax=00, _nt[ANfan], I[ANfan], comptri=0; for(i=0;iTpMax) TpMax=Tp[ntp[nMax=i]]; j=Inci64_abs(F[c]); T[i]=FindPolyCircuits(P,p,F[c],j); } for(d2=TpMax-d; d2>0; d2--) for(i=0;i= nmf){ #if (TRACE_TRIANGULATION) printf("F%d 2ndary dim=%d new circ.= C%d #maxTri=%d\n",ntp[i],d2,j,nmt[j]); #endif X=&X[t+1]; // CHECK !! if(nmt[nmf]>1) for(j=0;j1) if(Inci64_abs(T[i]&C[j]) > 3){ printf("Check compatibility of induced triangulation: "); prnI(p,T[i]); printf(" & "); prnI(p,C[j]); printf(" = "); prnI(p,T[i]&C[j]); puts(""); comptri=1; } C[nmf++]=T[i];} } #ifdef TRACE_TRIANGULATION__ if(comptri){puts("Maximal triangulations from secondary fans:"); for(j=0;j2) if(!Compatible_Tri(C[j],C[k], // nt[j][I[j]],CT[j][I[j]],nt[k][I[k]],CT[k][I[k]],p)) j=k=nmf+1; //printf("ML(j=%d)=",j);for(k=0;k1) // check compatib for(j=0;j1) if(Inci64_abs(C[j]&C[k])>3) // triangulations if(!Compatible_Tri(C[j],C[k],_nt[j],_CT[j],_nt[k],_CT[k],p))goodtri=0;} if(goodtri){ for(j=0;j T[*t]; * assuming 4 dimensions and at most 3 non-vertices, etc.; * triangulate and call "InterSectionRing(T,t,P,p);" for each T[] * if simplicial add <=3 pts by hand else use GKZ for <= 3d secondary fan * Old code: assuming: initial simplex, i.e. facets are 5 tetrahedra; * 3 add. points subdivision by points on edges in each step * -> find points on edge = at intersection of >= 3 max-dim. triangles */ void Subdivide(PolyPointList *P,int v,Inci64 I[],int p,Inci64 *T,int *t, MORI_Flags *_Flag, FibW *F){ int i,j,ni=*t,d=P->n, ns2=0, nPS=0, nVS=0, num_facetIPs=P->np-1-p, // ni=E.ne C[3][3],c[3]={0,0,0}, ntp[VERT_Nmax], Tv[VERT_Nmax], Tp[VERT_Nmax]; /* * Determine the facets that are not simplicial looking for those that * have more points than d+1 with d=dim. of the lattice. * Gives the number of non-simplicial facets: nPS. * Writes a vector, ntp, with nPS entries, whose entries are the numbers * corresponding the non simplicial facets: e.g. ntp=(2,4,5) means that * there are nPS=3 non simplicial facets, precisely the 2nd, 4th and 5th facet. * */ for(i=0;id) nVS++; // nVS = #not-vertex-simplicial /* control: facets must have always at least d vertexes */ else assert(Tv[j]==d); Tp[j]=Tv[j]; // ntp[] = non-P.Simpl. facets /* counts the number of points on the j-facet */ for(i=v;id)ntp[nPS++]=j; // C[i][f]= facets containing P.x[v+i], f p-v-ns2 on edges if(nPS==0){ // no triang. needed InterSectionRing(T,t,P,p,_Flag,F); return; } else if((P->n!=4)||(p>v+3)) { printf("P* requires triangulation. The present routinwes can "); puts("triangulate only 4-polytopes"); puts("with up to 3 points that are neither vertices nor interior to P* or"); puts("a facet. Use option `-M' for providing a triangulation as input."); exit(1);} if(num_facetIPs > 0 && _Flag->H){ if(num_facetIPs == 1) printf("WARNING: there is %d facet-IP ignored in the triangulation. This may lead to unresolved singularities in the hypersurface. \n", num_facetIPs); else printf("WARNING: there are %d facet-IPs ignored in the triangulation. These may lead to unresolved singularities in the hypersurface. \n", num_facetIPs); } /* * C[i][] is a vector whose entries are the numbers corresponding to the * facets that contain the non-vertex point x_i. */ for(i=v;i 2){ printf("Too many (%d) non-vertex points (at most 3 were expected). Extension to be done!\n", i-v+1); exit(0);} assert(c[i-v]>1); if(c[i-v]==2) ns2++;} // ns2 = #pts @ codim2=triangle #if TRACE_TRIANGULATION for(j=0;j2){ printf("p%d on edge:",i+v); for(j=0;jx[i].PN->x[j]+\d(k,j)>=0 forall j int SectionCount(PolyPointList *PN,int k,PolyPointList *PM){int i,n=0; for(i=0;inp;i++){int j; for(j=0;jnp;j++) {Long e = (k==j); int l; for(l=0;ln;l++) e+=PM->x[i][l]*PN->x[j][l]; if(e<0) break;} if(j==PN->np) n++;} return n;} #if(NewtonMonomCOORD) #if((NewtonMonomCOORD<1)||(NewtonMonomCOORD>2)) #error NewtonMonomCOORD has to be 1 or 2 #endif void NewtonMonomial(Long *X,int d){int num=0,den=0,i,t=NewtonMonomCOORD==1; for(i=0;i0) num++; else if(X[i]) den++; if(num) {for(i=0;i0) {if(t)printf("t_%d",i+1); else {char uvw[2]={'u',0}; uvw[0]+=i;printf("%s",uvw);} if(X[i]>1)printf("^%d",(int)X[i]);}} else printf("1"); if(den) {printf("/"); if(den>1)printf("("); for(i=0;i1)printf(")");}} #endif /* Hypersurface divisors Q(charges) permutes the N-lattice points of * non-intersecting divisors to the end of the PPL *_P, calls IP_Simplex_Fiber * and then prints the charges = linear relations */ void HyperSurfDivisorsQ(PolyPointList *_P, VertexNumList *V, EqList *E, MORI_Flags * _Flag){ int i=V->nv,j,cp=_P->np-1,t=E->ne,d=_P->n,Dh0[VERT_Nmax]/*,Dh2[VERT_Nmax]*/; Inci64 I[VERT_Nmax], T[FACE_Nmax]; Long Wsum[VERT_Nmax]; FibW *F = (FibW *) malloc( sizeof(FibW) ); assert(F!=NULL); /************************************************************************* * RECAST PPL * * Permutes the points that do not intersect facets * to the right of the poly point matrix * Should read: Permutes the Facets-IP to the rights of the PPL. * */ /* initialize the incidence relations I[1]=0,...,I[#facets]=0*/ for(j=0;jne;j++) I[j]=0; /* i runs over the poly points */ if (!_Flag->M) for(i=0;ine;j++) /* add 1 to fi if the i-point lies on the j-facet. * OPTIM: can't we use INCI arithmetic instead of Eval_Eq_on_V? */ if(0==Eval_Eq_on_V(&(E->e[j]),_P->x[i],_P->n)) fi++; /* if fi<=1 then permutes the i-point with the (cp-1)-point. * And reduces cp to the number of intersecting divisors */ if(fi<=1) Swap_Vecs(_P->x[i--],_P->x[--cp],_P->n); } /************************************************************************/ /* Generates the IP_simplices among point of codim >1 */ IP_Simplex_Fiber(_P->x,cp,_P->n,F,FIB_Nmax,0); if(_Flag->P){ /************************************************************************ * PRINT IP */ // fi==2::dual to edges whose length is Dh0 /* prints the PPL */ Print_PPL(_P,"points of P* and IP-simplices"); for(i=0; inw); /* If there are more weight-relations than prim.div.cl. print the info * that there are more IP-simplexes than the Nr. of independent vectors */ if(F->nw>cp-_P->n) fprintf(outFILE," > %d=#pts-dim",cp-_P->n); fprintf(outFILE,"\n"); /* Prints the weight matrix */ for(i=0; inw; i++){ /* i runs over # weight relations = IP-simplices */ int cd=_P->n-cp+1 ; /* j runs over the facet intersecting divisors */ for(j=0;jW[i][j]) cd++; /* Prints the single rows of the matrix */ Aux_IPS_Print_WP(F->W[i],cp,cd); // if(F->ZS) /* Prints the quotient group if any */ if(F->nz[i]) Print_QuotZ(&F->Z[F->n0[i]],&F->M[F->n0[i]],cp,F->nz[i]); fprintf(outFILE,"\n"); } } /* End of P-flag */ else if (_Flag->M) Print_PPL(_P,""); /******************************************************************** * FACET INCIDENCES */ /* First creates the Incidences I */ for(i=0;ine;j++) // INCIdence if(0==Eval_Eq_on_V(&(E->e[j]),_P->x[i],_P->n)) { putN(i,&I[j]); if(fi<3) FI[fi++]=j; } Wsum[i]=0; for(j=0;jnw;j++)Wsum[i]+=F->W[i][j]; Dh0[i]=1; if(fi==2){ Long g=E->e[FI[1]].a[0]-E->e[FI[0]].a[0]; // h0(D_i) for(j=1;je[FI[1]].a[j]-E->e[FI[0]].a[j]); Dh0[i]=g;} } /*******************************************************************/ if(_Flag->K){ /****************************************************************** * KREUZER polytope */ if (_Flag->M) puts("Option -K should not be combined with option -M"); else{ printf("KreuzerPoly="); for(i=0;inv;i++) { if(i)printf("+"); NewtonMonomial(_P->x[i],d); } for(i=V->nv;ix[i],d); } printf(";"); if(cp<_P->np-1) printf(" intpts=%d;",_P->np-cp-1); j=cp-_P->n; for(i=0;i1){ j+=Dh0[i]-1; printf(" multd%d=%d;",i+1,Dh0[i]); } if(_Flag->H == 0) printf(" Pic=%d",j); printf("\n");} /*****************************************************************/ } if(_Flag->I){ /******************************************************************* * PRINT INCIDENCES */ /* prints the incidences */ fprintf(outFILE,"Incidence:"); /* j runs over the facets */ for(j=0;jne;j++) { fprintf(outFILE," "); /* prints the incidence of the j-facet*/ fprI(cp,I[j]);} fprintf(outFILE,"\n"); /******************************************************************/ } #if (PRINT_MONOMIALS) for(j=0;jne;j++) { for(i=0;ie[j]),_P->x[i],_P->n)); puts(" monomial");} #endif // h02(D_i): enumerate $\sum c_kD_k=D_i$ with $c_i=-1$ and 0<=c_k for k!=i // where "=" means equal charges, i.e. columns in F->W[n]; but: the $c_k$ // are sections $\chi_m$ i.e. $c_k==m_i v_ki$ only if $m_i$ are // admitted to be fractional in case of torsion gradings. Hence the correct // formula enumerates $m$ with $+a_j\ge0$ for sections of $\sum a_jD_j$. // c=Init_Multiloop(N,L,&j,&J); Dh2[i]=0; // 0<=I[j]M) TriList_to_MoriList(_P, F, _Flag); else if (_Flag->g||_Flag->m||_Flag->b||_Flag->i ||_Flag->c||_Flag->t||_Flag->d||_Flag->H) Subdivide(_P,V->nv,I,cp,T,&t, _Flag ,F); if (0) { /* seems to be left-over rubbish */ PolyPointList *DP = (PolyPointList *) malloc(sizeof(PolyPointList)); EqList *DE = (EqList *) malloc(sizeof(EqList)); PairMat PM,DPM; Make_Dual_Poly(_P,V,E,DP); Make_VEPM(_P,V,E,PM); VNL_to_DEL(_P, V, DE); assert(Transpose_PM(PM,DPM,V->nv,E->ne)); Complete_Poly(DPM,DE,E->ne,DP); //for(i=0;inv,I,cp,T,&t, _Flag ,F); } free(F); } /**************************************************************** * MORI CONE: mori.x -DM **************************************************************** * The following functions are needed for option -M * * Example: * echo -e "2 8\n0 -1 -1 0 1 -1 -1 0\n0 2 -1 -1 0 0 1 1\n1\n7 10011000 10100100 10110000 10000110 11000010 10001001 11000001" | ./mori.x -DM * * These routines are those contained in the old mori.c * of version palp-1.1. It would be desirable to clean up this * part and harmonically integrate it in the code above: * 1) some functions do very similar things as others already * contained in the code above (e.g. Print_Mori_Old <-> Print_Mori) * 2) note the use of INCI instead of Inci64 * ****************************************************************/ #define Inci64_EQ(x,y) ((x) == (y)) /* check on equality */ #define Inci64_0() (0) /* set all bits to 0 */ #define Inci64_1() (1) /*set only first bit to 1 */ #define Inci64_EQ_0(x) Inci64_EQ(x,Inci64_0())/* check if all bits = 0 */ #define Inci64_OR(x,y) ((x) | (y)) /* bitwise logical or */ #define Inci64_PN(x,y) (2 * (x) + !(y)) /* shift and set first bit */ #define Inci64_D2(x) ((x) / 2) /* shift by one bit */ #define Inci64_M2(x) ((x) % 2) /* value of first bit */ void IFerr(void){puts( "\n ************ INPUT FORMAT ERROR ************");} void FE(char *c){puts("Input format error in ");puts(c);exit(0);} /*needed from Read_Tri*/ void Read_EOL(void){ char c; while('\n'!=(c=fgetc(inFILE))) if(feof(inFILE))FE("EOF"); } int ReadInt(void) { int n; char c=fgetc(inFILE); if(!IsDigit(c)&&(c!='-')) FE("ReadInt"); ungetc(c,inFILE); fscanf(inFILE,"%d",&n); while(' '==(c=fgetc(inFILE))); ungetc(c,inFILE); return n; } /*needed from Read_Tri*/ Inci64 Read_INCI(int p){ Inci64 X=Inci64_1(); /* dirty: starts with the 1 required by the old format */ char c; while(' '==(c=fgetc(inFILE))); ungetc(c,inFILE); while(IsDigit(c=fgetc(inFILE))) {assert(c<'2'); X=Inci64_PN(X,'1'-c); p--;} if(p) { IFerr(); printf("Input format error: INCI string too %s\n\n", (p>0)? "short" : "long"); fprintf(outFILE,"Type -h for help.\n"); exit(0);} ungetc(c,inFILE); return X; } void Write_INCI(Inci64 X,int v) { int i; char c[VERT_Nmax+1]; c[v]=0; for(i=0;inv=0; while(!Inci64_EQ_0(X)) {n--; if(Inci64_M2(X)) _V->v[_V->nv++]=n; X=Inci64_D2(X);} Sort_VL(_V);} /*needed from Read_Tri*/ void Test_INCI(int *nI, Inci64 *ILi,int p){ Inci64 X=ILi[0]; VertexNumList V; int i; for(i=1;i<*nI;i++)X=Inci64_AND(X,ILi[i]); INCI_2_VNL(X,&V,p); if((V.nv!=1)||(V.v[0]!=0)){IDerr();puts("INCI intersection must be 10...0"); exit(0);}X=ILi[0];for(i=1;i<*nI;i++)X=Inci64_OR(X,ILi[i]);INCI_2_VNL(X,&V,p); if(V.nv!=p) {IDerr();puts("INCI union must be 11...1"); exit(0);}} void Read_Tri(int p, int *nI, int *nIA, Inci64 **_I){ int i; Inci64 *I=*_I;assert(0<=(*nIA)); if(*nIA < (*nI = ReadInt())) { if(0 < *nIA) free(I); *nIA = *nI; /* realloc I */ assert(NULL != ( I = (Inci64 *) malloc(*nIA * sizeof(Inci64)) )); *_I=I; } for(i=0;i<*nI;i++) I[i]=Read_INCI(p-1); Read_EOL(); Test_INCI(nI,I,p); } void Print_INCI_list(int nI, Inci64 *I,int v){int i; printf("INCI[%d]:",nI); for(i=0;i 000 ... 0000 0111 */ Inci64 Inci64_revert(Inci64 X, int n) { Inci64 Y=0; int i; for(i=0; in,p=P->np,ngen=0,pli[POLY_Dmax+1],/*ng0,*/e0=0,nm=0,nv,np; int m[VERT_Nmax]; Long Z[POLY_Dmax+1]; VertexNumList V; Inci64 IE[VERT_Nmax]; PolyPointList *UT = (PolyPointList *) malloc(sizeof(PolyPointList)); Matrix R,VT,G; EqList *E = (EqList*)malloc(sizeof(EqList)); assert(E!=NULL); assert(UT!=NULL); for(i=1;iV.v[k]) pli[0]=V.v[x=k]; /* pli[x-1] < pli[0] < pli[x] */ else{if(kpli"); if(x>1) assert(pli[0]>pli[x-1]); if(xx[pli[a]][b]; MoriGen(VT,Z); for(a=0;a0) for(a=0;a<=d;a++) R.x[r][pli[a]]=Z[a]; else for(a=0;a<=d;a++) R.x[r][pli[a]]=-Z[a]; //for(a=0;anp=ngen=r; r=Make_G_for_GxMT_UT(R,G); if(r!=P->np-P->n-1) { Matrix GR; R.v=ngen;Print_LMatrix(R,"R"); Print_LMatrix(G,"GLZ"); Init_Matrix(&GR,R.v,p); for(i=0;inp>=POINT_Nmax){fprintf(outFILE,"need POINT_Nmax>=%d\n",UT->np+1); exit(0);} UT->n=r; if(r>POLY_Dmax){fprintf(outFILE,"need POLY_Dmax>=%d\n",UT->n);exit(0);} for(i=0;ix[i][j]=VxV(G.x[j],R.x[i],p); for(i=0;in;i++)UT->x[UT->np][i]=0; UT->np++; Find_Equations(UT,&V,E); np=UT->np-1; nv=V.nv-1; Sort_VL(&V); if(np!=V.v[nv]) {IDerr(); puts("Suspected INCI data error:"); Print_INCI_list(nI,I,p); puts("... non-convex triangulation?\n"); exit(0);} for(i=0;ine;i++) if(Eval_Eq_on_V(&E->e[i],UT->x[np],UT->n)==0){e0++; for(j=0;je[i],UT->x[V.v[j]],r));}/* compute Eq(0)-INCIs for Vs */ if(e0>VERT_Nmax){fprintf(outFILE,"need VERT_Nmax >= %d\n",e0);exit(0);} //printf("p=%d nm=%d\n",p,nm); for(i=0;i=r); fprintf(outFILE, "%d MORI GENERATORS / dim(cone)=%d" // ": rays=%d (%d) #eq=%d (%d) #v=%d (%d)" "\n", nm,r //,ngen,ng0,e0,E->ne,nm,V.nv ); //printf("p=%d nm=%d\n",p,nm);fflush(0); for(i=0;inp/2; long long bico=P->np, Abi; if(j>P->n)j=P->n+1; while(inp-i); bico/=++i; } assert(P->npnp/2, m,n, nG[POLY_Dmax+1], g=0,d,v=P->np-1; if(j>P->n)j=P->n+1; //bico=P->np; while(inp-i); bico/=++i;} assert(P->npn+1;d++){n=0; nG[d]=0; // G[d]=&SRG[g]; for(i=0;iFilterFlag) inFILE = stdin; _POF->n = _P->n; _POF->np = _P->np; for (j=0;j<_P->np-1;j++) for (i=0;i<_P->n;i++) _POF->x[j+1][i] = _P->x[j][i]; for (i=0;i<_P->n;i++) _POF->x[0][i] = 0; if (!_Flag->FilterFlag) printf("`#triangulations': \n"); Ntri=ReadInt(); Read_EOL(); //Print_PPL(_POF, "_POF:"); if (!_Flag->FilterFlag) fprintf(outFILE, "%d triangulations:\n", Ntri); fflush(0); for(n=0; nnp, &nI, &nIA, &I); /* gives everything in the old format from input without leading 1 */ IOF = (Inci64 *) malloc(nI * sizeof(Inci64)); for (i=0; ig){ fprintf(outFILE,"%d SR-ideal\n",NrInz); for(i=0;inp);}} //fprintf(outFILE,"\n"); } // fprintf(outFILE, "\nDIAGNOSTIC: NrInz= %d ; SRG= %d ; Abi= %d" , // NrInz, SRG, Abi); /*** From here starts the code needed for composite options like -DM -i, -t, -b, -c, -d, -a, -H ***/ if(_Flag->i || _Flag->t || _Flag->b || _Flag->c || _Flag->d || _Flag->a || _Flag->H){ SR.nmax = T.nmax = VERT_Nmax; SR.d = T.d = _P->n; SR.v = T.v = _P->np; T.n = nI; T.I = I; SR.n = NrInz; SR.I = SRG; /* Redefine triang T, SR with the digit corresponding to the origin (first inci entry to the left) dropped. */ for(i=0; i>(T.v-1)) ^ 0){ T.I[i] &= ~(1 << (T.v-1)); } } T.v = SR.v = T.v-1; // reduce by one the number of entries in the incidences //Diagnostics: prints the triangulation without the origin entry // // int j; // puts(" "); // for(i=0;i>(T.v-j-1))%2);} // fprintf(outFILE, " T[%d]=%d", i, T.I[i]);// diagnostics // } /* * Invert ordering of digits of the triang and SR-ideal * incidences: e.g. 110 100--> 011 001 */ for(i=0; i>(SR.v-j-1))%2);} // fprintf(outFILE, " SR[%d]=%d", i, SR.I[i]);// diagnostics // } puts(" "); int cp = _P->np-1; IP_Simplex_Fiber(_P->x,cp,_P->n,F,FIB_Nmax,0); // Diagnostics: print the CWS computed via IP_Simplex_Fiber // // for(i=0; i< F->nw;i++){ // for(j=0;jW[i][j]); // } // fprintf(outFILE, "\n"); // } HyperSurfSingular(_P,&T,&SR,_Flag,F,&cp); } /****** End -DMi ********************************************************/ else fputs("\n",outFILE); if (_Flag->m) Print_Mori_Old(_POF, nI, IOF); free(IOF); } assert(I!=NULL); free(I); if (_Flag->FilterFlag) inFILE = NULL; } palp-2.21/lgotwist.c0000664000177600017760000012756614572603263014007 0ustar skarkeskarke/* ====================================================================== */ /* ========== lgotwist.c Sep 29 / 02 ================= */ /* ====================================================================== */ /* aao2.6 002244 4 3 4 3 4 3 -21 21 0 1 -19 19 0 2 -9 9 0 3 */ #include #include #ifdef __MSDOS__ #define NM 9 /*13*/ /* maximum number of fields */ #define WM 1024 /*8192*/ /* maximum number of words */ /* (a word is binary code for a subset of X_i) */ #define NS 10 /*14*/ /* maximum number of generators */ #define HODDIM 500 #else #define NM 13 /* maximum number of fields */ #define NS 14 /* maximum number of generators */ #define WM 8192 /* maximum number of words */ #define HODDIM 4000 #endif #define NPN 1000 #define NP 10 /* maximum number of prime factors */ #define LONGOUT (0) /* (1) for long output, otherwise (0) */ #define ONLYINV (0) /* (1) iff only invertibles are computed */ #define MAXPN 512 /* maximum number of pointers at one point */ #define SAFER (1) /* SAFER=1 ==> b01 with rat, less danger of overflow */ #define ADDZD (0) /* ADDZD = 1 (0) iff Z_d is (not) to be added */ int mask[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384}; int interb01(); /* ... interface to "mhodge" conventions */ FILE *infi, *outfi; int stdi=0, bugcount=0, invertible; /* stdi=1 if called without "infile" (see: main, readline) */ /* ====================================================================== */ /* ========== integer and rational stuff ========== */ /* ====================================================================== */ /* ========== rat.h (header -> #include "rat.h") ========== */ /* ====================================================================== */ #define lint long #define sint int #define mod(a,b) ((a)%(b)) /* ((a)-(b)*((a)/(b))) */ #define MOD(a,b) ((b) ? mod(a,b) : (a)) #define min(a,b) (((a)<(b)) ? (a) : (b)) #define max(a,b) (((a)>(b)) ? (a) : (b)) #define lcm(a,b) ((a)*(b)/gcd((a),(b))) #define plcm(a,b) (a)*((b)/pgcd(a,b)) #define abs(a) (((a)<0) ? (-(a)) : (a)) lint gcd(lint a, lint b); /* modulus of greatest common div.; gcd(0,n)=|n| */ typedef struct {lint num; lint den;} rat; rat rI(lint a); /* conversion lint -> rat */ rat rR(lint a, lint b); /* conversion a/b -> rat */ rat rS(rat a, rat b); /* a + b */ rat rD(rat a, rat b); /* a - b */ rat rP(rat a, rat b); /* a * b */ rat rQ(rat a, rat b); /* a / b */ void fS(rat *a, rat *b); /* fast sum: add rat *b to rat *a */ void iS(rat *a, int *b); /* fast sum: add int *b to rat *a */ /* ====================================================================== */ /* ========== rat.c (source code: cc -c rat.c generates rat.o) ========== */ /* ========== cc -o prog prog.c rat.o incl. obj. code rat.o ========== */ /* #include "rat.h" ================================================ */ rat rI(register lint a) {rat c; c.num=a; c.den=1; return c; } /* a/1 */ rat rR(register lint a, register lint b) /* a/b */ { register lint g=gcd(a,b); rat c; g=(b<0) ? -g:g; c.num=a/g;c.den=b/g; return c; } rat rS(rat a, rat b) /* a + b */ { register rat c; register lint g=gcd(a.den,b.den); g=gcd(c.den=a.den*(b.den/g),c.num=a.num*(b.den/g)+b.num*(a.den/g)); c.num/=g; c.den/=g; return c; } rat rD(rat a, rat b) /* a - b */ { register rat c; register lint g=gcd(a.den,b.den); g=gcd(c.den=a.den*(b.den/g),c.num=a.num*(b.den/g)-b.num*(a.den/g)); c.num/=g; c.den/=g; return c; /** register rat c; register lint g=gcd(c.num=a.num*b.den-b.num*a.den, c.den=a.den*b.den); c.num/=g; c.den/=g; return c; */ } rat rP(rat a, rat b) /* a * b */ { register lint g=gcd(a.num,b.den); register lint h=gcd(b.num,a.den); register rat c; c.num=(a.num/g)*(b.num/h); c.den=(a.den/h)*(b.den/g); return c; } rat rQ(rat a, rat b) /* a / b */ { register lint g=gcd(a.num,b.num); register lint h=gcd(b.den,a.den); register rat c; c.num=(a.num/g)*(b.den/h); c.den=(a.den/h)*(b.num/g); #ifdef TEST if (!c.den) fprintf(outfi,"warning: vanishing denominator in rQ in %s!\n",infun); #endif if (c.den<0) {c.num=-c.num; c.den=-c.den;} return c; } lint gcd(register lint a, register lint b) { a = (a<0) ? -a:a; b = (b<0) ? -b:b; if (!a) return b; if (!b) return a; {register lint c; while(c=mod(a,b)) {a=b;b=c;} return b;} } lint argint(char* s) /* string to integer */ { lint d=(*s)-'0'; sint i=1; while(s[i]) d=10*d+s[i++]-'0'; return d; } void prat(rat a) {fprintf(outfi,"%ld/%ld ",a.num,a.den);} /* ====================================================================== */ /* ========== end of integer and rational stuff ========== */ /* ====================================================================== */ /****************************************************************************/ /* Construction of the maximal abelian symmetry */ /****************************************************************************/ typedef sint spectrum[3]; /* b01 change */ typedef sint pointlist[NM+1]; typedef lint symlist[NS]; typedef sint primelist[NP]; typedef sint prsymlist[NS][NP]; typedef symlist symsymlist[NS]; typedef lint sympointlist[NM+1][NS]; typedef sint prsympointlist[NM+1][NS][NP]; typedef sint prsymsymlist[NS][NS][NP]; typedef lint worte[WM+1][3]; lint lcmd, specnum, symnum, totsymnum=0, totspecnum=0, maxsymnum=0, maxspecnum=0, modelnum=0; /* lcmd = least common multiple of the orders of the generators of the maximal group */ sint n, norig, ns, npr, addsyms, evenn, oddd, over=1, D; /* D=sum(1-2q_i) */ /* n = number of points X_i; */ /* ns = number of phase symmetries, nsN=0; if(stdi) printf("skeleton? "); while(' '!=(i=fgetc(infi))) if(i==EOF) return 0; else s->p[s->N++]=i-'0'; for(i=0;i<(s->N);i++) fscanf(infi,"%d",&s->a[i]); n=(*s).N; while(fgetc(infi)-'\n'); return 1; } long pgcd(register long a, register long b) { register long c; while(c=mod(a,b)) {a=b;b=c;} return b; } int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83, 89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191, 193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293, 307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419, 421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541, 547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653, 659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787, 797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919, 929,937,941,947,953,967,971,977,983,991,997}; void printpri(prili li) { int i; fprintf(outfi,"\nlist of primes:\n"); for(i=1;i<=*li.p;i++) {fprintf(outfi,"%d,",li.p[i]); if(!mod(i,20)) fprintf(outfi,"\n");} fprintf(outfi,"\nmaximal multiplicities (in one generator):\n"); for(i=1;i<=*li.p;i++) {fprintf(outfi,"(%d,%d) ",li.p[i],li.m[i]); if(!mod(i,10)) fprintf(outfi,"\n");} fprintf(outfi,"\n"); } prili prideco(long x) { int n=0,p; long q; prili l; *l.p=*l.m=1; l.m[1]=0; while(x>=((p=prime[n++])^2)) { while(!(x-p*(q=x/p))) {x=q; l.m[*l.p]++;} if(l.m[*l.p]){l.p[*l.p]=p;*l.m=max(*l.m,l.m[*l.p]);l.m[++(*l.p)]=0;}} if(x==1) (*l.p)--; else {l.m[*l.p]=1; l.p[*l.p]=x;} return l; } void maxpri(prili pn) /* pmax = prime decomposistion of lcm of group orders */ { int i=1,j=1,n=1; prili po=pmax; *pmax.m=max(*po.m,*pn.m); po.p[*po.p+1]=pn.p[*pn.p+1]=po.p[*po.p]+pn.p[*pn.p]+1; if(*po.p){while((i<=*po.p)||(j<=*pn.p)) { if(po.p[i]pn.p[j]) {pmax.p[n]=pn.p[j];pmax.m[n]=pn.m[j++];} else{pmax.m[n]=max(po.m[i],pn.m[j]);pmax.p[n]=po.p[i++];j++;}n++;} *pmax.p=n-1;} else pmax=pn; /* printpri(pmax); */ } /* analy first finds all minimal member of loops (or fermats): value = i * * for any such i its connected component of the graph is reconstructed: * * i=lo[1] -> lo[2] -> ... -> lo[*lo] -> i; * * the remaining variables are on "ord[1],...,ord[*ord]" such that all * * pointers go from right to left (or from ord to lo, of course). * * inv[k][1],...,inv[k][*inv[k]] are all variables pointing at k. */ /* Now go thru ord from right to left and calculate lcm=prod(t) with t_k * * dividing the corresponding exponent s.a[], divide the orders of the * * groups corresponding to inv[] by t_k and evaluate the new generator */ /* finally repeat this for the loop of i and evaluate its symm.-generator */ void analy(skelet s) { long ph[NM][NM+1], /* p[i][0] = order of sym. i1) invertible=0; for(i=0;ii)) j=s.p[j]; if(j==i){ /* check for i == minimal loop member '{{' */ int m=0; *lo=s.N-n; /* comlete connected component */ if(*lo==1) {*lo=0; n=2;ord[m=1]=i;} /* if i fermat -> no loop! */ else {lo[1]=i; n=1; /* initialize lo[] and evaluation of ord: */ for(j=2;j<=*lo;j++) lo[j]=s.p[lo[j-1]]; while(m<*inv[i]) {if(lo[*lo]!=(ord[n]=inv[i][++m])) n++;} for(j=2;j<=*lo;j++) {m=0; while(m<*inv[lo[j]]) if(lo[j-1]!=(ord[n]=inv[lo[j]][++m])) n++;}} lopo=n-1; /* now ord[1],...,ord[lopo] are the pointers at loop(i) */ for(m=1;m0) calculate symmetry for the loop of the component of i: */ /* remember that ord[1],...,ord[lopo] point at the loop */ if(*lo>1) {prili pli; long P=s.a[lo[*lo]],b[NM+1], tli[NM], lcm; b[1]=1; for(j=1;j<*lo;++j) b[j+1]=-b[j]*s.a[lo[j]]; P *= b[j]; if((++P)<0) P=-P; den[i]=P; /* P = prod(exp(j)) +/- 1 */ lcm=1; /* nt[*nt] -> ord[lopo] */ for(j=0;(j++)NM) {printf("infinit loop(1): fac=%d ",fac);return;} ... debug */} fac=b[fac]; while(pgcd(abs(fac),*ph[ord[n]])>1) {fac-=P; /* if(abs(fac/P)>NM) {printf("infinit loop(2): fac=%d ",fac);return;} debug*/} fac*=lcm/(*ph[ord[n]]); for(j=1;j<=*ord;j++) ph[i][ord[j]+1]-=fac*ph[ord[n]][ord[j]+1];} for(j=1;j<=lopo;j++) *ph[ord[j]]/=tli[j]; /* divide orders by t_j */ } maxpri(prideco(*ph[i])); if(*lo<2) {num[i]=1;den[i]=s.a[i];} /* calculate weights num[j]/den[j] */ else {num[i]=1-s.a[lo[2]]; for(j=2;j<*lo;num[i]=1-s.a[lo[++j]]*num[i]); d=pgcd(den[i],num[i]=abs(num[i])); num[i]/=d; den[i]/=d;} for(j=1;j<*lo;j++) {den[n=lo[j+1]]=den[lo[j]]; d=pgcd(den[n], num[n]=den[n]-s.a[lo[j]]*num[lo[j]]); num[n]/=d;den[n]/=d;} for(j=1+(*lo==0);j<=*ord;j++){den[ord[j]]=s.a[ord[j]]*den[n=s.p[ord[j]]]; d=pgcd(den[ord[j]],num[ord[j]]=den[n]-num[n]); num[ord[j]]/=d;den[ord[j]]/=d;} /* end of calculation of weights */ }} /* '}}' */ d=*den; for(j=1;j1) { n++; if(LONGOUT)fprintf(outfi,"\n%d->Z[%ld]: ",j,*ph[j]); wei[s.N][n]=ph[j][0]; for(k=1;k<=s.N;k++){ wei[k-1][n]=ph[j][k]; if(LONGOUT)fprintf(outfi," %ld",ph[j][k]);} G*=*ph[j];} ns=n; if(LONGOUT) {fprintf(outfi,"\nskeleton ="); fprintf(outfi," ");} if(invertible || !ONLYINV) { for(l=0;l1 /* prd[0][j] for torsion */){ imax=0; for (i=1;i<=ns;i++) if (prdet[i][j].den==maxdetden){ if (!imax) imax=i; else { if (prd[i][j]>prd[imax][j]) {ig=i; is=imax;} else {ig=imax; is=i;}; k=0; while (mod(prdet[ig][j].num+k*prdet[is][j].num,maxdetden)) k++; for (l=0;lprd[imax][j]) imax=k; if (imax>i) { for (k=0;k1)&&(i=MAXPN) { printf("pointernum too large\n"); return 1;} monlist[i][pn]=mon[0]; linklist[i][pn]=link; targlist[i][pn]=targets|mask[i]; return 0; }; }; return 1; } sint checkweight(){ /* checks whether our weight system allows a non-degenerate symmetry-respecting potential */ sint i, j; for (i=0;i=0;i--) if (wo[i][0]+wo[i][2]) { prod=rI(1); for (j=0;j n+2 n+2 0 1 und n n 0 6 -> n+6 n+6 0 3. */ if ((spec[2]!=0)&&(spec[2]!=1)&&(spec[2]!=3)&&(D==3)) { fprintf(outfi,"caution: b01=%d\n", spec[2]); bugcount++;} ng = -(zsum1/mo/over+2)/2; ngb = (zsum2/mo/over-2)/2; if (zsum1 != -2*(ng+1)*mo*over) {fprintf(outfi,"ng is not integer!\n");bugcount++;} if (zsum2 != 2*(ngb+1)*mo*over) {fprintf(outfi,"ngb is not integer!\n");bugcount++;} chi = 2*(ngb-ng); if(LONGOUT) fprintf(outfi,"ngb: %ld ng: %ld chi: %d\n",ngb,ng,chi); spec[0]=ngb; spec[1]=chi; addhod(spec); } /************* End of calculation of Hodge numbers **********/ /****************************************************************************/ /* Construction of all symmetries */ /****************************************************************************/ sint forbidden(sint i, sint j, sint sprns) { sint l; for (l=0;l=npr) processym(); else if (k>=sprns){ if (zdtest(j,sprns)){ /* if nprwei contains projection of Z_d calculate auxwei: */ if (j==0) {imax=0; auxns[0]=sprns;} else {imax=min(auxns[j-1],sprns); auxns[j]=max(auxns[j-1],sprns);} for (i=0;i0) for (i=imax;iprns[j]){ /* calculate nprwei[.][k][j] from sprwei[l][k][j] */ for (m=0;mnorm[k][j]) while (sprwei[l][k][j]=0) { sprwei[l][k][j]=0; if (lnorm[k][j]) while (sprwei[l][k][j]norm[sprns-1][j]) sprd[sprns][j]=min(prd[i][j],sprd[sprns-1][j]); else sprd[sprns][j]=min(prd[i][j],sprd[sprns-1][j]/pr[j]); while (sprd[sprns][j]>1) { reccon(j,sprns+1); sprd[sprns][j]/=pr[j]; }; } } /****** End of construction of symmetries *********************************/ /****************************************************************************/ /* Input/output/statistics part */ /****************************************************************************/ void datain() /* asks for input, reads input, calculates det */ { int i, k, evenn=mod(n-D,2), addtriv=2*((addsyms+1)/2)+evenn; norig=n; /* n-1 -> n-D with D=sum(1-2q_i) */ d[0]=wei[n][0]; oddd=mod(d[0],2); lcmd=d[0]; det[0]=0; for (k=1;k<=ns;k++){ det[k]=0; for (i=0;i<=n;i++) det[k]+=wei[i][k]; d[k]=wei[n][k]; det[k]=mod(det[k], d[k]); lcmd=lcm(lcmd,d[k]); } if (addtriv){ /* add correct trivial factor + triv. symm. */ if(oddd){ for (i=0;i<=n;i++) wei[i][0]*=2; d[0]=wei[n][0]; } wei[n+addtriv][0] = d[0]; for (i=0;ihodge2[2]) return 1; if (hodge1[1]hodge2[1]) return 1; if (hodge1[0]hodge2[0]) return 1; return 0; } spectrum search={0,0,0}; void searchspec(spectrum); void addhod(spectrum hodge){ sint i, j, k; searchspec(hodge); for(j=0; ((hodcomp(hodge, hodlist[j])>0)&&(jj;k--) for (i=0;i<3;i++) hodlist[k][i]=hodlist[k-1][i]; for (i=0;i<3;i++) hodlist[j][i]=hodge[i]; specnum++; } } void finishmodel() { sint j; if(LONGOUT)fprintf(outfi,"\nspecnum, symnum: "); fprintf(outfi,"sp=%ld sy=%ld\n", specnum, symnum); for (j=0;j0 => c=0"); /* search={a,c=2(a-g),b} */ ReadEOL(); search[0]=a; search[1]=c; search[2]=b;} void PrintUse(char *s){puts(s); puts("Either '-s' or '-g # -a #' is required, the rest is optional"); puts(" -s ask for spectrum"); puts(" -g h12 #generations"); puts(" -a h11 #anti-generations"); puts(" -b h01 #(01)-forms"); puts(" -t # # of trivial pairs [1]"); puts(" -i InFile "); puts(" -o OutFile"); exit(0);} void LgoTwistInit(int narg, char* fn[]){ int n=1,t=0, /* t-> # trivial pairs */ g=0,a=0,b=0; char *c; infi=stdin; stdi=1; outfi=stdout; if(narg<2)PrintUse(""); while(n1) infi=fopen(fn[1],"r"); aao2.6 002244 4 3 4 3 4 3 else { infi=stdin; stdi=1; printf("usage: arg1=input file [stdin]; arg2=output file [stdout];\n"); printf(" arg3=#pairs of trivial fields to be added;\n"); printf("skeleton = string[#] exp_1 ... exp_#\n");} if (narg>2) outfi=fopen(fn[2],"w"); else outfi=stdout; if (narg>3) addsyms= *fn[3]-'0'; else addsyms=0; if (narg>4) search[1]=atoi(fn[4]); if (narg>5) search[0]=atoi(fn[5]); if (narg>6) search[2]=atoi(fn[6]); search[1]=2*(search[0]-search[1]); */ while(readline(&s)&&!bugcount){ /* search={a,c=2(a-g),b} */ analy(s); if(invertible || !ONLYINV) { datain(); if(LONGOUT)longoutput0(); primedecomp(); if(LONGOUT)longoutput1(); gooddets(); if(LONGOUT)longoutput2(); reccon(0,0); finishmodel();} } /* fprintf(outfi,"modelnum, totsymnum, maxsymnum, totspecnum, maxspecnum: "); fprintf(outfi,"%ld %ld %ld %ld %ld", modelnum, totsymnum, maxsymnum, totspecnum, maxspecnum); */ fprintf(outfi, "#skel=%ld, #sym=%ld, sym/skel<=%ld, #spectra=%ld, spec/skel<=%ld", modelnum, totsymnum, maxsymnum, totspecnum, maxspecnum); printpri(pmax); } /* ========================= b01 ========================= */ int interb01(/*struct ein */); /* ... interface to "mhodge" conventions */ /* calculate b01 for NG generators: Z_{*gen[j]}: (gen[j][1],...,gen[j][N]) * * 0<=j "exit" (i.e. pow[j++]++); else * * if j==0 ==> "do it"; else "call" (i.e. {pow[--j]=0; initializations;}) * * code: pow[j=NG-1]=0;while(jnum=mod(a->num,a->den);} int b01(sint N, sint NG, sint zd[NM+1], lint gen[NS][NM+1]) { int b=0, i,j, eq[NM+1],pow[NS+1]; /* eq=th_i==q_i; pow(er) of generator */ over=0; pow[j=NG-1]=0; while(j set eq */ for(k=0;k set eq */ {lint th=0; for(k=0;k ns; *e.n -> n; *e.w -> wei; PM->NS */ { sint i,j,zd[NM+1]; lint gen[NS][NM+1]; zd[0]=wei[n][0]; for(i=1-ADDZD;i<=ns;i++) gen[i][0]=wei[n][i]; for(i=1;i4) #define SIMPLE_CTH (0) #define INCOMPLETE_SL_REDUCTION (0) #define TEST_Aided_IP_CHECK (0) #ifndef CEQ_Nmax #define CEQ_Nmax EQUA_Nmax #endif #define IMPROVE_SL_COORD (0) /* 0=no 1=SL(old) 2=GL(new) */ #define IMPROVE_SL_REGCD (0) typedef struct {int nk, k[VERT_Nmax];} KeepList; typedef struct {int ne; Equation e[CEQ_Nmax];} CEqList; /* ========== Auxiliary routines from other modules ========== */ Long CompareEq(Equation *X, Equation *Y, int n); int IsGoodCEq(Equation *_E, PolyPointList *_P, VertexNumList *_V); int Finish_IP_Check(PolyPointList *_P, VertexNumList *_V, EqList *_F, CEqList *_CEq, INCI *F_I, INCI *CEq_I); /* from Vertex.c */ int Improve_Coords(PolyPointList *_P,VertexNumList *_V); /* from Polynf.c */ int New_Improve_Coords(PolyPointList *_P,VertexNumList *_V) { switch(IMPROVE_SL_COORD) { case 0: return 1; case 1: return Improve_Coords(_P,_V); case 2: Make_Poly_UTriang(_P); return 1; default: assert(0);} } /* ====================================================================== */ /* ========== ========== */ /* ========== S U B P O L Y S ========== */ /* ========== ========== */ /* ====================================================================== */ int IsNewEq(Equation *E, CEqList *_C, EqList *_F, int *_n){ int i=_C->ne; while(i--) if(!CompareEq(E,&_C->e[i],*_n)) return 0; i=_F->ne; while(i--) if(!CompareEq(E,&_F->e[i],*_n)) return 0; return 1; } int Irrel(INCI *_INCI, INCI *INCI_List, int *n_irrel){ int i; for (i=0;i<*n_irrel;i++) if (INCI_EQ(*_INCI, INCI_List[i])) return 1; return 0; } void INCI_To_VertexNumList(INCI X, VertexNumList *_V, int n){ _V->nv=0; while(!INCI_EQ_0(X)) {n--; if(INCI_M2(X)) _V->v[_V->nv++]=n; X=INCI_D2(X);} } void Remove_INCI_From_List(INCI New_INCI, INCI *INCI_List, int *n_INCI){ int i; for (i=*n_INCI-1;i>=0;i--) { if(INCI_LE(INCI_List[i],New_INCI)) INCI_List[i]=INCI_List[--(*n_INCI)];} } void Add_INCI_To_List(INCI New_INCI, INCI *INCI_List, int *n_INCI){ int i; for (i=*n_INCI-1;i>=0;i--) { if(INCI_LE(New_INCI,INCI_List[i])) return; if(INCI_LE(INCI_List[i],New_INCI)) INCI_List[i]=INCI_List[--(*n_INCI)];} assert(*n_INCI < CD2F_Nmax); INCI_List[(*n_INCI)++]=New_INCI; } /* An INCI_List corresponds to a list of facets of some polytope, which might be the original polytope or one of its faces. This implies that no two INCIs x,y of the INCI_List fulfill INCI_LE(x,y). Consequently, Add_INCI_To_List enhances INCI_List by New_INCI only if there is no y in INCI_List such that INCI_LE(New_INCI,y) is fulfilled; at the same time it removes any y with INCI_LE(y,New_INCI) from INCI_List. Remove_INCI_From_List removes any y with INCI_LE(y,New_INCI) from INCI_List. */ INCI List_Complete(int n, int n_polys, int n_facets, INCI *polys, INCI *facets); INCI Poly_Complete(int n, int *n_polyfacets, INCI *poly, INCI *polyfacets){ int j, k, n_cd2_faces=0; INCI cd2_faces[CD2F_Nmax]; INCI X=INCI_0(); for (j=0;j<*n_polyfacets;j++) X=INCI_OR(X,polyfacets[j]); if (n==1) return INCI_XOR(X,*poly); for (j=0;j<*n_polyfacets;j++) for (k=j+1;k<*n_polyfacets;k++) Add_INCI_To_List(INCI_AND(polyfacets[j],polyfacets[k]), cd2_faces,&n_cd2_faces); return INCI_OR(INCI_XOR(X,*poly), List_Complete(n-1,*n_polyfacets,n_cd2_faces,polyfacets,cd2_faces)); } INCI List_Complete(int n, int n_polys, int n_facets, INCI *polys, INCI *facets){ int i, j, n_polyfacets; INCI polyfacets[CEQ_Nmax]; INCI X=INCI_0(); for (i=0;in){ printf("Hole_Verts.nv=%d\n",Hole_Verts.nv); puts("Hole_Verts:"); Print_INCI(Hole_Vert_INCI); puts("\nCEq_INCI:"); for(i=0;i<_CEq->ne;i++) {Print_INCI(CEq_INCI[i]); puts("");} Print_VL(_P,_V,""); Print_EL((EqList *) _E,&_P->n,0,""); Print_EL((EqList *) _CEq,&_P->n, 0,""); exit(0);} P.n=_P->n; P.np=Hole_Verts.nv; for (i=0;in;j++) P.x[i][j]=_P->x[Hole_Verts.v[i]][j]; Find_Equations(&P,&Hole_Verts,&BVE); assert(BVE.ne); for (i=0;in)){ n_new_Eq++; assert(_CEq->nene]=Eq_To_INCI(&BVE.e[i],_P,_V); _CEq->e[_CEq->ne++]=BVE.e[i];} assert(n_new_Eq); } void Close_the_Hole(PolyPointList *_P, VertexNumList *_V, EqList *_E, CEqList *_CEq, int old_ne, int n_old_v, int n_Hole_Faces, INCI *E_INCI, INCI *CEq_INCI, INCI Hole_Verts, INCI *Hole_Faces){ INCI Bad_Vert_INCI, cd2_Faces[CD2F_Nmax]; int n_cd2_Faces=n_Hole_Faces, np=_P->np, i, j; /* puts("CTH"); Print_PPL(_P); fprintf(outFILE,"_E:\n"); for (i=0;i<_E->ne;i++){ for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ", _E->e[i].a[j]); fprintf(outFILE," %d\n", _E->e[i].c);} fprintf(outFILE,"n_irrel=%d, n_old_v=%d\n", n_irrel, n_old_v); fprintf(outFILE,"E_INCI: "); for (i=0;i<_E->ne;i++) Print_INCI(E_INCI[i]); fprintf(outFILE,"\nHole_Faces: "); for (i=0;inp=n_old_v; while(n_Hole_Faces--){ int not_found=1; VertexNumList Other_Verts; Equation Eq, E1, E2; /* Connect the codim 2 faces along the hole with other vertices bounding the hole; calculate corresponding equations and check if they are good and new */ for (j=0;(j<_E->ne)&¬_found;j++) if (INCI_LE(Hole_Faces[n_Hole_Faces],E_INCI[j])){ E1=_E->e[j]; not_found=0;} if (not_found) fprintf(outFILE,"Equation1 not found in Close_The_Hole!\n"); not_found=1; for (j=_E->ne;(je[j]; not_found=0;} if (not_found) fprintf(outFILE,"Equation2 not found in Close_The_Hole!\n"); INCI_To_VertexNumList(INCI_XOR(Hole_Faces[n_Hole_Faces],Hole_Verts), &Other_Verts, n_old_v); for (i=0;ix[Other_Verts.v[i]],_P->n); if (IsGoodCEq(&Eq,_P,_V)) { CEq_INCI[_CEq->ne]=Eq_To_INCI(&Eq,_P,_V); if (!Irrel(&(CEq_INCI[_CEq->ne]),E_INCI,&_E->ne)){ assert(_CEq->nee[_CEq->ne]=Eq; Remove_INCI_From_List(CEq_INCI[_CEq->ne], Hole_Faces,&n_Hole_Faces); _CEq->ne++; break;}}}} /* for (i=0;i<_CEq->ne;i++){ fprintf(outFILE,"_CEq->e[%d]: ",i); for (j=0;j<_P->n;j++) fprintf(outFILE," %d",_CEq->e[i].a[j]); fprintf(outFILE," %d\n",_CEq->e[i].c);} for (i=0;i<_E->ne;i++){ fprintf(outFILE,"_E->e[%d]: ",i); for (j=0;j<_P->n;j++) fprintf(outFILE," %d",_E->e[i].a[j]); fprintf(outFILE," %d\n",_E->e[i].c);} fflush(0); */ for (i=0;i<_CEq->ne;i++) for (j=0;jn-1) continue; for (k=0;k<_CEq->ne;k++) if (INCI_LE(New_Face,CEq_INCI[k])) if((k!=i)&&(k!=j)) break; if (k<_CEq->ne) continue; for (k=0;k<_E->ne;k++) if (INCI_LE(New_Face,E_INCI[k])) break; if (k<_E->ne) continue; assert(n_cd2_Facesn-1, _CEq->ne, n_cd2_Faces, CEq_INCI, cd2_Faces); if (!INCI_EQ_0(Bad_Vert_INCI)) FE_Close_the_Hole(_P, _V, _E, _CEq, n_old_v, CEq_INCI, Bad_Vert_INCI); _P->np=np; } int Aided_IP_Check(PolyPointList *_P, VertexNumList *_V, EqList *_E, int n_irrel, int n_old_v){ /* The first n_old_v entries of _P are the old vertices; the first n_irrel entries of _E are the irrelevant old facets (which remain facets), the remaining facets are the relevant facets */ int i, j, n_Hole_Faces=0, old_ne=_E->ne; INCI CEq_INCI[CEQ_Nmax], Hole_Verts; INCI E_INCI[EQUA_Nmax]; INCI Hole_Faces[CD2F_Nmax]; CEqList CEq; if (n_irrel==0) { fprintf(outFILE, "n_irrel=0 in Aided_IP_Check!"); exit(0); } /* Create E_INCI: Incidences between _E and old vertices; Intersect relevant and irrelevant facets to get the codim 2 faces that bound the hole; Create Hole_Verts as the union of Hole_Faces */ for (i=0;i<_E->ne;i++){ E_INCI[i]=INCI_0(); for (j=0;je[i]),_P->x[j],_P->n));} for (i=0;ine;j++) { INCI New_Face=INCI_AND(E_INCI[i],E_INCI[j]); int k; if (INCI_abs(New_Face)<_P->n-1) continue; for (k=0;k<_E->ne;k++) if (INCI_LE(New_Face,E_INCI[k])) if((k!=i)&&(k!=j)) break; if (k<_E->ne) continue; assert(n_Hole_Facesn,0); puts("E_INCI:"); for(i=0;i<_E->ne;i++) {Print_INCI(E_INCI[i]); puts("");} printf("n_irrel=%d\n", n_irrel); */ Hole_Verts=INCI_0(); for (i=n_irrel;i<_E->ne;i++) Hole_Verts=INCI_OR(Hole_Verts, E_INCI[i]); for (i=0;iv[i]=i; _V->nv=n_old_v; _E->ne=n_irrel; if (n_irrel==1) { /* Find vertex of maximal distance from the irrelevant facet and make Candidate equations by connecting it with the Hole_Faces */ Long maxdist; int newvert=n_old_v; if (n_old_v==_P->np) return 0; maxdist=Eval_Eq_on_V(&(_E->e[0]),_P->x[n_old_v],_P->n); for (i=n_old_v+1; i<_P->np; i++){ Long dist=Eval_Eq_on_V(&(_E->e[0]),_P->x[i],_P->n); if (dist>maxdist) { newvert=i; maxdist=dist; continue;} if (dist==maxdist) if (Vec_Greater_Than(_P->x[i],_P->x[newvert],_P->n)){ newvert=i; maxdist=dist;}} _V->v[_V->nv++]=newvert; for (i=0;ie[j]; not_found=0;} if (not_found) fprintf(outFILE,"Equation1 not found in Aided_IP_Check!\n"); not_found=1; for (j=n_irrel;(je[j]; not_found=0;} if (not_found) fprintf(outFILE,"Equation2 not found in Aided_IP_Check!\n"); CEq.e[i]=EEV_To_Equation(&E1,&E2,_P->x[newvert],_P->n); for (j=0;jx[j],_P->n))){ if (dist<0){ int k; CEq.e[i].c=-CEq.e[i].c; for(k=0;k<_P->n;k++) CEq.e[i].a[k]=-CEq.e[i].a[k]; } break;}} E_INCI[0]=INCI_PN(E_INCI[0],1); for (i=0;in;j++) fprintf(outFILE," %d",CEq.e[i].a[j]); fprintf(outFILE," %d\n",CEq.e[i].c);} fprintf(outFILE,"CEq_INCI: "); for (i=0;ine;i++){ fprintf(outFILE,"_E->e[%d]: ",i); for (j=0;j<_P->n;j++) fprintf(outFILE," %d",_E->e[i].a[j]); fprintf(outFILE," %d\n",_E->e[i].c);} fprintf(outFILE,"E_INCI: "); for (i=0;i<_E->ne;i++) Print_INCI(E_INCI[i]); fflush(0); */ return Finish_IP_Check(_P, _V, _E, &CEq, E_INCI, CEq_INCI); } void Make_All_Subpolys(PolyPointList *_P, EqList *_E, VertexNumList *_V, KeepList *_KL, NF_List *_NFL); int Relevant(Long *X, int *n, EqList *_E, int *n_irrel){ int i; for (i=0;i<*n_irrel;i++) if (!Eval_Eq_on_V(&(_E->e[i]),X,*n)) return 0; for (i=0;i<*n;i++) if (X[i]) return 1; return 0; } int kept(int i, KeepList *_KL){ int j; for(j=0;j<_KL->nk;j++) if(_KL->k[j]==i) return j; return -1; } void Drop_and_Keep(PolyPointList *_P, VertexNumList *_V, EqList *_E, KeepList *_KL, int drop_num, NF_List *_NFL){ int i, j, n_irrel=0, IP; int *new2old =(int *) malloc(sizeof(int)*POINT_Nmax); Long drop_point[POLY_Dmax]; VertexNumList red_V; EqList *new_E=(EqList *) malloc(sizeof(EqList)); PolyPointList *red_P = (PolyPointList *) malloc(sizeof (PolyPointList)); if(red_P==NULL) {puts("Unable to allocate space for red_P"); exit(0);} if(new2old==NULL) {puts("Unable to allocate space for new2old"); exit(0);} for (j=0;j<_P->n;j++) drop_point[j]=_P->x[_V->v[drop_num]][j]; /* Create new_E: Same as *_E, but irrelevant facets first */ new_E->ne=_E->ne; for (i=0;i<_E->ne;i++){ if (Eval_Eq_on_V(&(_E->e[i]),drop_point,_P->n)){ for (j=0;j<_P->n;j++) new_E->e[n_irrel].a[j]=_E->e[i].a[j]; new_E->e[n_irrel++].c=_E->e[i].c;} else { for (j=0;j<_P->n;j++) new_E->e[_E->ne+n_irrel-i-1].a[j]=_E->e[i].a[j]; new_E->e[_E->ne+n_irrel-i-1].c=_E->e[i].c;}} /* Create red_P: old vertices, points that are not on irrelevant facets */ red_P->np=0; red_P->n=_P->n; for (i=0;i<_V->nv;i++) if (i!=drop_num){ for (j=0;j<_P->n;j++) red_P->x[red_P->np][j]=_P->x[_V->v[i]][j]; new2old[red_P->np++]=_V->v[i];} for (i=0;i<_P->np;i++) if ((i!=_V->v[drop_num])&&Relevant(_P->x[i],&_P->n,new_E,&n_irrel)){ for (j=0;j<_P->n;j++) red_P->x[red_P->np][j]=_P->x[i][j]; new2old[red_P->np++]=i;} /* Print_PPL(_P); fprintf(outFILE,"new_E:\n"); for (i=0;ine;i++){ for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ", new_E->e[i].a[j]); fprintf(outFILE," %d\n", new_E->e[i].c);} fprintf(outFILE,"\n"); Print_PPL(red_P); fprintf(outFILE,"\n"); printf("drop_point: "); for (i=0;i<_P->n;i++) printf("%d ", (int) drop_point[i]); puts("");*/ _NFL->nIP++; #if UnAided_IP_CHECK IP=IP_Check(red_P,&red_V,new_E); #else IP=Aided_IP_Check(red_P,&red_V,new_E,n_irrel,_V->nv-1); #endif /* puts("After AIP (in D&K):"); Print_VL(red_P,&red_V); Print_EL(new_E,&red_P->n,0); */ free(red_P); if(IP){ VertexNumList new_V; #if TEST_Aided_IP_CHECK VertexNumList test_V; EqList test_E; #endif /* Create new_V from red_V */ new_V.nv=red_V.nv; for (i=0;inp-1) new_V.v[i]=_V->v[drop_num]; /* Drop the vertex _V->v[drop_num]: */ _P->np--; for (j=0;j<_P->n;j++) _P->x[_V->v[drop_num]][j]=_P->x[_P->np][j]; j=kept(_P->np,_KL); if (j>=0) _KL->k[j]=_V->v[drop_num]; #if TEST_Aided_IP_CHECK if(!IP_Check(_P,&test_V,&test_E)||(test_V.nv!=red_V.nv)|| (test_E.ne!=new_E->ne)){ int k; fprintf(outFILE,"_V: "); for (i=0;i<_V->nv;i++) fprintf(outFILE,"%d ",_V->v[i]); fprintf(outFILE,"\n"); fprintf(outFILE,"_E:\n"); for (i=0;i<_E->ne;i++){ for (k=0;k<_P->n;k++) fprintf(outFILE,"%d ", (int) _E->e[i].a[k]); fprintf(outFILE," %d\n", (int) _E->e[i].c);} fprintf(outFILE,"\n"); fprintf(outFILE,"drop_num: %d\n",drop_num); fprintf(outFILE,"drop_point: "); for (i=0;i<_P->n;i++) fprintf(outFILE,"%d ", (int) drop_point[i]); fprintf(outFILE,"\n"); fprintf(outFILE,"_KL: "); for (i=0;i<_KL->nk;i++) fprintf(outFILE,"%d ", _KL->k[i]); fprintf(outFILE,"\n"); fprintf(outFILE,"red_V: "); for (i=0;ine;i++){ for (k=0;k<_P->n;k++) fprintf(outFILE,"%d ", (int) new_E->e[i].a[k]); fprintf(outFILE," %d\n", new_E->e[i].c);} fprintf(outFILE,"\n"); fprintf(outFILE,"n_irrel: %d\n",n_irrel); fprintf(outFILE,"new2old:"); for (i=0;inp;i++) fprintf(outFILE," %d", new2old[i]); fprintf(outFILE,"\n"); fprintf(outFILE,"test_V: "); for (i=0;in;k++) fprintf(outFILE,"%d ", (int) test_E.e[i].a[k]); fprintf(outFILE," %d\n", (int) test_E.e[i].c);} fprintf(outFILE,"\n"); exit(0);} #endif Make_All_Subpolys(_P, new_E, &new_V, _KL, _NFL); /* Reconstruct _P */ if (j>=0) _KL->k[j]=_P->np; for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[_V->v[drop_num]][j]; _P->x[_V->v[drop_num]][j]=drop_point[j];} _P->np++;} /* Attach a keep label to the vertex _V->v[drop_num]: */ _KL->k[_KL->nk]=_V->v[drop_num]; _KL->nk++; free(new2old); free(new_E); } void Start_Make_All_Subpolys(PolyPointList *_P, NF_List *_NFL){ int i,j; VertexNumList V, new_V; EqList E, new_E; KeepList KL; Long drop_point[POLY_Dmax]; _NFL->nIP++; if (_NFL->rf) _NFL->rf=_NFL->rd; _NFL->rd=0; if(!IP_Check(_P,&V,&E)) { fprintf(outFILE,"IP_check negative!\n"); return;} if(_NFL->Nmin==0) {PairMat PM; Make_VEPM(_P,&V,&E,PM); /* complete poly if */ Complete_Poly(PM, &E, V.nv, _P); _NFL->Nmin=_P->np;} /* non-CWS input */ /* fprintf(outFILE,"StartMASP:\n"); for (i=0;in;j++) fprintf(outFILE,"%d ",(int) _P->x[V.v[i]][j]); fprintf(outFILE,"\n");} for (i=0;in;j++) fprintf(outFILE,"%d ", (int) E.e[i].a[j]); fprintf(outFILE," %d\n", (int) E.e[i].c);} fflush(0);*/ KL.nk=0; if(_NFL->kf){ fprintf(outFILE,"The vertices are:\n"); for (i=0;in;j++) fprintf(outFILE,"%d ",(int) _P->x[V.v[i]][j]); fprintf(outFILE,"\n"); } fprintf(outFILE,"How many of them do you want to keep?\n"); fscanf(inFILE,"%d",&(KL.nk)); fprintf(outFILE,"Which %d of them do you want to keep?\n",KL.nk); for (i=0; in;j++) fprintf(outFILE,"%d ",(int) _P->x[KL.k[i]][j]); fprintf(outFILE,"\n"); }} else for(i=0;inp--; for (j=0;j<_P->n;j++){ drop_point[j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=_P->x[_P->np][j]; } if (!IP_Check(_P,&new_V,&new_E)) KL.k[KL.nk++]=V.v[i]; /* Reconstruct _P */ for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=drop_point[j];} _P->np++; } Make_All_Subpolys(_P, &E, &V, &KL, _NFL); } void IREgcd(Long *vec_in, int *d, Long *vec_out){ int i, j, n_rem_perm, n_perm=1, a, b, perm_j, inv_perm[POLY_Dmax]; Long perm_vec_in[POLY_Dmax], perm_vec_out[POLY_Dmax], abs_sum, max_abs_sum=0; for (i=1;i<=*d;i++) n_perm*=i; for (i=0;i0;j--){ n_rem_perm/=j; a=b/n_rem_perm; b=b%n_rem_perm; perm_j=*d; while (a>=0){ perm_j--; if (inv_perm[perm_j]<0) a--;} perm_vec_in[j-1]=vec_in[perm_j]; inv_perm[perm_j]=j-1;} REgcd(perm_vec_in, d, perm_vec_out); abs_sum=0; for (j=0;j<*d;j++) abs_sum+=labs(perm_vec_out[j]); if ((i==0)||(abs_sume[badfacet]; Rat VPM_checksum_old, VPM_checksum_new; /*Generate new_P (in old coordinates!): */ new_P->np=0; new_KL.nk=0; new_P->n=_P->n; for (i=0;i<_P->np;i++){ Long dist=0; for (j=0;j<_P->n;j++) dist-=BE.a[j]*_P->x[i][j]; if (!(dist%BE.c)){ for (j=0;j<_P->n;j++) new_P->x[new_P->np][j]=_P->x[i][j]; if (kept(i,_KL)>=0) new_KL.k[new_KL.nk++]=new_P->np; new_P->np++; } } /* Print_PPL(new_P); fprintf(outFILE,"kept: "); for (j=0;jnk) {free(new_P); return;} _NFL->nIP++; if(!IP_Check(new_P,&V,_E)) {free(new_P); return;} VPM_checksum_old=rI(0); for (i=0;i<_E->ne;i++) { Long s=0; for (j=0;je[i]),new_P->x[V.v[j]], new_P->n); VPM_checksum_old=rS(VPM_checksum_old, rQ(rI(s),rI(_E->e[i].c)));} /* Generate RedVec: */ if (!Make_RedVec(_P->n, BE.a, RedVec)){ Print_PPL(_P,""); fprintf(outFILE,"Bad Facet: "); for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) BE.a[j]); fprintf(outFILE," %d\n",(int) BE.c); fprintf(outFILE,"kept: "); for (j=0;j<_KL->nk;j++) fprintf(outFILE,"%d ",_KL->k[j]); fprintf(outFILE,"\n"); fprintf(outFILE,"RedVec: "); for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) RedVec[j]); fprintf(outFILE,"\n"); exit(0);} /*Coordinates of new_P: */ for (i=0;inp;i++){ Long dist=0; for (j=0;jn;j++) dist-=BE.a[j]*new_P->x[i][j]; if (!(dist%BE.c)){ for (j=0;jn;j++) new_P->x[i][j]-=(dist-dist/BE.c)*RedVec[j]; } } /* Print_PPL(new_P); fprintf(outFILE,"\n\n"); */ if(!New_Improve_Coords(new_P,&V)) { Print_PPL(_P,""); fprintf(outFILE,"Bad Facet: "); for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) BE.a[j]); fprintf(outFILE," %d\n",(int) BE.c); fprintf(outFILE,"kept: "); for (j=0;j<_KL->nk;j++) fprintf(outFILE,"%d ",_KL->k[j]); fprintf(outFILE,"\n"); fprintf(outFILE,"RedVec: "); for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) RedVec[j]); fprintf(outFILE,"\n"); puts("WARNING: INCOMPLETE SL REDUCTION"); fflush(stdout); #if INCOMPLETE_SL_REDUCTION free(new_P); return; #else exit(0); #endif } if(!IP_Check(new_P,&V,_E)) { fprintf(outFILE,"Trouble in Reduce_Poly!"); exit(0);} VPM_checksum_new=rI(0); for (i=0;i<_E->ne;i++) { Long s=0; for (j=0;je[i]),new_P->x[V.v[j]],new_P->n); VPM_checksum_new=rS(VPM_checksum_new, rQ(rI(s),rI(_E->e[i].c)));} if(VPM_checksum_new.D*VPM_checksum_old.N- VPM_checksum_new.N*VPM_checksum_old.D) { fprintf(outFILE,"Checksums don't match in Reduce_Poly!"); exit(0); } Make_All_Subpolys(new_P,_E,&V,&new_KL, _NFL); free(new_P); } void Make_All_Subpolys(PolyPointList *_P, EqList *_E, VertexNumList *_V, KeepList *_KL, NF_List *_NFL){ /* Creates all subpolyhedra of an IP-polyhedron given by _P, _E, _V. The basic structure is: Search for bad facet; If (reflexive) if (!Add_NF_to_List) return; Drop_and_Keep vertices (on bad facet / everywhere); If (bad facet exists) Reduce_Poly; */ int i, j, badfacet=-1, nbadvert=0, maxnkept=-1; KeepList new_KL=*_KL; /* fprintf(outFILE,"MASP:\n"); Print_PPL(_P); Print_VL(_P,_V); Print_EL(_E,&_P->n,0); fflush(0);*/ if (_V->nv>_NFL->VN) _NFL->VN=_V->nv; if (_E->ne>_NFL->FN) _NFL->FN=_E->ne; /* Choose bad facet with largest number of kept vertices: */ for (i=0;i<_E->ne;i++) if (_E->e[i].c>1){ int nkept=0; for (j=0;j<_KL->nk;j++) if (!Eval_Eq_on_V(&(_E->e[i]),_P->x[_KL->k[j]],_P->n)) nkept++; if (nkept>maxnkept){ maxnkept=nkept; badfacet=i; }} if (!_NFL->rf) if (badfacet==-1){ /* not recover mode && reflexive */ if (_NFL->of<=-2) { /* flags -o0 (break on reflexive) */ if (_NFL->rd) { /* or -oc (recover missing) */ if(_NFL->of==-2){Add_NF_to_List(_P,_V,_E,_NFL); return;} /* flag -o0 */ else {if(!Add_NF_to_List(_P,_V,_E,_NFL)) return;} /* flag -oc */ }} else if(!Add_NF_to_List(_P,_V,_E,_NFL)) return;} /* standard */ if(0 < _NFL->of) if(_NFL->of <= _NFL->rd) return; /* limit rd */ if (badfacet!=-1) { /* Find vertices on bad facet: */ nbadvert=0; for (i=0;i<_V->nv;i++) if (!Eval_Eq_on_V(&(_E->e[badfacet]),_P->x[_V->v[i]],_P->n)){ j=_V->v[nbadvert]; _V->v[nbadvert]=_V->v[i]; _V->v[i]=j; nbadvert++; } } if (_NFL->rf&&(_NFL->rf<_NFL->rd)) fprintf(outFILE,"_NFL->rf<_NFL->rd\n"); if (_NFL->rf==_NFL->rd) _NFL->rf=0; if (_NFL->rf) for (i=0;i<_NFL->b[_NFL->rd];i++) if((kept(_V->v[i],&new_KL)<0)) new_KL.k[new_KL.nk++]=_V->v[i]; _NFL->rd++; for(i=0;i<((badfacet==-1)?_V->nv:nbadvert);i++) if((kept(_V->v[i],&new_KL)<0)){ _NFL->b[_NFL->rd-1]=i; Drop_and_Keep(_P, _V, _E, &new_KL, i, _NFL); } /* If a bad facet is kept, reduce the poly: */ if((_NFL->of==0)||(_NFL->of==-3)) if (badfacet!=-1) {/* -oc recover[of=-3] */ int currentSL=_NFL->SL; _NFL->SL=1; _NFL->b[_NFL->rd-1]=nbadvert; Reduce_Poly(_P, _E, &new_KL, _NFL, badfacet); _NFL->SL=currentSL; } _NFL->rd--; } void Ascii_to_Binary(CWS *W, PolyPointList *P, char *dbin, char *polyi, char *polyo){ NF_List *_NFL=(NF_List *) malloc(sizeof(NF_List)); VertexNumList V; EqList F; assert(_NFL!=NULL); if(!(*polyo)) { puts("You have to specify an output file via -po in -a-mode!\n"); printf("For more help type use option `-h'\n"); exit(0);} _NFL->of=0; _NFL->rf=0; _NFL->iname=polyi; _NFL->oname=polyo; _NFL->dbname=dbin; Init_NF_List(_NFL); _NFL->SL=0; while(Read_CWS_PP(W,P)) { _NFL->hc = 0; _NFL->V= _NFL->F= _NFL->VN= _NFL->FN = _NFL->Xnuc = _NFL->Xdif = 0; _NFL->Nmin=P->np; _NFL->Nmax=0; if(_NFL->d==0) _NFL->d=P->n; else if(_NFL->d-P->n) {puts("different dim!"); exit(0);} if (!IP_Check(P,&V,&F)){ puts("IP_Check failed in Ascii_to_Binary!\n"); exit(0);} if (Add_NF_to_List(P,&V,&F,_NFL)) if (outFILE!=stdout){ int i, j; for(i=0;inw;i++) { fprintf(outFILE,"%d ",(int) W->d[i]); for(j=0;jN;j++) fprintf(outFILE,"%d ",(int) W->W[i][j]); if(i+1nw) fprintf(outFILE," "); else fprintf(outFILE,"\n"); } fflush(0);} } Write_List_2_File(polyo,_NFL); free(_NFL); } void Do_the_Classification(CWS *W, PolyPointList *P, /* char *fn, */ int oFlag, int rFlag, int kFlag, char *polyi, char *polyo, char *dbin) { /* static int nw; */ NF_List *_NFL=(NF_List *) malloc(sizeof(NF_List)); time_t W_SAVE_TIME=time(NULL); if(!(*polyo)) { puts("You have to specify an output file via -po!\n"); printf("For more help use option '-h'\n"); exit(0);} assert(_NFL!=NULL); _NFL->of=oFlag; _NFL->rf=rFlag; _NFL->kf=kFlag; _NFL->iname=polyi; _NFL->oname=polyo; _NFL->dbname=dbin; Init_NF_List(_NFL); rFlag=0; /* now used as "read flag" */ while(Read_CWS_PP(W,P)) { /* make subpolys */ if(W->nw>0) _NFL->Nmin=P->np; else _NFL->Nmin=0 /* :: Complete_Poly() */ ; _NFL->Nmax=0; _NFL->SL = _NFL->hc = 0; _NFL->V= _NFL->F= _NFL->VN= _NFL->FN = _NFL->Xnuc = _NFL->Xdif = 0; if(_NFL->d==0) _NFL->d=P->n; else if(_NFL->d-P->n) {puts("different dim!"); exit(0);} if(rFlag) {Read_File_2_List(polyo,_NFL); rFlag=0;} Start_Make_All_Subpolys(P, _NFL); Print_Weight_Info(W,_NFL); if((WRITE_DIM <= P->n) && (MIN_NEW <= _NFL->NP)) if((int)difftime(time(NULL),W_SAVE_TIME) > MIN_W_SAVE_TIME) { Write_List_2_File(polyo,_NFL); rFlag=1; _NFL->SAVE=W_SAVE_TIME=time(NULL); } } if(rFlag==0) Write_List_2_File(polyo,_NFL); _NFL->TIME=time(NULL); fputs(ctime(&_NFL->TIME),stdout); free(_NFL); } /* ====================================================================== */ /* ========== ========== */ /* ========== S U B L A T T I C E S ========== */ /* ========== ========== */ /* ====================================================================== */ void Write_VPM(FILE *F,int *v, int *f, subl_int x[][VERT_Nmax]){ int i,j; fprintf(F,"%d %d\n",*v,*f); for(i=0;i<*f;i++) { for(j=0;j<*v-1;j++) fprintf(F,"%lld ",(long long) x[i][j]); fprintf(F,"%lld\n",(long long) x[i][j]); } } void Write_M(FILE *F,int *v, int *f, subl_int x[][POLY_Dmax]) { int i,j; fprintf(F,"%d %d\n",*v,*f); for(i=0;i<*f;i++) { for(j=0;j<*v-1;j++) fprintf(F,"%lld ",(long long) x[i][j]); fprintf(F,"%lld\n",(long long) x[i][j]); } } void Make_All_Sublat(NF_List *_L, int n, int v, subl_int diag[POLY_Dmax], subl_int u[][VERT_Nmax], char *mFlag, PolyPointList *_P){ /* create all inequivalent decompositions diag=s*t into upper triangular matrices s,t; t*(first lines of u) becomes the poly P; choose the elements of t (columns rising, line # falling), calculate corresponding element of s at the same time; finally calculate P and add to list */ VertexNumList V; EqList F; subl_int s[POLY_Dmax][POLY_Dmax], t[POLY_Dmax][POLY_Dmax], ts_lincol; int i,j,k, lin=0, col=0, err=0; _L->d=_P->n=n; _P->np=V.nv=v; for(i=0;i=j)-1; while (col>=0){ /* fprintf(outFILE,"t[%d][%d]=%lld\n",lin, col, t[lin][col]); */ if (lin==col){ do t[lin][col]++; while ((diag[lin]%t[lin][col])&&(t[lin][col]<=diag[lin])); if (t[lin][col]>diag[lin]){ if (col==0) return; t[lin][col]=0; lin=0; col--;} else{ s[lin][col]=diag[lin]/t[lin][col]; if (col==0) lin=col=1; else lin--; } } else{ /* (t*s)[lin][col]=sum_j t[lin][j]*s[j][col]=0 */ ts_lincol=0; for (j=col;j>lin;j--) ts_lincol+=t[lin][j]*s[j][col]; do{ t[lin][col]++; ts_lincol+=s[col][col];} while ((ts_lincol%t[lin][lin])&&(t[lin][col]=t[lin][lin]){ t[lin][col]=-1; lin++;} else{ s[lin][col]=-ts_lincol/t[lin][lin]; if (lin) lin--; else if (colx[j][i]=s[i][i]*u[i][j]; for (k=i+1;kx[j][i]+=s[i][k]*u[k][j]; } */ subl_int Pji=s[i][i]*u[i][j]; for (k=i+1;kx[j][i]=Pji; if (labs(Pji)>20000000) err=1;} _P->np=v; if (err){ Print_PPL(_P,""); fprintf(outFILE,"u: "); Write_VPM(outFILE,&v,&v,u); fprintf(outFILE,"s: "); Write_M(outFILE,&n,&n,s); fprintf(outFILE,"t: "); Write_M(outFILE,&n,&n,t);} for(i=0;i0 ? x : -x);} int Line_Recomb(int i, int line, int v, int f, subl_int x[][VERT_Nmax]){ int j, k, changes=0; subl_int y11, y12, y21, y22, g, new_; if (SI_abs(x[i][i])==1) return 0; for (j=line;j new_ */ if ((g=LEgcd(x[i][i],x[i][col],&y11,&y12))<0) {y11*=-1; y12*=-1; g*=-1;} y21=-x[i][col]/g; y22=x[i][i]/g; for (k=i;klin_max) lin_max=SI_abs(x[lin][col]);} if (lin_max) if ((!min_lin_gcd)||(lin_gcdcol_max) col_max=SI_abs(x[lin][col]); if (!col_max){printf("col_max==0!!!"); exit(0);} if ((chosen_col==-1)||(SI_abs(x[chosen_lin][col])rem_gcd){ for (col=i+1;col*max_order) *max_order=order; if (i>POLY_Dmax) {printf("diag has %d entries!!!\n", i); exit(0);} if (order>1) Make_All_Sublat(_L, i, v, diag, u, mFlag, _P); } void uc_nf_to_P(PolyPointList *_P, int *MS, int *d, int *v, int *nuc, unsigned char *uc){ Long tNF[POLY_Dmax][VERT_Nmax]; int i, j; UCnf2vNF(d, v, nuc, uc, tNF, MS); _P->n=*d; _P->np=*v; (*MS)%=4; for(i=0;i<*v;i++) for(j=0;j<*d;j++) _P->x[i][j]=tNF[j][i]; } void Find_Sublat_Polys(char mFlag, char *dbin, char *polyi, char *polyo, PolyPointList *_P){ NF_List *_NFL=(NF_List *) malloc(sizeof(NF_List)); VertexNumList Vnl; EqList Fel; subl_int x[VERT_Nmax][VERT_Nmax], y[VERT_Nmax][VERT_Nmax]; time_t Tstart; int v, nu, i, j, k, max_order=1; assert(_NFL!=NULL); if(!(*polyo)) { puts("You have to specify an output file via -po in -sm-mode."); printf("For more help use option `-h'\n"); exit(0);} _NFL->of=0; _NFL->rf=0; _NFL->iname=polyi; _NFL->oname=polyo; _NFL->dbname=dbin; Init_NF_List(_NFL); _NFL->SL=0; if (*dbin){ DataBase *DB=&(_NFL->DB); char *dbname = (char *) malloc(1+strlen(dbin)+File_Ext_NCmax), *fx; unsigned char uc_poly[NUC_Nmax]; int MS; strcpy(dbname,dbin); strcat(dbname,"."); fx=&dbname[strlen(dbin)+1]; printf("Reading DB-files, calculating sublattices:\n"); fflush(0); /* read the DB-files and calculate Sublattices */ for (v=2;v<=DB->nVmax;v++) if(DB->nNUC[v]){ FILE *dbfile; char ext[4]={'v',0,0,0}; ext[1]='0' + v / 10; ext[2]='0' + v % 10; Tstart=time(NULL); strcpy(fx,ext); dbfile=fopen(dbname,"rb"); assert(dbfile!=NULL); if (!mFlag) {printf("Reading %s\n", dbname); fflush(0);} for (nu=0;nu<=DB->NUCmax;nu++) for (i=0; iNFnum[v][nu]; i++){ for (j=0; jd), &v, &nu, uc_poly); if (MS>3) {printf("MS=%d!!!\n",MS); exit(0);} assert(IP_Check(_P,&Vnl,&Fel)); assert(v==Vnl.nv); /* compute VPM */ for(j=0;jx[Vnl.v[k]],_P->n)-1; for(j=0;j1) MakePolyOnSublat(_NFL, y, Fel.ne, Vnl.nv, &max_order, &mFlag, _P); } if(ferror(dbfile)) {printf("File error in %s\n",dbname); exit(0);} fclose(dbfile); printf(" %dp (%ds)\n", (int)_NFL->NP, (int) difftime(time(NULL),Tstart)); fflush(0); }} else { CWS W; while(Read_CWS_PP(&W,_P)){ assert(IP_Check(_P,&Vnl,&Fel)); /* compute VPM */ for(j=0;jx[Vnl.v[i]],_P->n)-1; MakePolyOnSublat(_NFL, x, Vnl.nv, Fel.ne, &max_order, &mFlag, _P); if (!mFlag) Print_Weight_Info(&W,_NFL);}} printf("max_order=%d\n", max_order); Write_List_2_File(polyo,_NFL); _NFL->TIME=time(NULL); fputs(ctime(&_NFL->TIME),stdout); free(_NFL); } /* ====================================================================== */ /* ========== ========== */ /* ========== I R , V I R & M A X ========== */ /* ========== ========== */ /* ====================================================================== */ int irred(PolyPointList *_P) { int i,j,drop_point[POLY_Dmax]; VertexNumList V,NV; EqList E; for (j=0;j<_P->n;j++) drop_point[j]=0; /* just to silence the compiler */ IP_Check(_P,&V,&E); for(i=0;inp--; for (j=0;j<_P->n;j++){ drop_point[j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=_P->x[_P->np][j]; } if (IP_Check(_P,&NV,&E)) return 0; /* Reconstruct _P */ for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=drop_point[j];} _P->np++; } return 1; } void DPircheck(CWS *_W, PolyPointList *_P){ int i, j, k; EqList E,DE; VertexNumList V,DV; EqList *B=&_W->B; PolyPointList *_RDP= (PolyPointList *) malloc(sizeof (PolyPointList)); PolyPointList *_PD = (PolyPointList *) malloc(sizeof (PolyPointList)); if(_RDP==NULL) {puts("Unable to allocate space for _P"); exit(0);} if(_PD==NULL) {printf("Unable to allocate _PD\n"); exit(0);} IP_Check(_P,&V,&E); Make_Dual_Poly(_P,&V,&E,_PD); _RDP->n=_P->n; _RDP->np=B->ne; for (i=0;ine;i++) for (j=0;j<_P->n;j++) _RDP->x[i][j]=B->e[i].a[j]; IP_Check(_RDP,&DV,&DE); _RDP->np=0; for (i=0;i<_PD->np;i++){ int Good=1; for (k=0;kn;j++) Pairing+=DE.e[k].a[j]*_PD->x[i][j]; if (Pairing<0) Good=0;} if(Good){ for (j=0;j<_P->n;j++) _RDP->x[_RDP->np][j]=_PD->x[i][j]; _RDP->np++;}} /* Print_PPL(_RDP); */ if (irred(_RDP)){ /* Print_PPL(_RDP); */ for(i=0;i<_W->nw;i++){ fprintf(outFILE,"%d ",(int) _W->d[i]); for(j=0;j<_W->N;j++) fprintf(outFILE,"%d ",(int) _W->W[i][j]); if(i+1<_W->nw) fprintf(outFILE," "); } fprintf(outFILE,"\n"); } free(_PD); free(_RDP); } int virred(PolyPointList *_P, EqList *B) { int i,j,k,drop_point[POLY_Dmax],equal; VertexNumList V; EqList E; assert(Ref_Check(_P,&V,&E)); for (j=0;j<_P->n;j++) drop_point[j]=0; /* just to silence the compiler */ /* for(i=0;(in);j++) fprintf(outFILE,"%d ",(int) _P->x[V.v[i]][j]); fprintf(outFILE,"\n");} fprintf(outFILE,"_CL->B:\n"); for(k=0;kne;k++){ for (j=0;(j<_P->n);j++) fprintf(outFILE,"%d ",(int) _CL->B[k][j]); fprintf(outFILE,"\n");} */ for(k=0;kne;k++){ equal=0; for(i=0;(in)&&equal;j++) if (_P->x[V.v[i]][j]-B->e[k].a[j]) equal=0; } /* if (equal) break;}*/ i--; if (!equal){ fprintf(outFILE,"Vertex not found!\n"); for(i=0;(in);j++) fprintf(outFILE,"%d ",(int) _P->x[V.v[i]][j]); fprintf(outFILE,"\n");} for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) _P->x[V.v[i]][j]); fprintf(outFILE,"\n"); for (j=0;j<_P->n;j++) fprintf(outFILE,"%d ",(int) B->e[k].a[j]); fprintf(outFILE,"\n"); return 1;} /* Dropping the vertex V.v[i]: */ _P->np--; for (j=0;j<_P->n;j++){ drop_point[j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=_P->x[_P->np][j]; } if (IP_Check(_P,&V,&E)) return 0; /* Reconstruct _P */ for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=drop_point[j];} _P->np++; assert(Ref_Check(_P,&V,&E));} return 1; } void DPvircheck(CWS *_W, PolyPointList *_P) { int i, j; EqList E; EqList *B=&_W->B; VertexNumList V; PolyPointList *_PD = (PolyPointList *) malloc(sizeof (PolyPointList)); if(_PD==NULL) {printf("Unable to allocate _PD\n"); exit(0);} Ref_Check(_P,&V,&E); Make_Dual_Poly(_P,&V,&E,_PD); if (virred(_PD,B)){ /* Print_PPL(_PD); */ for(i=0;i<_W->nw;i++){ fprintf(outFILE,"%d ",(int) _W->d[i]); for(j=0;j<_W->N;j++) fprintf(outFILE,"%d ",(int) _W->W[i][j]); if(i+1<_W->nw) fprintf(outFILE," "); } fprintf(outFILE,"\n"); } free(_PD); } int Find_Ref_Subpoly(PolyPointList *_P, EqList *_E, VertexNumList *_V, KeepList *_KL, int *rd); int Find_RSP_Drop_and_Keep(PolyPointList *_P, VertexNumList *_V, EqList *_E, KeepList *_KL, int drop_num, int *rd){ int i, j, n_irrel=0, IP/*, test_IP*/; int *new2old =(int *) malloc(sizeof(int)*POINT_Nmax); Long drop_point[POLY_Dmax]; VertexNumList red_V/*, test_V*/; EqList new_E/*, test_E*/; PolyPointList *red_P = (PolyPointList *) malloc(sizeof (PolyPointList)); if(red_P==NULL) {puts("Unable to allocate space for red_P"); exit(0);} if(new2old==NULL) {puts("Unable to allocate space for new2old"); exit(0);} for (j=0;j<_P->n;j++) drop_point[j]=_P->x[_V->v[drop_num]][j]; /* Create new_E: Same as *_E, but irrelevant facets first */ new_E.ne=_E->ne; for (i=0;i<_E->ne;i++){ if (Eval_Eq_on_V(&(_E->e[i]),drop_point,_P->n)){ for (j=0;j<_P->n;j++) new_E.e[n_irrel].a[j]=_E->e[i].a[j]; new_E.e[n_irrel++].c=_E->e[i].c;} else { for (j=0;j<_P->n;j++) new_E.e[_E->ne+n_irrel-i-1].a[j]=_E->e[i].a[j]; new_E.e[_E->ne+n_irrel-i-1].c=_E->e[i].c;}} /* Create red_P: old vertices, points that are not on irrelevant facets */ red_P->np=0; red_P->n=_P->n; for (i=0;i<_V->nv;i++) if (i!=drop_num){ for (j=0;j<_P->n;j++) red_P->x[red_P->np][j]=_P->x[_V->v[i]][j]; new2old[red_P->np++]=_V->v[i];} for (i=0;i<_P->np;i++) if ((i!=_V->v[drop_num])&&Relevant(_P->x[i],&_P->n,&new_E,&n_irrel)){ for (j=0;j<_P->n;j++) red_P->x[red_P->np][j]=_P->x[i][j]; new2old[red_P->np++]=i;} IP=Aided_IP_Check(red_P,&red_V,&new_E,n_irrel,_V->nv-1); /* test_IP=IP_Check(red_P,&test_V,&test_E); printf("%d %d %d\n", _P->np, red_P->np, *rd); fflush(0); printf("%d %d %d\n", test_V.nv, test_E.ne, test_IP); printf("%d %d \n", red_V.nv, new_E.ne); fflush(0); if (IP) if ((!test_IP)||(test_V.nv!=red_V.nv)|| (test_E.ne!=new_E.ne)){ int k; fprintf(outFILE,"red_P:\n");fflush(0); Print_PPL(red_P); fprintf(outFILE,"\n"); fprintf(outFILE,"red_V: "); for (i=0;in;k++) fprintf(outFILE,"%d ", (int) new_E.e[i].a[k]); fprintf(outFILE," %d\n", (int) new_E.e[i].c);} fprintf(outFILE,"\n"); fprintf(outFILE,"n_irrel: %d\n",n_irrel); fprintf(outFILE,"new2old:"); for (i=0;inp;i++) fprintf(outFILE," %d", new2old[i]); fprintf(outFILE,"\n"); fprintf(outFILE,"test_V: "); for (i=0;in;k++) fprintf(outFILE,"%d ", (int) test_E.e[i].a[k]); fprintf(outFILE," %d\n", (int) test_E.e[i].c);} fprintf(outFILE,"\n"); exit(0);} */ free(red_P); if(IP){ VertexNumList new_V; /* Create new_V from red_V */ new_V.nv=red_V.nv; for (i=0;inp-1) new_V.v[i]=_V->v[drop_num]; /* Drop the vertex _V->v[drop_num]: */ _P->np--; for (j=0;j<_P->n;j++) _P->x[_V->v[drop_num]][j]=_P->x[_P->np][j]; j=kept(_P->np,_KL); if (j>=0) _KL->k[j]=_V->v[drop_num]; if (Find_Ref_Subpoly(_P, &new_E, &new_V, _KL, rd)) { free(new2old); return 1;} /* Reconstruct _P */ if (j>=0) _KL->k[j]=_P->np; for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[_V->v[drop_num]][j]; _P->x[_V->v[drop_num]][j]=drop_point[j];} _P->np++;} /* Attach a keep label to the vertex _V->v[drop_num]: */ _KL->k[_KL->nk]=_V->v[drop_num]; _KL->nk++; free(new2old); return 0; } int Start_Find_Ref_Subpoly(PolyPointList *_P){ int i,j; VertexNumList V, new_V; EqList E, new_E; KeepList KL; Long drop_point[POLY_Dmax]; int rd=0; if(!IP_Check(_P,&V,&E)) { fprintf(outFILE,"IP_check negative!\n"); exit(0);} KL.nk=0; for (j=0;j<_P->n;j++) drop_point[j]=0; /* just to silence the compiler */ for(i=0;inp--; for (j=0;j<_P->n;j++){ drop_point[j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=_P->x[_P->np][j]; } if (!IP_Check(_P,&new_V,&new_E)) KL.k[KL.nk++]=V.v[i]; /* Reconstruct _P */ for (j=0;j<_P->n;j++){ _P->x[_P->np][j]=_P->x[V.v[i]][j]; _P->x[V.v[i]][j]=drop_point[j];} _P->np++; } return Find_Ref_Subpoly(_P, &E, &V, &KL, &rd); } int Find_Ref_Subpoly(PolyPointList *_P, EqList *_E, VertexNumList *_V, KeepList *_KL, int *rd){ /* Creates all subpolyhedra of an IP-polyhedron given by _P, _E, _V. The basic structure is: Search for bad facet; If (reflexive) if (!Add_NF_to_List) return; Drop_and_Keep vertices (on bad facet / everywhere); If (bad facet exists) Reduce_Poly; */ int i, j, badfacet=-1, nbadvert=0, maxnkept=-1; KeepList new_KL=*_KL; /* Choose bad facet with largest number of kept vertices: */ for (i=0;i<_E->ne;i++) if (_E->e[i].c>1){ int nkept=0; for (j=0;j<_KL->nk;j++) if (!Eval_Eq_on_V(&(_E->e[i]),_P->x[_KL->k[j]],_P->n)) nkept++; if (nkept>maxnkept){ maxnkept=nkept; badfacet=i; }} if (*rd>0) if (badfacet==-1) return 1; if (badfacet!=-1) { /* Find vertices on bad facet: */ nbadvert=0; for (i=0;i<_V->nv;i++) if (!Eval_Eq_on_V(&(_E->e[badfacet]),_P->x[_V->v[i]],_P->n)){ j=_V->v[nbadvert]; _V->v[nbadvert]=_V->v[i]; _V->v[i]=j; nbadvert++; } } (*rd)++; for(i=0;i<((badfacet==-1)?_V->nv:nbadvert);i++) if((kept(_V->v[i],&new_KL)<0)) if (Find_RSP_Drop_and_Keep(_P, _V, _E, &new_KL, i, rd)) return 1; (*rd)--; return 0; } void Max_check(CWS *_W, PolyPointList *_P) { int i, j; EqList E; VertexNumList V; IP_Check(_P,&V,&E); if (Poly_Max_check(_P,&V,&E)){ for(i=0;i<_W->nw;i++){ fprintf(outFILE,"%d ",(int) _W->d[i]); for(j=0;j<_W->N;j++) fprintf(outFILE,"%d ",(int) _W->W[i][j]); if(i+1<_W->nw) fprintf(outFILE," "); } fprintf(outFILE,"\n"); } } int Poly_Max_check(PolyPointList *_P, VertexNumList *_V, EqList *_E){ int rm; PolyPointList *_PD = (PolyPointList *) malloc(sizeof(PolyPointList)); assert(_PD!=NULL); Make_Dual_Poly(_P,_V,_E,_PD); rm=!Start_Find_Ref_Subpoly(_PD); free(_PD); return rm; } int Poly_Min_check(PolyPointList *_P, VertexNumList *_V, EqList *_E){ PairMat PM; Make_VEPM(_P,_V,_E,PM); Complete_Poly(PM, _E, _V->nv, _P); return !Start_Find_Ref_Subpoly(_P); } void Overall_check(CWS *_W, PolyPointList *_P) { int i, j, k, span, lpm=0, vm=0, r=0; EqList E, DE; VertexNumList V, DV; EqList *B=&_W->B; PolyPointList *_RDP= (PolyPointList *) malloc(sizeof (PolyPointList)); PolyPointList *_PD = (PolyPointList *) malloc(sizeof (PolyPointList)); PolyPointList *_PD2 = (PolyPointList *) malloc(sizeof (PolyPointList)); if(_RDP==NULL) {puts("Unable to allocate space for _P"); exit(0);} if(_PD==NULL) {printf("Unable to allocate _PD\n"); exit(0);} if(_PD2==NULL) {printf("Unable to allocate _PD\n"); exit(0);} if ((_P->n<5) ? !IP_Check(_P,&V,&E) : !Ref_Check(_P,&V,&E)) { free(_PD); free(_PD2); free(_RDP); return;} /* assert(Ref_Equations(&E)); */ for(i=0;i<_W->nw;i++){ fprintf(outFILE,"%d ",(int) _W->d[i]); for(j=0;j<_W->N;j++) fprintf(outFILE,"%d ",(int) _W->W[i][j]); if(i+1<_W->nw) fprintf(outFILE," "); } fflush(0); span=Span_Check(&E, B, &_P->n); Make_Dual_Poly(_P,&V,&E,_PD); *_PD2=*_PD; _RDP->n=_P->n; _RDP->np=B->ne; for (i=0;ine;i++) for (j=0;j<_P->n;j++) _RDP->x[i][j]=B->e[i].a[j]; IP_Check(_RDP,&DV,&DE); _RDP->np=0; for (i=0;i<_PD->np;i++){ int Good=1; for (k=0;kn;j++) Pairing+=DE.e[k].a[j]*_PD->x[i][j]; if (Pairing<0) Good=0;} if(Good){ for (j=0;j<_P->n;j++) _RDP->x[_RDP->np][j]=_PD->x[i][j]; _RDP->np++;}} if (irred(_RDP)) lpm=1; if (!Start_Find_Ref_Subpoly(_PD)) r=1; if (span) if (virred(_PD2,B)) vm=1; if ((!span&&vm)||(!lpm&&vm)||(r!=vm)) fprintf(outFILE,"span:%d lpm:%d vm:%d r:%d\n", span, lpm, vm, r); else{ if(r) fprintf(outFILE,"r"); if(lpm) fprintf(outFILE,"l"); if(span) fprintf(outFILE,"s"); if(!r&&!lpm&&!span) fprintf(outFILE,"-"); fprintf(outFILE,"\n");} fflush(0); free(_PD); free(_PD2); free(_RDP); } palp-2.21/Rat.h0000664000177600017760000000430614572603263012650 0ustar skarkeskarke#ifndef __Rat__ #define __Rat__ typedef struct {Long N; Long D;} Rat; /* = N/D */ Long Fgcd(Long a, Long b); /* Fast greatest common divisor */ Long NNgcd(Long a, Long b); /* NonNegative gcd handling zero */ Long Egcd(Long, Long, Long*,Long*); /* extended gcd(a,b) */ Long REgcd(Long *vec_in, int *d, Long *vec_out);/* extended gcd(a_1,...a_d) */ Rat rI(Long a); /* conversion Long -> Rat */ Rat rR(Long a, Long b); /* conversion a/b -> Rat */ Rat irP(Long a, Rat b); /* a b integer * Rat */ Rat rS(Rat a, Rat b); /* a + b rational Sum */ Rat rD(Rat a, Rat b); /* a - b rational Difference */ Rat rP(Rat a, Rat b); /* a * b rational Product */ Rat rQ(Rat a, Rat b); /* a / b rational Quotient */ int rC(Rat a, Rat b); /* Compare = [1 / 0 / -1] if a [gt/eq/lt] b */ void Rpr(Rat c); /* write "c.N/c.D" to outFN */ #endif typedef struct {LLong N; LLong D;} LRat; /* = N/D */ LLong LFgcd(LLong a, LLong b); /* Fast greatest common divisor */ LLong LNNgcd(LLong a, LLong b); /* NonNegative gcd handling zero */ LLong LEgcd(LLong, LLong, LLong*,LLong*); /* extended gcd(a,b) */ LLong LREgcd(LLong *vec_in, int *d, LLong *vec_out); /* extended gcd(a_1,...a_d) */ LRat LrI(LLong a); /* conversion LLong -> LRat */ LRat LrR(LLong a, LLong b); /* conversion a/b -> LRat */ LRat LirP(LLong a, LRat b); /* a b integer * LRat */ LRat LrS(LRat a, LRat b); /* a + b LRational Sum */ LRat LrD(LRat a, LRat b); /* a - b LRational Difference */ LRat LrP(LRat a, LRat b); /* a * b LRational Product */ LRat LrQ(LRat a, LRat b); /* a / b LRational Quotient */ int LrC(LRat a, LRat b); /* Compare = [1 / 0 / -1] if a [gt/eq/lt] b */ void LRpr(LRat c); /* write "c.N/c.D" to outFN */ /* Map Permutations: Do "ArgFun" for all permutations pi of *d elements */ #define ARG_FUN void (*ArgFun)(int *d,int *pi,int *pinv,void *info) void Map_Permut(int *d,int *pi,int *pinv,ARG_FUN,void *AuxPtr); Long W_to_GLZ(Long *W, int *d, Long **GLZ); /* "triangluar" form of GLZ */ Long PW_to_GLZ(Long *W, int *d, Long **GLZ); /* improved by permutations */ palp-2.21/LG.c0000664000177600017760000014053314572603263012422 0ustar skarkeskarke#include "Global.h" #include "Rat.h" #include "LG.h" #define SHOW_b01_TWIST (0) #define Tout (0) #define DET_WARN_ONLY (0) /* continue if group has det!=1 */ #define COEFF_Nmax (d*D+2*N) #define ABBREV_POLY_PRINT (4) /* !=0 => #(leading/trailing terms */ #define NO_COORD_IMPROVEMENT /* switch off weight permutation */ #undef W_PERM_CODE int Is_Gen_CY(int index, PolyPointList *P) { int i; Long *IP=P->x[P->np]; VertexNumList V; /* IP = IP(index * P) */ EqList *E = (EqList *) malloc(sizeof(EqList)); assert(E!=NULL); Find_Equations(P,&V,E); for(i=0;ine;i++) E->e[i].c *= index; for(i=0;ine;i++) if(1!=Eval_Eq_on_V(&E->e[i],IP,P->n)) break; free(E); return i==E->ne; } void WZerror(char *c) { printf("Format error %s in Read_WZeight\n",c);exit(0); } int auxString2SInt(char *c,int *n) { int j=0,neg=0; *n=0; if(c[0]=='-')if(('0'M; int FilterFlag=(inFILE==NULL); char C, c[999],b=' '; Long BM[W_Nmax][W_Nmax], *B[W_Nmax], Wa[POLY_Dmax], Za[POLY_Dmax], F[W_Nmax], G[POLY_Dmax][POLY_Dmax], GI[POLY_Dmax][POLY_Dmax],X; if(FilterFlag) inFILE=stdin; else if(inFILE==stdin) printf("type degree and weights [d w1 w2 ...]: "); C=fgetc(inFILE); if( !IsDigit(C) ) return 0; ungetc(C,inFILE); *nz=0; fscanf(inFILE,"%d",I); for(i=1; iN=i-1; if(WZ->N>W_Nmax) { puts("Increase POLY_Dmax"); exit(0); } for(i=0;i<=WZ->N;i++) assert(I[i]>0); if(I[WZ->N]>I[0]) { WZ->d=I[WZ->N]; shift=0; } else WZ->d=I[0]; for(i=0;iN;i++) {WZ->w[i]=I[i+shift]; assert(WZ->w[i]d);} WZ->r=0; for(i=0;iN;i++) WZ->r+=WZ->w[i]; if(WZ->r%WZ->d)WZ->r=0; else WZ->r/=WZ->d; for(n=0;n<999;n++) /* read /Z*: * * * */ { c[n]=fgetc(inFILE); if(feof(inFILE)) {if(FilterFlag) inFILE=NULL; return 0;} if(c[n]=='\n') break; } if(n==999) {puts("Out of space in Read_WZeight");exit(0);} i=0; while(c[i]==b)i++; if((c[i]=='=')&&(c[i+1]=='d'))i+=2; while(c[i]==b)i++; while(im[*nz]=0; while((im[*nz]=10*WZ->m[*nz]+c[i++]-'0'; j=0; if(WZ->m[*nz]<=0) WZerror("Order not positive"); if(c[i+j]!=':') WZerror(":"); else {i+=j+1; while(c[i]==b)i++;} for(k=0;kN;k++) { if((j=auxString2SInt(&c[i],&WZ->z[*nz][k]))) {if(j) i+=j; else WZerror("missing");} } s=0; for(k=0;kN;k++) s+=WZ->z[*nz][k]; /* if(s % WZ->m[*nz]) WZerror("det!=1") */; (WZ->M)++; } /* Eq_i::{c=Ai a[]=Bi[]} 0<=A+B*x r=sum(w)/d rI=IP(r*P) n=(r,rI) */ a=WZ->N; for(i=0;iw,&a,B) ); if(1==WZ->r) for(i=0;iA[i]=F[i]=1; /* Z.(X-F) \cong 0 */ else {for(i=0;iA[i]=WZ->d*B[0][i]; F[i]=0;} for(j=0;jM;j++) {Long s=0; for(n=0;nz[j][n]; if(s%WZ->m[j]){puts("det=1 required if Gorenstein index r>1:"); #if DET_WARN_ONLY WZ->M=0; } #else Write_Weight(WZ); exit(0);} #endif }} d=a-1; n=0; shift=1; for(i=0;iB[i][j]=B[j+1][i]; /* LATTICE BASIS */ for(i=a-1;i>0;i--) { X = 1 - WZ->r * WZ->A[i]; for(j=i;jrI[j]*WZ->B[i][j]; assert(0==(X%WZ->B[i][i-1])); WZ->rI[i-1]=X/WZ->B[i][i-1];} for(i=0;i<*nz;i++) /* divide by symmetries: */ { Long g=WZ->m[i]; X=0; for(j=0;jz[i][k]*WZ->B[k][j]; g=NNgcd(Za[j],g);} if(Tout){printf("WZ->m[%d]=%d g=%ld ",i,WZ->m[i],g);if(g==WZ->m[i])puts("");} if(g==WZ->m[i]) continue; if(g>1) for(k=0;kB[k][l]; for(l=0;lB[k][l]=0; for(j=0;jB[k][l] += Wa[j]*G[l][j]; } /* shift A to A'=A+B.x with x=dx=Z_ia*(F_a-A_a) */ X+=WZ->z[i][k]*(WZ->A[k]-F[k]); } X%=WZ->m[i];/* IP = r*A+B.rI, B'=B.G^T => rI' = GI^T . rI + r dx */ if(X<-WZ->m[i]/2)X+=WZ->m[i]; else if(X>WZ->m[i]/2)X-=WZ->m[i]; if(Tout) printf("X=%ld\n",X); for(k=0;kA[k]-=X*WZ->B[k][0]; for(j=0;jrI[j]; WZ->rI[j]=0;} WZ->rI[0] =X*WZ->r; for(j=0;jrI[j]+=Za[k]*GI[k][j]; g=WZ->m[i]/g; for(k=0;kB[k][0]*=g; /* goto sublattice */ assert((WZ->rI[0]%g)==0); WZ->rI[0]/=g; shift*=g; } X=1; for(j=0;j<*nz;j++) X*=WZ->m[j]; assert(X%shift==0); shift=X/shift; if(Tout){for(j=0;jA[j]); printf("=A rI="); for(j=0;jrI[j]); puts(""); for(k=0;kB[k][j]);puts("=B");} for(j=0;jB[j][k]*WZ->rI[k]; printf("%2ld ",X);} puts("=B.rI");Write_Weight(WZ);} { PairMat VPM; VertexNumList V; PolyPointList *P=WZ->P; EqList *E=(EqList *)malloc(sizeof(EqList));assert(E!=NULL); for(i=0;ie[i].c=WZ->A[i]; VPM[i][0]=WZ->d/WZ->w[i]; for(j=0;je[i].a[j]=WZ->B[i][j];} E->ne=a; WZ->P->n=d; WZ->P->np=0; Complete_Poly(VPM,E,1,WZ->P); /* assert(POINT_Nmax>WZ->P->np); / * Print_PPL(WZ->P,""); obsolete */ /* for(i=0;iP->x[WZ->P->np][i]=WZ->rI[i]; / * obsolete */ for(i=0;irI[i]) break; if(i make P0=0 */ { for(i=1;inp;i++) for(j=0;jx[i][j]-=P->x[0][j]; for(i=0;iA[i]+=WZ->B[i][j]*P->x[0][j]; for(i=0;irI[i]-=WZ->r*P->x[0][i]; P->x[0][i]=0;} } Find_Equations(WZ->P,&V,E); for(i=0;ine;i++) E->e[i].c *= WZ->r; for(i=0;ine;i++) if(1!=Eval_Eq_on_V(&E->e[i],WZ->rI,d)) break; WZ->R = (i==E->ne); free(E); } if(shift!=1) /* normalize sublattice data */ { Long *PB[W_Nmax], Z[POLY_Dmax][VERT_Nmax], M[POLY_Dmax], D[POLY_Dmax]; for(i=0;iB[i]; Sublattice_Basis(d,a,PB,Z,M,&k,G,D); for(i=0;im[i]=M[i]; for(j=0;jz[i][j]=Z[i][j];} WZ->M=k; /* printf("shift=%d rank=%d \n",shift,k); */ } X=0; for(j=0;jw[j]*WZ->A[j]; /* X=w.A */ for(i=0;iM;i++) {Long A=0,M=WZ->m[i],cx,cm,g; /* A=Z.A */ for(j=0;jz[i][j]*WZ->A[j]; if(0==(A%=M)) continue; g=Egcd(X%M,M,&cx,&cm); assert(0==(A%g)); /* Z_i -= cx * A/g * w_ */ cx*=A/g; if(cx>0)cx-=M; for(j=0;jz[i][j]-=cx*WZ->w[j]; WZ->z[i][j]%=M;} } X=0;for(j=0;jw[j]*WZ->A[j];assert(X==WZ->d);/* TEST w.A=d */ for(j=0;jr*WZ->A[j]; for(k=0;kB[j][k]*WZ->rI[k]; assert(X==1);} /* TEST: r*A+B.rI==IP */ for(i=0;iM;i++) {X=0; for(j=0;jz[i][j]*WZ->A[j];assert(0==X%WZ->m[i]);}/* TEST: A*z[]%m[]==0 */ if(FilterFlag) inFILE=NULL; return 1; } #undef TEST_PP /* print some diagnostic info */ #define TEST_PD /* check Poincare duality of PP */ extern FILE *inFILE, *outFILE; typedef struct {Long x[POINT_Nmax][W_Nmax]; int N, np;} AmbiPointList; typedef struct {Long x[POLY_Dmax][W_Nmax]; int N, n;} AmbiLatticeBasis; Long Wperm_to_GLZ(Long *W, int *d, Long **G, int *P); void WeightLatticeBasis(Weight *_w, AmbiLatticeBasis *_B); void WeightMakePoints(Weight *_W , AmbiPointList *_P); int ChangeToTrianBasis(AmbiPointList*, AmbiLatticeBasis *, PolyPointList *); /* ========== I/O functions: ========== */ int IsDigit(char c) { return (('0'<=c) && (c<='9'));} void Write_Weight(Weight *W) { int n; fprintf(outFILE,"%d",(int) W->d); for(n=0; n < W->N; n++) fprintf(outFILE," %d",(int) W->w[n]); #if WZinput { int i,j; if(W->M>0)printf(" "); for(i=0;iM;i++) { fprintf(outFILE,"/Z%d: ",W->m[i]); for(j=0;jN;j++) fprintf(outFILE,"%d ",W->z[i][j]); } } #endif fprintf(outFILE,"\n"); /* puts(" = d w_1 ... w_N"); */ } int Read_Weight(Weight *_W) /* read "d w_i" [ or "w_i d" if last=max ] */ { char c; int i, shift=1, I[W_Nmax+2], FilterFlag=(inFILE==NULL); if(FilterFlag) inFILE=stdin; else if(inFILE==stdin) printf("type degree and weights [d w1 w2 ...]: "); c=fgetc(inFILE); if( !IsDigit(c) ) return 0; ungetc(c,inFILE); fscanf(inFILE,"%d",I); for(i=1; iN=i-1; if(_W->N>W_Nmax) { puts("Increase POLY_Dmax"); exit(0); } for(i=0;i<=_W->N;i++) assert(I[i]>0); if(I[_W->N]>I[0]) { _W->d=I[_W->N]; shift=0; } else _W->d=I[0]; for(i=0;i<_W->N;i++) {_W->w[i]=I[i+shift]; assert(_W->w[i]<_W->d);} if(FilterFlag) inFILE=NULL; return 1; } void Write_WH(Weight *_W, BaHo *_BH, VaHo *_VH, int rc, int tc, PolyPointList *_P, VertexNumList *_V, EqList *_E){ int i, j; #if WZinput fprintf(outFILE,"%d ",(int)_W->d); for(i=0;i<_W->N;i++) fprintf(outFILE,"%d ",(int)_W->w[i]); for(i=0;i<_W->M;i++){fprintf(outFILE,"/Z%d: ",(int)_W->m[i]); for(j=0;j<_W->N;j++)fprintf(outFILE,"%d ",(int)_W->z[i][j]);} #else for(i=0;i<_W->N;i++) fprintf(outFILE,"%d ",(int)_W->w[i]); fprintf(outFILE,"%d=d ",(int)_W->d); #endif fprintf(outFILE,"M:%d %d ",_P->np,_V->nv); /* PolyData */ if(rc) fprintf(outFILE,"N:%d %d ",_BH->np,_E->ne); else fprintf(outFILE,"F:%d ",_E->ne); /* END of PolyData */ if(tc&&(_P->n!=1+_VH->D)) { int D=0, d=_W->d; /* LG non-geometric */ fprintf(outFILE,"LG: "); for(i=0;i<_W->N;i++) D+=d-2*_W->w[i]; if(D%d) {int g=Fgcd(D,d); fprintf(outFILE,"c/3=%d/%d\n",D/g,d/g);} else { int r=_W->N-(D/=d); if((r%2)||(r<=2)) r=0;assert(D==_VH->D); for(i=0;i<=D;i++) {fprintf(outFILE,"%sH%d:",i?" ":"",i); for(j=0;j<=D-i;j++)fprintf(outFILE,"%s%d",j?",":"",(int)_VH->h[i][j]);} #if WZinput /* if(r) fputs(_W->R ? " RefGC": " NOrgc",outFILE); */ if(r) { if(_W->R) fprintf(outFILE," RefI%d",_W->r); else fputs(" nonRG",outFILE); } #endif fputs("\n",outFILE); } return ; } if((!tc)&&(!rc)){fprintf(outFILE,"non-transversal\n");return;} if(_P->n>2){ if(tc&&rc) for(i=1;i<_P->n-1;i++) if(_VH->h[1][i]!=_BH->h1[i]) { puts("Vafa!=Batyrev"); for(i=1;i<_P->n-1;i++) printf( "V[1,%d]=%d B[1,%d]=%d\n",i,_VH->h[1][i],i,_BH->h1[i]);exit(0);} if(tc) { fprintf(outFILE,"V:%d",_VH->h[1][1]); for(i=2;i<_P->n-1;i++) fprintf(outFILE,",%d",_VH->h[1][i]); if(_P->n > 5){ for (j=2; 2*j <= _P->n-1; j++){ fprintf(outFILE,";%d",_VH->h[j][j]); for(i=j+1;i<_P->n-j;i++) fprintf(outFILE,",%d",_VH->h[j][i]);}} } else if(rc) { fprintf(outFILE,"H:%d",_BH->h1[1]); for(i=2;i<_P->n-1;i++) fprintf(outFILE,",%d",_BH->h1[i]); } if(6<_P->n) fprintf(outFILE," [???]\n"); else if(tc||rc) /* Euler number */ { int chi=0, *ho=_BH->h1; if(tc) ho=_VH->h[1]; if(_P->n==3) chi=4+ho[1]; if(_P->n==4) chi=2*(ho[1]-ho[2]); if(_P->n==5) chi=48+6*(ho[1]-ho[2]+ho[3]); if(_P->n==6) chi=24*(ho[1]-ho[2]+ho[3]-ho[4]); fprintf(outFILE," [%d]\n",chi); } else fprintf(outFILE,"\n");} else fprintf(outFILE,"\n"); } void TEST_LatticeBasis(AmbiLatticeBasis *_B) /* print AmbiLatticeBasis */ { int p,a; for(p=0;p<_B->n;p++){ for(a=0;a<_B->N;a++) printf(" %3d",(int) _B->x[p][a]); puts(""); } } #ifdef TEST void TEST_WeightMakePoints(AmbiPointList *_P) { int i,j; static int MaxPoNum; if(_P->np>MaxPoNum) MaxPoNum = _P->np; if(_P->np>20) { for(i=0;i<_P->np;i++) { for(j=0;j<_P->N;j++) printf("%d ",_P->x[i][j]); puts("");} } else { for(i=0;i<_P->N;i++) { for(j=0;j<_P->np;j++) printf("%4d",_P->x[j][i]); puts("");} } printf("PointNum=%d [max=%d]\n",_P->np,MaxPoNum); } #endif void Ambi_2_Lattice(Long *A,AmbiLatticeBasis *B,Long *P) { int i, p=B->n; while(p--) { int a=p + B->N - B->n; P[p]=A[a] /* -Ai[a]*/ ; for(i=p+1; in; i++) P[p] -= P[i]*B->x[i][a]; if(P[p] % B->x[p][a]) { puts("Error in BasisChange!"); exit(0);} else P[p] /= B->x[p][a]; } } void Make_Poly_Points(Weight *_W_in, PolyPointList *_PP) { AmbiLatticeBasis B; Weight *_W=_W_in; int /* index=0,*/ nip; AmbiPointList * _AP = (AmbiPointList *) malloc(sizeof (AmbiPointList)); #ifndef NO_COORD_IMPROVEMENT /* ==== Perm Coord Improvement ==== */ Weight Waux=(*_W); _W=&Waux; { int i,n=_W->N,pi[AMBI_Dmax]; Long M[AMBI_Dmax][AMBI_Dmax], *G[AMBI_Dmax]; for(i=0;iw,&n,G,pi);for(i=0;iw[pi[i]]; } #endif /* = End of Perm Coord Improvement = */ if(_AP==NULL) {printf("Unable to allocate space for _AP\n"); exit(0);} WeightLatticeBasis(_W, &B); /* TEST_LatticeBasis(&B); */ WeightMakePoints(_W, _AP); #ifdef TEST puts("\nWeights:"); Write_Weight(_W); puts("AmbiPoints:"); TEST_WeightMakePoints(_AP); puts("Basis:"); TEST_LatticeBasis(&B); printf("POINT_Num=%d\n",_AP->np); #endif assert(_AP->np <= POINT_Nmax); nip=ChangeToTrianBasis(_AP, &B, _PP); #ifdef TEST Print_PPL(_PP,"PolyPoints:"); #endif #ifdef GEN_CY { int i; for(i=0;i<_W->N;i++) index+=_W->w[i]; if(index%_W->d)index=0;} index/=_W->d; if(index>1) { Long A[AMBI_Dmax];int i;for(i=0;ix[nip][i]; assert(_PP->npx[_PP->np]); } #endif free(_AP); return; } #if (WZinput) int Read_W_PP(Weight *W, PolyPointList *P){ W->P=P; return Read_WZ_PP(W); } #else int Read_W_PP(Weight *_W, PolyPointList *_PP){ if (!Read_Weight(_W)) return 0; Make_Poly_Points(_W,_PP); return 1; } #endif /* ========== WeightLatticeBasis(Weight *_w, AmbiLatticeBasis *_B) * * M[0]:= (-n1, n0, 0, ...) / gcd(n0,n1); * M[i]:= (0,...,0,g/ng,0,...)- (ni/ng) * egcd.Vout(n0,...,n(i-1),0,...); * with g=gcd(n0,...,n[i-1]); ng=gcd(g,ni); * */ #ifdef TEST void NormTriangularBasis(AmbiLatticeBasis *_B) { int p=_B->n-1, a=_B->N-1; while(p--) { int pi=_B->n; while(0==_B->x[p][--a]); while(--pi > p) { int ai=a+1, r = _B->x[pi][a] / _B->x[p][a]; /**/ if((_B->x[pi][a] % _B->x[p][a]) < 0) r--; /**/ if(r) while(ai--) _B->x[pi][ai] -= r * _B->x[p][ai]; } } } void OldWeightLatticeBasis(Weight *_w, AmbiLatticeBasis *_B) { int i, j; Long *V, Vin[W_Nmax], Vout[W_Nmax]; for(i=0; i<_w->N; i++) Vin[i]=_w->w[i]; V=_B->x[0]; *Vout=Fgcd(Vin[0],Vin[1]); V[0] = -Vin[1] / *Vout; V[1] = *Vin / *Vout; _B->N=_w->N; _B->n=_w->N-1; for(j=2; j<_w->N; j++) V[j]=0; for(i=2; i<_w->N; i++) { int g=REgcd(Vin, &i, Vout), gn=Fgcd(g,_w->w[i]); V=_B->x[i-1]; V[i] = g/gn; g = _w->w[i]/gn; for(j=0;jN) V[j++]=0; } NormTriangularBasis(_B); /* TEST_LatticeBasis(_B); */ } #endif void WeightLatticeBasis(Weight *_w, AmbiLatticeBasis *_B) { Long *B[W_Nmax], E[W_Nmax]; int i; _B->N=_w->N; _B->n=_w->N-1; B[0]=E; for(i=0;i<_B->n;i++) B[i+1]=_B->x[i]; W_to_GLZ(_w->w,&(_w->N),B); } /* ========== WeightMakePoints(Weight *_W, AmbiPointList *_P) * * MakePoints: X[i]-IP[i] = x[j] * B[j][i] :: i-1<=jN-1, X_max[W_Nmax], d_Rest[W_Nmax], X[W_Nmax+1]={0}; _P->np=0; _P->N=_W->N; d_Rest[i]=_W->d; X_max[i]=d_Rest[i]/_W->w[i]; while(i<_W->N) { if(X[i]>X_max[i]) X[++i]++; else if(i) { d_Rest[i-1]=d_Rest[i]-X[i]*_W->w[i]; X[--i]=0; X_max[i]=d_Rest[i]/_W->w[i]; } else { int j; Long *Y; *d_Rest=d_Rest[1]-X[1]*_W->w[1]; if( !(*d_Rest % *(_W->w)) ) { if(POINT_Nmax <= _P->np){puts("increase POINT_Nmax");exit(0);} Y=_P->x[(_P->np)++]; *Y= *d_Rest/ *(_W->w); for(j=1;j<_W->N;j++) Y[j]=X[j]; } X[1]++; i=1; } } } /* ========== ChangeToTrianBasis(AmbiPointList *, Basis *, PolyPointList *) * * Assuming that AmbiLatticeBasis is of triangular form, i.e.: * _B->x[p][a] = 0 for a < p + CoDim ... a < W_Nmax and p < POLY_Dmax * this solves AP=B.PP for AP (to be precise we must take AP.x-IP, * where IP is the unique interior point.) * DP=AP.x-IP; DP[a]=PP[p]*B[p][a] => * PP[p]*B[p][p+1] = DP[p+1] - sum_{a>p+1} PP[p]*B[p][p+1] * */ int ChangeToTrianBasis(AmbiPointList *_AP, AmbiLatticeBasis *_B, PolyPointList *_PP) { int n, ipcount=0, nIP=0; if( _AP->N - _B->N) {puts("Dimensions don't match!"); exit(0);} else { _PP->n = _B->n; _PP->np = _AP->np; } for(n=0; n<_AP->np; n++) { int i, p=1; for(i=0; i < _B->N; i++) if( ! _AP->x[n][i] ) p=0; if(p) { ipcount++; nIP=n; } } #ifdef TEST if(ipcount-1) puts("*** Wrong IP-count: take any point as origin! ***"); #endif for(n=0; n<_AP->np; n++) { int i, p=_B->n; while(p--) { int a=p + _B->N - _B->n; _PP->x[n][p]=_AP->x[n][a]-_AP->x[nIP][a]; for(i=p+1; i<_B->n; i++) _PP->x[n][p] -= _PP->x[n][i]*_B->x[i][a]; if(_PP->x[n][p] % _B->x[p][a]) { puts("Error in BasisChange!"); exit(0);} else _PP->x[n][p] /= _B->x[p][a]; } } return nIP; } /* ============= make weights =========== */ int IfRefWWrite(Weight *W, PolyPointList *P) { VertexNumList V; EqList E; Make_Poly_Points(W, P); if(Ref_Check(P,&V,&E)) {Write_Weight(W); fflush(stdout); return 1;} else return 0; } void Rec_RefWeights(Weight *W, PolyPointList *P, int g, int sum, int *npp, int *nrp, int n) { int wmax=W->d/(W->N-n+1); wmax=min(wmax,W->w[n+1]); wmax=min(wmax,sum-n); if(n) for(W->w[n]=wmax;(n+1)*W->w[n]>=sum;W->w[n]--) Rec_RefWeights(W,P,Fgcd(g,W->w[n]),sum-W->w[n],npp,nrp,n-1); else if(1==Fgcd(g,W->w[0]=sum)) {(*npp)++;if(IfRefWWrite(W,P))(*nrp)++;}; } void MakeRefWeights(int N, int from_d, int to_d) { int npp=0, nrp=0; Weight W; PolyPointList *P = (PolyPointList *) malloc (sizeof(PolyPointList)); W.N=N; assert((N<=W_Nmax)&&(Nn;i++){ #if ABBREV_POLY_PRINT int a=ABBREV_POLY_PRINT; if((a<=i)&&(in-a)) {if(i==a) printf("+ ... ");} else #endif { int co=abs(P->c[i]); printf("%s ", i ? ((P->c[i] > 0) ? "+" : "-" ) : "");if(!i&&(P->c[0]<0))printf("- "); if(co!=1) printf("%d ",co); printf("x^%d ",(int)P->e[i]); }} puts(i ? "" : " 0"); } void UnitPoly(PoCoLi *P) { P->n=1; P->e[0]=0; P->c[0]=1; } void Add_Mono_2_Poly(int e, Pint c, PoCoLi *P) /* use bisection */ { int m=-1, M=P->n; if(P->n) if(e <= P->e[P->n-1]) while(M-m>1) { int pos=(M+m)/2; if(e > P->e[pos]) m=pos; else if (e < P->e[pos]) M=pos; else { P->c[pos]+=c; return; }/* e exists */ } if(P->A<=P->n){printf("n=A=%d\n",P->A); fflush(0); assert(P->n < P->A);} /* check #(coeff.) of Poly. */ for(m=P->n++;Mc[m]=P->c[m-1]; P->e[m]=P->e[m-1]; } P->e[m]=e;P->c[m]=c; #ifdef TEST_PP {static int M=1; if(P->n/1000000 > M) {printf("#c=%dM ",++M);fflush(0);}} #endif } void Init1_xN(PoCoLi *P,int N) /* 1 - x^N */ { UnitPoly(P); Add_Mono_2_Poly(N,-1,P); } void Remove_Zeros(PoCoLi *AB) { int i, s=0; for(i=0; in; i++) /* s=shift: eliminatet zeros */ { if(0==AB->c[i]) s++; else if(s) { AB->c[i-s]=AB->c[i]; AB->e[i-s]=AB->e[i]; } } AB->n -= s; } void PolyCopy(PoCoLi *X,PoCoLi *Y) { assert(X->n<=Y->A); for(Y->n=0;Y->nn;Y->n++){ Y->e[Y->n]=X->e[Y->n]; Y->c[Y->n]=X->c[Y->n];} } int BottomUpQuot(PoCoLi *N,PoCoLi *D,PoCoLi *Q,PoCoLi *R) /* Q*D = N-R */ { int i, c, Npos, e, E, dD, dN; Q->n=R->n=0; /* return R==0 */ assert(D->n>0); if(N->n==0) return 1; assert(N->n>0); /* assume D != 0 */ dD=D->e[D->n-1]-D->e[0]; dN=N->e[N->n-1]-N->e[0]; e=N->e[0]-D->e[0]; if((e<0)||(dD>dN)) { PolyCopy(N,R); return 0; } for(Npos=0;Nposn;Npos++) { if(N->e[Npos]<=e+dD)Add_Mono_2_Poly(N->e[Npos],N->c[Npos],R); else break; } E = N->e[N->n-1] - D->e[D->n-1]; while(0==(R->c[0]%D->c[0])) { Add_Mono_2_Poly(e,c=R->c[0]/D->c[0],Q); /* next Q.c[] */ for(i=0;in;i++)Add_Mono_2_Poly(e+D->e[i],-c*D->c[i],R); /* R-cQ */ Remove_Zeros(R); if((Npos==N->n)&&(0==R->n)) return 1; /* finished? */ e = (R->n) ? R->e[0]-D->e[0] : N->e[Npos]-D->e[0]; /* next Q.e[] */ while(Nposn) { if(N->e[Npos]<=e+dD) { Add_Mono_2_Poly(N->e[Npos],N->c[Npos],R); Npos++;} else break; Remove_Zeros(R); if(e > E) return 0; } } while(Nposn){Add_Mono_2_Poly(N->e[Npos],N->c[Npos],R); Npos++;} return 0; } void PolyProd(PoCoLi *A,PoCoLi *B,PoCoLi *AB) /* AB = A*B */ { int i, j, s=A->n+B->n-1; AB->n=0; assert(sA); for(i=0;in) ? 0 : i+1-B->n, M = (in) ? i+1 : A->n; for(j=m;je[j]+B->e[i-j],A->c[j]*B->c[i-j],AB); } Remove_Zeros(AB); } void Poly_Sum(PoCoLi *A,PoCoLi *B,PoCoLi *S) /* S = A+B */ { int a, b=0; S->n=0; for(a=0;an;a++) { int q=1; while(bn) if(A->e[a]<=B->e[b]) break; else {Pint s=B->c[b++]; if(s) {if(S->n>=S->A){printf("S.n>%d in S=A+B\n",S->n);exit(0);} S->c[S->n]=s; S->e[S->n++]=B->e[b-1];}} if(bn)if(B->e[b]==A->e[a]){Pint s=A->c[a]+B->c[b++]; q=0; if(s) {assert(S->nA); S->e[S->n]=A->e[a]; S->c[S->n++]=s;} } if(q) if(A->c[a]) {assert(S->nA); S->e[S->n]=A->e[a]; S->c[S->n++]=A->c[a];} } while(bn) if(B->c[b]) {assert(S->nA); S->e[S->n]=B->e[b]; S->c[S->n++]=B->c[b++];} else b++; } void Poly_Dif(PoCoLi *A,PoCoLi *B,PoCoLi *D) /* D = A-B */ { int a, b=0; D->n=0; for(a=0;an;a++) { int q=1; while(bn) if(A->e[a]<=B->e[b]) break; else {Pint d=-B->c[b++]; if(d) {assert(D->nA); D->c[D->n]=d; D->e[D->n++]=B->e[b-1];}} if(bn)if(B->e[b]==A->e[a]){Pint d=A->c[a]-B->c[b++]; q=0; if(d) {assert(D->nA); D->e[D->n]=A->e[a]; D->c[D->n++]=d;} } if(q) if(A->c[a]) {assert(D->nA); D->e[D->n]=A->e[a]; D->c[D->n++]=A->c[a];} } while(bn) if(B->c[b]) {assert(D->nA); D->e[D->n]=B->e[b]; D->c[D->n++]=-B->c[b++];} else b++; } void AllocPoCoLi(PoCoLi *P) /* allocate e[A] and c[A] */ { assert(0A); assert( NULL != ( P->e = (int *) malloc( P->A * (sizeof(int)+sizeof(Pint) ) ) )); P->c = (Pint *) & P->e[P->A]; // printf("AllocPoCoLi: P->A = %d\n", P->A); } void Free_PoCoLi(PoCoLi *P) { free(P->e); } /* free P.e and P.c */ void PoincarePoly(int N, int *w, int d, PoCoLi *P, PoCoLi *Z,PoCoLi *R) { int i, e[2]; Pint c[2]; PoCoLi B, *In=Z,*Out=P,*aux; if(N==0) {UnitPoly(P); return;} B.e=e; B.c=c; B.A=B.n=2; e[0]=0; c[0]=1; c[1]=-1; Init1_xN(In,d - w[0]); for(i=1;ih[i][j]);} } int DoHodgeTest(VaHo *V)/*[holo] Poincare duality, Hodge duality, sum rule */ { int i,j,D=V->D,X;for(i=D/2;i<=D;i++){if(V->h[i][0]!=V->h[D-i][0])return 0; for(j=0;j<=D;j++)if(V->h[i][j]!=V->h[D-i][D-j]) return 0;} V->E=X=0; for(i=0;i<=D;i++)for(j=i+1;j<=D;j++)if(V->h[i][j]!=V->h[j][i]) return 0; for(i=0;i<=D;i++)for(j=0;j<=D;j++){int x=2*i-D; x=x*x*V->h[i][j]; if((i+j)%2) {V->E -= V->h[i][j];X-=x;} else {V->E += V->h[i][j];X+=x;}} assert(3*X==D*V->E); return (V->h[0][0]==1); } int Hodge_Test(VaHo *V) /* [holo] Poincare duality, Hodge duality, sum rule */ { if(DoHodgeTest(V)) return 1; else {Print_VaHo(V); return 0;} } /* do {;} while(Multiloop(N,I,j,J)); <--> do forall 0<=I[j]0);} assert(0<=*J); if((*J)==0) {N[0]=1; I[0]=0;} /* safe also for J=0 */ for(*j=0;*j<*J;(*j)++) X*=N[*j]; *j=0; return X; /* return order=prod(N) */ } int Multiloop(int *N,int *I,int *j,int *J)/* need j=I[]=0 => Init_Multiloop */ { assert((*j)==0); if(++(I[0])M,N=W->N,vac=0; for(j=0;jm[j]; for(l=0;ld;l++) /* Z_d==GSO */ { c=Init_Multiloop(M,I,&j,&J); do { /* BEGIN generate group */ int i,can=1, sum=0, k; /* can(didate) for b01-contribution */ for(i=0;can&&(iw[i],W->d); /* th=0/q -> eq[] */ for(k=0;kz[k][i],M[k]));} th.N%=th.D; assert(th.N>=0); if(th.N) {th=rP(th,rR(W->d,W->w[i])); if(th.N!=th.D) can=0; else {eq[i]=1;sum+=W->d-2*W->w[i];}} else eq[i]=0;} /* eq=(th_i==q_i); */ if(sum&&(sum != W->d)) can=0; /* i.e. charge=1? */ for(k=0;can&&(kz[k][i]; gph%=M[k];} if(gph) can=0; } if(can) {if(sum) b++; else vac++;} #if (SHOW_b01_TWIST) if(can&&sum){ if(b==1)puts("");printf("b01=%d: j^%d, I[]=",b,l); for(k=0;k> V.D<=3 <<-- via index and trace */ { int i,j,k,l,c, b01=0; /* ... from "proced" in lgotwist.c */ int fac, wort, nvar, expo, ns=W->M, N=W->N, R, mask[W_Nmax+1], n=N; Long zsum1=0, zsum2=0, mo=W->d, ng, ngb, kgV=mo, omega[POLY_Dmax]; int *wo[3],*woG,*woA,*woS, WM=1<D=0; for(i=0;iN;i++) V->D+= W->d-2*W->w[i]; assert(V->D%W->d==0); V->D/=W->d; assert((0D)&&(V->D<=3)); V->h[0][0]=V->h[0][V->D]=V->h[V->D][0]=V->h[V->D][V->D]=1; if(V->D==1){assert(Count_b01(W)==1); return;} if(V->D==2){b01=Count_b01(W); V->h[0][1]=V->h[1][0]=V->h[2][1]=V->h[1][2]=b01; assert((b01==0)||(b01==2)); V->h[1][1]=(b01) ? 4 : 20; return;} wo[0] = woG = (int *) malloc(WM*3*sizeof(int)); assert(woG!=NULL); wo[1]=woS=&woG[WM]; wo[2]=woA=&woS[WM]; for(i=0;i<=N;i++) mask[i]=1<m[k]/Fgcd(kgV,W->m[k]); mo*=W->m[k];} for(k=0;km[k]; R=kgV/W->d; for(l=0;ld;l++) /* Z_d==GSO */ { c=Init_Multiloop(W->m,I,&j,&ns); do { /* BEGIN generate group */ nvar=0; for(i=0;iw[i]*R; for(k=0;kz[k][i];if(!(expo%kgV))nvar+=mask[i];}woS[nvar]++; assert(0<(c--));}while(Multiloop(W->m,I,&j,&ns));assert(c==0);/* END */ } assert(woS[mask[n]-1]==1); /* over=overcount=wo[mask[n]-1][1]; */ for(i=0;i=0;i--) if (woG[i]+woA[i]) { prod=rI(1); for (j=0;jw[j]-W->d,W->w[j])); if (prod.D != 1){ fprintf(outFILE, "\nDenominator != 1 in Fast_c9_VaHo (LG.c)\n");exit(0);} zsum1+= woG[i]*prod.N; zsum2+= woA[i]*prod.N;} ng = -(zsum1/mo+2)/2; ngb = (zsum2/mo-2)/2; /* /over */ assert((zsum1==-2*(ng+1)*mo) && (zsum2 == 2*(ngb+1)*mo)); /* *over */ free(woG); /* woS[word] = #group elements :: survivors==word */ /* woG / woA = contributions to ng / ngb */ if(ng==ngb){b01=Count_b01(W); assert((b01==0)||(b01==1)||(b01==3));} for(i=1;i<=2;i++){ V->h[i][i]=ngb-2*b01; V->h[i][3-i]=ng-2*b01; V->h[0][i]=V->h[3][i]=b01; V->h[i][0]=V->h[i][3]=b01; V->h[0][0]=V->h[3][3]=V->h[3][0]=V->h[0][3]=1; } } int WIndex_HTrace(Weight *W, int *WI, int *T)/* T=sum(Hij), return over=H00 */ { int i,j,k,l,c,vacnum; /* ... from "proced" in lgotwist.c */ int fac, wort, nvar, expo, ns=W->M, N=W->N, R, mask[W_Nmax+1], n=N; Long zsum1=0, zsum2=0, mo=W->d, kgV=mo, omega[POLY_Dmax]; int *wo[3],*woG,*woA,*woS, WM=1<m[k]/Fgcd(kgV,W->m[k]); mo*=W->m[k];} for(k=0;km[k]; R=kgV/W->d; for(l=0;ld;l++) /* Z_d==GSO */ { c=Init_Multiloop(W->m,I,&j,&ns); do { /* BEGIN generate group */ nvar=0; for(i=0;iw[i]*R; for(k=0;kz[k][i];if(!(expo%kgV))nvar+=mask[i];}woS[nvar]++; assert(0<(c--));}while(Multiloop(W->m,I,&j,&ns));assert(c==0);/* END */ } vacnum=woS[mask[n]-1]; /* over=overcount=wo[mask[n]-1][1]; */ for(i=0;i=0;i--) if (woG[i]+woA[i]) { prod=rI(1); for (j=0;jw[j]-W->d,W->w[j])); if (prod.D != 1){ fprintf(outFILE, "\nDenominator != 1 in Fast_c9_VaHo (LG.c)\n");exit(0);} zsum1+= woG[i]*prod.N; zsum2+= woA[i]*prod.N;} free(woG); /* woS[word] = #group elements :: survivors==word */ /* woG / woA = contributions to ng / ngb */ assert(zsum1%mo==0); assert(zsum2%mo==0); assert(vacnum==1); *WI=(zsum2+zsum1)/mo; *T=(zsum2-zsum1)/mo; return vacnum; } /* Z_d is taken care of by the integral charge condition. * * x[j]=lcm(phase denom.), go over G=\prod M[j], denom=\prod(1-t^(w*x)) * * numerator: go over group G and project: this is a critical part that * * can have extremely many terms * * U=charge unit for th[i], X=phase unit for (non-GSO) group projection * * QL=sum(th_i-q_i)+Q_ring; dQ=QR-QL=sum(1-2th_i); * * proj: g|h> = (-1)^(Kg*Kh) \e(g,h)(\det g_h)/(det g)|h>, thus * * K=\e=0 => ph[j] is the sum of the phases on invariant fields. * */ int Test_BottomUpQuot(PoCoLi *Num,PoCoLi *Den,PoCoLi *Quo,PoCoLi *Rem) { int i=BottomUpQuot(Num,Den,Quo,Rem); if(Rem->n)assert(i==0); if(i)return 1; printf("Num="); PrintPoCoLi(Num); printf("Den="); PrintPoCoLi(Den); printf("Quo=");PrintPoCoLi(Quo); printf("Rem="); PrintPoCoLi(Rem); /* printf("N=%d D=%d Q=%d R=%d\n",Num.A,Den.A,Quo.A,Rem.A);exit(0);fflush(0);*/ { PoCoLi A; A.A=10000;AllocPoCoLi(&A);PolyProd(Den,Quo,&A); Poly_Dif(&A,Num,Den);Poly_Sum(Den,Rem,&A); assert(A.n==0); Free_PoCoLi(&A); puts("BottomUpQuot: Test o.k."); } return 0; } void pff(char *c){puts(c);fflush(0);} typedef struct {int X, n, *d, **mt;} /* mt[i][j]=mobius(j,i) */ MobiusData; void MakeMobius(MobiusData *M,int X) /* d[i] divisors, mt[i][j] 0<=j<=i<=n */ { int i,j=0,n=0,*d; for(i=1;in=n=2*n+(X==i*i); /* #(Div(X)) */ M->d = d = (int *)malloc(((n*(n+3))/2) * sizeof(int) + n * sizeof(int*)); assert(d != NULL); M->mt = (int **) &d[(n*(n+3))/2]; M->mt[0]=&(d[n]); for(i=1;imt[i]=&M->mt[i-1][i]; for(i=1;i<=X/i;i++) if(X%i==0){d[j]=i;d[n-(++j)]=X/i;} for(i=0;imt[i][i]=1; for(j=i-1;0<=j;j--) {M->mt[i][j]=0; for(k=j+1;k<=i;k++) if(d[i]%d[k]==0) if(d[k]%d[j]==0) M->mt[i][j] -= M->mt[i][k];}} #ifdef PRINT_MOBIUS_FUNCTION printf("Div(%d)=",X);for(i=0;imt[i][j]);} ;puts(""); #endif } void FreeMobius(MobiusData *M){free(M->d);} void Calc_VaHo(Weight *W,VaHo *V); void PoincarePoly(int N, int *w, int d, PoCoLi *P, PoCoLi *Z,PoCoLi *R); void Aux_Phase_Poly(PoCoLi *P,int w,int d, int r, int s, int x); int Index_Trace_Test(VaHo *V,int WI,int T) { int i,j,D=V->D;for(i=0;i<=D;i++)for(j=0;j<=D;j++){T-=V->h[i][j]; if((i+j)%2) WI += V->h[i][j]; else WI -= V->h[i][j];} assert((T==0)&&(WI==0)); return 1; } /* Thru 4-folds it is sufficient to know boundary (i.e. H{0i} and H{di} *) * * contributions, Witten index and trace for the twisted sectors; the * * untwisted sector can be reconstructed from "WIndex_HTrace(W,&WI,&T)". * * goint twice over the group is not too costly if the projection is reduced * * to the effectively acting subgroup for each twisted sector */ void LGO_VaHo(Weight *W,VaHo *V) { int i,d=W->d,D=0; for(i=0;iN;i++) D+=d-2*W->w[i];assert(!(D%d));D/=d; /* printf("In LGO_VaHo: W->N: %d W->M: %d D: %d\n", W->N, W->M, D); */ /* From palp-2.0 to palp-2.11 the next lines were * if((V->sts)||(D>3)) {if(W->M==0) W->m[0]=1;} * else {if(D<=3) {Fast_c9_VaHo(W,V);return;} * if(W->M==0){Calc_VaHo(W,V);return;}} * but that makes no sense since it's equivalent to * if((V->sts)||(D>3)) {if(W->M==0) W->m[0]=1;} * else {Fast_c9_VaHo(W,V);return;} * therefore: */ if ((V->sts == 0) && (W->M == 0)) { /* V->sts ... lg-flag set to 2, W->M ... # of Z_n symmetries */ if (D<=3) {Fast_c9_VaHo(W,V);return;} else {Calc_VaHo(W,V);return;} } if(W->M==0) W->m[0]=1; { Long dQ,QL,q; PoCoLi *S,*SO,*SN;/* dQ=sum(1-2th)=QR-QL; QL=sum(th-w) */ int j,k,s, J=W->M, M[POLY_Dmax],I[POLY_Dmax],X=W->m[0],x[POLY_Dmax]; int WI,T; Long ph[POLY_Dmax], th[W_Nmax], U=X*d/Fgcd(X,d), rd=U/d, G=1; PoCoLi Den,Num,Quo,Rem; MobiusData MX; MakeMobius(&MX,X); Den.A = (1<N); AllocPoCoLi(&Den); Quo.A = X*d*D+2*W->N; AllocPoCoLi(&Quo); Num.A=Rem.A= Quo.A; AllocPoCoLi(&Num); AllocPoCoLi(&Rem); V->D=D; for(i=0;i<=D;i++) for(j=0;j<=D;j++) V->h[i][j]=0; for(j=0;jm[j]); assert(*M%M[j]==0); x[j]=X/M[j];} S = (PoCoLi *) malloc( 2*X*sizeof(PoCoLi) ); assert(S!=NULL); for(k=0;kd;k++) /* Z_d==GSO */ { int v,a=Init_Multiloop(W->m,I,&v,&J); do { /*BEGIN gen TWISTS */ int n[W_Nmax], N=0,h[POLY_Dmax+1],hn=0; QL=dQ=0; for(j=0;jN;i++) {th[i]=k*W->w[i]*rd; for(j=0;jz[j][i]*(U/W->m[j]); assert(th[i]>=0); th[i]%=U; if(th[i]) {QL+=th[i]-W->w[i]*rd; dQ+=U-2*th[i];} else{n[N++]=i;for(j=0;jz[j][i];} } assert((dQ%U)==0); assert((QL%rd)==0); assert(QL+dQ>=0); dQ/=U; QL/=rd; for(j=0;j_gs */ /* int pntw=0; if(100*k+10*I[0]+I[1]==202)pntw=1; */ /* U==lcm(X,d)=d*rd -> th[i]/U, X==lcm(M[])=x[j]*M[j] -> ph[j]/X |g> */ /* QL/d+dQ G=\prod M[j]=|group| n[i], i l=(l1 X - a1 s1)/g1, */ /* A g1+B g2=g, if((s1 a1 g2/g - s2 a2 g1/g) % X ==0) then */ /* l=l' X/g +(B X-a1 s1)/g1 = l' X/g - (A X +a2 s2)/g2 else break; */ /* r'=g, s'=(A X + a2 s2)/g2, a'=1; assert(s' % g' ==0); */ if(N==1) {int w=W->w[*n], r=0,g=X; Long A,B; s=0; for(j=0;jz[j][*n]*x[j])%X, sj=ph[j]%X; assert(0<=rj); if(rj==0) { if(sj==0) continue; else {g=0;break;} } g=Egcd(rj,X,&A,&B); sj=(sj*A)%X; assert(rj>0);assert(g>0);assert(sj%g==0); if(sj%g) {g=0;break;} rj=g; g=Egcd(r,rj,&A,&B); assert(g>0); if((s*rj-sj*r)% (g*X)) {g=0;break;} r=g; s=(A*X+sj)/rj; if(s%g) {g=0;break;} } assert((j1); */ Aux_Phase_Poly(&Num,w,d,r,s,X/g);} if(g) {Init1_xN(&Den,w*(X/g)); BottomUpQuot(&Num,&Den,&Quo,&Rem); for(i=0;i1) /* N>1: S[] sector -> SN[] new sector PoCoLi */ { int u,b,l,L[POLY_Dmax],w[W_Nmax],o[W_Nmax],io[W_Nmax],mm=1; for(i=0;iw[n[j]]w[n[i]]) swap(&n[i],&n[j]); for(i=0;iw[n[i]]; o[i]=1; for(j=0;jz[j][n[i]],W->m[j]); u=W->m[j]/u; o[i]=u*o[i]/Fgcd(o[i],u);} mm=mm*o[i]/Fgcd(mm,o[i]);} /* phase(g.s.) = gs/mm; mm=lcm(o[i]); phase(X(n(i))=z[i]/o[i]; */ /* BEGIN GROUP PROJECTION */ if(mm>1){int *mo, m, ego=1; /* effective group order */ PoCoLi *A,*B,*C,Ax; Ax.A=Quo.A; AllocPoCoLi(&Ax); Num.n=0; for(j=0;jz[j][n[0]]; for(i=1;iz[j][n[i]]); M[j] = W->m[j] / NNgcd(g,W->m[j]);} for(m=0;mz[j][n[i]]*o[i])/W->m[j]); io[i]=mm/o[i]; gs+=io[i]*z[i];} gs%=mm; assert(gs>=0); SO=S; SN=&S[mm]; /* for each projection group element */ for(s=0;s1)Aux_Phase_Poly(&S[s],w[0],d,z[0],-ds/io[0], o[0]); else Init1_xN(&S[s],d-w[0]);} for(i=1;in=0; for(s=0;s1) Aux_Phase_Poly(A,w[i],d,z[i],-s/io[i],o[i]); else Init1_xN(A,d-w[i]); PolyProd(&SO[(mm+t-s)%mm],A,B); Poly_Sum(B,C,A); ac=A;A=C;C=ac;} SN[t].A=C->A; AllocPoCoLi(&SN[t]); PolyCopy(C,&SN[t]); } for(t=0;tN;i++) fprintf(outFILE," %2ld",th[i]); /*fprintf(outFILE,"/%d ",U);*/ /*fprintf(outFILE," %d*ph=",U);for(i=0;im,I,&v,&J));assert(a==0); /* END gen TWISTS */ } free(S); FreeMobius(&MX); Free_PoCoLi(&Rem); Free_PoCoLi(&Quo); assert(Hodge_Test(V)); Free_PoCoLi(&Den); Free_PoCoLi(&Num); assert(1==WIndex_HTrace(W,&WI,&T)); assert(Index_Trace_Test(V,WI,T)); if(V->sts) printf("WittenIndex=%d, Trace=%d\n",WI,T); } } /* T=\x*t: (1-T^(d-w))/(1-T^w)=(1-T^(d-w))*(1+T^w+T^2w+...+T^(x-1)w)/(1-T^wx)* * phase(\x)=r/x. All terms in numerator with phase s/x, p=0,...,x-1 => * * exp=p mod x in numerator 1+...+T^(x-1)w-T^(d-w)-T^d-...-T^(d+w(x-2)) */ void Aux_Phase_Poly(PoCoLi *P,int w,int d, int r, int s, int x) { int i, nocancel = (d%w) || (x*w1); P->n=0; for(i=0;i<=posmax;i+=w) if((r*(i/w)-s) % x == 0) Add_Mono_2_Poly(i,1,P); for(i=negmin;i<=negmax;i+=w)if((r*(i-d)/w-s)%x==0)Add_Mono_2_Poly(i,-1,P); } void Calc_VaHo(Weight *W,VaHo *V) { int i, j, k, D=0, w[W_Nmax], N=W->N, d=W->d; PoCoLi A,B,C, *Z=&A, *R=&B, *P=&C; for(i=0;iw[i]; D+=d-2*w[i]; } if(D % d) {V->D=0; return;} else V->D = (D/=d); for(i=0;iA=Z->A=COEFF_Nmax; R->A=w[N-1]+1; //printf("%d %d %d", P->A, Z->A, R->A); AllocPoCoLi(P); AllocPoCoLi(Z); AllocPoCoLi(R); PoincarePoly(N,w,d,P,Z,R); assert(D*d==P->e[P->n-1]); { int n=P->n, cM=0; long long sum=0,num=1,den=1; /* check sum = P(0) */ for(i=0;ic[i]; assert(co>0); if(co>cM) cM=co; sum+=co; } for(i=0;iN;i++){ num*=W->d-W->w[i]; den*=W->w[i]; {long long g=LFgcd(num,den); num/=g; den/=g; }} #ifdef TEST_PP if(P->n<99) {printf("PP =");PrintPoCoLi(P);} else printf( "#(Exp,Co)=%d Exp<=%d Coeff<=%d sum=%lld\n",n,P->e[n-1],cM,sum); #endif if(den==1) assert(num==sum); else { printf("sum=%lld test=%lld/%lld \n",sum,num,den);} } for(i=0;i<=D;i++) for(j=0;j<=D;j++) V->h[i][j] = 0; for(i=0;in;i++)if(P->e[i] % d==0) {j=P->e[i]/d; V->h[D-j][j]=P->c[i];} #ifdef TEST_PP for(i=0;i<=D;i++){for(j=0;j<=D;j++)printf("%6d ",(int)V->h[i][j]); puts("= V-pri");}fflush(0); #endif for(k=1;kw[i]) % (long long)d)) { et+=th[i]-W->w[i];eT+=W->d-th[i]-W->w[i];} else { Deff+=W->d-2*W->w[i]; w[n++]=W->w[i];} /* effective w */ } if(0 == ((Tmt=eT-et) % d)) { for(i=0;ie[P->n-1]); Tmt/=d; for(i=0;in;i++) { j=et+P->e[i]; if(j % d==0) {j/=d; if(j+Tmt>=0)V->h[D-j][j+Tmt]+=P->c[i];} } } } Free_PoCoLi(P); Free_PoCoLi(Z); Free_PoCoLi(R); #ifdef TEST_PP for(i=0;i<=D;i++){for(j=0;j<=D;j++)printf("%6d ",V->h[i][j]);puts("= V");} #endif } /* ============= Trans_Check(Weight W) ========== */ /* OLD version ignores * orbifold projection */ int OLDsymcheck(int sum, int link, int *mon, Weight W, int *mask){ /* symcheck returns 1 if there is a monomial mon in * the variables indicated by link whose total weight is sum and which * transforms under the k'th symmetry with a phase sum[k]; * if X_i occurs in the monomial then mon[i] is set to 1. */ int i, j, newsum, newlink; for (i=0;i mighty[j] <= mighty[targets[j]] */ int Trans_Check(Weight W){ /* returns 1 if non-degenerate potential exists */ int i, j, k, l; /* j represents the link!!! */ symlist dw; static int mask[1+W_Nmax], *targets, *mighty; assert(W.N<=W_Nmax); if(targets==NULL) Init_Trans_Check(mask,&targets,&mighty); targets[0]=0; for (i=0;i */ for (k=0;k<=i;k++) targets[j]=targets[j]|targets[j&~mask[k]]; for (k=0;(k] [in-file [out-file]]\n", c); printf("Options (concatenate any number of them into ):\n"); printf(" -h print this information \n"); printf(" -f use as filter\n"); printf(" -g general output: triangulation and Stanley-Reisner ideal\n"); printf(" -I incidence information of the facets (ignoring IPs of facets)\n"); printf(" -m Mori generators of the ambient space\n"); printf(" -P IP-simplices among points of P* (ignoring IPs of facets)\n"); printf(" -K points of P* in Kreuzer polynomial form\n"); printf(" -b arithmetic genera and Euler number\n"); printf(" -i intersection ring\n"); printf(" -c Chern classes of the (CY) hypersurface\n"); printf(" -t triple intersection numbers\n"); printf(" -d topological information on toric divisors & del Pezzo conditions\n"); printf(" -a all of the above except h, f, I and K\n"); printf(" -D lattice polytope points of P* as input (default CWS)\n"); printf(" -H arbitrary (also non-CY) hypersurface `H = c1*D1 + c2*D2 + ...'\n"); printf(" input: coefficients `c1 c2 ...'\n"); printf(" -M manual input of triangulation\n"); puts("Input: 1) standard: degrees and weights `d1 w11 w12 ... d2 w21 w22 ...'"); puts(" 2) alternative (use -D): `d np' or `np d' (d=Dimension, np=#[points])"); puts(" and (after newline) np*d coordinates"); puts("Output: as specified by options"); } int main (int narg, char* fn[]){ int n=0, i, k; /* flags */ MORI_Flags Flag; Flag.FilterFlag = 0; // filter Flag.g = 0; // -g: general output Flag.m = 0; // -m: Mori cone Flag.P = 0; // -P: IP simplices Flag.K = 0; // -K: Newton polynomial Flag.i = 0; // -i: intersection ring Flag.t = 0; // -t: triple intersection number Flag.c = 0; // -c: Chern classes Flag.d = 0; // -d; del Pezzo Flag.a = 0; // -a: all of the above except h,f and K Flag.b = 0; // -b: Hodge number of toric div Flag.D = 0; // -D: dual poly as input Flag.H = 0; // -H: arbitrary hypersurface Flag.I = 0; // -I: incidence information Flag.M = 0; // -M: allows to insert a triangulation Flag.Read_HyperSurfCounter = 0; // see Mori.h for description char c; CWS *CW=(CWS *) malloc(sizeof(CWS)); VertexNumList V; EqList *E = (EqList *) malloc(sizeof(EqList)); EqList *DE = (EqList *) malloc(sizeof(EqList)); PolyPointList *_P = (PolyPointList *) malloc(sizeof(PolyPointList)), *_DP = (PolyPointList *) malloc(sizeof(PolyPointList)); PairMat *PM = (PairMat *) malloc(sizeof(PairMat)), *DPM = (PairMat *) malloc(sizeof(PairMat)); if((CW==NULL)||(E==NULL)||(_P==NULL)||(DE==NULL)||(_DP==NULL)||(PM==NULL)||(DPM==NULL)){ puts("Allocation failure: Reduce dimensions!"); exit(0); } CW->nw=0; while(narg > ++n) { if(fn[n][0]!='-') break; k=0; while ((c=fn[n][++k])!='\0'){ if(c=='h') { PrintUsage(fn[0]); exit(0);} if(c=='f') Flag.FilterFlag=1; if(c=='g') Flag.g=1; if(c=='m') Flag.m=1; if(c=='P') Flag.P=1; if(c=='K') Flag.K=1; if(c=='i') Flag.i=1; if(c=='t') Flag.t=1; if(c=='c') Flag.c=1; if(c=='d') Flag.d=1; if(c=='a') Flag.a=1; if(c=='b') Flag.b=1; if(c=='D') Flag.D=1; if(c=='H') Flag.H=1; if(c=='I') Flag.I=1; if(c=='M') Flag.M=1; } } n--; /*if ((Flag.M)&&(!Flag.D)){ puts("-M works only when combined with -D!"); exit(0);}*/ if(Flag.g + Flag.m + Flag.P + Flag.K + Flag.i + Flag.t + Flag.c + Flag.d + Flag.a + Flag.b + Flag.H + Flag.I ==0) Flag.g=1; if(Flag.a){ Flag.g=1; Flag.m=1; Flag.P=1; //Flag.K=1; Flag.i=1; Flag.t=1; Flag.c=1; Flag.d=1; Flag.b=1; } if(Flag.H==1 && (Flag.g + Flag.m + Flag.P + Flag.K + Flag.i + Flag.t + Flag.c + Flag.d + Flag.a + Flag.b + Flag.I ==0 )){ Flag.b=1; //Flag.g=1; } if(Flag.FilterFlag) {inFILE=NULL; outFILE=stdout;} else { if (narg > ++n) inFILE=fopen(fn[n],"r"); else inFILE=stdin; if (inFILE==NULL){printf("Input file %s not found!\n",fn[n]);exit(0);} if (narg > ++n) outFILE=fopen(fn[n],"w"); else outFILE=stdout; } while((Flag.D ? Read_PP(_P) : Read_CWS(CW,_P))) { if (!Ref_Check(_P,&V,E)){ fprintf(outFILE,"Input not reflexive!\n"); continue; } if (Flag.D == 0){ /* dualize: _P should become the N-polytope! */ assert(EL_to_PPL(E, _P, &_P->n)); assert(Ref_Check(_P,&V,E));} Sort_VL(&V); if (!(Flag.D&&Flag.M)){ Make_VEPM(_P,&V,E,*PM); Complete_Poly(*PM,E,V.nv,_P); for (i=V.nv; i<_P->np-1; i++) if(Vec_is_zero(_P->x[i],_P->n)) { Swap_Vecs(_P->x[i],_P->x[_P->np-1],_P->n); break; } } else { for (i=0; i<_P->np; i++) if(Vec_is_zero(_P->x[i],_P->n)) { Swap_Vecs(_P->x[i],_P->x[_P->np-1],_P->n); break; } if (i==_P->np){ for (k=0;k<_P->n;k++) _P->x[_P->np][k]=0; _P->np++; } } if(Flag.M){ if (POLY_Dmax < (_P->np - _P->n)){ printf("Please increase POLY_Dmax to at least %d = %d - %d - 1\n", (_P->np - _P->n -1), _P->np, _P->n); printf("(%s -M requires POLY_Dmax >= #(points) - dim N -1)\n", fn[0]); exit(0); } } HyperSurfDivisorsQ(_P,&V,E,&Flag); fflush(outFILE); } return 0; } palp-2.21/tests/0000775000177600017760000000000014572603263013110 5ustar skarkeskarkepalp-2.21/tests/3.2.24-poly-Z.sh0000775000177600017760000000104614572603263015366 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 3.2.24 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 17-18 COMMAND="./poly-${DIM}d.x -VZD tests/input/3.2.24-poly-Z.txt" DESCRIPTION="poly-${DIM}d.x -Z example on pages 17-18" EXPECTED=$(cat<<-EOF 3 5 vertices of P-dual and IP-simplices -1 -1 2 0 0 -1 2 -1 0 0 0 0 0 1 -1 ------------------------- #IP-simp=2 I=3 /Z3: 2 1 0 0 0 1 1 1 0 0 3=d codim=1 /Z3: 2 1 0 0 0 0 0 0 1 1 2=d codim=2 EOF ) run_test palp-2.21/tests/6.4.7-nef-p.sh0000775000177600017760000000144014572603263015125 0ustar skarkeskarke#!/bin/sh # # Test the nef -p examples in Section 6.4.7 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 38 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '8 1 1 1 1 1 1 1 1' | ./nef-${DIM}d.x -f -c4 -p | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -c4 -p example on page 38" EXPECTED=$(cat<<-EOF 8 1 1 1 1 1 1 1 1 M:6435 8 N:9 8 codim=4 #part=5 P:0 V0:2 3 V1:4 5 V2:6 7 np=1 d:0 p:4 EOF ) if [ $DIM -lt 10 ]; then EXPECTED="Please increase POLY_Dmax to at least 10 = 7 + 4 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" else if [ -z "${LONG}" ]; then # This test takes forever to run SKIP=true SKIPREASON="long-running test requires make checklong" fi fi run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/6.4.9-nef-P.sh0000775000177600017760000000072314572603263015072 0ustar skarkeskarke#!/bin/sh # # Test the nef -P examples in Section 6.4.9 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 39 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -P | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -P example on page 39" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 H:[0] P:0 V:2 3 H:[0] P:1 V:3 np=1 d:0 p:1 EOF ) run_test palp-2.21/tests/2.2-error-handling.sh0000775000177600017760000000150414572603263016661 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 2.2 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 6, only makes sense for POLY_Dmax < 7. if [ $DIM -ge 7 ]; then SKIP=true SKIPREASON="POLY_Dmax too large" fi COMMAND="echo '8 1 1 1 1 1 1 1 1' | ./poly-${DIM}d.x -f" DESCRIPTION="poly-${DIM}d.x POLY_Dmax example on page 6" EXPECTED="Please increase POLY_Dmax to at least 7" run_test "${SKIP}" "${SKIPREASON}" # Page 8, nef will fail and complain about POLY_Dmax for all # current values of DIM. We can't "fix" this example because # we would need to change VERT_Nmax as well. COMMAND="echo '7 9' | ./nef-${DIM}d.x -f -Lp -N -c6 -P" DESCRIPTION="nef-${DIM}d.x example on page 8" EXPECTED=$(cat<<-EOF Please increase POLY_Dmax to at least 12 = 7 + 6 - 1 (POLY_Dmax >= dim N + codim - 1 is required) EOF ) run_test palp-2.21/tests/6.4.20-nef-R.sh0000775000177600017760000000066214572603263015147 0ustar skarkeskarke#!/bin/sh # # Test the nef -R example in Section 6.4.20 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 49 INPUT="6 3 2 1 0 0 5 0 0 1 1 3" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -R" DESCRIPTION="nef-${DIM}d.x -R example on page 49" EXPECTED=$(cat<<-EOF 3 7 Vertices of input polytope: -1 1 0 0 1 0 -1 0 1 -1 1 4 4 1 -1 0 0 0 -1 -1 -1 EOF ) run_test palp-2.21/tests/7.2.10-mori-c.sh0000775000177600017760000000130614572603263015360 0ustar skarkeskarke#!/bin/sh # # Test the mori -c example in Section 7.2.10 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 62 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fc" DESCRIPTION="mori-${DIM}d.x -fc example on page 62" EXPECTED=$(cat<<-EOF SINGULAR -> divisor classes (integral basis J1 ... J2): d1=J1+3*J2, d2=J1, d3=-J1+J2, d4=J2, d5=J1, d6=J2 SINGULAR -> Chern classes of the CY-hypersurface: c1(CY)= 0 c2(CY)= 10*J1*J2+12*J2^2 c3(CY)= -252 *[pt] SINGULAR -> divisor classes (integral basis J1 ... J2): d1=J1+3*J2, d2=J1, d3=-J1+J2, d4=J2, d5=J1, d6=J2 SINGULAR -> Chern classes of the CY-hypersurface: c1(CY)= 0 c2(CY)= 10*J1*J2+12*J2^2 c3(CY)= -252 *[pt] EOF ) run_test palp-2.21/tests/6.4.11-nef-c.sh0000775000177600017760000000210114572603263015156 0ustar skarkeskarke#!/bin/sh # # Test the nef -c examples in Section 6.4.11 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 40 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '3 1 1 1 0 0 0 3 0 0 0 1 1 1' | ./nef-${DIM}d.x -f -c3 | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -c3 example on page 40" EXPECTED=$(cat<<-EOF 3 1 1 1 0 0 0 3 0 0 0 1 1 1 M:100 9 N:7 6 codim=3 #part=7 H:[0] P:0 V0:1 3 V1:4 5 H:[0] P:1 V0:2 3 V1:4 5 np=1 d:1 p:5 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 4 + 3 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test COMMAND="echo '5 1 1 1 1 1' | ./nef-${DIM}d.x -f -c1 | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -c1 example on page 40" EXPECTED=$(cat<<-EOF 5 1 1 1 1 1 M:126 5 N:6 5 codim=1 #part=1 H:1 101 [-200] P:0 np=1 d:0 p:0 EOF ) run_test COMMAND="echo '5 1 1 1 1 1' | ./poly-${DIM}d.x -f" DESCRIPTION="poly-${DIM}d.x example on page 40" EXPECTED=$(cat<<-EOF 5 1 1 1 1 1 M:126 5 N:6 5 H:1,101 [-200] EOF ) run_test palp-2.21/tests/7.2.5-mori-m.sh0000775000177600017760000000216314572603263015320 0ustar skarkeskarke#!/bin/sh # # Test the mori -m examples in Section 7.2.5 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 59 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fm" DESCRIPTION="mori-${DIM}d.x -fm example on page 59" EXPECTED=$(cat<<-EOF 2 MORI GENERATORS / dim(cone)=2 3 0 1 1 0 1 I:10 0 3 -4 -1 3 -1 I:01 2 MORI GENERATORS / dim(cone)=2 1 1 -1 0 1 0 I:10 0 -3 4 1 -3 1 I:01 EOF ) if [ $DIM -lt 6 ]; then # The incidence numbers 01/10 flip for some reason? EXPECTED=$(cat<<-EOF 2 MORI GENERATORS / dim(cone)=2 3 0 1 1 0 1 I:01 0 3 -4 -1 3 -1 I:10 2 MORI GENERATORS / dim(cone)=2 1 1 -1 0 1 0 I:01 0 -3 4 1 -3 1 I:10 EOF ) fi run_test INPUT="3 1 1 1 0 0 0 0 2 0 0 0 1 1 0 0 2 0 0 0 0 0 1 1" COMMAND="echo '${INPUT}' | ./mori-${DIM}d.x -fm" DESCRIPTION="mori-${DIM}d.x -m example on page 59" EXPECTED=$(cat<<-EOF 3 MORI GENERATORS / dim(cone)=3 0 0 0 0 0 0 0 I:110 1 1 0 0 0 0 1 I:101 0 0 1 0 0 1 0 I:011 EOF ) SKIP=1 SKIPREASON="unknown, pre-existing output deviation" run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/6.4.14-nef-S.sh0000775000177600017760000000133114572603263015145 0ustar skarkeskarke#!/bin/sh # # Test the nef -S example in Section 6.4.14 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 44 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -S | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -S example on page 44" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 #points in largest cone: layer: 1 #p: 6 #ip: 0 layer: 2 #p: 21 #ip: 1 layer: 3 #p: 56 #ip: 6 #points in largest cone: layer: 1 #p: 20 #ip: 0 layer: 2 #p: 105 #ip: 1 layer: 3 #p: 336 #ip: 20 H:[0] P:0 V:2 3 np=1 d:0 p:1 EOF ) run_test palp-2.21/tests/6.4.8-nef-D.sh0000775000177600017760000000132114572603263015050 0ustar skarkeskarke#!/bin/sh # # Test the nef -D examples in Section 6.4.8 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 38 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="3 1 1 1 0 0 0 3 0 0 0 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -D | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -D example on page 38" EXPECTED=$(cat<<-EOF 3 1 1 1 0 0 0 3 0 0 0 1 1 1 M:100 9 N:7 6 codim=2 #part=5 H:4 [0] h1=2 P:0 V:2 3 5 D H:20 [24] P:1 V:3 4 5 H:20 [24] P:2 V:3 5 H:20 [24] P:3 V:4 5 np=3 d:1 p:1 EOF ) if [ $DIM -lt 5 ]; then EXPECTED="Please increase POLY_Dmax to at least 5 = 4 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/6.4.22-nef-Q.sh0000775000177600017760000000164714572603263015154 0ustar skarkeskarke#!/bin/sh # # Test the nef -Q examples in Section 6.4.22 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 50 # The "sed" command strips the unpredictable timing information INPUT="3 1 1 1 0 0 0 3 0 0 0 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -Q | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Q first example on page 50" EXPECTED=$(cat<<-EOF 3 1 1 1 0 0 0 3 0 0 0 1 1 1 M:100 9 N:7 6 codim=2 #part=5 H:4 [0] h1=2 P:0 V:2 3 5 D np=4 d:1 p:0 EOF ) if [ $DIM -lt 5 ]; then EXPECTED="Please increase POLY_Dmax to at least 5 = 4 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test # Page 50 # The "sed" command strips the unpredictable timing information COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -Q | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Q second example on page 50" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 np=2 d:0 p:0 EOF ) run_test palp-2.21/tests/6.3-nef-N-output.sh0000775000177600017760000000154214572603263016256 0ustar skarkeskarke#!/bin/sh # # Test the nef -N example in Section 6.3 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 33 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="./nef-${DIM}d.x -N tests/input/6.3-nef-N-output.txt | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -N output example on page 33" EXPECTED=$(cat<<-EOF M:300 18 N:9 8 codim=2 #part=15 H:3 51 [-96] P:0 V:2 3 4 7 H:3 51 [-96] P:1 V:2 4 6 7 H:3 60 [-114] P:2 V:2 4 7 H:3 51 [-96] P:3 V:2 6 7 H:3 69 [-132] P:4 V:2 7 H:9 27 [-36] P:5 V:3 4 6 7 H:3 75 [-144] P:6 V:3 4 7 H:19 19 [0] P:8 V:4 5 6 7 H:6 51 [-90] P:9 V:4 6 7 H:3 75 [-144] P:10 V:4 7 H:3 75 [-144] P:13 V:6 7 np=11 d:2 p:2 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/4.2.1-cws-w.sh0000775000177600017760000000043714572603263015153 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 4.2.1 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 22 COMMAND="./cws-${DIM}d.x -w2" DESCRIPTION="cws-${DIM}d.x -w2 example on page 22" EXPECTED=$(cat<<-EOF 3 1 1 1 rt 4 1 1 2 rt 6 1 2 3 rt #=3 #cand=3 EOF ) run_test palp-2.21/tests/3.2.11-poly-l.sh0000775000177600017760000000145414572603263015407 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 3.2.11 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 14 COMMAND="echo '5 1 1 1 1 1' | ./poly-${DIM}d.x -fl" DESCRIPTION="poly-${DIM}d.x -l first example on page 14" EXPECTED="5 1 1 1 1 1 M:126 5 N:6 5 V:1,101 [-200]" run_test COMMAND="echo '3 1 1 1 1 1 1' | ./poly-${DIM}d.x -fl" DESCRIPTION="poly-${DIM}d.x -l second example on page 14" EXPECTED="3 1 1 1 1 1 1 M:56 6 F:6 LG: H0:1,0,1 H1:0,20 H2:1 RefI2" [ $DIM -lt 5 ] && EXPECTED="Increase POLY_Dmax" run_test COMMAND="echo '3 1 1 1 1 1 1 /Z3: 0 1 2 0 1 2 3 1 1 1 1 1 1' | ./poly-${DIM}d.x -fl" DESCRIPTION="poly-${DIM}d.x -l third example on page 14" EXPECTED="3 1 1 1 1 1 1 /Z3: 0 1 2 0 1 2 M:20 6 F:6 LG: H0:1,0,1 H1:0,20 H2:1 RefI2" [ $DIM -lt 5 ] && EXPECTED="Increase POLY_Dmax" run_test palp-2.21/tests/6.3-nef-output.sh0000775000177600017760000000170414572603263016063 0ustar skarkeskarke#!/bin/sh # # Test the nef example in Section 6.3 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 32 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="3 1 1 1 0 0 0 0 0 2 0 0 0 1 1 0 0 0 3 0 0 0 0 0 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x output example on page 32" EXPECTED=$(cat<<-EOF 3 1 1 1 0 0 0 0 0 2 0 0 0 1 1 0 0 0 3 0 0 0 0 0 1 1 1 M:300 18 N:9 8 codim=2 #part=15 H:19 19 [0] P:0 V:2 4 6 7 H:9 27 [-36] P:2 V:3 4 6 7 H:3 51 [-96] P:3 V:3 5 6 7 H:3 75 [-144] P:4 V:3 6 7 H:3 51 [-96] P:6 V:4 5 6 7 H:3 51 [-96] P:7 V:4 5 6 H:6 51 [-90] P:8 V:4 6 7 H:3 75 [-144] P:9 V:4 6 H:3 60 [-114] P:10 V:5 6 7 H:3 69 [-132] P:11 V:5 6 H:3 75 [-144] P:12 V:6 7 np=11 d:2 p:2 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/6.4.21-nef-V.sh0000775000177600017760000000100114572603263015140 0ustar skarkeskarke#!/bin/sh # # Test the nef -V example in Section 6.4.21 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 49-50 # The "sed" command strips the unpredictable timing information COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -V | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -V example on pages 49-50" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 3 4 Vertices of P: -1 0 0 1 -1 0 1 0 -1 1 0 0 H:[0] P:0 V:2 3 np=1 d:0 p:1 EOF ) run_test palp-2.21/tests/6.4.24-nef-d.sh0000775000177600017760000007351314572603263015202 0ustar skarkeskarke#!/bin/sh # # Test the nef -d example in Section 6.4.24 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 52 COMMAND="./nef-${DIM}d.x -N -d2 tests/input/6.4.24-nef-d.txt" DESCRIPTION="nef-${DIM}d.x -N -d2 example on page 52" EXPECTED=$(cat<<-EOF M:300 18 N:9 8 codim=2 #part=15 7 63 Points of dual PG: (nv=27) 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 -1 0 1 1 0 -1 -1 -1 0 0 0 1 1 1 1 1 1 0 0 0 -1 0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 -1 1 -1 0 1 1 1 -1 1 1 0 0 0 -1 -1 0 0 1 1 0 -1 0 0 0 0 1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 1 1 1 0 -1 1 -1 -1 -1 0 0 0 1 -1 -1 1 0 0 0 0 0 0 0 0 1 0 1 -1 0 0 0 1 1 1 -1 -1 0 0 1 1 -1 -1 -1 0 1 1 -1 -1 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 0 1 -1 -1 1 0 0 1 0 1 -1 1 0 1 0 0 1 1 0 1 0 -1 0 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 1 0 0 1 1 -1 0 0 0 0 0 0 1 -1 -1 0 0 0 -1 -1 0 -1 0 0 -1 1 1 1 1 -1 -1 1 0 0 1 0 0 -1 -1 0 0 0 0 1 -1 0 0 0 0 1 1 -1 0 1 -1 0 -1 -1 0 1 -1 1 -1 0 0 1 0 -1 0 0 -1 0 0 0 1 0 0 0 -1 -1 0 1 0 -1 -1 0 0 7 72 Points of dual PG: (nv=36) 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 1 -1 0 0 0 -1 0 1 1 1 1 1 1 1 -1 -1 0 0 0 0 0 -1 -1 -1 -1 -1 0 1 -1 -1 -1 1 1 1 -1 0 0 -1 0 0 -1 0 1 0 1 1 0 -1 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 1 0 1 1 -1 0 0 0 0 1 0 1 1 1 1 -1 0 -1 -1 0 0 0 0 0 1 1 1 1 0 0 0 -1 -1 -1 -1 -1 0 -1 1 1 1 -1 -1 -1 0 1 1 0 1 -1 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 1 0 1 1 -1 -1 0 -1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 -1 -1 0 0 0 1 1 -1 -1 0 0 0 1 1 -1 0 0 -1 -1 0 0 -1 0 0 -1 0 0 -1 0 0 0 0 0 0 0 0 -1 0 0 -1 -1 0 0 1 -1 1 1 0 -1 1 0 1 1 -1 0 1 -1 1 1 -1 0 0 0 0 0 0 -1 0 2 0 -1 0 0 -1 2 0 0 2 0 0 -1 2 0 0 2 0 -1 0 -1 0 -1 2 -1 -1 0 -1 -1 0 -1 0 1 1 -1 0 -1 -1 -1 0 -1 1 1 0 -1 -1 0 0 -1 1 1 1 -1 0 0 1 1 -1 -1 0 0 1 1 -1 1 0 0 -1 1 1 1 1 -1 -1 1 1 0 0 -1 -1 1 -1 -1 0 0 -1 -1 1 -1 -1 1 0 0 0 0 -1 1 1 0 0 1 0 0 0 -1 0 0 0 0 1 1 0 1 -1 0 0 1 0 0 0 0 -1 0 0 1 0 0 -1 0 0 1 0 0 -1 0 0 -1 0 0 7 90 Points of dual PG: (nv=35) 1 0 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 1 1 -1 -1 -1 0 0 0 1 1 1 -1 1 -1 -1 0 -1 0 -1 0 -1 1 0 1 0 1 1 -1 -1 0 0 0 1 1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 -1 0 0 1 -1 1 1 0 1 0 0 -1 -1 -1 -1 0 -1 -1 -1 1 -1 0 0 -1 -1 0 -1 0 -1 1 -1 0 -1 1 1 1 0 0 0 -1 -1 1 -1 -1 -1 0 -1 1 1 1 1 0 0 0 0 -1 -1 -1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 -1 0 -1 0 -1 -1 1 -1 -1 -1 -1 -1 -1 0 0 -1 -1 -1 -1 0 -1 -1 1 0 -1 -1 0 0 0 0 -1 1 0 1 0 0 0 0 1 1 0 0 0 -1 -1 0 0 0 -1 0 -1 0 -1 0 0 0 0 -1 -1 -1 0 1 1 1 1 1 0 0 0 0 0 0 -1 0 -1 0 0 -1 0 0 0 0 0 0 0 0 0 0 -1 0 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 0 -1 -1 -1 0 -1 0 -1 0 -1 1 -1 0 1 0 0 1 -1 -1 -1 1 -1 0 -1 1 1 0 -1 1 1 0 0 1 -1 1 -1 0 1 0 1 0 -1 -1 -1 0 0 1 1 -1 -1 0 0 0 -1 -1 -1 0 0 1 -1 -1 -1 0 -1 1 0 -1 0 0 0 -1 -1 0 0 -1 0 -1 1 0 -1 -1 0 -1 -1 0 0 -1 0 -1 0 0 -1 0 1 0 -1 1 1 1 1 -1 -1 1 0 0 1 -1 -1 1 1 -1 -1 1 1 0 -1 0 -1 0 0 0 0 -1 -1 -1 1 1 0 0 0 0 -1 0 1 -1 0 -1 -1 0 0 -1 0 0 -1 0 1 -1 0 -1 -1 0 1 -1 1 -1 -1 0 0 0 -1 0 0 -1 0 1 0 0 -1 -1 1 0 -1 -1 0 0 -1 0 -1 -1 0 0 -1 -1 -1 0 7 72 Points of dual PG: (nv=27) 0 0 0 1 1 0 0 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 0 1 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 -1 -1 0 0 -1 -1 0 1 1 1 1 1 1 -1 -1 -1 -1 0 -1 -1 -1 -1 1 1 0 0 -1 0 0 0 -1 0 0 -1 0 0 0 1 1 1 -1 1 -1 1 1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 -1 -1 0 -1 -1 -1 -1 0 0 1 1 1 1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 -1 1 0 1 1 -1 -1 -1 -1 -1 0 0 0 0 0 1 -1 1 0 0 0 0 -1 1 -1 -1 -1 -1 -1 0 0 0 -1 -1 0 0 0 0 0 0 0 1 -1 0 0 1 -1 0 1 1 -1 -1 0 0 1 1 -1 -1 0 1 1 -1 -1 1 -1 0 0 0 -1 0 0 0 -1 0 -1 0 0 -1 0 0 0 0 0 0 0 0 -1 0 -1 0 -1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 -1 -1 0 0 0 0 0 -1 -1 2 0 -1 -1 0 0 -1 0 -1 2 0 0 -1 0 -1 2 0 -1 0 -1 -1 -1 -1 -1 -1 -1 1 1 0 -1 0 0 1 1 -1 -1 -1 0 -1 0 -1 1 1 -1 -1 0 -1 -1 -1 -1 0 0 0 -1 -1 -1 -1 0 -1 -1 0 0 -1 0 -1 0 0 -1 1 1 1 1 -1 -1 1 1 1 0 0 0 0 -1 -1 0 0 0 0 -1 0 0 0 0 1 1 0 1 1 1 -1 0 0 1 0 0 -1 0 0 0 1 0 0 0 0 -1 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 7 117 Points of dual PG: (nv=26) 1 0 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 1 1 -1 -1 -1 -1 0 0 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 0 0 0 1 1 0 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 1 1 1 1 1 1 1 -1 1 -1 -1 0 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 -1 0 -1 0 -1 1 -1 0 -1 1 1 1 0 0 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 0 1 1 0 0 0 0 0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 0 1 0 1 1 1 -1 0 0 -1 -1 -1 1 1 -1 -1 -1 1 1 -1 1 0 0 0 0 0 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 -1 -1 -1 0 0 0 0 0 0 -1 -1 -1 -1 1 -1 1 1 -1 -1 1 1 1 1 1 1 -1 1 -1 1 1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 -1 1 1 -1 -1 -1 -1 0 -1 0 -1 0 -1 1 -1 -1 1 0 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 0 1 0 1 0 -1 1 -1 0 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 -1 1 0 1 0 -1 -1 -1 -1 0 0 1 0 -1 0 0 -1 -1 0 0 -1 -1 -1 -1 -1 0 0 1 0 -1 1 0 0 0 -1 0 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 0 -1 -1 0 0 0 -1 -1 0 0 -1 1 1 1 1 -1 -1 1 0 0 1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 1 1 0 0 0 0 -1 -1 0 0 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 0 -1 -1 0 -1 0 1 -1 0 -1 0 0 -1 -1 0 0 -1 0 1 1 -1 0 1 -1 0 -1 0 0 -1 -1 0 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 0 0 1 -1 0 -1 -1 -1 0 0 7 48 Points of dual PG: (nv=15) 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 0 0 -1 2 -1 0 0 0 0 -1 -1 2 2 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 -1 0 -1 0 0 0 0 0 -1 0 0 0 0 2 -1 -1 0 0 0 0 2 2 -1 -1 -1 -1 0 1 0 -1 -1 -1 0 0 0 0 0 0 0 1 1 1 -1 -1 -1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 -1 1 0 0 0 1 -1 1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 1 -1 1 1 0 0 0 0 0 -1 -1 -1 2 0 0 2 0 -1 0 -1 0 -1 -1 0 -1 -1 -1 0 -1 -1 0 0 1 1 2 -1 -1 0 -1 -1 0 -1 -1 0 -1 1 0 1 0 0 1 1 -1 0 0 -1 1 1 1 1 -1 1 -1 -1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 -1 1 -1 0 -1 0 1 0 0 1 0 0 1 0 0 -1 0 0 0 0 -1 0 1 0 0 7 69 Points of dual PG: (nv=15) 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 2 -1 0 -1 -1 -1 2 2 -1 0 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 -1 2 -1 2 2 -1 -1 -1 -1 0 0 -1 0 -1 2 0 2 -1 2 -1 -1 -1 0 0 0 0 1 1 1 1 1 1 -1 2 0 2 2 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 -1 0 -1 -1 0 0 -1 0 0 0 0 1 0 0 -1 0 0 0 0 0 0 1 1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 -1 0 1 -1 -1 1 -1 1 1 0 1 0 -1 -1 -1 0 0 1 0 -1 1 0 0 0 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 0 0 0 -1 0 -1 -1 0 0 -1 1 1 1 1 -1 1 -1 -1 -1 -1 0 0 0 0 -1 0 1 -1 0 -1 0 0 -1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 1 -1 0 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 0 -1 0 0 -1 0 1 0 0 7 40 Points of dual PG: (nv=12) 0 0 1 1 1 0 0 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 0 1 1 1 1 1 1 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 1 1 1 1 1 0 1 0 0 0 -1 2 -1 0 0 0 -1 2 -1 0 -1 1 0 -1 0 0 1 0 0 0 0 -1 0 1 1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 -1 -1 0 0 0 2 -1 -1 0 1 0 -1 1 0 0 -1 0 0 0 0 0 1 -1 0 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 -1 -1 -1 0 0 -1 0 -1 0 0 -1 0 0 0 0 0 0 0 0 -1 -1 1 1 -1 1 1 1 1 1 -1 0 0 -1 -1 0 0 0 2 -1 -1 0 0 0 2 0 0 0 0 -1 -1 0 0 0 1 1 0 0 0 0 0 0 -1 -1 0 0 0 0 1 1 0 0 0 -1 2 0 0 0 -1 -1 2 0 0 0 -1 0 0 0 0 0 1 0 -1 1 -1 0 0 0 0 0 0 0 0 1 0 -1 0 1 -1 0 0 0 0 7 72 Points of dual PG: (nv=24) 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 -1 2 -1 0 0 0 -1 -1 -1 2 2 2 -1 -1 -1 0 -1 2 -1 -1 2 -1 0 -1 0 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 1 0 0 0 0 0 -1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 1 1 -1 1 -1 0 -1 0 0 0 0 0 0 0 0 2 -1 -1 0 0 0 2 2 2 -1 -1 -1 -1 -1 -1 0 2 -1 -1 2 -1 -1 0 0 0 1 -1 -1 0 0 0 1 1 1 -1 1 0 -1 -1 -1 0 0 1 -1 0 0 -1 1 1 1 -1 -1 -1 0 0 0 0 -1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 0 1 -1 -1 0 -1 -1 0 -1 -1 0 0 -1 -1 -1 0 0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 -1 -1 -1 0 0 0 0 0 -1 -1 0 0 -1 0 0 0 0 0 0 0 0 0 -1 -1 -1 -1 -1 -1 1 -1 1 1 -1 -1 0 0 0 0 -1 -1 -1 2 0 0 0 -1 -1 0 -1 -1 0 -1 -1 2 -1 -1 -1 0 0 0 -1 -1 -1 0 -1 0 -1 -1 0 -1 -1 0 0 0 -1 -1 -1 0 -1 -1 -1 -1 1 1 -1 -1 -1 0 -1 -1 0 -1 -1 0 0 -1 0 -1 -1 0 0 -1 1 1 -1 -1 0 0 -1 1 1 1 1 -1 1 -1 0 1 0 0 1 0 0 1 0 -1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 0 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 -1 0 0 1 0 0 7 126 Points of dual PG: (nv=23) 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 2 -1 -1 -1 -1 0 2 2 -1 -1 0 0 -1 2 -1 0 -1 0 -1 2 2 -1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 -1 2 -1 -1 2 2 0 0 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 -1 2 0 2 2 -1 -1 -1 -1 -1 -1 0 -1 -1 0 0 0 -1 0 -1 2 -1 2 2 0 -1 -1 -1 -1 0 0 2 -1 -1 0 2 0 2 -1 -1 -1 0 0 0 0 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 -1 0 0 -1 -1 -1 0 -1 -1 1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 1 2 1 2 2 1 -1 -1 -1 -1 -1 -1 0 0 0 0 1 0 -1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 2 -1 0 -1 -1 1 0 0 -1 -1 2 -1 2 0 -1 -1 0 -1 1 0 0 0 0 0 0 0 0 0 0 1 1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 0 -1 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 1 -1 0 1 -1 1 -1 1 0 -1 -1 -1 1 1 0 -1 1 -1 1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 1 -1 0 -1 0 0 1 -1 0 -1 -1 0 0 -1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 0 -1 -1 0 0 -1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 -1 -1 -1 0 0 1 0 -1 -1 0 0 0 0 -1 -1 0 0 -1 1 1 1 1 -1 -1 1 -1 -1 -1 -1 0 0 1 1 1 0 -1 0 -1 -1 -1 -1 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 0 0 -1 0 -1 0 0 0 0 -1 0 1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 -1 -1 0 1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 0 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 -1 0 1 -1 0 -1 0 0 -1 -1 0 -1 -1 1 0 -1 0 0 -1 -1 -1 -1 0 7 96 Points of dual PG: (nv=21) 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 -1 2 -1 0 -1 2 -1 -1 -1 2 2 -1 -1 -1 2 -1 -1 2 -1 1 1 1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 -1 -1 0 0 1 0 0 0 1 1 1 1 1 1 2 2 2 1 0 0 -1 -1 -1 -1 -1 -1 -1 0 -1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 2 -1 2 0 -1 -1 -1 2 2 -1 -1 2 2 -1 -1 -1 -1 -1 -1 0 0 -1 0 0 1 -1 -1 -1 0 0 0 1 1 1 2 2 2 -1 -1 -1 0 0 1 1 0 0 -1 1 1 1 -1 -1 -1 0 0 0 -1 -1 -1 -1 0 1 0 0 0 0 1 1 1 -1 1 0 -1 -1 -1 -1 0 0 0 1 1 1 -1 -1 -1 0 0 0 0 1 -1 0 0 0 0 0 1 1 -1 0 1 -1 -1 1 1 1 1 -1 -1 1 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 -1 -1 1 1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 0 0 0 0 -1 -1 -1 2 -1 -1 -1 0 -1 0 -1 0 -1 0 0 0 -1 -1 -1 -1 0 0 0 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 -1 -1 1 1 -1 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 0 -1 -1 -1 -1 0 -1 -1 0 0 0 -1 -1 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 -1 -1 0 0 -1 1 1 1 1 -1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 -1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test # Pages 53-54 # The "sed" command strips the unpredictable timing information COMMAND="./nef-${DIM}d.x -N -Lv tests/input/6.4.24-nef-N-Lv.txt | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -N -Lv example on pages 53-54" EXPECTED=$(cat<<-EOF M:24 15 N:39 12 codim=2 #part=2 5 12 Vertices in N-lattice: 0 0 -1 2 -1 0 0 0 -1 2 -1 0 0 0 2 -1 -1 0 0 0 2 -1 -1 0 0 1 0 0 0 1 1 0 -1 -1 -1 0 -1 -1 0 0 0 2 -1 -1 0 0 0 2 -1 2 0 0 0 -1 -1 2 0 0 0 -1 ------------------------------------------------------------ 1 1 2 2 0 1 0 0 0 0 2 0 d=9 codim=0 1 1 1 1 0 0 0 0 0 0 1 1 d=6 codim=0 1 1 2 0 2 1 0 0 0 2 0 0 d=9 codim=0 1 1 1 0 1 0 0 0 0 1 0 1 d=6 codim=0 1 1 1 0 0 1 0 0 0 1 1 0 d=6 codim=0 2 2 1 0 0 0 0 0 0 1 1 2 d=9 codim=0 1 1 0 2 2 1 0 0 2 0 0 0 d=9 codim=0 1 1 0 1 1 0 0 0 1 0 0 1 d=6 codim=0 1 1 0 1 0 1 0 0 1 0 1 0 d=6 codim=0 2 2 0 1 0 0 0 0 1 0 1 2 d=9 codim=0 1 1 0 0 1 1 0 0 1 1 0 0 d=6 codim=0 2 2 0 0 1 0 0 0 1 1 0 2 d=9 codim=0 3 3 0 0 0 3 0 0 2 2 2 0 d=15 codim=0 3 3 0 0 0 0 0 0 1 1 1 3 d=12 codim=0 1 0 1 1 0 1 0 1 0 0 1 0 d=6 codim=0 1 0 1 0 1 1 0 1 0 1 0 0 d=6 codim=0 2 0 1 0 0 2 0 2 0 1 1 0 d=9 codim=0 1 0 0 1 1 1 0 1 1 0 0 0 d=6 codim=0 2 0 0 1 0 2 0 2 1 0 1 0 d=9 codim=0 2 0 0 0 1 2 0 2 1 1 0 0 d=9 codim=0 3 0 0 0 0 3 0 3 1 1 1 0 d=12 codim=0 1 0 0 0 0 0 0 1 0 0 0 1 d=3 codim=3 0 1 3 3 0 1 1 0 0 0 3 0 d=12 codim=0 0 1 2 2 0 0 1 0 0 0 2 1 d=9 codim=0 0 1 3 0 3 1 1 0 0 3 0 0 d=12 codim=0 0 1 2 0 2 0 1 0 0 2 0 1 d=9 codim=0 0 2 3 0 0 2 2 0 0 3 3 0 d=15 codim=0 0 1 1 0 0 0 1 0 0 1 1 1 d=6 codim=0 0 1 0 3 3 1 1 0 3 0 0 0 d=12 codim=0 0 1 0 2 2 0 1 0 2 0 0 1 d=9 codim=0 0 2 0 3 0 2 2 0 3 0 3 0 d=15 codim=0 0 1 0 1 0 0 1 0 1 0 1 1 d=6 codim=0 0 2 0 0 3 2 2 0 3 3 0 0 d=15 codim=0 0 1 0 0 1 0 1 0 1 1 0 1 d=6 codim=0 0 1 0 0 0 1 1 0 1 1 1 0 d=6 codim=0 0 3 0 0 0 0 3 0 2 2 2 3 d=15 codim=0 0 0 1 1 1 0 0 0 0 0 0 0 d=3 codim=3 0 0 2 2 0 1 1 1 0 0 2 0 d=9 codim=0 0 0 1 1 0 0 1 1 0 0 1 1 d=6 codim=0 0 0 2 0 2 1 1 1 0 2 0 0 d=9 codim=0 0 0 1 0 1 0 1 1 0 1 0 1 d=6 codim=0 0 0 1 0 0 1 1 1 0 1 1 0 d=6 codim=0 0 0 1 0 0 0 2 2 0 1 1 2 d=9 codim=0 0 0 0 2 2 1 1 1 2 0 0 0 d=9 codim=0 0 0 0 1 1 0 1 1 1 0 0 1 d=6 codim=0 0 0 0 1 0 1 1 1 1 0 1 0 d=6 codim=0 0 0 0 1 0 0 2 2 1 0 1 2 d=9 codim=0 0 0 0 0 1 1 1 1 1 1 0 0 d=6 codim=0 0 0 0 0 1 0 2 2 1 1 0 2 d=9 codim=0 0 0 0 0 0 3 3 3 2 2 2 0 d=15 codim=0 0 0 0 0 0 0 3 3 1 1 1 3 d=12 codim=0 H:19 19 [0] P:0 V:1 2 3 4 5 6 13 15 17 19 21 23 25 26 28 30 32 34 36 (6 3) (3 3) (6 3) (3 3) (3 3) (3 6) (6 3) (3 3) (3 3) (3 6) (3 3) (3 6) (6 9) (3 9) (3 3) (3 3) (3 6) (3 3) (3 6) (3 6) (3 9) (0 3) (9 3) (6 3) (9 3) (6 3) (9 6) (3 3) (9 3) (6 3) (9 6) (3 3) (9 6) (3 3) (3 3) (6 9) (3 0) (6 3) (3 3) (6 3) (3 3) (3 3) (3 6) (6 3) (3 3) (3 3) (3 6) (3 3) (3 6) (6 9) (3 9) H:19 19 [0] P:1 V:2 3 4 8 9 10 16 17 18 19 20 21 24 29 30 31 32 33 34 (6 3) (3 3) (6 3) (3 3) (3 3) (3 6) (6 3) (3 3) (3 3) (3 6) (3 3) (3 6) (6 9) (3 9) (3 3) (3 3) (3 6) (3 3) (3 6) (3 6) (3 9) (0 3) (9 3) (6 3) (9 3) (6 3) (9 6) (3 3) (9 3) (6 3) (9 6) (3 3) (9 6) (3 3) (3 3) (6 9) (3 0) (6 3) (3 3) (6 3) (3 3) (3 3) (3 6) (6 3) (3 3) (3 3) (3 6) (3 3) (3 6) (6 9) (3 9) np=2 d:0 p:0 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/6.4.5-nef-Lv.sh0000775000177600017760000000230314572603263015244 0ustar skarkeskarke#!/bin/sh # # Test the nef -Lv examples in Section 6.4.5 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 37 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="5 1 1 1 1 1 0 0 4 0 0 0 1 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -Lv | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lv example on page 37" EXPECTED=$(cat<<-EOF 5 1 1 1 1 1 0 0 4 0 0 0 1 1 1 1 M:378 12 N:8 7 codim=2 #part=8 5 7 Vertices in N-lattice: 0 -1 0 1 0 0 0 0 -1 1 0 0 0 0 -1 0 0 0 0 0 1 -1 1 0 0 1 0 0 -1 1 0 0 0 1 0 ----------------------------------- 1 1 1 1 0 0 1 d=5 codim=1 1 0 0 0 1 1 1 d=4 codim=2 H:2 64 [-124] P:0 V:0 6 (2 3) (2 2) H:2 64 [-124] P:1 V:0 1 6 (3 2) (2 2) H:2 74 [-144] P:2 V:2 3 5 (2 3) (1 3) H:2 64 [-124] P:3 V:3 5 6 (2 3) (2 2) H:2 86 [-168] P:4 V:3 5 (1 4) (1 3) H:2 74 [-144] P:5 V:3 6 (2 3) (1 3) np=6 d:0 p:2 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/7.2.12-mori-d.sh0000775000177600017760000000126114572603263015363 0ustar skarkeskarke#!/bin/sh # # Test the mori -d example in Section 7.2.12 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 64 COMMAND="echo '5 1 1 1 1 1 0 2 0 0 0 0 1 1' | ./mori-${DIM}d.x -fd" DESCRIPTION="mori-${DIM}d.x -d example on page 64" # Note: on my machine, the output is "wrong" but only up to a # permutation (it looks like divisors two and four are switched). # This might be due to a change in Singular, but in any case, I'm # basically guessint that it shouldn't be fatal. EXPECTED=$(cat<<-EOF SINGULAR -> topological quantities of the toric divisors: Euler characteristics: 46 9 46 46 46 55 Arithmetic genera: 4 1 4 4 4 5 dPs: 1 ; d2(6) nonint: 1 ; d2 EOF ) run_test palp-2.21/tests/4.2.6-cws-N.sh0000775000177600017760000000045614572603263015110 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 4.2.6 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 24 COMMAND="./cws-${DIM}d.x -N tests/input/4.2.6-cws-N.txt" DESCRIPTION="cws-${DIM}d.x -N example on page 22" EXPECTED="5 1 1 1 1 1 /Z5: 4 1 0 0 0 /Z5: 4 0 1 0 0 /Z5: 4 0 0 1 0 " run_test palp-2.21/tests/7.2.4-mori-I.sh0000775000177600017760000000052514572603263015253 0ustar skarkeskarke#!/bin/sh # # Test the mori -I example in Section 7.2.4 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 59 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fI" DESCRIPTION="mori-${DIM}d.x -fI example on page 59" EXPECTED=$(cat<<-EOF Incidence: 110101 111100 011111 101011 101110 100111 111001 EOF ) run_test palp-2.21/tests/2.1-polytope-input.sh0000775000177600017760000000235714572603263016764 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 2.1 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 5: Test both the transposed and non-transposed inputs. for t in "" "-transpose"; do COMMAND="./poly-${DIM}d.x tests/input/2.1-polytope-input${t}.txt" DESCRIPTION="poly-${DIM}d.x example on page 5" [ -n "${t}" ] && DESCRIPTION="${DESCRIPTION} (transposed)" EXPECTED="M:6 3 F:3" run_test done # Page 5/6 COMMAND="echo '5 1 1 1 1 1' | ./poly-${DIM}d.x -fv tests/input/2.1-polytope-input-b.txt" DESCRIPTION="poly-${DIM}d.x -v example on pages 5/6" EXPECTED=$(cat<<-EOF 4 5 Vertices of P -1 4 -1 -1 -1 -1 -1 4 -1 -1 -1 -1 -1 4 -1 -1 -1 -1 -1 4 EOF ) run_test # Page 6 COMMAND="echo '2 1 1 0 0 2 0 0 1 1' | ./poly-${DIM}d.x -fv tests/input/2.1-polytope-input-c.txt" DESCRIPTION="poly-${DIM}d.x -v first example on page 6" EXPECTED=$(cat<<-EOF 2 4 Vertices of P -1 1 -1 1 -1 -1 1 1 EOF ) run_test COMMAND="echo '2 1 1 0 0 2 0 0 1 1 /Z2: 1 0 1 0' | ./poly-${DIM}d.x -fv tests/input/2.1-polytope-input-d.txt" DESCRIPTION="poly-${DIM}d.x -v second example on page 6" EXPECTED=$(cat<<-EOF 2 4 Vertices of P -1 0 0 1 1 -1 1 -1 EOF ) run_test palp-2.21/tests/6.4.4-nef-H.sh0000775000177600017760000000522014572603263015052 0ustar skarkeskarke#!/bin/sh # # Test the nef -H examples in Section 6.4.4 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 35 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '7 1 1 1 1 1 1 1' | ./nef-${DIM}d.x -f -H | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -H example on page 35" EXPECTED=$(cat<<-EOF 7 1 1 1 1 1 1 1 M:1716 7 N:8 7 codim=2 #part=3 h 0 0 h 1 0 h 0 1 h 2 0 h 1 1 h 0 2 h 3 0 h 2 1 h 1 2 h 0 3 h 4 0 h 3 1 h 2 2 h 1 3 h 0 4 h 4 1 h 3 2 h 2 3 h 1 4 h 4 2 h 3 3 h 2 4 h 4 3 h 3 4 h 4 4 1 0 0 0 1 0 0 0 0 0 1 237 996 237 1 0 0 0 0 0 1 0 0 0 1 h 0 0 h 1 0 h 0 1 h 2 0 h 1 1 h 0 2 h 3 0 h 2 1 h 1 2 h 0 3 h 4 0 h 3 1 h 2 2 h 1 3 h 0 4 h 4 1 h 3 2 h 2 3 h 1 4 h 4 2 h 3 3 h 2 4 h 4 3 h 3 4 h 4 4 1 0 0 0 1 0 0 0 0 0 1 356 1472 356 1 0 0 0 0 0 1 0 0 0 1 np=2 d:0 p:1 EOF ) if [ $DIM -lt 7 ]; then EXPECTED="Please increase POLY_Dmax to at least 7 = 6 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" else if [ -z "${LONG}" ]; then # This test takes forever to run SKIP=true SKIPREASON="long-running test requires make checklong" fi fi run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/6.4.23-nef-g.sh0000775000177600017760000001106614572603263015177 0ustar skarkeskarke#!/bin/sh # # Test the nef -g example in Section 6.4.23 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 51 COMMAND="./nef-${DIM}d.x -N -g2 tests/input/6.4.23-nef-g.txt" DESCRIPTION="nef-${DIM}d.x -N -g2 example on page 51" EXPECTED=$(cat<<-EOF M:300 18 N:9 8 codim=2 #part=15 7 10 Points of PG: (nv=8) 1 1 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 0 1 0 1 0 0 0 1 0 0 1 0 1 0 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 0 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 0 1 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 0 0 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 1 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 1 0 1 0 0 0 1 0 0 0 0 1 0 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 7 10 Points of PG: (nv=8) 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/3.2.25-poly-numbers.sh0000775000177600017760000000267214572603263016637 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 3.2.25 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 18. The expected output in the manual is truncated, but the # part that's there should agree. COMMAND="echo '84 1 1 12 28 42' | ./poly-${DIM}d.x -f -12" DESCRIPTION="poly-${DIM}d.x -12 example on pages 18" EXPECTED=$(cat<<-EOF 4 25 Em:7 3 n:7 3 Km:24 4 n:24 4 M:680 5 N:26 5 p=13bgjn256789acdefhiklmo04 1 0 -2 -1 0 -1 0 -14 -12 -10 -8 -6 -4 -9 -7 -5 -3 -4 -2 -7 -5 -3 -2 0 -28 0 1 -3 -2 -1 -1 0 -21 -18 -15 -12 -9 -6 -14 -11 -8 -5 -7 -4 -10 -7 -4 -3 0 -42 0 0 0 0 0 0 1 -6 -5 -4 -3 -2 -1 -4 -3 -2 -1 -2 -1 -3 -2 -1 -1 0 -12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 EOF ) if [ $DIM -lt 6 ]; then # When POLY_Dmax < 6, the first two rows are swapped, but only # after the first two columns. This is a little weird to me but # it's not impossible if e.g. the first two represent a relabeling # of a basis in a subspace orthogonal to the rest. EXPECTED=$(cat<<-EOF 4 25 Em:7 3 n:7 3 Km:24 4 n:24 4 M:680 5 N:26 5 p=13bgjn256789acdefhiklmo04 1 0 -3 -2 -1 -1 0 -21 -18 -15 -12 -9 -6 -14 -11 -8 -5 -7 -4 -10 -7 -4 -3 0 -42 0 1 -2 -1 0 -1 0 -14 -12 -10 -8 -6 -4 -9 -7 -5 -3 -4 -2 -7 -5 -3 -2 0 -28 0 0 0 0 0 0 1 -6 -5 -4 -3 -2 -1 -4 -3 -2 -1 -2 -1 -3 -2 -1 -1 0 -12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 EOF ) fi run_test palp-2.21/tests/7.2.9-mori-i.sh0000775000177600017760000000113114572603263015312 0ustar skarkeskarke#!/bin/sh # # Test the mori -i example in Section 7.2.9 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 62 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fi" DESCRIPTION="mori-${DIM}d.x -fi example on page 62" EXPECTED=$(cat<<-EOF SINGULAR -> divisor classes (integral basis J1 ... J2): d1=J1+3*J2, d2=J1, d3=-J1+J2, d4=J2, d5=J1, d6=J2 SINGULAR -> intersection polynomial: 2*J1*J2^2+2*J2^3 SINGULAR -> divisor classes (integral basis J1 ... J2): d1=J1+3*J2, d2=J1, d3=-J1+J2, d4=J2, d5=J1, d6=J2 SINGULAR -> intersection polynomial: 2*J1*J2^2+2*J2^3 EOF ) run_test palp-2.21/tests/3.2.7-poly-e.sh0000775000177600017760000000211014572603263015313 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 3.2.7 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 13 COMMAND="./poly-${DIM}d.x -e tests/input/3.2.7-poly-e.1.txt" DESCRIPTION="poly-${DIM}d.x -e first example on page 13" EXPECTED=$(cat<<-EOF 3 2 Equations of P 1 0 0 0 1 0 -1 -1 1 EOF ) if [ $DIM -lt 6 ]; then # The output equations are permuted when POLY_Dmax < 6 (the first # and third rows are swapped), but they're the same equations. EXPECTED=$(cat<<-EOF 3 2 Equations of P -1 -1 1 0 1 0 1 0 0 EOF ) fi run_test COMMAND="./poly-${DIM}d.x -e tests/input/3.2.7-poly-e.2.txt" DESCRIPTION="poly-${DIM}d.x -e second example on page 13" EXPECTED=$(cat<<-EOF 3 2 Vertices of P-dual <-> Equations of P 2 -1 -1 2 -1 -1 EOF ) if [ $DIM -lt 6 ]; then # The output equations are permuted when POLY_Dmax < 6 (the first # and third rows are swapped), but they're the same equations. EXPECTED=$(cat<<-EOF 3 2 Vertices of P-dual <-> Equations of P -1 -1 -1 2 2 -1 EOF ) fi run_test palp-2.21/tests/6.4.17-nef-n.sh0000775000177600017760000000063614572603263015212 0ustar skarkeskarke#!/bin/sh # # Test the nef -n example in Section 6.4.17 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 46 COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -n" DESCRIPTION="nef-${DIM}d.x -n example on page 46" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 3 5 Points of Poly in N-Lattice: -1 0 0 1 0 -1 0 1 0 0 -1 1 0 0 0 EOF ) run_test palp-2.21/tests/6.4.3-nef-Lv.sh0000775000177600017760000000215014572603263015242 0ustar skarkeskarke#!/bin/sh # # Test the nef -Lv examples in Section 6.4.3 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 34 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="./nef-${DIM}d.x -Lv tests/input/6.4.3-nef-Lv.1.txt | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lv example on page 34" EXPECTED=$(cat<<-EOF M:5 4 N:35 4 codim=2 #part=0 3 4 Vertices in N-lattice: -1 -1 -1 3 -1 -1 3 -1 -1 3 -1 -1 -------------------- 1 1 1 1 d=4 codim=0 np=0 d:0 p:0 EOF ) #if [ $DIM -lt 6 ]; then # EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 #(POLY_Dmax >= dim N + codim - 1 is required)" #fi run_test COMMAND="./nef-${DIM}d.x -Lv -N tests/input/6.4.3-nef-Lv.2.txt | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lv -N example on pages 34-35" EXPECTED=$(cat<<-EOF M:35 4 N:5 4 codim=2 #part=2 3 4 Vertices in N-lattice: -1 0 0 1 -1 0 1 0 -1 1 0 0 -------------------- 1 1 1 1 d=4 codim=0 H:[0] P:0 V:2 3 (2 2) np=1 d:0 p:1 EOF ) run_test palp-2.21/tests/lib/0000775000177600017760000000000014572603263013656 5ustar skarkeskarkepalp-2.21/tests/lib/run-test.sh0000664000177600017760000000276014572603263016000 0ustar skarkeskarke# Run one test and print the result. Most of its arguments # are passed via environment variables and are required: # # - COMMAND: the test command to run # - DESCRIPTION: a short (one-line) description of the test # - EXPECTED: the expected output from the test # # In addition, this function takes two positional arguments, # # - skip: non-null if the test should be skipped # - skipreason: the reason why the test was skipped; # required if "skip" is non-null. # # These are positional to avoid a common pitfall where e.g. SKIP would # be set to true at the top of a file, for the first test, and then # forgotten in subsequent tests causing them to be skipped. run_test() { _SKIP=$1 _SKIPREASON=$2 printf "Checking ${DESCRIPTION}... " if [ -n "${_SKIP}" ]; then printf "SKIP (${_SKIPREASON})" printf "\n" return fi # Use eval to support pipes in COMMAND. This isn't # a great way to run a stored command, but we also # want to _print_ it when the test fails, and that # complicates things. If we need to change this in # the future, we could instead insist that our caller # define (for example) a _test_command() function to # perform the test. ACTUAL=$(eval "${COMMAND}") if [ "${ACTUAL}" = "${EXPECTED}" ]; then printf "PASS\n" else printf "FAIL\n" echo "Failed command: ${COMMAND}" echo "Expected output" echo "---------------" echo "${EXPECTED}" echo "Actual output" echo "-------------" echo "${ACTUAL}" exit 1 fi } palp-2.21/tests/6.4.13-nef-y.sh0000775000177600017760000000076314572603263015222 0ustar skarkeskarke#!/bin/sh # # Test the nef -y example in Section 6.4.13 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 43 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="./nef-${DIM}d.x -y -N tests/input/6.4.13-nef-y.txt" DESCRIPTION="nef-${DIM}d.x -y -N example on page 43" EXPECTED=$(cat<<-EOF 3 4 Vertices of Poly in M-lattice: M:35 4 N:5 4 codim=2 #part=2 -1 -1 -1 3 -1 -1 3 -1 -1 3 -1 -1 EOF ) run_test palp-2.21/tests/README0000664000177600017760000000273214572603263013774 0ustar skarkeskarkeThis directory contains a collection of test scripts that are executed by "make check" and/or "make checklong". The basic setup and execution of an individual tests looks like, COMMAND="the command to run" DESCRIPTION="a description of the test" EXPECTED="the expected output from $COMMAND" run_test The run_test() function will then run the given $COMMAND, and report the result; that is, whether or not the actual output matches the $EXPECTED output. There are a few more variables you can use: the run_test() function is defined and documented in lib/run-test.sh. Variables ========= A few environment variables are passed from the GNUmakefile to the test scripts: * DIM: the value of POLY_Dmax to use. The "all-dims" target produces multiple executables, each compiled with a different value for POLY_Dmax. For example, poly-4d.x, poly-5d.x, ..., poly-11d.x. The value of $DIM tells the test script which of those executables to test. The GNUmakefile loops through all possible values of DIM, to ensure that all executables get tested. As a result, the test scripts themselves do not need to repeat any tests. * LONG: if set to a non-null value, indicates that the script is allowed to run tests that take a long time to run. The "make checklong" command sets this automatically; a plain "make check" does not. Return value ============ Each script succeeds (exits with code zero) if all of its tests pass, and fails with a non-zero code otherwise. palp-2.21/tests/6.4.10-nef-t.sh0000775000177600017760000000153614572603263015211 0ustar skarkeskarke#!/bin/sh # # Test the nef -t examples in Section 6.4.10 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 39 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '8 1 1 1 1 1 1 1 1' | ./nef-${DIM}d.x -f -t -c4 | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -t -c4 example on page 39" EXPECTED=$(cat<<-EOF 8 1 1 1 1 1 1 1 1 M:6435 8 N:9 8 codim=4 #part=5 BEGIN S-Poly BEGIN B-Poly BEGIN E-Poly H:1 65 [-128] P:0 V0:2 3 V1:4 5 V2:6 7 np=1 d:0 p:4 EOF ) if [ $DIM -lt 10 ]; then EXPECTED="Please increase POLY_Dmax to at least 10 = 7 + 4 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" else if [ -z "${LONG}" ]; then # This test takes forever to run SKIP=true SKIPREASON="long-running test requires make checklong" fi fi run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/3.2.23-poly-P.sh0000775000177600017760000000207314572603263015354 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 3.2.23 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 17 COMMAND="echo '6 1 2 3' | ./poly-${DIM}d.x -fP" DESCRIPTION="poly-${DIM}d.x -P example on page 17" EXPECTED=$(cat<<-EOF 2 7 points of P-dual and IP-simplices 1 0 -2 -1 0 -1 0 0 1 -3 -2 -1 -1 0 ------------------------------ #IP-simp=4 2 3 1 0 0 0 6=d codim=0 1 2 0 1 0 0 4=d codim=0 1 1 0 0 0 1 3=d codim=0 0 1 0 0 1 0 2=d codim=1 EOF ) if [ $DIM -lt 6 ]; then # In this example, the first and third COLUMNS # are switched for POLY_Dmax < 6. EXPECTED=$(cat<<-EOF 2 7 points of P-dual and IP-simplices -2 0 1 -1 0 -1 0 -3 1 0 -2 -1 -1 0 ------------------------------ #IP-simp=4 1 3 2 0 0 0 6=d codim=0 0 2 1 1 0 0 4=d codim=0 0 1 1 0 0 1 3=d codim=0 0 1 0 0 1 0 2=d codim=1 EOF ) fi run_test palp-2.21/tests/7.2-mori-P.sh0000775000177600017760000000163214572603263015120 0ustar skarkeskarke#!/bin/sh # # Test the mori -P example in Section 7.2 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 57-58 INPUT="8 4 1 1 1 1 0 6 3 1 0 1 0 1" COMMAND="echo '${INPUT}' | ./mori-${DIM}d.x -fP" DESCRIPTION="mori-${DIM}d.x -P example on pages 57-58" EXPECTED=$(cat<<-EOF 4 8 points of P* and IP-simplices -1 0 0 0 1 3 1 0 0 0 0 1 0 -1 0 0 -1 1 0 0 0 3 1 0 1 0 1 0 0 -4 -1 0 ------------------------------ #IP-simp=2 4 1 0 1 1 1 8=d codim=0 3 0 1 1 0 1 6=d codim=1 EOF ) run_test # Might as well include the repeated example from section 7.2.2, which # is the same as above except using -f and a pipeline rather than an # input file. COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fP" DESCRIPTION="mori-${DIM}d.x -fP example on page 58" run_test palp-2.21/tests/3.2.35-poly-C2.sh0000775000177600017760000000206214572603263015422 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 3.2.35 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 21 COMMAND="./poly-${DIM}d.x -C2 tests/input/3.2.35-poly-C2.txt" DESCRIPTION="poly-${DIM}d.x -C2 example on page 21" EXPECTED=$(cat<<-EOF pic=1 deg=64 h12= 0 rk=0 #sq=0 #dp=0 py=1 F=5 10 10 5 #Fano=1 4 5 Vertices of P* (N-lattice) M:201 5 N:7 5 1 0 0 0 -1 0 0 1 0 -1 0 1 0 0 -1 0 0 0 1 -4 P/2: 36 points (5 vertices) of P'=P/2 (M-lattice): P/2: 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 P/2: 0 0 4 0 0 1 2 3 0 1 2 3 0 1 2 0 1 0 1 2 3 0 1 2 0 1 0 0 1 2 0 1 0 0 1 0 P/2: 0 0 0 4 0 0 0 0 1 1 1 1 2 2 2 3 3 0 0 0 0 1 1 1 2 2 3 0 0 0 1 1 2 0 0 1 P/2: 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 EOF ) if [ $DIM -lt 6 ]; then SKIP=true SKIPREASON="unknown, pre-existing output deviation" fi run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/7.2.8-mori-b.sh0000775000177600017760000000130314572603263015303 0ustar skarkeskarke#!/bin/sh # # Test the mori -b example in Section 7.2.8 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 61 COMMAND="echo '4 1 1 1 1' | ./mori-${DIM}d.x -bf" DESCRIPTION="mori-${DIM}d.x -bf first example on page 61" EXPECTED=$(cat<<-EOF SINGULAR -> Arithmetic genera and Euler number of the CY: chi_0: 2 , chi_1: -20 [ 24 ] EOF ) run_test COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -bf" DESCRIPTION="mori-${DIM}d.x -bf second example on page 61" EXPECTED=$(cat<<-EOF SINGULAR -> Arithmetic genera and Euler number of the CY: chi_0: 0 , chi_1: 126 [ -252 ] SINGULAR -> Arithmetic genera and Euler number of the CY: chi_0: 0 , chi_1: 126 [ -252 ] EOF ) run_test palp-2.21/tests/input/0000775000177600017760000000000014572603263014247 5ustar skarkeskarkepalp-2.21/tests/input/6.4.3-nef-Lv.1.txt0000664000177600017760000000003714572603263016744 0ustar skarkeskarke3 4 -1 0 0 1 -1 0 1 0 -1 1 0 0 palp-2.21/tests/input/6.4.18-nef-v.txt0000664000177600017760000000004614572603263016557 0ustar skarkeskarke4 1 1 1 1 3 1 1 1 0 0 0 3 0 0 0 1 1 1 palp-2.21/tests/input/3.2.7-poly-e.1.txt0000664000177600017760000000002014572603263017011 0ustar skarkeskarke3 2 1 0 0 1 0 0 palp-2.21/tests/input/2.1-polytope-input-transpose.txt0000664000177600017760000000005514572603263022332 0ustar skarkeskarke3 2 This text is ignored by PALP 2 0 0 2 0 0 palp-2.21/tests/input/3.2.35-poly-C2.txt0000664000177600017760000000007414572603263016764 0ustar skarkeskarke4 5 -1 7 -1 -1 -1 -1 -1 7 -1 -1 -1 -1 -1 7 -1 -1 -1 -1 -1 1 palp-2.21/tests/input/6.4.3-nef-Lv.2.txt0000664000177600017760000000003714572603263016745 0ustar skarkeskarke3 4 -1 0 0 1 -1 0 1 0 -1 1 0 0 palp-2.21/tests/input/6.4.25-nef-G.2.txt0000664000177600017760000000002014572603263016626 0ustar skarkeskarke3 2 0 0 1 0 0 1 palp-2.21/tests/input/6.4.13-nef-y.txt0000664000177600017760000000003714572603263016555 0ustar skarkeskarke3 4 -1 0 0 1 -1 0 1 0 -1 1 0 0 palp-2.21/tests/input/6.3-nef-N-output.txt0000664000177600017760000000013114572603263017610 0ustar skarkeskarke5 8 1 0 -1 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 1 -1 palp-2.21/tests/input/7.2.14-mori-D.txt0000664000177600017760000000006014572603263016662 0ustar skarkeskarke4 5 -1 2 0 0 0 -1 1 2 0 0 0 -1 1 0 2 0 0 -1 1 1 palp-2.21/tests/input/6.4.24-nef-N-Lv.txt0000664000177600017760000000022014572603263017055 0ustar skarkeskarke5 12 0 0 -1 2 -1 0 0 0 -1 2 -1 0 0 0 2 -1 -1 0 0 0 2 -1 -1 0 0 1 0 0 0 1 1 0 -1 -1 -1 0 -1 -1 0 0 0 2 -1 -1 0 0 0 2 -1 2 0 0 0 -1 -1 2 0 0 0 -1 palp-2.21/tests/input/3.2.7-poly-e.2.txt0000664000177600017760000000002214572603263017014 0ustar skarkeskarke3 2 1 0 0 1 -1 -1 palp-2.21/tests/input/4.2.6-cws-N.txt0000664000177600017760000000007414572603263016445 0ustar skarkeskarke4 5 -1 -1 -1 -1 4 -1 -1 -1 4 -1 -1 -1 4 -1 -1 -1 4 -1 -1 -1 palp-2.21/tests/input/3.2.24-poly-Z.txt0000664000177600017760000000004714572603263016727 0ustar skarkeskarke3 5 -1 -1 2 0 0 -1 2 -1 0 0 0 0 0 1 -1 palp-2.21/tests/input/6.4.24-nef-d.txt0000664000177600017760000000013114572603263016525 0ustar skarkeskarke5 8 1 0 -1 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 1 -1 palp-2.21/tests/input/3.2.27-poly-B.txt0000664000177600017760000000010414572603263016674 0ustar skarkeskarke5 6 1 1 1 1 1 0 1 0 0 0 -1 0 0 1 0 0 -1 0 0 0 1 0 -1 0 0 0 0 1 -1 0 palp-2.21/tests/input/2.1-polytope-input.txt0000664000177600017760000000005514572603263020316 0ustar skarkeskarke3 2 This text is ignored by PALP 2 0 0 2 0 0 palp-2.21/tests/input/6.4.25-nef-G.1.txt0000664000177600017760000000002414572603263016631 0ustar skarkeskarke4 2 0 0 0 1 1 0 1 1 palp-2.21/tests/input/6.4.23-nef-g.txt0000664000177600017760000000013114572603263016527 0ustar skarkeskarke5 8 1 0 -1 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 1 -1 palp-2.21/tests/6.4.19-nef-m.sh0000775000177600017760000000354314572603263015213 0ustar skarkeskarke#!/bin/sh # # Test the nef -m examples in Section 6.4.19 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 48 # The "sed" command strips the unpredictable timing information COMMAND="echo '14 1 1 1 1 4 6' | ./nef-${DIM}d.x -f -Lv | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lv example on page 48" EXPECTED=$(cat<<-EOF 14 1 1 1 1 4 6 M:1271 13 N:10 8 codim=2 #part=2 5 8 Vertices in N-lattice: 0 -1 0 0 0 1 0 0 0 -1 1 0 0 0 0 0 0 -1 0 1 0 0 0 0 0 -4 0 0 1 0 -1 -1 1 -6 0 0 0 0 -1 -2 ---------------------------------------- 6 1 1 1 4 1 0 0 d=14 codim=0 1 0 0 0 1 0 1 0 d=3 codim=3 2 0 0 0 1 0 0 1 d=4 codim=3 H:1 149 [-296] P:1 V:3 4 5 7 8 (6 8) (1 2) (2 2) np=1 d:0 p:1 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test # Pages 48-49 # The "sed" command strips the unpredictable timing information COMMAND="echo '14 1 1 1 1 4 6 d=2 12' | ./nef-${DIM}d.x -f -Lv -m | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lv m example on pages 48-49" EXPECTED=$(cat<<-EOF 14 1 1 1 1 4 6 d=2 12 M:1270 12 N:11 7 codim=2 #part=2 5 7 Vertices in N-lattice: 0 -1 0 0 0 1 0 0 -1 1 0 0 0 0 0 -1 0 1 0 0 0 0 -4 0 0 1 0 -2 1 -6 0 0 0 0 -3 ----------------------------------- 6 1 1 1 4 1 0 d=14 codim=0 3 0 0 0 2 0 1 d=6 codim=3 d=12 2H:3 243 [-480] P:0 V:3 5 (2 12) (0 6) np=1 d:0 p:1 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax (POLY_Dmax >= number of weights is required)" fi run_test palp-2.21/tests/7.2.14-mori-D.sh0000775000177600017760000000127114572603263015326 0ustar skarkeskarke#!/bin/sh # # Test the mori -D example in Section 7.2.14 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 65 COMMAND="./mori-${DIM}d.x -DP tests/input/7.2.14-mori-D.txt" DESCRIPTION="mori-${DIM}d.x -DP example on page 65" EXPECTED=$(cat<<-EOF 4 9 points of P* and IP-simplices -1 2 0 0 0 0 0 1 0 -1 1 2 0 0 0 1 1 0 0 -1 1 0 2 1 1 0 0 0 0 -1 1 1 1 0 0 0 ----------------------------------- #IP-simp=3 8 4 2 1 1 0 0 16=d codim=0 4 2 1 0 0 1 0 8=d codim=1 2 1 0 0 0 0 1 4=d codim=2 EOF ) run_test palp-2.21/tests/3.2.27-poly-B.sh0000775000177600017760000000203114572603263015334 0ustar skarkeskarke#!/bin/sh # # Test the example in Section 3.2.27 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 19-20 # We sort the output because for lower POLY_Dmax, it's # violently permuted. The "-r" simply ensures that the # vol=... header appears before the coordinates. COMMAND="./poly-${DIM}d.x -B2 tests/input/3.2.27-poly-B.txt | sort -br" DESCRIPTION="poly-${DIM}d.x -B2 example on pages 19-20" EXPECTED=$(cat<<-EOF vol=5, baricent=(5,0,0,0,0)/6 IPs: 2 2 0 0 0 cd=4 2 1 1 0 0 cd=3 2 1 0 1 0 cd=3 2 1 0 0 1 cd=3 2 1 0 0 0 cd=0 2 0 2 0 0 cd=4 2 0 1 1 0 cd=3 2 0 1 0 1 cd=3 2 0 1 0 0 cd=0 2 0 0 2 0 cd=4 2 0 0 1 1 cd=3 2 0 0 1 0 cd=0 2 0 0 0 2 cd=4 2 0 0 0 1 cd=0 2 0 0 0 0 cd=0 2 0 -1 -1 -1 cd=3 2 -2 -2 -2 -2 cd=4 2 -1 0 -1 -1 cd=3 2 -1 -1 0 -1 cd=3 2 -1 -1 -1 0 cd=3 2 -1 -1 -1 -1 cd=0 1 1 0 0 0 cd=4 1 0 1 0 0 cd=4 1 0 0 1 0 cd=4 1 0 0 0 1 cd=4 1 0 0 0 0 cd=0 1 -1 -1 -1 -1 cd=4 0 0 0 0 0 cd=5 EOF ) [ $DIM -lt 5 ] && EXPECTED="Please increase POLY_Dmax to at least 5" run_test palp-2.21/tests/6.4.15-nef-T.sh0000775000177600017760000000157514572603263015161 0ustar skarkeskarke#!/bin/sh # # Test the nef -S -T example in Section 6.4.15 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 44-45 # The "sed" command strips the unpredictable timing information # from the ends of the lines. COMMAND="echo '4 1 1 1 1' | ./nef-${DIM}d.x -f -S -T | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -S -T example on pages 44-45" EXPECTED=$(cat<<-EOF 4 1 1 1 1 M:35 4 N:5 4 codim=2 #part=2 #points in largest cone: layer: 1 #p: 6 #ip: 0 layer: 2 #p: 21 #ip: 1 layer: 3 #p: 56 #ip: 6 layer: 4 #p: 125 #ip: 21 layer: 5 #p: 246 #ip: 56 #points in largest cone: layer: 1 #p: 20 #ip: 0 layer: 2 #p: 105 #ip: 1 layer: 3 #p: 336 #ip: 20 layer: 4 #p: 825 #ip: 105 layer: 5 #p: 1716 #ip: 336 H:[0] P:0 V:2 3 np=1 d:0 p:1 EOF ) run_test palp-2.21/tests/3.2.18-poly-S.sh0000775000177600017760000000074314572603263015365 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 3.2.18 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 15 COMMAND="echo '5 1 1 1 1 1' | ./poly-${DIM}d.x -fS" DESCRIPTION="poly-${DIM}d.x -S first example on page 15" EXPECTED="#GL(Z,4)-Symmetries=120, #VPM-Symmetries=120" run_test COMMAND="echo '5 1 1 1 1 1 /Z5: 0 1 2 3 4' | ./poly-${DIM}d.x -fS" DESCRIPTION="poly-${DIM}d.x -S second example on page 15" EXPECTED="#GL(Z,4)-Symmetries=20, #VPM-Symmetries=120" run_test palp-2.21/tests/6.4.16-nef-s.sh0000775000177600017760000000353614572603263015220 0ustar skarkeskarke#!/bin/sh # # Test the nef -s -Lv example in Section 6.4.16 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 45 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="3 1 1 1 0 0 0 3 0 0 0 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -s -Lv | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -s -Lv example on page 45" EXPECTED=$(cat<<-EOF 3 1 1 1 0 0 0 3 0 0 0 1 1 1 M:100 9 N:7 6 codim=2 #part=31 4 6 Vertices in N-lattice: 0 0 0 1 0 -1 0 0 1 0 0 -1 -1 0 0 0 1 0 -1 1 0 0 0 0 ------------------------------ 1 1 0 0 1 0 d=3 codim=2 0 0 1 1 0 1 d=3 codim=2 H:20 [24] P:2 V:4 5 (1 2) (1 2) H:20 [24] P:4 V:0 5 (1 2) (1 2) H:20 [24] P:5 V:0 4 (2 1) (0 3) H:20 [24] P:6 V:0 4 5 (2 1) (1 2) H:20 [24] P:8 V:1 5 (1 2) (1 2) H:20 [24] P:9 V:1 4 (2 1) (0 3) H:20 [24] P:10 V:1 4 5 (2 1) (1 2) H:20 [24] P:11 V:0 1 (2 1) (0 3) H:20 [24] P:12 V:0 1 5 (2 1) (1 2) H:20 [24] P:14 V:2 3 (0 3) (2 1) H:20 [24] P:16 V:2 5 (0 3) (2 1) H:20 [24] P:17 V:2 4 (1 2) (1 2) H:20 [24] P:18 V:2 4 5 (1 2) (2 1) H:20 [24] P:19 V:0 2 (1 2) (1 2) H:20 [24] P:20 V:0 2 5 (1 2) (2 1) H:20 [24] P:21 V:0 2 4 (2 1) (1 2) H:20 [24] P:22 V:1 3 (1 2) (1 2) H:20 [24] P:23 V:1 2 (1 2) (1 2) H:20 [24] P:24 V:1 2 5 (1 2) (2 1) H:20 [24] P:25 V:1 2 4 (2 1) (1 2) H:20 [24] P:26 V:0 3 (1 2) (1 2) H:20 [24] P:27 V:0 1 2 (2 1) (1 2) H:20 [24] P:28 V:3 4 (1 2) (1 2) H:20 [24] P:29 V:3 5 (0 3) (2 1) np=24 d:1 p:6 EOF ) if [ $DIM -lt 5 ]; then EXPECTED="Please increase POLY_Dmax to at least 5 = 4 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" elif [ $DIM -eq 5 ]; then SKIP=1 SKIPREASON="Unknown, pre-existing output deviation" fi run_test "${SKIP}" "${SKIPREASON}" palp-2.21/tests/3.2.20-poly-N.sh0000775000177600017760000000145714572603263015354 0ustar skarkeskarke#!/bin/sh # # Test the examples in Section 3.2.20 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 16 COMMAND="echo '3402 40 41 486 1134 1701' | ./poly-${DIM}d.x -fN" DESCRIPTION="poly-${DIM}d.x -N first example on page 16" # When POLY_Dmax < 6, it looks like it takes fewer permutations # to arrive at the normal form. This information is purely... # informational, so it shouldn't trigger a failure. _perm=43210 [ $DIM -lt 6 ] && _perm=43201 EXPECTED=$(cat<<-EOF 4 5 Normal form of vertices of P perm=${_perm} 1 0 0 0 -42 0 1 0 0 -28 0 0 1 0 -12 0 0 0 1 -1 EOF ) run_test COMMAND="echo '3486 41 42 498 1162 1743' | ./poly-${DIM}d.x -fN" DESCRIPTION="poly-${DIM}d.x -N second example on page 16" # EXPECTED is unchanged from the previous example run_test palp-2.21/tests/7.2.6-mori-P.sh0000775000177600017760000000125714572603263015267 0ustar skarkeskarke#!/bin/sh # # Test the mori -P example in Section 7.2.6 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 60 COMMAND="echo '16 8 4 2 1 1' | ./mori-${DIM}d.x -fP" DESCRIPTION="mori-${DIM}d.x -fP example on page 60" EXPECTED=$(cat<<-EOF 4 9 points of P* and IP-simplices -1 0 0 2 0 0 0 1 0 -1 0 0 1 2 0 1 1 0 0 0 2 -1 1 1 1 0 0 0 1 1 0 -1 1 0 0 0 ----------------------------------- #IP-simp=3 8 1 1 4 2 0 0 16=d codim=0 4 0 0 2 1 1 0 8=d codim=1 2 0 0 1 0 0 1 4=d codim=2 EOF ) run_test palp-2.21/tests/6.4.12-nef-F.sh0000775000177600017760000000330714572603263015133 0ustar skarkeskarke#!/bin/sh # # Test the nef -F examples in Section 6.4.12 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 41 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="12 4 2 2 2 1 1 0 8 4 0 0 0 1 1 2" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -Lp -F3 | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -f -Lp -F3 example on page 40" EXPECTED=$(cat<<-EOF 12 4 2 2 2 1 1 0 8 4 0 0 0 1 1 2 M:371 12 N:10 7 codim=2 #part=5 5 10 Points of Poly in N-Lattice: 0 0 0 1 0 -1 0 0 0 0 0 0 1 0 0 -1 0 0 0 0 -1 4 0 0 0 0 0 1 2 0 0 -1 0 0 1 0 0 0 0 0 -1 2 0 0 0 1 1 1 1 0 -------------------------------------------------- 4 1 2 2 1 2 0 0 0 d=12 codim=0 4 1 0 0 1 0 2 0 0 d=8 codim=2 2 0 1 1 0 1 0 0 1 d=6 codim=1 2 0 0 0 0 0 1 0 1 d=4 codim=3 1 0 0 0 0 0 0 1 0 d=2 codim=4 --------------------------------------------- #fibrations=3 v v _ _ v _ v p p cd=2 m: 35 4 n: 7 4 v _ v v _ v v p v cd=1 m:117 9 n: 8 6 v _ _ _ _ _ v p v cd=3 m: 9 3 n: 5 3 H:4 58 [-108] P:1 V:0 2 (6 6) (4 4) (3 3) (2 2) (1 1) H:3 65 [-124] P:2 V:0 2 3 (8 4) (4 4) (4 2) (2 2) (1 1) H:3 83 [-160] P:3 V:3 5 (4 8) (0 8) (2 4) (0 4) (0 2) np=3 d:0 p:2 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/6.4.6-nef-Lp.sh0000775000177600017760000000217614572603263015247 0ustar skarkeskarke#!/bin/sh # # Test the nef -Lp examples in Section 6.4.6 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Pages 37-38 # The "sed" command strips the unpredictable timing information # from the ends of the lines. INPUT="5 1 1 1 1 1 0 0 10 2 2 2 2 0 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -Lp | sed 's/ *[0-9]*sec.*//g'" DESCRIPTION="nef-${DIM}d.x -Lp example on pages 37-38" EXPECTED=$(cat<<-EOF 5 1 1 1 1 1 0 0 10 2 2 2 2 0 1 1 M:378 6 N:8 6 codim=2 #part=4 5 8 Points of Poly in N-Lattice: -1 0 0 0 1 0 0 0 -1 0 1 0 0 0 0 0 -1 0 0 1 0 0 0 0 -1 2 0 0 0 0 1 0 -1 1 0 0 0 1 1 0 ---------------------------------------- 2 1 2 2 2 1 0 d=10 codim=0 1 0 1 1 1 0 1 d=5 codim=1 H:2 86 [-168] P:0 V:1 5 6 (2 8) (1 4) H:2 68 [-132] P:1 V:2 3 4 (6 4) (3 2) H:2 68 [-132] P:2 V:3 4 (4 6) (2 3) np=3 d:0 p:1 EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/6.4.25-nef-G.sh0000775000177600017760000000357014572603263015142 0ustar skarkeskarke#!/bin/sh # # Test the nef -G example in Section 6.4.25 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 54 COMMAND="./nef-${DIM}d.x -G tests/input/6.4.25-nef-G.1.txt" DESCRIPTION="nef-${DIM}d.x -G first example on page 54" EXPECTED=$(cat<<-EOF M:4 4 N:4 4 H:[0] h0=0 EOF ) run_test COMMAND="echo '3 1 1 1 1 1 1' | ./nef-${DIM}d.x -f -G" DESCRIPTION="nef-${DIM}d.x -G second example on page 54" EXPECTED=$(cat<<-EOF 3 1 1 1 1 1 1 M:56 6 N:6 6 H:20 [24] EOF ) if [ $DIM -lt 6 ]; then EXPECTED="Please increase POLY_Dmax to at least 6 = 5 + 1 (option -G requires POLY_Dmax >= dim(cone) = dim(support) + 1)" fi run_test COMMAND="echo '7 1 1 1 2 3 3 3' | ./nef-${DIM}d.x -f -G" DESCRIPTION="nef-${DIM}d.x -G third example on page 54" EXPECTED=$(cat<<-EOF 7 1 1 1 2 3 3 3 M:154 18 F:9 EOF ) if [ $DIM -lt 7 ]; then EXPECTED="Please increase POLY_Dmax to at least 7 = 6 + 1 (option -G requires POLY_Dmax >= dim(cone) = dim(support) + 1)" fi run_test COMMAND="echo '7 1 1 2 2 2 3 3' | ./nef-${DIM}d.x -f -G" DESCRIPTION="nef-${DIM}d.x -G fourth example on page 54" EXPECTED=$(cat<<-EOF 7 1 1 2 2 2 3 3 M:116 18 N:9 9 H:2 70 [-136] EOF ) if [ $DIM -lt 7 ]; then EXPECTED="Please increase POLY_Dmax to at least 7 = 6 + 1 (option -G requires POLY_Dmax >= dim(cone) = dim(support) + 1)" fi run_test COMMAND="./nef-${DIM}d.x -G tests/input/6.4.25-nef-G.2.txt" DESCRIPTION="nef-${DIM}d.x -G fifth example on page 54" EXPECTED=$(cat<<-EOF Warning: Input has index 3, should be 2! M:3 3 F:3 EOF ) run_test INPUT="1 1 1 0 0 0 0 2 0 0 1 1 1 1" COMMAND="echo '${INPUT}' | ./nef-${DIM}d.x -f -G" DESCRIPTION="nef-${DIM}d.x -G sixth example on page 55" EXPECTED=$(cat<<-EOF 1 1 1 0 0 0 0 2 0 0 1 1 1 1 M:20 8 N:6 6 H:[0] EOF ) if [ $DIM -lt 5 ]; then EXPECTED="Please increase POLY_Dmax to at least 5 = 4 + 1 (option -G requires POLY_Dmax >= dim(cone) = dim(support) + 1)" fi run_test palp-2.21/tests/7.2.11-mori-t.sh0000775000177600017760000000141414572603263015402 0ustar skarkeskarke#!/bin/sh # # Test the mori -t example in Section 7.2.11 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 63 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -ft | head -n37" DESCRIPTION="mori-${DIM}d.x -ft example on page 63" EXPECTED=$(cat<<-EOF SINGULAR -> triple intersection numbers: d6^3->2, d5*d6^2->2, d4*d6^2->2, d3*d6^2->0, d2*d6^2->2, d1*d6^2->8, d5^2*d6->0, d4*d5*d6->2, d3*d5*d6->2, d2*d5*d6->0, d1*d5*d6->6, d4^2*d6->2, d3*d4*d6->0, d2*d4*d6->2, d1*d4*d6->8, d3^2*d6->-2, d2*d3*d6->2, d1*d3*d6->2, d2^2*d6->0, d1*d2*d6->6, d1^2*d6->30, d5^3->0, d4*d5^2->0, d3*d5^2->0, d2*d5^2->0, d1*d5^2->0, d4^2*d5->2, d3*d4*d5->2, d2*d4*d5->0, d1*d4*d5->6, d3^2*d5->2, d2*d3*d5->0, d1*d3*d5->6, d2^2*d5->0, d1*d2*d5->0, d1^2*d5->18, EOF ) run_test palp-2.21/tests/6.4.18-nef-v.sh0000775000177600017760000000234714572603263015224 0ustar skarkeskarke#!/bin/sh # # Test the nef -v examples in Section 6.4.18 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 46 COMMAND="./nef-${DIM}d.x -v tests/input/6.4.18-nef-v.txt" DESCRIPTION="nef-${DIM}d.x -v example on page 46" EXPECTED=$(cat<<-EOF 3 4 P:35 E -1 3 -1 -1E -1 -1 3 -1E -1 -1 -1 3 4 9 P:100 E -1 2 -1 -1 2 -1 -1 2 -1E -1 -1 2 -1 -1 2 -1 -1 2E -1 -1 -1 2 2 2 -1 -1 -1E -1 -1 -1 -1 -1 -1 2 2 2 2 of 2 35# 1 100# 1 EOF ) if [ $DIM -lt 5 ]; then EXPECTED="3 4 P:35 E -1 3 -1 -1E -1 -1 3 -1E -1 -1 -1 3 Please increase POLY_Dmax to at least 5 = 4 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test # Page 46 COMMAND="./nef-${DIM}d.x -v -u50 tests/input/6.4.18-nef-v.txt" DESCRIPTION="nef-${DIM}d.x -v -u50 example on page 46" EXPECTED=$(cat<<-EOF 3 4 P:35 E -1 3 -1 -1E -1 -1 3 -1E -1 -1 -1 3 1 of 2 35# 1 EOF ) if [ $DIM -lt 5 ]; then EXPECTED="3 4 P:35 E -1 3 -1 -1E -1 -1 3 -1E -1 -1 -1 3 Please increase POLY_Dmax to at least 5 = 4 + 2 - 1 (POLY_Dmax >= dim N + codim - 1 is required)" fi run_test palp-2.21/tests/7.2.3-mori-g.sh0000775000177600017760000000074214572603263015311 0ustar skarkeskarke#!/bin/sh # # Test the mori -g example in Section 7.2.3 of the PALP manual # . tests/lib/run-test.sh : ${DIM:=6} # Page 58 COMMAND="echo '8 4 1 1 1 1 0 6 3 1 0 1 0 1' | ./mori-${DIM}d.x -fg" DESCRIPTION="mori-${DIM}d.x -fg example on page 58" EXPECTED=$(cat<<-EOF 8 Triangulation 110101 111100 101011 101110 100111 111001 001111 011101 2 SR-ideal 010010 101101 9 Triangulation 110101 111100 101011 101110 100111 111001 010111 011011 011110 2 SR-ideal 110010 001101 EOF ) run_test palp-2.21/Subadd.c0000664000177600017760000016127314572603263013326 0ustar skarkeskarke#include "Global.h" #include "Subpoly.h" /* VF_2_ucNF / UCnf2vNF compression/decompression assumes that vNF[0][0]==1 * (see UCnf2vNF: "{ off=NF[0][0]-1; ..." */ /* Write_List_2_File */ /* BIN File Format: ==[FileINFO|data] MAX_REC_DEPTH * [FileINFO]:: [RecDepth<128] or [128+rd/256,rd%256] but: .<7 !!! * L->b[] rd byte <256 !! * d #Vposs #Vmax NUCmax 4 byte <256 !! * #li #NF #SM #NM #NB 5*4byte <2^32!! but: NB%2^32 * sublattice #N? #SM #NM #NB 4*4byte * #v_ #nu_ #v2 nu2 ... 2 byte <256 !! * -> nu nNF 1+4byte ... li=sum_{#nu(v)} */ #define TEST_UCnf /* ==== check that decomp(compress)=id ==== */ #if ( 2 * WATCHREF > SAVE_INC ) #error increase SAVE_INC / WATCHREF #endif #ifdef ADD_LIST_LENGTH /* ... square root of SAVE_INC */ #if ( 2 * ADD_LIST_LENGTH > SAVE_INC ) #error increase SAVE_INC / ADD_LIST_LENGTH #endif #else int IntSqrt(int q) /* sqrt(q) => r=1; r'=(q+r*r)/(2r); */ { assert(q>0); if(q<4) return 1; else { /* troubles: e.g. 9408 */ long long r=(q+1)/2,n; while(r > (n=(q+r*r)/(2*r))) r=n; if(qj) omitted === */ #define INCREMENTAL_TIME /* these flags should stay "on" */ #define INCREMENTAL_WRITE /* write no polys from pi-file */ #define ACCEL_PEntComp /* speed optimization flags */ #define USE_UNIT_ENCODE /* ========== Auxiliary routines from Polynf.c ========== */ void Eval_Poly_NF(int *d,int *v,int *f, Long VM[POLY_Dmax][VERT_Nmax], Long VPM[VERT_Nmax][VERT_Nmax], /* in */ Long pNF[POLY_Dmax][VERT_Nmax], int t); /* out */ int Init_rVM_VPM(PolyPointList *P, VertexNumList *_V,EqList *_F, /* in */ int *d,int *v,int *f, Long VM[POLY_Dmax][VERT_Nmax], /* out */ Long VPM[VERT_Nmax][VERT_Nmax]); /* return reflexive */ typedef struct {int base[VERT_Nmax+1][NB_MAX], nuc[VERT_Nmax+1][NB_MAX], v[VERT_Nmax+1];} Base_List; void VF_2_ucNF(PolyPointList *P, VertexNumList *V, EqList *E, /* IN */ int *NV, int *nUC, unsigned char *UC); /* OUT */ void Print_Statistics(NF_List *); void Init_BaseList(Base_List **BL,int *d); /* malloc + init.; BL=&(list) */ void Insert_PPent_into_Pent(NF_List *S); void Read_In_File(NF_List *); void Read_Aux_File(NF_List *); /* ========= End of Headers and TypeDefs ========== */ /* ===================================================================== */ void Init_FInfoList(FInfoList *FI) { int i, j; FI->nNF= FI->nSM= FI->nNM= FI->NB=0; FI->nVmax= FI->NUCmax= FI->nV=0; for(i=0;i<=VERT_Nmax;i++) FI->nNUC[i]=0; FI->NFli=NULL; for(i=0;i<=VERT_Nmax;i++) for(j=0;jNFnum[i][j]=0; } void Init_New_List(NF_List *S) { S->ANB = (SAVE_INC+SL_Nmax) * CperR_MAX; S->NewNB = S->NP = S->nSLP = 0; S->RemNB=S->PEN=S->PPEN=S->SLN=0; S->peNM=S->peSM=S->slNM=S->slSM=0; S->PE = (PEnt *) malloc( (SAVE_INC+SL_Nmax) * sizeof(PEnt) ); S->PPE = (PPEnt *) malloc( ADD_LIST_LENGTH * sizeof(PPEnt) ); S->SLp = (int *) malloc( SL_Nmax * sizeof(int) ); S->NewNF = (unsigned char *) malloc( S->ANB * sizeof(char) ); S->NC = 0; assert((S->PE!=NULL)&&(S->PPE!=NULL)&&(S->SLp!=NULL)&&(S->NewNF!=NULL)); #ifdef __DECC /* printf("NULL=%p S->PE=%p S->NewNF=%p\n",NULL,S->PE,S->NewNF); */ #endif } NF_List *AuxNFLptr=NULL; /* dirty trick for Xmin Xmax Xdif */ void Init_NF_List(NF_List *L) { L->TIME= L->SAVE= time(NULL); fputs(ctime(&L->TIME),stdout); L->CLOCK= clock(); L->IP_Time = L->NF_Time = 0; L->d = L->nNF = L->nIP = L->nSLNF = 0; Init_FInfoList(&L->In); if(*L->iname) Read_In_File(L); if(*L->dbname) Init_DB(L); Init_FInfoList(&L->Aux); Init_New_List(L); L->savedNP= 0; AuxNFLptr=L; if(L->rf) Read_Aux_File(L); else L->rd=0; } void PrintNumbers(NF_List *S) { printf( "NP=%lld nSLP=%d H=2*%lld - %lldnm - %dsm SL=2*%d - %dnm - %dsm\n", S->NP, S->nSLP, S->Aux.nNF+S->PEN+S->PPEN, S->Aux.nNM+S->peNM, S->peSM+S->Aux.nSM, S->SLN, S->slNM, S->slSM); fflush(stdout); } void Test_SLnbMS(NF_List *S) { int i, tNB=0, tNM=0, tSM=0, testNB=!(S->PEN||S->PPEN); if(testNB)assert(S->RemNB==0); for(i=0;iSLN;i++) { unsigned char *C=&S->NewNF[S->SLp[i]]; int ms=C[2]%4; if(C[0]>VERT_Nmax) {printf("v[%d]=%d\n",i,C[0]);exit(0);} tNB+=C[1]+2; if(ms) {if(ms<3)tNM++;} else tSM++; } if((S->slNM!=tNM) || (S->slSM!=tSM) || (testNB&&(S->NewNB!=tNB))) { printf("Test_SLnbMS NM: %d=%d SM: %d=%d NM: %lld=%d",S->slNM,tNM, S->slSM,tSM,S->NewNB,tNB); exit(0); } assert(S->nSLP==2*S->SLN-tSM-tNM); } void Test_ucNF(int *d, int *tnv, int *tnuc, unsigned char *tuc, PolyPointList *_P); void Test_NF_List(NF_List *S, PolyPointList *_P) { int i; if(S->PPEN) Insert_PPent_into_Pent(S); printf("test PEN=%d ",S->PEN); for(i=0;iPEN;i++) { unsigned char *C=&S->NewNF[S->PE[i].c], *uc=&C[2]; int nv=C[0], nuc=C[1]; Test_ucNF(&S->d,&nv,&nuc,uc,_P); if(i) { unsigned char *oldC=&S->NewNF[S->PE[i-1].c], *olduc=&C[2]; unsigned int oldn=S->PE[i-1].n; if(oldC[0]>nv) { printf("NV failed at i=%d\n",i);exit(0); } if(oldC[0]==nv) { assert(oldC[1]<=nuc); if(oldC[1]==nuc) if(RIGHTminusLEFT(olduc,uc,&nuc)<0) { printf("failed at i=%d\n",i);exit(0); } if(oldC[1]==nuc) if(oldn>S->PE[i].n) { printf("oldn>S->PE[%d].n\n",i);exit(0); } } } } /* printf("test SLN=%d ",S->SLN); for(i=0;iSLN;i++) { unsigned char *C=&S->NewNF[S->SLp[i]], *uc=&C[2]; int nv=C[0], nuc=C[1]; Test_ucNF(&S->d,&nv,&nuc,uc); } puts("Test o.k."); */ } void Test_PPEN(NF_List *S) { int i; /* printf("test PPEN=%d ",S->PPEN); */ for(i=0;iPPEN;i++) { unsigned char *C=&S->NewNF[S->PPE[i].pe.c], *uc=&C[2]; int nv=C[0], nuc=C[1]; /** / Test_ucNF(&S->d,&nv,&nuc,uc); / **/ if(i) { unsigned char *oldC=&S->NewNF[S->PPE[i-1].pe.c], *olduc=&oldC[2]; if(oldC[0]>nv) { printf("NV failed at i=%d: v%d=%d v%d=%d\n", i,i,*C,i-1,*oldC);exit(0); } if(oldC[0]==nv) { assert(oldC[1]<=nuc); if(oldC[1]==nuc) if(RIGHTminusLEFT(olduc,uc,&nuc)<0) { printf("failed at i=%d\n",i);exit(0); } } } } } int InfoSize(int rd, int lists, FInfoList *FI) { return (rd/128+rd+1 + 4+ 2*FI->nV+ lists) + sizeof(int) * (9 + lists); } unsigned int fgetUI(FILE *F) /* read unsigned int from bin file */ { unsigned char A,B,C,D; /* L=D+256*(C+256*(B+256*A)); */ fscanf(F,"%c%c%c%c",&A,&B,&C,&D); return (((unsigned int)A * 256 + (unsigned int)B) * 256 + (unsigned int)C) * 256 + (unsigned int)D; } void Read_Bin_Info(FILE *F, int *d, unsigned *li, int *SLN, int *slSM, int *slNM, Along *NewSLnb, FInfoList *FI) { int i,j,v; unsigned tli=0; Along tNF=0,tNB=0; *d=fgetc(F); assert(*d <= POLY_Dmax); FI->nV=fgetc(F); FI->nVmax=fgetc(F); FI->NUCmax=fgetc(F); *li=fgetUI(F); FI->nNF=fgetUI(F); FI->nSM=fgetUI(F); FI->nNM=fgetUI(F); FI->NB=fgetUI(F); *SLN=fgetUI(F); *slSM=fgetUI(F); *slNM=fgetUI(F); *NewSLnb=fgetUI(F); for(i=0;inV;i++) { v=fgetc(F); tli+=(FI->nNUC[v]=fgetc(F)); for(j=0;jnNUC[v];j++) { unsigned nu, nnb=FI->NFnum[v][nu=fgetc(F)]=fgetUI(F); tNF+=nnb; tNB+=nnb*nu; } } assert(tNF==FI->nNF); assert(tli==*li); assert( 0 == (unsigned int) (tNB-FI->NB) ); FI->NB=tNB; } void Read_Honest_Poly(FILE *F,FInfoList *FI,NF_List *L) { int i, v, nu; unsigned li; Along tNF=0, pos=0; Init_FInfoList(FI); L->rd=fgetc(F); if(128<=(L->rd)) { assert((L->rd-=128)<7); L->rd = 128*L->rd + fgetc(F); /* DirtyFix rd */ } for(i=0;ird;i++) L->b[i]=fgetc(F); Read_Bin_Info(F,&L->d,&li,&L->SLN,&L->slSM,&L->slNM,&L->NewNB,FI); L->nSLP=2*L->SLN-L->slSM-L->slNM; L->PEN=L->PPEN=L->peNM=L->peSM=0; L->NP=L->savedNP=L->nSLP+2*FI->nNF-FI->nSM-FI->nNM; L->RemNB=0; printf("%lld+%dsl %lldm+%ds %lldb",L->NP-L->nSLP,L->nSLP, FI->nNF-FI->nSM-FI->nNM,FI->nSM, FI->NB+L->NewNB); if(L->rd) printf(" rd=%d",L->rd); if(FI->NFli != NULL) printf("WARNing: NFli != NULL"); fflush(stdout); FI->NFli = (unsigned char *) malloc( FI->NB * sizeof(char) ); if(FI->NFli==NULL) {puts("Aux.NFli allocation failed");exit(0);} for(v=L->d+1;v<=FI->nVmax;v++) if(FI->nNUC[v]) for(nu=1;nu<=FI->NUCmax;nu++) if(FI->NFnum[v][nu]) { unsigned j; FI->NF[v][nu]=&FI->NFli[pos]; tNF+=FI->NFnum[v][nu]; for(j=0;jNFnum[v][nu];j++) for(i=0;iNFli[pos++]=fgetc(F); } assert(pos==FI->NB); /* printf("\nRead: tNF=%d pos=%d\n",tNF,pos); for(v=L->d+1;v<=FI->nVmax;v++) if(FI->nNUC[v]) for(nu=1;nu<=FI->NUCmax;nu++) for(j=0;jNFnum[v][nu];j++) Test_ucNF(&L->d,&v,&nu,&FI->NF[v][nu][nu*j]); puts("o.k."); */ } void Read_SubLat_Poly(FILE *F,NF_List *L) { int i, j, pos=0; for(i=0;iSLN;i++) { unsigned char *C=&L->NewNF[pos]; L->SLp[i]=pos; L->NewNF[pos++]=fgetc(F); L->NewNF[pos++]=fgetc(F); for(j=0;jNewNF[pos++]=fgetc(F); } assert(pos==L->NewNB); } void Read_In_File(NF_List *S) { time_t Tstart=time(NULL); FILE *F=fopen(S->iname,"rb"); /* F=fopen */ printf("Reading In-File %s: ",S->iname);fflush(stdout); if(F==NULL) {puts("Cannot open (read)!"); exit(0);} Read_Honest_Poly(F,&S->In,S); S->NP=S->nSLP=0; assert(S->rd==0); fclose(F); printf(" done (%ds)\n",(int) difftime(time(NULL),Tstart)); fflush(stdout); } void Read_File_2_List(char *fn,NF_List *L) /* ... like Read_Aux_File */ { time_t Tstart=time(NULL); FILE *F=fopen(fn,"rb"); printf("Reading %s: ",fn); if(F==NULL) {puts("Cannot open (read)!"); exit(0);} Read_Honest_Poly(F,&L->Aux,L); Read_SubLat_Poly(F,L); printf(" done (%ds)\n",(int) difftime(time(NULL),Tstart)); fclose(F); fflush(stdout); } void Read_Aux_File(NF_List *L) { time_t Tstart=time(NULL); FILE *F; /* F=fopen */ int NCalloc=strlen(L->oname)+strlen(SAVE_FILE_EXT)+ (USE_TMP_DIR ? 6 : 1); char *auxfn = (char *) malloc(NCalloc); if(USE_TMP_DIR) {strcpy(auxfn,"/tmp/"); strcat(auxfn,L->oname);} else strcpy(auxfn,L->oname); strcat(auxfn,SAVE_FILE_EXT); F=fopen(auxfn,"rb"); printf("Reading %s: ",auxfn); fflush(stdout); if(F==NULL) puts("No aux-file found!"); else { Read_Honest_Poly(F,&L->Aux,L); Read_SubLat_Poly(F,L); printf(" done (%ds)\n",(int) difftime(time(NULL),Tstart)); fclose(F); fflush(stdout); #ifdef MOVE_SAVE_FILE /* inconsistent with USE_TMP_DIR !! */ {char *Mfn=(char *) malloc(1+strlen(L->oname)+strlen(MOVE_SAVE_FILE)); strcpy(Mfn,L->oname); strcat(Mfn,MOVE_SAVE_FILE); assert(!rename(auxfn,Mfn)); free(Mfn);} #endif } fflush(stdout); free(auxfn); } void fputUI(unsigned int l,FILE *F) /* write unsigned int to bin file */ { unsigned char A,B,C,D; D=l % 256; l/=256; C=l % 256; l/=256; B=l % 256; l/=256; A=l; fprintf(F,"%c%c%c%c",A,B,C,D); } void TestMSbits(NF_List *S, PolyPointList *_P) { int i, v, nu, tc, peNF=0,peSM=0,peNM=0, slNF=0, slSM=0,slNM=0,axSM=0; UPint axNF=0,axNM=0; for(i=0;iPEN;i++) { unsigned char *C=&S->NewNF[S->PE[i].c]; int ms=C[2]%4; peNF++; { /* int nv=*C,nuc=C[1]; Test_ucNF(&S->d,&nv,&nuc,&C[2]);*/ } if(ms==0) (peSM)++; else if(ms!=3) (peNM)++; } for(i=0;iPPEN;i++) { unsigned char *C=&S->NewNF[S->PPE[i].pe.c]; int ms=C[2]%4; peNF++; { /* int nv=*C,nuc=C[1]; Test_ucNF(&S->d,&nv,&nuc,&C[2]);*/ } if(ms==0) (peSM)++; else if(ms!=3) (peNM)++; } for(v=S->d+1;v<=S->Aux.nVmax;v++) if(S->Aux.nNUC[v]) for(nu=1;nu<=S->Aux.NUCmax;nu++) if((tc=S->Aux.NFnum[v][nu])) for(i=0;iAux.NF[v][nu][nu*i]; int ms=C[0]%4; axNF++; if(ms==0) (axSM)++; else if(ms!=3) (axNM)++; } printf("\nTEST: hNP=%lld hNF=%d+%lld=%d+%d nNM=%d+%d nSM=%d+%d\n", S->NP-S->nSLP,S->PEN+S->PPEN,S->Aux.nNF,peNF,axNF,peNM,axNM,peSM, axSM); fflush(stdout); assert(S->NP-S->nSLP == 2*peNF-peNM-peSM + 2*axNF-axNM-axSM); for(i=0;iSLN;i++) { unsigned char *C=&S->NewNF[S->SLp[i]]; int ms=C[2]%4; slNF++; {int nv=*C,nuc=C[1]; Test_ucNF(&S->d,&nv,&nuc,&C[2],_P); } if(ms==0) (slSM)++; else if(ms!=3) (slNM)++; } printf(" sl: slNP=%d slNF=%d=%d slNM=%d slSM=%d\n\n", S->nSLP,S->SLN,slNF,slNM,slSM); fflush(stdout); assert(S->nSLP == 2*slNF-slNM-slSM); } void AuxCalcNumbers(NF_List *S,FInfoList *AI) { int i,j; Init_FInfoList(AI); if(S->PPEN) Insert_PPent_into_Pent(S); for(i=0;iPEN;i++) { unsigned char *C=&S->NewNF[S->PE[i].c]; int ms=C[2]%4; AI->nNF++; ++(AI->NFnum[C[0]][C[1]]); if(ms==0) (AI->nSM)++; else if(ms!=3) (AI->nNM)++; } for(i=S->d+1;i<=VERT_Nmax;i++) for(j=0;jNFnum[i][j]) { AI->nNUC[i]++; if(j>AI->NUCmax)AI->NUCmax=j; AI->NB += j * AI->NFnum[i][j]; } /* TestMSbits(S); */ for(i=S->d+1;i<=VERT_Nmax;i++) if(AI->nNUC[i]) AI->nVmax=i; } /* uchar=unsigned char uint=unsigned int * NP=#Polys NB=#Bytes #files=#nv's with NP>0 #lists=#(nv,nuc) with NP>0 * * uchar rd k_1 ... k_rd // ... not in data base !! * // big rd: "128+rd/128" "rd%128" * uchar dim #files nv_max nuc_max * uint #lists hNF hSM hNM hNB slNF slSM slNM slNB * uchar v1 #nuc's with v1 * uchar nuc1 uint #NF(v1,nuc1) uchar nuc2 uint #NV(v1,nuc2) ... * uchar v2 #nuc's with v2 * uchar nuc1 uint #NF(v2,nuc1) uchar nuc2 uint #NV(v2,nuc2) ... * uchar "all hNF honest nf's" * uchar "all slNF sublattice {nv nuc nf[]}'s" */ void Write_Bin_File(FILE *F,NF_List *L) { unsigned int i,j,fi=0,li=0,v,nu,tc=0,pen=0, tnb; UPint NFnum[VERT_Nmax][NUC_Nmax]; int n; unsigned char *C, nVmax,NUCmax; FInfoList AI, *_AI = (FInfoList *) &AI; printf("%lld+%dsl %lldm+%ds %lldb",L->NP-L->nSLP,L->nSLP, L->Aux.nNF - L->Aux.nNM - L->Aux.nSM + L->PEN + L->PPEN - L->peNM - L->peSM, L->Aux.nSM + L->peSM, /* nNF :: L->Aux.nNF+L->PEN+L->PPEN+L->SLN, */ L->Aux.NB+L->NewNB-L->RemNB-2*(L->PEN+L->PPEN)); if(L->rd) printf(" rd=%d",L->rd); #ifdef USE_UNIT_ENCODE if(L->NC>0) printf(" u%lld",L->NC*100 / (L->Aux.nNF+L->PEN+L->PPEN) ); #endif AuxCalcNumbers(L,_AI); Print_Expect(_AI); fflush(stdout); nVmax=max(L->Aux.nVmax,AI.nVmax); NUCmax=max(L->Aux.NUCmax,AI.NUCmax); for(i=L->d+1;i<=nVmax;i++) { int v_li=0; for(j=1;j<=NUCmax;j++) if((NFnum[i][j]=L->Aux.NFnum[i][j]+AI.NFnum[i][j])) v_li++; li+=v_li; if(v_li) fi++; } assert(L->rd <= MAX_REC_DEPTH); if(L->rd < 128) fputc(L->rd,F); else {fputc(128+(L->rd)/128,F); fputc((L->rd)%128,F);} for(n=0;nrd;n++) fputc(L->b[n],F); fputc(L->d,F); fputc(fi,F); fputc(nVmax,F); fputc(NUCmax,F); fputUI(li,F); fputUI(L->Aux.nNF+AI.nNF,F); fputUI(L->Aux.nSM+AI.nSM,F); fputUI(L->Aux.nNM+AI.nNM,F); #ifdef TEST_Write printf("\nd=%d nV=%d nVmax=%d NUCmax=%d #lists=%d ", L->d,fi,nVmax,NUCmax,li); fflush(stdout); printf("%dnf %dsm %dnm %lldb sl: %d %d %d %lld\n",L->Aux.nNF+AI.nNF, L->Aux.nSM+AI.nSM,L->Aux.nNM+AI.nNM,L->Aux.NB+AI.NB,L->SLN, L->slSM,L->slNM,L->NewNB-L->RemNB-AI.NB-2*AI.nNF); fflush(stdout); #endif assert(L->NP-L->nSLP==2*AI.nNF-AI.nNM-AI.nSM +2*L->Aux.nNF-L->Aux.nNM-L->Aux.nSM); fputUI(tnb=L->Aux.NB+AI.NB,F); fputUI(L->SLN,F); fputUI(L->slSM,F); fputUI(L->slNM,F); assert(L->nSLP==2*L->SLN-L->slNM-L->slSM); fputUI(L->NewNB-L->RemNB-AI.NB-2*AI.nNF,F); for(v=L->d+1;v<=nVmax;v++) if(AI.nNUC[v]+L->Aux.nNUC[v]) { i=0; for(nu=1;nu<=NUCmax;nu++) if(NFnum[v][nu]) i++; #ifdef TEST_Write printf("v%d:n%d ",v,i); #endif fputc(v,F); fputc(i,F); /* v #nuc(v) */ for(nu=1;nu<=NUCmax;nu++) if(NFnum[v][nu]) { fputc(nu,F); fputUI(NFnum[v][nu],F); /* nuc #NF */ } } j=0; for(v=L->d+1;v<=nVmax;v++) if(AI.nNUC[v] || L->Aux.nNUC[v]) for(nu=1;nu<=NUCmax;nu++) if((tc=NFnum[v][nu])) { unsigned int k; pen+=AI.NFnum[v][nu]; /* n -> i; lipos -> j */ for(i=0; i < (L->Aux.NFnum[v][nu]); i++) { if(jPE[j].n == i) { C=&L->NewNF[L->PE[j++].c+2];for(k=0;kAux.NF[v][nu][nu*i]; for(k=0;kNewNF[L->PE[j++].c+2]; for(k=0;kSLN;n++) /* =S->nSLP */ { C=&L->NewNF[L->SLp[n]]; nu=C[1]+2; for(j=0;jNewNB-L->RemNB-AI.NB-2*AI.nNF); #ifdef More_File_IO_Data printf("\n nv<=%d nuc<=%d files=%d lists=%d nNF=%d NB=%lld ..", nVmax,NUCmax,fi,li,AI.nNF,AI.NB); #endif if(NULL!=L->Aux.NFli) {free(L->Aux.NFli); L->Aux.NFli=NULL;} } void Write_Aux_File(NF_List *S) { time_t Tstart=time(NULL); FILE *F; int NCalloc=strlen(S->oname)+strlen(SAVE_FILE_EXT)+ (USE_TMP_DIR ? 6 : 1); char *auxfn = (char *) malloc(NCalloc); #ifdef TEMP_FILE_EXT char *tmpfn = (char *) malloc(1+strlen(S->oname)+4); strcpy(tmpfn,S->oname); strcat(tmpfn,".tmp"); #else char *tmpfn = auxfn; #endif if(USE_TMP_DIR) {strcpy(auxfn,"/tmp/"); strcat(auxfn,S->oname);} else strcpy(auxfn,S->oname); strcat(auxfn,SAVE_FILE_EXT); F=fopen(tmpfn,"wb"); printf("Writing %s: ",auxfn); fflush(stdout); if(F==NULL){puts("Cannot open!");exit(0);} Write_Bin_File(F,S); if(ferror(F)) {puts("File ERROR!!");exit(0);} fclose(F); printf(" done: %ds\n",(int) difftime(time(NULL),Tstart)); fflush(stdout); free(auxfn); #ifdef TEMP_FILE_EXT rename(tmpfn,auxfn); free(tmpfn); #endif } void Write_List_2_File(char *fn,NF_List *S) { time_t Tstart=time(NULL); FILE *F=fopen(fn,"wb"); printf("Writing %s: ",fn); fflush(stdout); if(F==NULL){puts("Cannot open!");exit(0);} Write_Bin_File(F,S); if(ferror(F)) {puts("File ERROR!!");exit(0);} fclose(F); printf(" done: %ds\n",(int) difftime(time(NULL),Tstart)); S->SAVE=time(NULL); fflush(stdout); } void ReAlloc_SortList(NF_List *L) { Write_Aux_File(L); Read_Aux_File(L); /* Test_SLnbMS(L); TestMSbits(L); */ L->SAVE=time(NULL); } void CheckLastSaveTime(NF_List *L, int maxsec) { if((int)difftime(time(NULL),L->SAVE) > maxsec) { Print_Statistics(L); ReAlloc_SortList(L); } } int PEntComp(int *FIpos,int *nv,int *nuc,unsigned char *uc, /* pe/pos - uc */ PEnt *pe,NF_List *S) { unsigned char *C=&S->NewNF[pe->c]; int i = (int) C[0] - *nv; if(i) return i; i = (int) C[1] - *nuc; if(i) return i; #ifdef ACCEL_PEntComp i = pe->n - *FIpos; if(i) return i; #endif return RIGHTminusLEFT(uc,&(C[2]),nuc); } int SearchPEntList(int *nv,int *nuc,unsigned char *uc, /* 0 :: new */ int *PEpos, int *FIpos, NF_List *S) /* -1 exists(SL) */ { int i, n0, n1; /* +1 ex. honest */ *PEpos=0; if(!S->PEN) return 0; if((i = PEntComp(FIpos,nv,nuc,uc,&S->PE[n0=0],S))) /* i = PE[0] - uc */ { if(i>0) { return 0;}} else return 1; if((i = PEntComp(FIpos,nv,nuc,uc,&S->PE[n1=S->PEN-1],S))) { if(i<0) { *PEpos=S->PEN; return 0;}} else { *PEpos=n1; return 1; } while(n1>n0+1) { *PEpos=(n0+n1)/2; i=PEntComp(FIpos,nv,nuc,uc,&S->PE[*PEpos],S); if(i) if(i>0) n1=*PEpos; else n0=*PEpos; else return 1; } *PEpos=n1; return 0; /* exists: return 1; else PEpos=where it would go */ } void Insert_PPent_into_Pent(NF_List *S) { int Mpos=S->PEN, Spos=S->PPEN, pos=Mpos+Spos; if(S->PPEN<=0) { puts("This should not happen in Insert_PPent_into_Pent");exit(0); } assert(pos<=SAVE_INC+SL_Nmax); while(Spos--) { if(S->PPE[Spos].n == Mpos) S->PE[--pos] = S->PPE[Spos].pe; else break; } if(++Spos) while(Spos--) { while(S->PPE[Spos].n < Mpos) S->PE[--pos] = S->PE[--Mpos]; S->PE[--pos] = S->PPE[Spos].pe; } S->PEN+=S->PPEN; S->PPEN=0; /* Test_NF_List(S); */ } int PPEntComp(int *FIpos,int *PEpos,int *nv,int *nuc,unsigned char *uc, PPEnt *ppe,NF_List *S) /* ppe/pos - uc */ { unsigned char *C=&S->NewNF[ppe->pe.c]; int i = (int) C[0] - *nv; if(i) return i; i = (int) C[1] - *nuc; if(i) return i; #ifdef ACCEL_PEntComp i = ppe->n - *PEpos; if(i) return i; if((i=ppe->pe.n -*FIpos)) return i; #endif return RIGHTminusLEFT(uc,&(C[2]),nuc); } void InsertPNFintoPPEntList(int *spos, int *mpos, int *lpos, int *nv, int *nuc, unsigned char *uc, NF_List *S) { int l=S->PPEN++; unsigned char *C=&(S->NewNF[S->NewNB]); PPEnt *ppe=&S->PPE[*spos]; static int AddListLength; if(0==AddListLength) AddListLength=ADD_LIST_LENGTH; #ifdef USE_UNIT_ENCODE if((*uc % 8) > 3) S->NC ++; #endif if(*nuc+2+S->NewNB > S->ANB) { printf("increase CperR_MAX or write/read %s\n",S->iname); exit(0); } while(*spos < (l--)) S->PPE[l+1]=S->PPE[l]; ppe->n=*mpos; ppe->pe.n=*lpos; ppe->pe.c=S->NewNB; C[0]=*nv; C[1]=*nuc; C=&C[2]; for(l=0;l<*nuc;l++) C[l]=uc[l]; S->NewNB += *nuc+2; S->NP++; if(*C % 4) S->peNM++; else S->peSM++; if(S->PPEN==AddListLength) Insert_PPent_into_Pent(S); } int SearchPPEntList(int *nv,int *nuc,unsigned char *uc, /* new :: 0 */ int *Ppos, int *Mpos,int *Lpos, NF_List *S) /* exists :: 1 */ { int i, n0, n1; *Ppos=0; if(!S->PPEN) return 0; if((i = PPEntComp(Lpos,Mpos,nv,nuc,uc,&S->PPE[n0=0],S))) { if(i>0) { *Ppos=0; return 0;}} else return 1; if((i = PPEntComp(Lpos,Mpos,nv,nuc,uc,&S->PPE[n1=S->PPEN-1],S))) { if(i<0) { *Ppos=S->PPEN; return 0;}} else {*Ppos=n1; return 1;} while(n1>n0+1) { *Ppos=(n0+n1)/2; i=PPEntComp(Lpos,Mpos,nv,nuc,uc,&S->PPE[*Ppos],S); if(i) if(i>0) n1=*Ppos; else n0=*Ppos; else return 1; } *Ppos=n1; return 0; /* exists: return 1; else Ppos=where it would go */ } int SearchFIList(int *v,int *nu,unsigned char *uc, int *pos,FInfoList *FI) { int i, n0, n1; *pos=0; if(!FI->nNF) return 0; if(!FI->NFnum[*v][*nu]) return 0; if((i = RIGHTminusLEFT(uc,&FI->NF[*v][*nu][n0=0],nu))) { if(i>0) return 0;} else return 1; if((i = RIGHTminusLEFT(uc, &FI->NF[*v][*nu][(*nu)*(n1=FI->NFnum[*v][*nu]-1)],nu))) { if(i<0) { *pos=n1+1; return 0;}} else {*pos=n1; return 1;} while(n1>n0+1) { *pos=(n0+n1)/2; i=RIGHTminusLEFT(uc, &FI->NF[*v][*nu][(*nu)*(*pos)],nu); if(i) if(i>0) n1=*pos; else n0=*pos; else return 1; } *pos=n1; return 0; /* exists: return 1; else pos=where it would go */ } int SL_Comp(int *nv,int *nuc,unsigned char *uc,int *lipos,NF_List *S) { unsigned char *C=&S->NewNF[*lipos]; /* lipos - uc */ int i = (int) C[0] - *nv; if(i) return i; i = (int) C[1] - *nuc; if(i) return i; return RIGHTminusLEFT(uc,&(C[2]),nuc); } int SearchSL_List(int *nv,int *nuc,unsigned char *uc, int *SLnum,NF_List *S) { int i, n0, n1; /* 1 = exists (mirror or straight) */ *SLnum=0; if(!S->SLN) return 0; if((i = SL_Comp(nv,nuc,uc,&S->SLp[n0=0],S))) { if(i>0) { return 0;}} else return 1; if((i = SL_Comp(nv,nuc,uc,&S->SLp[n1=S->SLN-1],S))) { if(i<0) { *SLnum=S->SLN; return 0;}} else { *SLnum=n1; return 1;} while(n1>n0+1) { *SLnum=(n0+n1)/2; i=SL_Comp(nv,nuc,uc,&S->SLp[*SLnum],S); if(i) if(i>0) n1=*SLnum; else n0=*SLnum; else return 1; } *SLnum=n1; return 0; /* exists: return 1; else SLnum=where it would go */ } void SL_List_Insert(int *nv,int *nuc,unsigned char *uc,int *SLnum,NF_List *S) { int l=S->SLN++; unsigned char *C=&(S->NewNF[S->NewNB]); if(*nuc+2 + S->NewNB > S->ANB) { printf("increase CperR_MAX or write/read %s\n",S->iname); exit(0); } while(*SLnum < (l--)) S->SLp[l+1]=S->SLp[l]; S->SLp[*SLnum]=S->NewNB; C[0]=*nv; C[1]=*nuc; C=&C[2]; for(l=0;l<*nuc;l++) C[l]=uc[l]; S->NewNB+=*nuc+2; S->NP++;S->nSLP++; if(*C % 4)S->slNM++; else S->slSM++; if(S->SLN==SL_Nmax) {puts("Increase SL_Nmax");exit(0);} } void SL_List_Remove(int *NV,int *nUC, /* unsigned char *UC, */ int *SLnum, NF_List *S) { int l=*SLnum; unsigned char *C=&S->NewNF[S->SLp[l]]; S->RemNB += (2+C[1]); if(C[2] % 4) S->slNM--; else S->slSM--; assert((*NV==C[0]) && (*nUC==C[1])); /* assert(0==RIGHTminusLEFT(UC,&C[2],nUC)); */ while ((++l) < S->SLN) S->SLp[l-1]=S->SLp[l]; S->SLN--; S->NP--; S->nSLP--; } #define MirTest(A,B) ((((A)+(B)) % 4) != 3) /* 1=same, 0=only mirror */ /* ucNF_Sort_Add = 1 = continue = V is honest and new ; * 0 = SL or Ex(honest) * Search...List = 1 : 0 : -1 iff honest : new : sublattice */ int ucNF_Sort_Add(int *NV, int *nUC, unsigned char *UC, NF_List *S) { int InPos=0, FIpos=0, PEpos=0, NEWpos=0, NewH=0, NewSL=0; #ifdef INCREMENTAL_WRITE if(SearchFIList(NV,nUC,UC,&InPos, &S->In)) if(MirTest(*UC,S->In.NF[*NV][*nUC][(*nUC)*InPos])) { if(!S->SL) S->hc++; goto Ret0;} #endif if(*S->dbname) if(Is_in_DB(NV,nUC,UC,S)) {if(!S->SL) S->hc++; goto Ret0;} if(SearchFIList(NV,nUC,UC,&FIpos,&S->Aux)) { unsigned char *c=&(S->Aux.NF[*NV][*nUC][(*nUC)*FIpos]); if(MirTest(*UC,*c)) goto Ret0; /* if(S->con==S->AP) S->hc++; */ else if(!S->SL) { (*c) += ((*UC) % 4); S->Aux.nNM--; S->NP++; NewH=1; } /* Mir(honest) on Aux => not on New */ } else if(SearchPEntList (NV,nUC,UC,&PEpos,&FIpos,S)) { unsigned char *c=&(S->NewNF[S->PE[PEpos].c+2]); if(MirTest(*UC,*c)) goto Ret0; else if(!S->SL) { (*c) += ((*UC) % 4); S->peNM--; S->NP++; NewH=1; } /* Mir(honest) on PE => not on PPE */ } else if(SearchPPEntList(NV,nUC,UC,&NEWpos,&PEpos,&FIpos,S)) { unsigned char *c=&(S->NewNF[S->PPE[NEWpos].pe.c+2]); if(MirTest(*UC,*c)) goto Ret0; else if(!S->SL) { (*c) += ((*UC) % 4); S->peNM--; S->NP++; NewH=1; } } else if(!S->SL) { InsertPNFintoPPEntList(&NEWpos,&PEpos,&FIpos,NV,nUC,UC,S); NewH=1; } assert(NewH + S->SL == 1); if(SearchSL_List(NV,nUC,UC,&NEWpos,S)) { unsigned char *c=&(S->NewNF[S->SLp[NEWpos]+2]); if(NewH) { if(MirTest(*UC,*c)) { if((*c % 4) != 3) SL_List_Remove(NV,nUC, /*UC,*/ &NEWpos,S); else { (*c) -= (*UC % 4); S->slNM++; S->NP--; S->nSLP--;} NewSL=-1; } } else /* SubLattice case */ { if(MirTest(*UC,*c)) goto Ret0; else { (*c) += ((*UC) % 4); S->NP++; S->slNM--;S->nSLP++;NewSL=1;} } } else if(S->SL) {assert(NewH==0); NewSL=1; SL_List_Insert(NV,nUC,UC,&NEWpos,S);} if(NewH+NewSL) if(S->NP % WATCHREF == 0) { Print_Statistics(S); if(S->NP - S->savedNP > SAVE_INC - WATCHREF) /* printf("NP=%d PEN=%d peNM=%d peSM=%d\n", S->NP,S->PEN,S->peNM, S->peSM);fflush(stdout); if(2 *(S->PEN+S->PPEN) - S->peNM - S->peSM > SAVE_INC - WATCHREF)*/ { ReAlloc_SortList(S); S->con=0; } } if(S->NP%1000 == 0) CheckLastSaveTime(S,(19*GOOD_SAVE_TIME)/20); CheckLastSaveTime(S,GOOD_SAVE_TIME); return NewH; Ret0: CheckLastSaveTime(S,FORCE_SAVE_TIME); return 0; } /* ============================================================== */ /* ============================================================== */ void Print_Statistics(NF_List *_L) { clock_t CLOCK=clock(); time_t DATE=time(NULL); int CPUsec=(CLOCK-_L->CLOCK)/CLOCKS_PER_SEC; /* CLOCKS_PER_SEC::10^6 */ int REALsec= (int) difftime(DATE,_L->TIME), NFsec; /* int IPperNF; */ char bni[2]; int BNI=(_L->nNF>2000000) ? 1000000 : 1000; strcpy(bni,(BNI==1000) ? "k" : "M"); printf("%dkR-%d %dMB %d%sIP %d%sNF-%dk ", (int)_L->NP/1000, (int)_L->nSLP,(int) ((_L->NewNB-_L->RemNB+_L->Aux.NB)/1000000), (int) (_L->nIP/BNI),bni,(int)_L->nNF/BNI,bni,(int)_L->nSLNF/1000); printf("%d%s%d v%dr%d f%dr%d %db%d", _L->Nmin, _L->hc ? "-" : "_", _L->Nmax, _L->VN,_L->V, _L->FN,_L->F, _L->Xdif, _L->Xnuc); #ifdef INCREMENTAL_TIME /* if(_L->NF_Time>0)IPperNF=_L->IP_Time/_L->NF_Time; else IPperNF=-1; */ NFsec=_L->NF_Time/CLOCKS_PER_SEC; CPUsec=(_L->IP_Time+_L->NF_Time)/CLOCKS_PER_SEC; if(CPUsec<1000)printf(" %ds %du %dn",REALsec,CPUsec,NFsec); else if((CPUsec)<60000) printf(" %dm %du %dn",REALsec/60,CPUsec/60,NFsec/60); else printf(" %dh %du %dn",REALsec/3600,CPUsec/3600,NFsec/3600); #else CPUsec=(CLOCK-_L->CLOCK)/CLOCKS_PER_SEC; if(CPUsec<1000)printf(" %ds %du",REALsec,CPUsec); else if((CPUsec)<60000) printf(" %dm %du",REALsec/60,CPUsec/60); else printf(" %dh %du",REALsec/3600,CPUsec/3600); #endif _L->Nmin=1000; _L->Nmax=0; puts(""); fflush(stdout); } void Print_Expect(FInfoList *L) { int s=L->nSM; Along m=L->nNF-L->nNM-L->nSM, p=L->nNF+m; double x=p; /* if(d<2) {if(m)printf(" p^2/2m=%d",(p*p)/(2*m)); if(s)printf(" pp/ss=%d",(p*p)/(s*s));} */ /* if(m) {x*=(x+s)/(2*m);printf(" pP/2m=%g",x);} */ if(m) {x=p+s; x*=x/(2*m+s);printf(" pp/2m=%g",x);} if(s) {x=p; x/=s; x*=x; printf(" pp/ss=%g",x);} } /* ============================================================== */ /* ============================================================== */ /* SearchLongList:= { new(below *pos)::0, found::1 } */ /* SearchPEntLists:={ new::0, found::1 } */ /* Add_NF_to_List() assumes that _V and _F are assigned * * if(SL) { if(new) "add to dishonest"; return 0; } ::stop * if(exists on honest) return 0; ::stop * if(exists on dishonest) { "move to honest"; return 1; } ::cont * "add to honest"; return 1; ::cont * * Make_Poly_NF (Make_VPM_NF; Make_PNF_from_VNF;); * PNF_Sort_Add (NF[][],*d,*np,*nv,*nf,*S) := { List::+1, new::0, PEnt::-1 } * SearchLongList:= { new(below *pos)::0, found::1 } * SearchPEntLists:={ new::0, found::1 } */ int Add_NF_to_List(PolyPointList *_P, VertexNumList *_V, EqList *_E, NF_List *_L) { unsigned char UC[NB_MAX]; int nUC, NV; int NewNF; #ifdef INCREMENTAL_TIME long long cpuT=clock(), incT=cpuT - _L->CLOCK; if(incT>0) _L->IP_Time+=incT; _L->CLOCK=cpuT; #endif if((_E->ne)>_L->F) _L->F=_E->ne; /* check vertex numbers */ if((_V->nv)>_L->V) _L->V=_V->nv; if((_E->ne > VERT_Nmax)||(_V->nv > VERT_Nmax)) { printf("Increase VERT_Nmax: f=%d v=%d\n",_E->ne,_V->nv);exit(0); } if(_P->np>_L->Nmax) _L->Nmax=_P->np; if(_P->np<_L->Nmin) _L->Nmin=_P->np; _L->nNF++; if(_L->SL)_L->nSLNF++; VF_2_ucNF(_P, _V, _E, &NV, &nUC, UC); NewNF=ucNF_Sort_Add(&NV, &nUC, UC, _L); /* 1::new::cont. */ #ifdef INCREMENTAL_TIME cpuT=clock(), incT=cpuT - _L->CLOCK; if(incT>0) _L->NF_Time+=incT; _L->CLOCK=cpuT; #endif return NewNF; } /* #R sl hit #IP #NF TIME( r > u > AddNF) */ void Print_Weight_Info(CWS *W,NF_List *_L) { int i,j; #if POLY_Dmax>3 Print_Statistics(_L); #endif for(i=0;inw;i++) { fprintf(outFILE,"%ld ",W->d[i]); for(j=0;jN;j++) fprintf(outFILE,"%ld ", W->W[i][j]); } for(i=0;inz;i++) { fprintf(outFILE,"/Z%d: ",W->m[i]); for(j=0;jN;j++) fprintf(outFILE,"%d ",W->z[i][j]); } fprintf(outFILE,"R=%lld +%dsl hit=%d IP=%d NF=%d (%d)\n", _L->NP-_L->nSLP, _L->nSLP,_L->hc,_L->nIP,_L->nNF,_L->nSLNF); fflush(outFILE); } /* =============== compression package =================== */ #if (INT_MAX != 2147483647) /* UINT_MAX == 4294967295 */ #error use other date types /* ULLONG_MAX == 18446744073709551615 */ #endif #define UCM 256 /* Unsigned Char Modulo (= max+1) */ #define USM 65536 /* Unsigned Short Modulo (= max+1) */ #define Nint_XLong (NB_MAX + 1) / 2 #define NX(d,v) ((d)*(v)-((d)*(d-1))/2) #ifdef USE_UNIT_ENCODE #define UNIT_NX(d,v) ((d)*((v)-(d))+1) #define UNIT_OFF (8) #else #define UNIT_OFF (4) #endif #ifndef LL_BASE #define LL_BASE 32767 /* limit for 64-bit BaseGetInt: cf. NF of */ #endif /* 3198174 49 1723 74375 456882 1066058 1599087 */ typedef struct {int n; unsigned short x[Nint_XLong];} UXLong; void XPrint(UXLong *X) { int i; printf("X.n=%d:",X->n);for(i=0;in;i++)printf(" %d",X->x[i]); } void VPrint(int *d,int *v,Long V[POLY_Dmax][VERT_Nmax]) { int i,j; puts("");for(i=0;i<*d;i++) { for(j=0;j<*v;j++)printf("%4ld ",V[i][j]);puts("");} } void LLBasePutInt(int *base, int *x, UXLong *X) /* X = X * base + x */ { int i=0; long long z, ad=*x; while(in) { z=ad+(*base)*((long long)X->x[i]); X->x[i++]=z% USM; ad=z / USM; } while(ad) { assert(X->n < Nint_XLong); X->x[X->n++]=ad% USM; ad/=USM; } } void LLBaseGetInt(int *base, int *x, UXLong *X) /* x = X mod b, X /= b */ { int i; long long a, zq, zr; if(!X->n) {*x=0; return;} a=X->x[(i=X->n-1)]; while(i) { zq=a/(*base); zr=a%(*base); X->x[i]=zq; a=zr*USM+X->x[--i]; } zq=a/(*base); zr=a%(*base); X->x[i]=zq; *x=zr; for(i=X->n-1; 0<=i; i--) if(X->x[i]) return; else X->n--; } void BasePutInt(int *base, int *x, UXLong *X) /* X = X * base + x */ { int i=0, z, ad=*x; if(*base > LL_BASE) {LLBasePutInt(base,x,X); return;} while(in) { z=ad+(*base)*X->x[i]; X->x[i++]=z% USM; ad=z / USM; } if(ad) { assert(X->n <= (Nint_XLong-1)); X->x[X->n++]=ad; } } void BaseGetInt(int *base, int *x, UXLong *X) /* x = X mod b, X /= b */ { int i, a; div_t z; if(*base > LL_BASE) {LLBaseGetInt(base,x,X); return;} if(!X->n) {*x=0; return;} a=X->x[(i=X->n-1)]; while(i) { z=div(a,*base); X->x[i]=z.quot; a=z.rem*USM+X->x[--i]; } z=div(a,*base); X->x[i]=z.quot; *x=z.rem; for(i=X->n-1; 0<=i; i--) if(X->x[i]) return; else X->n--; } int BminOff(Long V[POLY_Dmax][VERT_Nmax], int *d, int *v, int *off, int *bmin) { int i, j, moff=0, vmax=0; for(i=0;i<*d;i++) for(j=i;j<*v;j++) { Long x=V[i][j]; if(moff>x) moff=x; if(vmaxn-1 => ... + xm*USM^xm */ for(i=0;i<*nx-1;i++) BasePutInt(base,&m,&X); m--; BasePutInt(base,&m,&X); i=UNIT_OFF; m=i-1; BasePutInt(&i,&m,&X); *nuc=2*X.n-(X.x[X.n-1]<256); } void AuxNextGoodBase(int *v,int *nx,Base_List *BL) /* nx= v*d -d*(d-1)/2 */ { int *bo=&(BL->base[*v][BL->v[*v]-1]), nuct, *bn=&(BL->base[*v][BL->v[*v]]), *nucn=&(BL->nuc[*v][BL->v[*v]]); *bn=*bo+1; AuxBase2nUC(bn,nx,nucn); do { (*bn)++; AuxBase2nUC(bn,nx,&nuct); } while (nuct==*nucn); (*bn)--; BL->v[*v]++; } void Init_BaseList(Base_List **bl, int *d) /* once: alloc and init BaseList */ { static Base_List *BL=NULL; int i; /* always: set *bl=BL=&BaseList */ if(BL!=NULL) {*bl=BL; return;} *bl = BL = (Base_List *) malloc(sizeof(Base_List)); assert(BL!=NULL); for(i=*d; i<=VERT_Nmax; i++) { int nx= NX(*d,i), bn=3, nuco, nucn; BL->v[i]=1; AuxBase2nUC(&bn,&nx,&nuco); nucn=BL->nuc[i][0]=nuco; while(nucn==nuco) { bn++; AuxBase2nUC(&bn,&nx,&nucn); } BL->base[i][0]=bn-1; } } void Bmin2BaseUCn(int *d, int *v, int *bmin, int *base, int *nuc) { int i, *n, nx = NX(*d,*v); Base_List *BL; Init_BaseList(&BL,d); n=&(BL->v[*v]); i=*n-1; if(*bmin<=BL->base[*v][i]) { while(i > 0 && *bmin <= (BL->base[*v][i-1])) --i; } else { do AuxNextGoodBase(v,&nx,BL); while(*bmin > (BL->base[*v][++i])); } *base=BL->base[*v][i]; *nuc=BL->nuc[*v][i]; } void NUCtoBase(int *d, int *v, int *nuc, int *Base) { int i, *n, nx = NX(*d,*v); Base_List *BL; Init_BaseList(&BL,d); n=&(BL->v[*v]); i=*n-1; if(*nuc<=BL->nuc[*v][i]) { while(i > 0 && *nuc <= (BL->nuc[*v][i-1])) --i; } else { do AuxNextGoodBase(v,&nx,BL); while(*nuc > (BL->nuc[*v][++i])); } assert(*nuc==BL->nuc[*v][i]); *Base=BL->base[*v][i]; } #ifdef USE_UNIT_ENCODE void UNIT_Init_BaseList(Base_List **bl, int *d) /* once: ainit BaseList */ { static Base_List *BL=NULL; int i; /* always: set *bl=BL=&BaseList */ if(BL!=NULL) {*bl=BL; return;} *bl = BL = (Base_List *) malloc(sizeof(Base_List)); assert(BL!=NULL); for(i=*d; i<=VERT_Nmax; i++) { int nx= UNIT_NX(*d,i), bn=3, nuco, nucn; BL->v[i]=1; AuxBase2nUC(&bn,&nx,&nuco); nucn=BL->nuc[i][0]=nuco; while(nucn==nuco) { bn++; AuxBase2nUC(&bn,&nx,&nucn); } BL->base[i][0]=bn-1; } } void UNIT_Bmin2BaseUCn(int *d, int *v, int *bmin, int *base, int *nuc) { int i, *n, nx = UNIT_NX(*d,*v); Base_List *BL; UNIT_Init_BaseList(&BL,d); n=&(BL->v[*v]); i=*n-1; if(*bmin<=BL->base[*v][i]) { while(i > 0 && *bmin <= (BL->base[*v][i-1])) --i; } else { do AuxNextGoodBase(v,&nx,BL); while(*bmin > (BL->base[*v][++i])); } *base=BL->base[*v][i]; *nuc=BL->nuc[*v][i]; } void UNIT_NUCtoBase(int *d, int *v, int *nuc, int *Base) { int i, *n, nx = UNIT_NX(*d,*v); Base_List *BL; UNIT_Init_BaseList(&BL,d); n=&(BL->v[*v]); i=*n-1; if(*nuc<=BL->nuc[*v][i]) { while(i > 0 && *nuc <= (BL->nuc[*v][i-1])) --i; } else { do AuxNextGoodBase(v,&nx,BL); while(*nuc > (BL->nuc[*v][++i])); } assert(*nuc==BL->nuc[*v][i]); *Base=BL->base[*v][i]; } #endif /* UNIT :: ms+=4 */ void AuxVnf2ucNF(Long nf[POLY_Dmax][VERT_Nmax], int *d, int *v, int *off, int *base, int *nuc, int *ms, unsigned char *UC) { int i, j, one=(*ms > 3); UXLong X; X.n=0; for(i=0;i<*d;i++) for(j = (one) ? *d : i ;j<*v;j++) { int x=nf[i][j]+(*off); BasePutInt(base,&x,&X); } if(one) BasePutInt(base,off,&X); i=UNIT_OFF; BasePutInt(&i,ms,&X); for(i=X.n;(2*i)<(*nuc);i++) X.x[i]=0; for(i=0;i<*nuc;i++)if(i%2) UC[i]=X.x[i/2] /UCM; else UC[i]=X.x[i/2] %UCM; } void UCnf2vNF(int *d, int *v, int *nuc, unsigned char *uc, /* IN */ Long NF[POLY_Dmax][VERT_Nmax], int *MS) /* OUT */ { int i, j, off=0, base, one; UXLong X; X.n=*nuc/2; if(*nuc % 2) X.x[X.n++]=uc[*nuc-1]; for(i=0;i<*nuc/2;i++) X.x[i]=uc[2*i]+UCM*uc[2*i+1]; i=UNIT_OFF; BaseGetInt(&i,MS,&X); one = (*MS > 3); #ifdef USE_UNIT_ENCODE if(one) {UNIT_NUCtoBase(d,v,nuc,&base); BaseGetInt(&base,&off,&X);} else #endif NUCtoBase(d,v,nuc,&base); i=*d; while(i--) { int m=(one) ? *d : i; j=*v;while(m<(j--)) {int Iau;BaseGetInt(&base,&Iau,&X);NF[i][j]=Iau;} j=i; while(j--) NF[i][j]=0; } #ifdef USE_UNIT_ENCODE if(one) { for(i=0;i<*d;i++) for(j=*d;j<*v;j++) NF[i][j]-=off; for(i=0;i<*d;i++) for(j=i;j<*d;j++) NF[i][j]=(i==j); } else #endif { off=NF[0][0]-1; for(i=0;i<*d;i++) for(j=i;j<*v;j++) NF[i][j]-=off;} for(i=0;i<*d;i++) for(j=0;jnvne) MS=1; if(V->nv>E->ne) MS=2; #endif /* else: priority to sorting by nuc */ assert(Init_rVM_VPM(P,V,E,&P->n,&V->nv,&E->ne,VM,VPM));/* make ref VPM */ if(MS <2) { Eval_Poly_NF(&P->n,&V->nv,&E->ne,VM,VPM,V_NF,0); /* V_NF */ vone=BminOff(V_NF,&P->n,&V->nv,&vo,&vbmin); #ifdef USE_UNIT_ENCODE if(vone) UNIT_Bmin2BaseUCn(&P->n,&V->nv,&vbmin,&vb,&vnuc); else #endif Bmin2BaseUCn(&P->n,&V->nv,&vbmin,&vb,&vnuc); } if(MS!=1) { int i, j, mi=(E->ne>V->nv) ? V->nv : E->ne; /* VM=E */ for(i=0;in;i++)for(j=0;jne;j++) VM[i][j]=E->e[j].a[i]; for(i=0;ine>V->nv) for(i=mi;ine;i++)for(j=0;jnv;j++)VPM[j][i]=VPM[i][j]; else for(i=mi;inv;i++)for(j=0;jne;j++)VPM[i][j]=VPM[j][i]; Eval_Poly_NF(&P->n,&E->ne,&V->nv,VM,VPM,F_NF,0); /* compute F_NF */ fone=BminOff(F_NF,&P->n,&E->ne,&fo,&fbmin); #ifdef USE_UNIT_ENCODE if(fone) UNIT_Bmin2BaseUCn(&P->n,&E->ne,&fbmin,&fb,&fnuc); else #endif Bmin2BaseUCn(&P->n,&E->ne,&fbmin,&fb,&fnuc); } if(MS==0) { if(vnucnvne) MS=1; if(E->nenv) MS=2; } /* sort vert */ #ifdef USE_UNIT_ENCODE if(MS==0) { if(vone>fone) MS=1; if(vonene : V->nv; MSone=MS; if(AuxNFLptr!=NULL) /* base:byte statistics */ { /* if(AuxNFLptr->Xmin>-vo) AuxNFLptr->Xmin=-vo; if(AuxNFLptr->XmaxXmax=vbmin-vo-1; */ if(MS==2) {if(AuxNFLptr->XdifXdif=fbmin;} else {if(AuxNFLptr->XdifXdif=vbmin;} if(AuxNFLptr->Xnuc<*nUC) AuxNFLptr->Xnuc=*nUC; if(((MS==2)&&(fbmin>BASE_MAX))||((MS<2)&&(vbmin>BASE_MAX))) { printf("WARNING MS=%d v=%d vb=%d vnuc=%d f=%d fb=%d fnuc=%d\n", MS,V->nv,vbmin,vnuc,E->ne,fbmin,fnuc); VPrint(&P->n,&V->nv,V_NF);puts("============= V_NF"); VPrint(&P->n,&E->ne,F_NF);puts("============= F_NF"); puts("BASE_MAX exceeded"); exit(0); } } #ifdef USE_UNIT_ENCODE if(MS <2) MSone += 4*vone; else MSone += 4*fone; #endif if(MS <2) AuxVnf2ucNF(V_NF, &P->n, &V->nv, &vo, &vb, &vnuc, &MSone, UC); else AuxVnf2ucNF(F_NF, &P->n, &E->ne, &fo, &fb, &fnuc, &MSone, UC); if(MS==0) /* nuc and nv agree => compare UC[] */ { int RmL; AuxVnf2ucNF(F_NF, &P->n, &E->ne, &fo, &fb, &fnuc, &MSone, auxUC); RmL=RIGHTminusLEFT(UC,auxUC,nUC); if(RmL>0) {MS=1; (*UC)++;} /* o.k. since *UC=4*(...) */ if(RmL<0) {int i; for(i=0;i<*nUC;i++)UC[i]=auxUC[i]; (*UC) += (MS=2);} } /* 6+8*(2+17(1+17(0+17(1+17(1+17(1+17(2))))))) {23 189 20 198} */ #ifdef TEST_UCnf /* One=K3[3/F]: 2 1 0 1 1 1 2 */ { Long tNF[POLY_Dmax][VERT_Nmax]; int tMS, i, j, *d=&P->n, err=0; static int pn, Err; pn++; UCnf2vNF(d, NV, nUC, UC, tNF, &tMS); if(MS<2) for(i=0;i<*d;i++) for(j=i;j<*NV;j++) err+=(tNF[i][j]!=V_NF[i][j]); if(err) err*=1000; if(MS-1) for(i=0;i<*d;i++) for(j=i;j<*NV;j++) err+=(tNF[i][j]!=F_NF[i][j]); if(err) Err=1; if(Err) { int base; #ifdef USE_UNIT_ENCODE if(MSone>3) UNIT_NUCtoBase(&P->n,NV,nUC,&base); else #endif NUCtoBase(&P->n,NV,nUC,&base); printf("\n#%d MS=%d 100*e(V)-e(F) = %d\n",pn,MS,err); for(i=0;i<*nUC;i++)printf("%d ",UC[i]); printf("= UC[%d] base=%d vo=%d fo=%d\n",*nUC,base,vo,fo); VPrint(&P->n,&V->nv,V_NF);puts("============= V_NF"); VPrint(&P->n,&E->ne,F_NF);puts("============= F_NF"); VPrint(&P->n,NV,tNF);puts("============= t_NF"); exit(0); } } #endif assert((*UC % 4)==MS); } void Test_ucNF(int *d, int *v, int *nuc, unsigned char *uc, PolyPointList *_P) { Long tNF[POLY_Dmax][VERT_Nmax]; int i, j, tMS, NV, NUC; unsigned char UC[POLY_Dmax*VERT_Nmax]; VertexNumList V; EqList E; UCnf2vNF(d, v, nuc, uc, tNF, &tMS); _P->n=*d; _P->np=*v; tMS %= 4; for(i=0;i<*v;i++)for(j=0;j<*d;j++)_P->x[i][j]=tNF[j][i]; assert(Ref_Check(_P,&V,&E)); VF_2_ucNF(_P,&V,&E,&NV,&NUC,UC); assert(*v==NV); assert(*nuc==NUC); assert(RIGHTminusLEFT(uc,UC,nuc)==0); assert((tMS==0)==((*uc%4)==0)); } void AuxGet_vn_uc(FILE *F,int *v, int *nu, unsigned char *uc) { int i; *v=fgetc(F); *nu=fgetc(F); for(i=0;i<*nu;i++) uc[i]=fgetc(F); } void AuxGet_uc(FILE *F,int *nu, unsigned char *uc) { int i; for(i=0;i<*nu;i++) uc[i]=fgetc(F); } void AuxPut_hNF(FILE *F,int *v,int *nu,unsigned char *Huc,FInfoList *Io, int *slNF,int *slSM,int *slNM,int *slNB,unsigned char *ucSL,int *SLp) { int i, Hms=(*Huc % 4); static int pos; unsigned char *Suc=NULL; for(i=0;i<*nu;i++) fputc(Huc[i],F); if(Hms) {if(Hms<3) Io->nNM++;} else Io->nSM++; while(pos<*slNF) { int HmSL; Suc=&ucSL[SLp[pos]]; HmSL=*v-*Suc; if(HmSL>0) {pos++; continue;} else if(HmSL<0) return; else HmSL=*nu-Suc[1]; if(HmSL>0) {pos++; continue;} else if(HmSL<0) return; else HmSL=RIGHTminusLEFT(&Suc[2],Huc,nu); if(HmSL>0) {pos++; continue;} else if(HmSL<0) return; else break; } if(pos<*slNF) { int Sms=Suc[2]%4; pos++; switch(10*Hms+Sms) { case 00: case 11: case 22: case 31: case 32: case 33: break; case 12: case 21: return; case 13: Suc[2]-=1; (*slNM)++; return; /* remove 1st */ case 23: Suc[2]-=2; (*slNM)++; return; /* remove 2nd */ default: puts("inconsistent MS flags in AuxPut_hNF"); exit(0);} if(Sms) {if(Sms<3) (*slNM)--;} else (*slSM)--; /* remove SL-entry */ for(i=pos--;i<*slNF;i++) SLp[i-1]=SLp[i]; (*slNF)--; (*slNB)-= *nu+2; } } /* Alloc & read SL; go thru pi / pa; write SL + statistics */ void Add_Polya_2_Polyi(char *polyi,char *polya,char *polyo) { FILE *FI=fopen(polyi,"rb"), *FA=fopen(polya,"rb"), *FO; FInfoList FIi, FIa, FIo; Along Ipos, Apos, HIpos, HApos; unsigned char ucI[NUC_Nmax], ucA[NUC_Nmax], *ucSL, *uc; int SLp[SL_Nmax]; int IslNF, IslSM, IslNM, vI, nuI, i, d; unsigned Ili; Along IslNB; int AslNF, AslSM, AslNM, vA=0, nuA=0, a, j; unsigned Ali; Along AslNB; int slNF=0,slSM=0,slNM=0, slNB=0, slNP=0, Oli=0, v, nu, AmI=0, ms, tnb=0; Init_FInfoList(&FIi); Init_FInfoList(&FIa); if(!*polyi||!*polyo) { puts("With -pa you require -pi and -po or -di and -do");exit(0);} if(NULL==FI) {printf("Cannot open %s\n",polyi);exit(0);} if(NULL==FA) {printf("Cannot open %s\n",polya);exit(0);} if(NULL==(FO=fopen(polyo,"wb"))){printf("Cannot open %s",polyo);exit(0);} ucSL = (unsigned char *) malloc( SL_Nmax * CperR_MAX * sizeof(char) ); assert(ucSL!=NULL); assert(!fgetc(FI)); assert(!fgetc(FA)); Read_Bin_Info(FI,&i,&Ili,&IslNF,&IslSM,&IslNM,&IslNB,&FIi); Read_Bin_Info(FA,&d,&Ali,&AslNF,&AslSM,&AslNM,&AslNB,&FIa); assert(d==i); HIpos=FTELL(FI); FSEEK(FI,0,SEEK_END); Ipos=FTELL(FI); HApos=FTELL(FA); FSEEK(FA,0,SEEK_END); Apos=FTELL(FA); printf("Data on %s: %lld+%dsl %lldb (%dd)\n", polyi, (FIi.nNF-FIi.nSM)+(FIi.nNF-FIi.nNM), /* Islp= */ 2*IslNF-IslNM-IslSM,Ipos,i); printf("Data on %s: %lld+%dsl %lldb (%dd)\n", polya, (FIa.nNF-FIa.nSM)+(FIa.nNF-FIa.nNM), /* Aslp= */ 2*AslNF-AslNM-AslSM,Apos,d); /* printf("HIpos=%lld NB=%lld sl=%lld pos=%lld\n",HIpos,FIi.NB,IslNB,Ipos); */ assert(HIpos+FIi.NB+IslNB==Ipos); FSEEK(FI,-IslNB,SEEK_CUR); /* printf("HApos=%lld NB=%lld sl=%lld pos=%lld\n",HApos,FIa.NB,AslNB,Apos); */ assert(HApos+FIa.NB+AslNB==Apos); FSEEK(FA,-AslNB,SEEK_CUR); a=0; if(a ",slNF,slSM,slNM,slNB); FSEEK(FI,HIpos,SEEK_SET); FSEEK(FA,HApos,SEEK_SET); Init_FInfoList(&FIo); FIo.nVmax=max(FIi.nVmax,FIa.nVmax); FIo.NUCmax=max(FIi.NUCmax,FIa.NUCmax); tnb=0; for(v=d+1;v<=FIo.nVmax;v++) for(nu=1;nu<=FIo.NUCmax;nu++) if((FIo.NFnum[v][nu]=FIi.NFnum[v][nu]+FIa.NFnum[v][nu])) { FIo.nNUC[v]++; Oli++; tnb+=FIo.NFnum[v][nu]; } FIo.nV=0; for(v=d+1;v<=FIo.nVmax;v++) if(FIo.nNUC[v]) FIo.nV++; fputc(0,FO); fputc(d,FO); fputc(FIo.nV,FO); fputc(FIo.nVmax,FO); fputc(FIo.NUCmax,FO); fputUI(Oli,FO); j=InfoSize(0,Oli,&FIo)-5-sizeof(int); for(i=0;i99) { long long tnp=(2*FIo.nNF-FIo.nNM-FIo.nSM)/1000; tnp*=tnp; tnp/=(2*tnb); printf(" [p^2/2m=%ldM]",tnp); }*/ Print_Expect(&FIo); puts(""); assert(ferror(FI)==0); fclose(FI); assert(ferror(FA)==0); fclose(FA); assert(ferror(FO)==0); fclose(FO); } /* ================== AffineNF modifications ================== */ void UCnf_2_ANF(int *d, int *v, int *nuc, unsigned char *uc, /* IN */ Long NF[POLY_Dmax][VERT_Nmax], int *MS) /* OUT */ { int i,off;UCnf2vNF(d,v,nuc,uc,NF,MS);off=NF[0][*v-1]; /* offset not 1 */ for(i=1;i<*d;i++)assert(NF[i][*v-1]==off); /* but last column ! */ for(i=0;i<*d;i++) {int c; for(c=0;cn,&V->nv,&vo,&vbmin); #ifdef USE_UNIT_ENCODE if(vone) UNIT_Bmin2BaseUCn(&P->n,&V->nv,&vbmin,&vb,&vnuc); else #endif Bmin2BaseUCn(&P->n,&V->nv,&vbmin,&vb,&vnuc); *nUC = vnuc; *NV = V->nv; MSone=1; if(AuxNFLptr!=NULL) /* base:byte statistics */ { if(AuxNFLptr->XdifXdif=vbmin; if(AuxNFLptr->Xnuc<*nUC) AuxNFLptr->Xnuc=*nUC; if(vbmin>BASE_MAX) { printf("WARNING MS=%d v=%d vb=%d vnuc=%d\n", 1,V->nv,vbmin,vnuc); VPrint(&P->n,&V->nv,V_NF);puts("============= V_NF"); puts("BASE_MAX exceeded"); exit(0); } } #ifdef USE_UNIT_ENCODE MSone += 4*vone; #endif AuxVnf2ucNF(V_NF, &P->n, &V->nv, &vo, &vb, &vnuc, &MSone, UC); #ifdef TEST_UCnf /* One=K3[3/F]: 2 1 0 1 1 1 2 */ { Long tNF[POLY_Dmax][VERT_Nmax]; int tMS, i, j, *d=&P->n, err=0; static int pn; pn++; UCnf_2_ANF(d, NV, nUC, UC, tNF, &tMS); for(i=0;i<*d;i++) for(j=0;j<*NV;j++) err+=(tNF[i][j]!=V_NF[i][j]); if(err) err*=1000; if(err) { int base; #ifdef USE_UNIT_ENCODE if(MSone>3) UNIT_NUCtoBase(&P->n,NV,nUC,&base); else #endif NUCtoBase(&P->n,NV,nUC,&base); printf("\n#%d MS=%d 100*e(V)-e(F) = %d\n",pn,1,err); for(i=0;i<*nUC;i++)printf("%d ",UC[i]); printf("= UC[%d] base=%d vo=%d\n",*nUC,base,vo); VPrint(&P->n,&V->nv,V_NF);puts("============= V_NF"); VPrint(&P->n,NV,tNF);puts("============= t_NF"); exit(0); } } #endif assert((*UC % 4)==1); } int Add_ANF_to_List(PolyPointList *_P, VertexNumList *_V, EqList *_E, NF_List *_L) { unsigned char UC[NB_MAX]; int nUC, NV, NewNF; #ifdef INCREMENTAL_TIME long long cpuT=clock(), incT=cpuT - _L->CLOCK; if(incT>0) _L->IP_Time+=incT; _L->CLOCK=cpuT; #endif if((_E->ne)>_L->F) _L->F=_E->ne; /* check vertex numbers */ if((_V->nv)>_L->V) _L->V=_V->nv; if((_E->ne > VERT_Nmax)||(_V->nv > VERT_Nmax)) { printf("Increase VERT_Nmax: f=%d v=%d\n",_E->ne,_V->nv);exit(0); } if(_P->np>_L->Nmax) _L->Nmax=_P->np; if(_P->np<_L->Nmin) _L->Nmin=_P->np; _L->nNF++; if(_L->SL)_L->nSLNF++; ANF_2_ucNF(_P, _V, _E, &NV, &nUC, UC); NewNF=ucNF_Sort_Add(&NV, &nUC, UC, _L); /* 1::new::cont. */ #ifdef INCREMENTAL_TIME cpuT=clock(), incT=cpuT - _L->CLOCK; if(incT>0) _L->NF_Time+=incT; _L->CLOCK=cpuT; #endif return NewNF; } void Gen_Ascii_to_Binary(CWS *W, PolyPointList *P, char *dbin, char *polyi, char *polyo) { NF_List *_NFL=(NF_List *) malloc(sizeof(NF_List)); VertexNumList V; EqList F; assert(_NFL!=NULL); if(!(*polyo)) { puts("You have to specify an output file via -po in -a-mode!\n"); printf("For more help use option '-h'\n"); exit(0);} _NFL->of=0; _NFL->rf=0; _NFL->iname=polyi; _NFL->oname=polyo; _NFL->dbname=dbin; Init_NF_List(_NFL); _NFL->SL=0; while(Read_CWS_PP(W,P)) { _NFL->hc = 0; _NFL->V= _NFL->F= _NFL->VN= _NFL->FN = _NFL->Xnuc = _NFL->Xdif = 0; _NFL->Nmin=P->np; _NFL->Nmax=0; if(_NFL->d==0) _NFL->d=P->n; else if(_NFL->d-P->n) {puts("different dim!"); exit(0);} Find_Equations(P,&V,&F); if (Add_ANF_to_List(P,&V,&F,_NFL)) if (outFILE!=stdout){ int i, j; for(i=0;inw;i++) { fprintf(outFILE,"%ld ",W->d[i]); for(j=0;jN;j++) fprintf(outFILE,"%ld ",W->W[i][j]); if(i+1nw) fprintf(outFILE," "); else fprintf(outFILE,"\n"); } fflush(0);} } Write_List_2_File(polyo,_NFL); free(_NFL); }