bool Matrix_Transform(gsl_matrix *T1,gsl_matrix *A,gsl_matrix *T2, gsl_matrix *M){ gsl_matrix *T; T=gsl_matrix_alloc(T1->size1,A->size2); Matrix_Product(T1,A,T); Matrix_Product(T,T2,M); return true; }
bool Matrix_Transform(gsl_matrix *M1,gsl_matrix_complex *A,gsl_matrix *M2,gsl_matrix_complex *M){ gsl_matrix_complex *T,*T1,*T2; T1=gsl_matrix_complex_alloc(M1->size1,M1->size2); T2=gsl_matrix_complex_alloc(M2->size1,M2->size2); T=gsl_matrix_complex_alloc(M1->size1,A->size2); Matrix_Copy_Real(M1,T1); Matrix_Copy_Real(M2,T2); Matrix_Product(T1,A,T); Matrix_Product(T,T2,M); return true; }
/** * 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); } }
bool Matrix_Product(gsl_matrix *A, gsl_matrix *B,gsl_matrix *C){ return Matrix_Product(1.0,CblasNoTrans,A,CblasNoTrans,B,0.0,C); }
bool Matrix_Product(gsl_matrix_complex *A, gsl_matrix_complex *B, gsl_matrix_complex *C ){ return Matrix_Product(gsl_complex_rect(1.0,0.0),CblasNoTrans,A,CblasNoTrans,B,gsl_complex_rect(0.0,0.0),C); }
/* Assumes C is a linear cone (i.e. with apex zero). * All equalities are removed first to speed up the computation * in zsolve. */ Matrix *Cone_Hilbert_Basis(Polyhedron *C, unsigned MaxRays) { unsigned dim; int i; Matrix *M2, *M3, *T; Matrix *CV = NULL; LinearSystem initialsystem; ZSolveMatrix matrix; ZSolveVector rhs; ZSolveContext ctx; remove_all_equalities(&C, NULL, NULL, &CV, 0, MaxRays); dim = C->Dimension; for (i = 0; i < C->NbConstraints; ++i) assert(value_zero_p(C->Constraint[i][1+dim]) || First_Non_Zero(C->Constraint[i]+1, dim) == -1); M2 = Polyhedron2standard_form(C, &T); matrix = Matrix2zsolve(M2); Matrix_Free(M2); rhs = createVector(matrix->Height); for (i = 0; i < matrix->Height; i++) rhs[i] = 0; initialsystem = createLinearSystem(); setLinearSystemMatrix(initialsystem, matrix); deleteMatrix(matrix); setLinearSystemRHS(initialsystem, rhs); deleteVector(rhs); setLinearSystemLimit(initialsystem, -1, 0, MAXINT, 0); setLinearSystemEquationType(initialsystem, -1, EQUATION_EQUAL, 0); ctx = createZSolveContextFromSystem(initialsystem, NULL, 0, 0, NULL, NULL); zsolveSystem(ctx, 0); M2 = VectorArray2Matrix(ctx->Homs, C->Dimension); deleteZSolveContext(ctx, 1); Matrix_Transposition(T); M3 = Matrix_Alloc(M2->NbRows, M2->NbColumns); Matrix_Product(M2, T, M3); Matrix_Free(M2); Matrix_Free(T); if (CV) { Matrix *T, *M; T = Transpose(CV); M = Matrix_Alloc(M3->NbRows, T->NbColumns); Matrix_Product(M3, T, M); Matrix_Free(M3); Matrix_Free(CV); Matrix_Free(T); Polyhedron_Free(C); M3 = M; } return M3; }
/* * Return the Z-polyhderon 'Zpol' in canonical form: 'Result' (for the Z-poly- * hedron in canonical form) and Basis 'Basis' (for the basis with respect to * which 'Result' is in canonical form. */ void CanonicalForm(ZPolyhedron *Zpol,ZPolyhedron **Result,Matrix **Basis) { Matrix *B1 = NULL, *B2=NULL, *T1 , *B2inv; int i, l1, l2; Value tmp; Polyhedron *Image, *ImageP; Matrix *H, *U, *temp, *Hprime, *Uprime, *T2; #ifdef DOMDEBUG FILE *fp; fp = fopen("_debug", "a"); fprintf(fp,"\nEntered CANONICALFORM\n"); fclose(fp); #endif if(isEmptyZPolyhedron (Zpol)) { Basis[0] = Identity(Zpol->Lat->NbRows); Result[0] = ZDomain_Copy (Zpol); return ; } value_init(tmp); l1 = FindHermiteBasisofDomain(Zpol->P,&B1); Image = DomainImage (Zpol->P,(Matrix *)Zpol->Lat,MAXNOOFRAYS); l2 = FindHermiteBasisofDomain(Image,&B2); if (l1 != l2) fprintf(stderr,"In CNF : Something wrong with the Input Zpolyhedra \n"); B2inv = Matrix_Alloc(B2->NbRows, B2->NbColumns); temp = Matrix_Copy(B2); Matrix_Inverse(temp,B2inv); Matrix_Free(temp); temp = Matrix_Alloc(B2inv->NbRows,Zpol->Lat->NbColumns); T1 = Matrix_Alloc(temp->NbRows,B1->NbColumns); Matrix_Product(B2inv,(Matrix *)Zpol->Lat,temp); Matrix_Product(temp,B1,T1); Matrix_Free(temp); T2 = ChangeLatticeDimension(T1,l1); temp = ChangeLatticeDimension(T2,T2->NbRows+1); /* Adding the affine part */ for(i = 0; i < l1; i ++) value_assign(temp->p[i][temp->NbColumns-1],T1->p[i][T1->NbColumns-1]); AffineHermite(temp,&H,&U); Hprime = ChangeLatticeDimension(H,Zpol->Lat->NbRows); /* Exchanging the Affine part */ for(i = 0; i < l1; i ++) { value_assign(tmp,Hprime->p[i][Hprime->NbColumns-1]); value_assign(Hprime->p[i][Hprime->NbColumns-1],Hprime->p[i][H->NbColumns-1]); value_assign(Hprime->p[i][H->NbColumns-1],tmp); } Uprime = ChangeLatticeDimension(U,Zpol->Lat->NbRows); /* Exchanging the Affine part */ for (i = 0;i < l1; i++) { value_assign(tmp,Uprime->p[i][Uprime->NbColumns-1]); value_assign(Uprime->p[i][Uprime->NbColumns-1],Uprime->p[i][U->NbColumns-1]); value_assign(Uprime->p[i][U->NbColumns-1],tmp); } Polyhedron_Free (Image); Matrix_Free (B2inv); B2inv = Matrix_Alloc(B1->NbRows, B1->NbColumns); Matrix_Inverse(B1,B2inv); ImageP = DomainImage(Zpol->P, B2inv, MAXNOOFRAYS); Matrix_Free(B2inv); Image = DomainImage(ImageP, Uprime, MAXNOOFRAYS); Domain_Free(ImageP); Result[0] = ZPolyhedron_Alloc(Hprime, Image); Basis[0] = Matrix_Copy(B2); /* Free the variables */ Polyhedron_Free (Image); Matrix_Free (B1); Matrix_Free (B2); Matrix_Free (temp); Matrix_Free (T1); Matrix_Free (T2); Matrix_Free (H); Matrix_Free (U); Matrix_Free (Hprime); Matrix_Free (Uprime); value_clear(tmp); return; } /* CanonicalForm */
/* * Given a Z-polyhderon 'A' and a Z-domain 'Head', return a new Z-domain with * 'A' added to it. If the new Z-polyhedron 'A', is already included in the * Z-domain 'Head', it is not added in the list. Othewise, the function checks * if the new Z-polyhedron 'A' to be added to the Z-domain 'Head' has a common * lattice with some other Z-polyhderon already present in the Z-domain. If it * is so, it takes the union of the underlying polyhdera; domains and returns. * The function tries to make sure that the added Z-polyhedron 'A' is in the * canonical form. */ static ZPolyhedron *AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head) { ZPolyhedron *Zpol, *temp, *temp1; Polyhedron *i; Bool Added; if ((A == NULL) || (isEmptyZPolyhedron(A))) return Head; /* For each "underlying" Pol, find the Cnf and add Zpol in Cnf*/ for(i=A->P; i!= NULL; i=i->next) { ZPolyhedron *Z, *Z1; Polyhedron *Image; Matrix *H, *U; Lattice *Lat ; Added = False; Image = Domain_Copy(i); Domain_Free(Image->next); Image->next = NULL; Z1 = ZPolyhedron_Alloc(A->Lat,Image); Domain_Free(Image); CanonicalForm(Z1,&Z,&H); ZDomain_Free(Z1); Lat = (Lattice *)Matrix_Alloc(H->NbRows,Z->Lat->NbColumns); Matrix_Product(H,Z->Lat,(Matrix *)Lat); Matrix_Free(H); AffineHermite(Lat,(Lattice **)&H,&U); Image = DomainImage(Z->P,U,MAXNOOFRAYS); ZDomain_Free(Z); Zpol=ZPolyhedron_Alloc((Lattice *)H,Image); Domain_Free(Image); Matrix_Free((Matrix *)Lat); Matrix_Free(H); Matrix_Free(U); if ((Head == NULL) || (isEmptyZPolyhedron (Head))) { Head = Zpol; continue; } temp1 = temp = Head; /* Check if the curr pol is included in the zpol or vice versa. */ for(; temp != NULL; temp = temp->next) { if (ZPolyhedronIncludes(Zpol, temp) == True) { ZPolyhedron_Free (Zpol); Added = True; break; } else if (ZPolyhedronIncludes(temp, Zpol) == True) { if (temp == Head) { Zpol->next = temp->next; Head = Zpol; ZPolyhedron_Free (temp); Added = True; break; } temp1->next = Zpol; Zpol->next = temp->next; ZPolyhedron_Free (temp); Added = True; break ; } temp1 = temp ; } if(Added == True) continue ; for(temp = Head; temp != NULL; temp = temp->next) { if(sameLattice(temp->Lat, Zpol->Lat) == True) { Polyhedron *Union; Union = DomainUnion (temp->P,Zpol->P,MAXNOOFRAYS); if (!Union) fprintf (stderr,"\n In AddZPolytoZDomain: Out of memory\n"); else { Domain_Free(temp->P); temp->P = Union; Added = True; ZPolyhedron_Free(Zpol); } break ; } temp1 = temp; } if (Added == False) temp1->next = Zpol; } return Head ; } /* AddZPolytoZDomain */