11#include "llvm/ADT/Sequence.h"
24 ConeV dual(numIneq, numVar, 0, 0);
30 for (
auto i : llvm::seq<int>(0, numIneq)) {
31 assert(cone.
atIneq(i, numVar) == 0 &&
32 "H-representation of cone is not centred at the origin!");
33 for (
unsigned j = 0;
j < numVar; ++
j) {
54 for (
unsigned i = 0; i < rows; ++i)
65 return DynamicAPInt(0);
108 std::vector<Point> denominator(numIneq);
110 for (
auto i : llvm::seq<int>(0, numVar)) {
111 row = generators.
getRow(i);
112 denominator[i] =
Point(row);
132 for (
auto i : llvm::seq<int>(0, numColumns)) {
133 for (
auto j : llvm::seq<int>(0, numRows))
134 ithCol[
j] = vertex(
j, i);
147 std::vector({numerator}),
148 std::vector({denominator}));
161std::optional<ParamPoint>
178 for (
unsigned i = 0; i < d; ++i) {
181 if (equations(i, i) == 0) {
182 for (
unsigned j = i + 1;
j < d; ++
j) {
183 if (equations(
j, i) == 0)
190 Fraction diagElement = equations(i, i);
193 for (
unsigned j = 0;
j < d; ++
j) {
196 if (equations(
j, i) == 0)
200 Fraction currentElement = equations(
j, i);
202 -currentElement / diagElement);
207 for (
unsigned i = 0; i < d; ++i)
208 equations.
scaleRow(i, 1 / equations(i, i));
239std::vector<std::pair<PresburgerSet, GeneratingFunction>>
241 unsigned numSymbols,
ArrayRef<std::pair<PresburgerSet, GeneratingFunction>>
242 regionsAndGeneratingFunctions) {
243 assert(!regionsAndGeneratingFunctions.empty() &&
244 "there must be at least one chamber!");
247 std::vector<std::pair<PresburgerSet, GeneratingFunction>> chambers = {
267 for (
const auto &[region, generatingFunction] :
268 regionsAndGeneratingFunctions) {
269 std::vector<std::pair<PresburgerSet, GeneratingFunction>> newChambers;
271 for (
const auto &[currentRegion, currentGeneratingFunction] : chambers) {
277 newChambers.emplace_back(currentRegion, currentGeneratingFunction);
282 newChambers.emplace_back(intersection,
283 currentGeneratingFunction + generatingFunction);
284 newChambers.emplace_back(currentRegion.subtract(region),
285 currentGeneratingFunction);
287 chambers = std::move(newChambers);
312std::vector<std::pair<PresburgerSet, GeneratingFunction>>
320 std::vector<ParamPoint> vertices;
323 std::vector<std::pair<PresburgerSet, GeneratingFunction>>
324 regionsAndGeneratingFunctions;
334 for (
unsigned i = numIneqs - numVars; i < numIneqs; ++i)
347 FracMatrix b2c2(numIneqs - numVars, numSymbols + 1);
348 a2 =
FracMatrix(remainder.getSubMatrix(0, numIneqs - numVars, 0, numVars));
349 b2c2 =
FracMatrix(remainder.getSubMatrix(0, numIneqs - numVars, numVars,
350 numVars + numSymbols + 1));
354 std::optional<ParamPoint> vertex =
359 if (llvm::is_contained(vertices, vertex))
363 vertices.emplace_back(*vertex);
393 FracMatrix activeRegion(numIneqs - numVars, numSymbols + 1);
394 for (
unsigned i = 0; i < numIneqs - numVars; i++) {
395 activeRegion.
setRow(i, vertex->preMultiplyWithRow(a2.
getRow(i)));
413 for (
unsigned j = 0, e = subset.getNumRows();
j < e; ++
j) {
415 for (
unsigned k = 0; k < numVars; ++k)
416 ineq[k] = subset(
j, k);
426 for (
const std::pair<int, ConeH> &signedCone : unimodCones) {
427 auto [sign, cone] = signedCone;
428 vertexGf = vertexGf +
433 regionsAndGeneratingFunctions.emplace_back(
PresburgerSet(activeRegionRel),
435 }
while (std::next_permutation(indicator.begin(), indicator.end()));
473 unsigned dim = vectors[0].size();
477 "all vectors need to be the same size!");
483 for (
unsigned d = 1; d < dim; ++d) {
485 maxDisallowedValue = -
Fraction(1, 0);
493 maxDisallowedValue = std::max(maxDisallowedValue, disallowedValue);
495 newPoint.emplace_back(maxDisallowedValue + 1);
516 assert(!den.empty() &&
"division by empty denominator in rational function!");
518 unsigned numParam = num[0].getNumInputs();
521 assert(llvm::all_of(num,
523 return num[0].isEqual(qp);
525 "the quasipolynomials should all belong to the same space!");
527 std::vector<QuasiPolynomial> coefficients;
528 coefficients.reserve(power + 1);
530 coefficients.emplace_back(num[0] / den[0]);
531 for (
unsigned i = 1; i <= power; ++i) {
533 coefficients.emplace_back(i < num.size() ? num[i]
538 unsigned limit = std::min<unsigned long>(i, den.size() - 1);
539 for (
unsigned j = 1;
j <= limit; ++
j)
540 coefficients[i] = coefficients[i] -
543 coefficients[i] = coefficients[i] / den[0];
545 return coefficients[power].simplify();
556static std::pair<QuasiPolynomial, std::vector<Fraction>>
558 const std::vector<Point> &ds,
const Point &mu) {
559 unsigned numDims = mu.size();
561 for (
const Point &d : ds)
562 assert(d.size() == numDims &&
563 "μ has to have the same number of dimensions as the generators!");
574 coefficients.reserve(numDims);
575 for (
const Point &d : ds)
576 coefficients.emplace_back(-
dotProduct(mu, d));
581 std::vector<std::vector<SmallVector<Fraction>>>
affine;
583 for (
unsigned j = 0;
j < numDims; ++
j)
584 affine.push_back({SmallVector<Fraction>{vTranspose.getRow(j)}});
587 num = num.simplify();
589 std::vector<Fraction> dens;
590 dens.reserve(ds.size());
593 for (
const Point &d : ds) {
609 std::vector<Fraction> &dens) {
612 unsigned numNegExps = 0;
614 for (
const auto &den : dens) {
629 if (numNegExps % 2 == 1)
636static std::vector<QuasiPolynomial>
639 std::vector<QuasiPolynomial> coefficients;
640 coefficients.reserve(r + 1);
641 coefficients.emplace_back(numParams, 1);
642 for (
unsigned j = 1;
j <= r; ++
j)
644 coefficients.emplace_back(
655 std::vector<Fraction> coefficients;
657 coefficients.emplace_back(1);
658 for (
unsigned j = 1;
j <= r; ++
j)
659 coefficients.emplace_back(coefficients[
j - 1] * (n - (
j - 1)) / (
j));
695 std::vector<Point> allDenominators;
697 llvm::append_range(allDenominators, den);
703 for (
unsigned i = 0, e = ds.size(); i < e; ++i) {
708 auto [numExp, dens] =
732 unsigned r = dens.size();
733 if (dens.size() % 2 == 1)
757 std::vector<QuasiPolynomial> numeratorCoefficients =
762 std::vector<std::vector<Fraction>> eachTermDenCoefficients;
763 std::vector<Fraction> singleTermDenCoefficients;
764 eachTermDenCoefficients.reserve(r);
767 eachTermDenCoefficients.emplace_back(
774 std::vector<Fraction> denominatorCoefficients;
775 denominatorCoefficients = eachTermDenCoefficients[0];
776 for (
unsigned j = 1, e = eachTermDenCoefficients.size();
j < e; ++
j)
778 eachTermDenCoefficients[
j]);
782 denominatorCoefficients) *
static std::vector< QuasiPolynomial > getBinomialCoefficients(const QuasiPolynomial &n, unsigned r)
Compute the binomial coefficients nCi for 0 ≤ i ≤ r, where n is a QuasiPolynomial.
static void normalizeDenominatorExponents(int &sign, QuasiPolynomial &num, std::vector< Fraction > &dens)
Normalize all denominator exponents dens to their absolute values by multiplying and dividing by the ...
static std::pair< QuasiPolynomial, std::vector< Fraction > > substituteMuInTerm(unsigned numParams, const ParamPoint &v, const std::vector< Point > &ds, const Point &mu)
Substitute x_i = t^μ_i in one term of a generating function, returning a quasipolynomial which repres...
Fraction determinant(FracMatrix *inverse=nullptr) const
DynamicAPInt determinant(IntMatrix *inverse=nullptr) const
An IntegerPolyhedron represents the set of points from a PresburgerSpace that satisfy a list of affin...
unsigned getNumSymbolVars() const
DynamicAPInt atIneq(unsigned i, unsigned j) const
Returns the value at the specified inequality row and column.
unsigned getNumVars() const
unsigned getNumRangeVars() const
unsigned getNumCols() const
Returns the number of columns in the constraint system.
IntMatrix getInequalities() const
void addInequality(ArrayRef< DynamicAPInt > inEq)
Adds an inequality (>= 0) from the coefficients specified in inEq.
unsigned getNumInequalities() const
unsigned getNumRows() const
Matrix< T > getSubMatrix(unsigned fromRow, unsigned toRow, unsigned fromColumn, unsigned toColumn) const
void scaleRow(unsigned row, const T &scale)
Multiply the specified row by a factor of scale.
void insertColumn(unsigned pos)
MutableArrayRef< T > getRow(unsigned row)
Get a [Mutable]ArrayRef corresponding to the specified row.
void setRow(unsigned row, ArrayRef< T > elems)
Set the specified row to elems.
std::pair< Matrix< T >, Matrix< T > > splitByBitset(ArrayRef< int > indicator)
Split the rows of a matrix into two matrices according to which bits are 1 and which are 0 in a given...
void removeRow(unsigned pos)
unsigned getNumColumns() const
T & at(unsigned row, unsigned column)
Access the element at the specified row and column.
Matrix< T > transpose() const
SmallVector< T, 8 > preMultiplyWithRow(ArrayRef< T > rowVec) const
The given vector is interpreted as a row vector v.
void negateMatrix()
Negate the entire matrix.
void swapRows(unsigned row, unsigned otherRow)
Swap the given rows.
void addToRow(unsigned sourceRow, unsigned targetRow, const T &scale)
Add scale multiples of the source row to the target row.
void negateRow(unsigned row)
Negate the specified row.
bool isFullDim() const
Return whether the given PresburgerRelation is full-dimensional.
PresburgerSet intersect(const PresburgerRelation &set) const
static PresburgerSet getUniverse(const PresburgerSpace &space)
Return a universe set of the specified type that contains all points.
static PresburgerSpace getSetSpace(unsigned numDims=0, unsigned numSymbols=0, unsigned numLocals=0)
static PresburgerSpace getRelationSpace(unsigned numDomain=0, unsigned numRange=0, unsigned numSymbols=0, unsigned numLocals=0)
QuasiPolynomial simplify()
unsigned getNumInputs() const
unsigned getNumParams() const
std::vector< ParamPoint > getNumerators() const
std::vector< std::vector< Point > > getDenominators() const
SmallVector< int > getSigns() const
IntegerRelation PolyhedronH
A polyhedron in H-representation is a set of inequalities in d variables with integer coefficients.
SmallVector< Fraction > Point
std::optional< ParamPoint > solveParametricEquations(FracMatrix equations)
Find the solution of a set of equations that express affine constraints between a set of variables an...
ConeV getDual(ConeH cone)
Given a cone in H-representation, return its dual.
QuasiPolynomial computeNumTerms(const GeneratingFunction &gf)
Find the number of terms in a generating function, as a quasipolynomial in the parameter space of the...
Point getNonOrthogonalVector(ArrayRef< Point > vectors)
Find a vector that is not orthogonal to any of the given vectors, i.e., has nonzero dot product with ...
GeneratingFunction computeUnimodularConeGeneratingFunction(ParamPoint vertex, int sign, const ConeH &cone)
Compute the generating function for a unimodular cone.
PolyhedronH defineHRep(int numVars, int numSymbols=0)
PolyhedronH ConeH
A cone in either representation is a special case of a polyhedron in that representation.
std::vector< std::pair< PresburgerSet, GeneratingFunction > > computeChamberDecomposition(unsigned numSymbols, ArrayRef< std::pair< PresburgerSet, GeneratingFunction > > regionsAndGeneratingFunctions)
Given a list of possibly intersecting regions (PresburgerSet) and the generating functions active in ...
std::vector< std::pair< PresburgerSet, GeneratingFunction > > computePolytopeGeneratingFunction(const PolyhedronH &poly)
Compute the generating function corresponding to a polytope.
DynamicAPInt getIndex(const ConeV &cone)
Get the index of a cone, i.e., the volume of the parallelepiped spanned by its generators,...
QuasiPolynomial getCoefficientInRationalFunction(unsigned power, ArrayRef< QuasiPolynomial > num, ArrayRef< Fraction > den)
Find the coefficient of a given power of s in a rational function given by P(s)/Q(s),...
DynamicAPInt floor(const Fraction &f)
Fraction abs(const Fraction &f)
Fraction dotProduct(ArrayRef< Fraction > a, ArrayRef< Fraction > b)
Compute the dot product of two vectors.
std::vector< Fraction > multiplyPolynomials(ArrayRef< Fraction > a, ArrayRef< Fraction > b)
Find the product of two polynomials, each given by an array of coefficients.
Include the generated interface declarations.
A class to represent fractions.
Eliminates variable at the specified position using Fourier-Motzkin variable elimination.