13template<
typename ValueType>
15 return create(halfspaces, boost::none);
18template<
typename ValueType>
20 return create(boost::none, points);
23template<
typename ValueType>
28template<
typename ValueType>
30 return create(boost::none, std::vector<Point>());
33template<
typename ValueType>
35 boost::optional<std::vector<Point>>
const& points) {
39template<
typename ValueType>
43 return createEmptyPolytope();
47 return createSelectiveDownwardClosure(points, dimensions);
50template<
typename ValueType>
55 return createEmptyPolytope();
57 if (selectedDimensions.
empty()) {
58 return create(points);
60 assert(points.front().size() == selectedDimensions.
size());
62 std::vector<Halfspace<ValueType>> halfspaces;
66 std::vector<Point> auxiliaryPoints = points;
67 auxiliaryPoints.reserve(auxiliaryPoints.size() * (1 + selectedDimensions.
getNumberOfSetBits()));
68 for (
auto const& point : points) {
69 for (
auto dim : selectedDimensions) {
70 auxiliaryPoints.push_back(point);
71 auxiliaryPoints.back()[dim] -= storm::utility::one<ValueType>();
74 std::vector<Halfspace<ValueType>> auxiliaryHalfspaces = create(auxiliaryPoints)->getHalfspaces();
76 for (
auto& h : auxiliaryHalfspaces) {
77 bool allGreaterEqZero =
true;
78 for (
auto dim : selectedDimensions) {
79 allGreaterEqZero &= (h.normalVector()[dim] >= storm::utility::zero<ValueType>());
81 if (allGreaterEqZero) {
82 halfspaces.push_back(std::move(h));
85 return create(halfspaces);
88template<
typename ValueType>
93template<
typename ValueType>
100 std::vector<Point> vertices = getVertices();
101 if (vertices.size() <= 2) {
105 STORM_LOG_THROW(vertices.front().size() == 2, storm::exceptions::IllegalFunctionCallException,
106 "Getting Vertices in clockwise order is only possible for a 2D-polytope.");
108 std::vector<storm::storage::BitVector> neighborsOfVertices(vertices.size(),
storm::storage::BitVector(vertices.size(),
false));
109 std::vector<Halfspace<storm::RationalNumber>> halfspaces = getHalfspaces();
110 for (
auto const& h : halfspaces) {
112 for (uint_fast64_t v = 0; v < vertices.size(); ++v) {
113 if (h.isPointOnBoundary(vertices[v])) {
114 verticesOnHalfspace.
set(v);
117 for (
auto v : verticesOnHalfspace) {
118 neighborsOfVertices[v] |= verticesOnHalfspace;
119 neighborsOfVertices[v].
set(v,
false);
123 std::vector<Point> result;
124 result.reserve(vertices.size());
127 uint_fast64_t currentVertex = 0;
128 for (uint_fast64_t v = 1; v < vertices.size(); ++v) {
129 if (vertices[v].front() < vertices[currentVertex].front()) {
133 STORM_LOG_ASSERT(neighborsOfVertices[currentVertex].getNumberOfSetBits() == 2,
134 "For 2D Polytopes with at least 3 vertices, each vertex should have exactly 2 neighbors");
135 uint_fast64_t firstNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(0);
136 uint_fast64_t secondNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(firstNeighbor + 1);
137 uint_fast64_t previousVertex = vertices[firstNeighbor].back() <= vertices[secondNeighbor].back() ? firstNeighbor : secondNeighbor;
139 unprocessedVertices.
set(currentVertex,
false);
140 result.push_back(std::move(vertices[currentVertex]));
142 STORM_LOG_ASSERT(neighborsOfVertices[currentVertex].getNumberOfSetBits() == 2,
143 "For 2D Polytopes with at least 3 vertices, each vertex should have exactly 2 neighbors");
144 firstNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(0);
145 secondNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(firstNeighbor + 1);
146 uint_fast64_t nextVertex = firstNeighbor != previousVertex ? firstNeighbor : secondNeighbor;
147 previousVertex = currentVertex;
148 currentVertex = nextVertex;
149 }
while (!unprocessedVertices.
empty());
154template<
typename ValueType>
156 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented.");
159 return std::vector<Point>();
162template<
typename ValueType>
165 std::vector<Point> idMatrix(b.size(),
Point(b.size(), storm::utility::zero<ValueType>()));
166 for (uint64_t
i = 0;
i < b.size(); ++
i) {
167 idMatrix[
i][
i] = storm::utility::one<ValueType>();
169 return affineTransformation(idMatrix, b);
172template<
typename ValueType>
174 std::vector<std::shared_ptr<Polytope<ValueType>>> result;
175 auto rhsHalfspaces = rhs->getHalfspaces();
176 std::shared_ptr<Polytope<ValueType>> remaining =
nullptr;
177 for (
auto const& h : rhsHalfspaces) {
180 if (!next->isEmpty()) {
181 result.push_back(next);
184 if (remaining->isEmpty()) {
191template<
typename ValueType>
193 return createDownwardClosure(this->getVertices());
196template<
typename ValueType>
198 std::string
const& namePrefix)
const {
199 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented for this polytope implementation.");
200 std::vector<storm::expressions::Variable> result;
204template<
typename ValueType>
206 std::vector<storm::expressions::Variable>
const& variables)
const {
207 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented for this polytope implementation.");
208 std::vector<storm::expressions::Expression> result;
212template<
typename ValueType>
213template<
typename TargetType>
218 auto halfspaces = getHalfspaces();
219 std::vector<Halfspace<TargetType>> halfspacesPrime;
220 halfspacesPrime.reserve(halfspaces.size());
221 for (
auto const& h : halfspaces) {
222 halfspacesPrime.emplace_back(storm::utility::vector::convertNumericVector<TargetType>(h.normalVector()),
223 storm::utility::convertNumber<TargetType>(h.offset()));
229template<
typename ValueType>
231 auto halfspaces = this->getHalfspaces();
232 std::stringstream stream;
233 stream <<
"Polytope with " << halfspaces.size() <<
" Halfspaces" << (halfspaces.empty() ?
"" :
":") <<
'\n';
234 for (
auto const& h : halfspaces) {
235 stream <<
" " << h.toString(numbersAsDouble) <<
'\n';
240template<
typename ValueType>
245template<
typename ValueType>
247 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"functionality not implemented for this polytope type.");
This class is responsible for managing a set of typed variables and all expressions using these varia...
A bit vector that is internally represented as a vector of 64-bit values.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
static std::shared_ptr< Polytope< ValueType > > create(boost::optional< std::vector< Halfspace< ValueType > > > const &halfspaces, boost::optional< std::vector< Point > > const &points)
Creates a NativePolytope from the given halfspaces or points.
std::vector< ValueType > Point
static std::shared_ptr< Polytope< ValueType > > createDownwardClosure(std::vector< Point > const &points)
Creates the downward closure of the given points (i.e., the set { x | ex.
virtual std::vector< Point > getVerticesInClockwiseOrder() const
Returns the vertices of this 2D-polytope in clockwise order.
std::vector< std::shared_ptr< Polytope< ValueType > > > setMinus(std::shared_ptr< Polytope< ValueType > > const &rhs) const
Computes the set {x \in this | x \notin rhs}.
static std::shared_ptr< Polytope< ValueType > > create(std::vector< Halfspace< ValueType > > const &halfspaces)
Creates a polytope from the given halfspaces.
virtual std::vector< storm::expressions::Expression > getConstraints(storm::expressions::ExpressionManager const &manager, std::vector< storm::expressions::Variable > const &variables) const
Returns the constrains defined by this polytope as an expression over the given variables.
virtual std::shared_ptr< Polytope< ValueType > > downwardClosure() const
Returns the downward closure of this, i.e., the set { x | ex.
virtual bool isNativePolytope() const
virtual std::shared_ptr< Polytope< ValueType > > clean()
Performs cleaning operations, e.g., deleting redundant halfspaces.
static std::shared_ptr< Polytope< ValueType > > createUniversalPolytope()
Creates the universal polytope (i.e., the set R^n)
virtual std::string toString(bool numbersAsDouble=false) const
std::shared_ptr< Polytope< TargetType > > convertNumberRepresentation() const
converts the intern number representation of the polytope to the given target type
static std::shared_ptr< Polytope< ValueType > > createEmptyPolytope()
Creates the empty polytope (i.e., emptyset)
virtual std::shared_ptr< Polytope< ValueType > > intersection(std::shared_ptr< Polytope< ValueType > > const &rhs) const =0
Intersects this polytope with rhs and returns the result.
static std::shared_ptr< Polytope< ValueType > > createSelectiveDownwardClosure(std::vector< Point > const &points, storm::storage::BitVector const &selectedDimensions)
Creates the downward closure of the given points but only with respect to the selected dimensions,...
std::shared_ptr< Polytope< ValueType > > shift(Point const &b) const
Returns the Polytope described by the set {x+b | x \in this}.
virtual std::vector< storm::expressions::Variable > declareVariables(storm::expressions::ExpressionManager &manager, std::string const &namePrefix) const
Declares one variable for each dimension and returns the obtained variables.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)