static void MakeQ(int n, int spl, const Matrix_t **endo) { int i; int dim = endo[0]->Nor; Matrix_t *q = MatAlloc(endo[0]->Field,spl,dim*dim); char fn[200]; for (i = 0; i < spl; ++i) { int j; Matrix_t *y = MatInverse(Trans[n]), *x; MatMul(y,endo[i]); x = MatTransposed(y); MatFree(y); for (j = 0; j < dim; ++j) MatCopyRegion(q,i,j * dim,x,j,0,1,-1); MatFree(x); } sprintf(fn,"%s.q.%d",TkiName,n+1); MESSAGE(2,("Writing %s\n",fn)); #if 0 if (InfoM.Cf[TKInfo.CfIndex[0][n]].peakword < 0) MatMulScalar(q,FF_ZERO); #endif MatSave(q,fn); MatFree(q); }
static void update_matrix(struct Transform *transform) { make_transform_matrix(transform->transform_order, transform->rotate_order, transform->translate[0], transform->translate[1], transform->translate[2], transform->rotate[0], transform->rotate[1], transform->rotate[2], transform->scale[0], transform->scale[1], transform->scale[2], transform->matrix); MatInverse(transform->inverse, transform->matrix); }
static void MakePQ(int n, int mj, int nj) { MatRep_t *rep_m; Matrix_t *estar[MAXENDO], *endo[MAXENDO], *e, *ei; char fn[200]; int dim = InfoM.Cf[mj].dim; int spl = InfoM.Cf[mj].spl; int i; Matrix_t *p; MESSAGE(1,("Condensing %s%s x ",InfoM.BaseName,Lat_CfName(&InfoM,mj))); MESSAGE(1,("%s%s, [E:k]=%d\n",InfoN.BaseName,Lat_CfName(&InfoN,nj),spl)); /* Read the generators for the constituent of M and make the endomorphism ring. --------------------------------------------------------- */ rep_m = Lat_ReadCfGens(&InfoM,mj,InfoM.Cf[mj].peakword >= 0 ? LAT_RG_STD : 0); MESSAGE(2,("Calculating endomorphism ring\n")); MkEndo(rep_m,InfoM.Cf + mj,endo,MAXENDO); MrFree(rep_m); /* Calculate the Q matrix ---------------------- */ MESSAGE(2,("Calculating embedding of E\n")); MakeQ(n,spl,(const Matrix_t **)endo); /* Calculate the E* matrices Note: We should use the symmetry under i<-->k here! --------------------------------------------------- */ MESSAGE(2,("Calculating projection on E\n")); MESSAGE(2,(" E* matrices\n")); e = MatAlloc(FfOrder,spl,spl); for (i = 0; i < spl; ++i) { PTR pptr = MatGetPtr(e,i); int k; for (k = 0; k < spl; ++k) { FEL f; Matrix_t *x = MatDup(endo[i]); MatMul(x,endo[k]); f = MatTrace(x); FfInsert(pptr,k,f); MatFree(x); } } ei = MatInverse(e); MatFree(e); for (i = 0; i < spl; ++i) { int k; PTR p; estar[i] = MatAlloc(FfOrder,dim,dim); p = MatGetPtr(ei,i); for (k = 0; k < spl; ++k) MatAddMul(estar[i],endo[k],FfExtract(p,k)); } MatFree(ei); /* Transpose the E* matrices. This simplifies the calculation of tr(z E*) below. ----------------------------------------------- */ MESSAGE(2,(" Transposing E* matrices\n")); for (i = 0; i < spl; ++i) { Matrix_t *x = MatTransposed(estar[i]); MatFree(estar[i]); estar[i] = x; } /* Calculate the P matrix ---------------------- */ MESSAGE(2,(" P matrix\n")); p = MatAlloc(FfOrder,dim*dim,spl); for (i = 0; i < dim; ++i) { int j; for (j = 0; j < dim; ++j) { int r; PTR pptr = MatGetPtr(p,i*dim + j); Matrix_t *x = MatAlloc(FfOrder,dim,dim); MatCopyRegion(x,0,i,Trans[n],0,j,dim,1); for (r = 0; r < spl; ++r) { FEL f = MatProd(x,estar[r]); FfInsert(pptr,r,f); } MatFree(x); } } sprintf(fn,"%s.p.%d",TkiName,n+1); MESSAGE(2,("Writing %s\n",fn)); #if 0 if (InfoM.Cf[mj].peakword < 0) MatMulScalar(p,FF_ZERO); #endif MatSave(p,fn); /* Clean up -------- */ MatFree(p); for (i = 0; i < spl; ++i) MatFree(endo[i]); }
/** * Given a system of equalities, looks if it has an integer solution in the * combined space, and if yes, returns one solution. * <p>pre-condition: the equalities are full-row rank (without the constant * part)</p> * @param Eqs the system of equations (as constraints) * @param I a feasible integer solution if it exists, else NULL. Allocated if * initially set to NULL, else reused. */ void Equalities_integerSolution(Matrix * Eqs, Matrix **I) { Matrix * Hm, *H=NULL, *U, *Q, *M=NULL, *C=NULL, *Hi; Matrix *Ip; int i; Value mod; unsigned int rk; if (Eqs==NULL){ if ((*I)!=NULL) Matrix_Free(*I); I = NULL; return; } /* we use: AI = C = (Ha 0).Q.I = (Ha 0)(I' 0)^T */ /* with I = Qinv.I' = U.I'*/ /* 1- compute I' = Hainv.(-C) */ /* HYP: the equalities are full-row rank */ rk = Eqs->NbRows; Matrix_subMatrix(Eqs, 0, 1, rk, Eqs->NbColumns-1, &M); left_hermite(M, &Hm, &Q, &U); Matrix_Free(M); Matrix_subMatrix(Hm, 0, 0, rk, rk, &H); if (dbgCompParmMore) { show_matrix(Hm); show_matrix(H); show_matrix(U); } Matrix_Free(Q); Matrix_Free(Hm); Matrix_subMatrix(Eqs, 0, Eqs->NbColumns-1, rk, Eqs->NbColumns, &C); Matrix_oppose(C); Hi = Matrix_Alloc(rk, rk+1); MatInverse(H, Hi); if (dbgCompParmMore) { show_matrix(C); show_matrix(Hi); } /* put the numerator of Hinv back into H */ Matrix_subMatrix(Hi, 0, 0, rk, rk, &H); Ip = Matrix_Alloc(Eqs->NbColumns-2, 1); /* fool Matrix_Product on the size of Ip */ Ip->NbRows = rk; Matrix_Product(H, C, Ip); Ip->NbRows = Eqs->NbColumns-2; Matrix_Free(H); Matrix_Free(C); value_init(mod); for (i=0; i< rk; i++) { /* if Hinv.C is not integer, return NULL (no solution) */ value_pmodulus(mod, Ip->p[i][0], Hi->p[i][rk]); if (value_notzero_p(mod)) { if ((*I)!=NULL) Matrix_Free(*I); value_clear(mod); Matrix_Free(U); Matrix_Free(Ip); Matrix_Free(Hi); I = NULL; return; } else { value_pdivision(Ip->p[i][0], Ip->p[i][0], Hi->p[i][rk]); } } /* fill the rest of I' with zeros */ for (i=rk; i< Eqs->NbColumns-2; i++) { value_set_si(Ip->p[i][0], 0); } value_clear(mod); Matrix_Free(Hi); /* 2 - Compute the particular solution I = U.(I' 0) */ ensureMatrix((*I), Eqs->NbColumns-2, 1); Matrix_Product(U, Ip, (*I)); Matrix_Free(U); Matrix_Free(Ip); if (dbgCompParm) { show_matrix(*I); } }
/** * Tests Constraints_fullDimensionize by comparing the Ehrhart polynomials * @param A the input set of constraints * @param B the corresponding context * @param the number of samples to generate for the test * @return 1 if the Ehrhart polynomial had the same value for the * full-dimensional and non-full-dimensional sets of constraints, for their * corresponding sample parameters values. */ int test_Constraints_fullDimensionize(Matrix * A, Matrix * B, unsigned int nbSamples) { Matrix * Eqs= NULL, *ParmEqs=NULL, *VL=NULL; unsigned int * elimVars=NULL, * elimParms=NULL; Matrix * sample, * smallerSample=NULL; Matrix * transfSample=NULL; Matrix * parmVL=NULL; unsigned int i, j, r, nbOrigParms, nbParms; Value div, mod, *origVal=NULL, *fullVal=NULL; Matrix * VLInv; Polyhedron * P, *PC; Matrix * M, *C; Enumeration * origEP, * fullEP=NULL; const char **fullNames = NULL; int isOk = 1; /* holds the result */ /* compute the origial Ehrhart polynomial */ M = Matrix_Copy(A); C = Matrix_Copy(B); P = Constraints2Polyhedron(M, maxRays); PC = Constraints2Polyhedron(C, maxRays); origEP = Polyhedron_Enumerate(P, PC, maxRays, origNames); Matrix_Free(M); Matrix_Free(C); Polyhedron_Free(P); Polyhedron_Free(PC); /* compute the full-dimensional polyhedron corresponding to A and its Ehrhart polynomial */ M = Matrix_Copy(A); C = Matrix_Copy(B); nbOrigParms = B->NbColumns-2; Constraints_fullDimensionize(&M, &C, &VL, &Eqs, &ParmEqs, &elimVars, &elimParms, maxRays); if ((Eqs->NbRows==0) && (ParmEqs->NbRows==0)) { Matrix_Free(M); Matrix_Free(C); Matrix_Free(Eqs); Matrix_Free(ParmEqs); free(elimVars); free(elimParms); return 1; } nbParms = C->NbColumns-2; P = Constraints2Polyhedron(M, maxRays); PC = Constraints2Polyhedron(C, maxRays); namesWithoutElim(origNames, nbOrigParms, elimParms, &fullNames); fullEP = Polyhedron_Enumerate(P, PC, maxRays, fullNames); Matrix_Free(M); Matrix_Free(C); Polyhedron_Free(P); Polyhedron_Free(PC); /* make a set of sample parameter values and compare the corresponding Ehrhart polnomials */ sample = Matrix_Alloc(1,nbOrigParms); transfSample = Matrix_Alloc(1, nbParms); Lattice_extractSubLattice(VL, nbParms, &parmVL); VLInv = Matrix_Alloc(parmVL->NbRows, parmVL->NbRows+1); MatInverse(parmVL, VLInv); if (dbg) { show_matrix(parmVL); show_matrix(VLInv); } srand(nbSamples); value_init(mod); value_init(div); for (i = 0; i< nbSamples; i++) { /* create a random sample */ for (j=0; j< nbOrigParms; j++) { value_set_si(sample->p[0][j], rand()%100); } /* compute the corresponding value for the full-dimensional constraints */ valuesWithoutElim(sample, elimParms, &smallerSample); /* (N' i' 1)^T = VLinv.(N i 1)^T*/ for (r = 0; r < nbParms; r++) { Inner_Product(&(VLInv->p[r][0]), smallerSample->p[0], nbParms, &(transfSample->p[0][r])); /* add the constant part */ value_addto(transfSample->p[0][r], transfSample->p[0][r], VLInv->p[r][VLInv->NbColumns-2]); value_pdivision(div, transfSample->p[0][r], VLInv->p[r][VLInv->NbColumns-1]); value_subtract(mod, transfSample->p[0][r], div); /* if the parameters value does not belong to the validity lattice, the Ehrhart polynomial is zero. */ if (!value_zero_p(mod)) { fullEP = Enumeration_zero(nbParms, maxRays); break; } } /* compare the two forms of the Ehrhart polynomial.*/ if (origEP ==NULL) break; /* NULL has loose semantics for EPs */ origVal = compute_poly(origEP, sample->p[0]); fullVal = compute_poly(fullEP, transfSample->p[0]); if (!value_eq(*origVal, *fullVal)) { isOk = 0; printf("EPs don't match. \n Original value = "); value_print(stdout, VALUE_FMT, *origVal); printf("\n Original sample = ["); for (j=0; j<sample->NbColumns; j++) { value_print(stdout, VALUE_FMT, sample->p[0][j]); printf(" "); } printf("] \n EP = "); if(origEP!=NULL) { print_evalue(stdout, &(origEP->EP), origNames); } else { printf("NULL"); } printf(" \n Full-dimensional value = "); value_print(stdout, P_VALUE_FMT, *fullVal); printf("\n full-dimensional sample = ["); for (j=0; j<sample->NbColumns; j++) { value_print(stdout, VALUE_FMT, transfSample->p[0][j]); printf(" "); } printf("] \n EP = "); if(origEP!=NULL) { print_evalue(stdout, &(origEP->EP), fullNames); } else { printf("NULL"); } } if (dbg) { printf("\nOriginal value = "); value_print(stdout, VALUE_FMT, *origVal); printf("\nFull-dimensional value = "); value_print(stdout, P_VALUE_FMT, *fullVal); printf("\n"); } value_clear(*origVal); value_clear(*fullVal); } value_clear(mod); value_clear(div); Matrix_Free(sample); Matrix_Free(smallerSample); Matrix_Free(transfSample); Enumeration_Free(origEP); Enumeration_Free(fullEP); return isOk; } /* test_Constraints_fullDimensionize */
static void kond(int mod, int cf) { const Lat_Info *li = &ModList[mod].Info; char fn[LAT_MAXBASENAME+10]; Matrix_t *peakword, *kern, *m, *k, *pw; int j, pwr; /* Make the peak word, find its stable power, and calculate both kernel and image. ------------------------------------------ */ peakword = WgMakeWord(ModList[mod].Wg,li->Cf[cf].peakword); MatInsert_(peakword,li->Cf[cf].peakpol); pw = MatDup(peakword); StablePower_(peakword,&pwr,&kern); MESSAGE(0,("pwr=%d, nul=%d, ",pwr,kern->Nor)); if (kern->Nor != li->Cf[cf].mult * li->Cf[cf].spl) MTX_ERROR("Something is wrong here!"); MatEchelonize(peakword); /* Write out the image ------------------- */ if (!opt_n) { sprintf(fn,"%s%s.im",li->BaseName,Lat_CfName(li,cf)); MatSave(peakword,fn); } /* Write out the `uncondense matrix' --------------------------------- */ m = QProjection(peakword,kern); k = MatInverse(m); MatFree(m); MatMul(k,kern); sprintf(fn,"%s%s.k",li->BaseName,Lat_CfName(li,cf)); MatSave(k,fn); /* Condense all generators ----------------------- */ MESSAGE(1,("(")); for (j = 0; j < li->NGen; ++j) { sprintf(fn,"%dk",j+1); gkond(li,cf,peakword,k,ModList[mod].Rep->Gen[j],fn); MESSAGE(1,("%d",j+1)); } MESSAGE(1,(")")); /* Condense the peak word ---------------------- */ gkond(li,cf,peakword,k,pw,"np"); /* Calculate the semisimplicity basis. ----------------------------------- */ if (opt_b) { Matrix_t *seed, *partbas; int pos = CfPosition(li,cf); seed = MatNullSpace_(pw,0); partbas = SpinUp(seed,ModList[mod].Rep,SF_EACH|SF_COMBINE|SF_STD,NULL,NULL); MatFree(seed); MESSAGE(0,(", %d basis vectors",partbas->Nor)); if (MatCopyRegion(ModList[mod].SsBasis,pos,0,partbas,0,0,-1,-1) != 0) { MTX_ERROR1("Error making basis - '%s' is possibly not semisimple", li->BaseName); } MatFree(partbas); } MatFree(pw); MESSAGE(0,("\n")); MatFree(k); MatFree(kern); MatFree(peakword); }