16template<
typename ValueType>
18 return create(halfspaces, boost::none);
21template<
typename ValueType>
23 return create(boost::none, points);
26template<
typename ValueType>
31template<
typename ValueType>
33 return create(boost::none, std::vector<Point>());
36template<
typename ValueType>
38 boost::optional<std::vector<Point>>
const& points) {
42template<
typename ValueType>
46 return createEmptyPolytope();
50 return createSelectiveDownwardClosure(points, dimensions);
53template<
typename ValueType>
58 return createEmptyPolytope();
60 if (selectedDimensions.
empty()) {
61 return create(points);
63 assert(points.front().size() == selectedDimensions.
size());
65 std::vector<Halfspace<ValueType>> halfspaces;
69 std::vector<Point> auxiliaryPoints = points;
70 auxiliaryPoints.reserve(auxiliaryPoints.size() * (1 + selectedDimensions.
getNumberOfSetBits()));
71 for (
auto const& point : points) {
72 for (
auto dim : selectedDimensions) {
73 auxiliaryPoints.push_back(point);
74 auxiliaryPoints.back()[dim] -= storm::utility::one<ValueType>();
77 std::vector<Halfspace<ValueType>> auxiliaryHalfspaces = create(auxiliaryPoints)->getHalfspaces();
79 for (
auto& h : auxiliaryHalfspaces) {
80 bool allGreaterEqZero =
true;
81 for (
auto dim : selectedDimensions) {
82 allGreaterEqZero &= (h.normalVector()[dim] >= storm::utility::zero<ValueType>());
84 if (allGreaterEqZero) {
85 halfspaces.push_back(std::move(h));
88 return create(halfspaces);
91template<
typename ValueType>
96template<
typename ValueType>
101#ifdef STORM_HAVE_CARL
104 std::vector<Point> vertices = getVertices();
105 if (vertices.size() <= 2) {
109 STORM_LOG_THROW(vertices.front().size() == 2, storm::exceptions::IllegalFunctionCallException,
110 "Getting Vertices in clockwise order is only possible for a 2D-polytope.");
112 std::vector<storm::storage::BitVector> neighborsOfVertices(vertices.size(),
storm::storage::BitVector(vertices.size(),
false));
113 std::vector<Halfspace<storm::RationalNumber>> halfspaces = getHalfspaces();
114 for (
auto const& h : halfspaces) {
116 for (uint_fast64_t v = 0; v < vertices.size(); ++v) {
117 if (h.isPointOnBoundary(vertices[v])) {
118 verticesOnHalfspace.set(v);
121 for (
auto v : verticesOnHalfspace) {
122 neighborsOfVertices[v] |= verticesOnHalfspace;
123 neighborsOfVertices[v].set(v,
false);
127 std::vector<Point> result;
128 result.reserve(vertices.size());
131 uint_fast64_t currentVertex = 0;
132 for (uint_fast64_t v = 1; v < vertices.size(); ++v) {
133 if (vertices[v].front() < vertices[currentVertex].front()) {
137 STORM_LOG_ASSERT(neighborsOfVertices[currentVertex].getNumberOfSetBits() == 2,
138 "For 2D Polytopes with at least 3 vertices, each vertex should have exactly 2 neighbors");
139 uint_fast64_t firstNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(0);
140 uint_fast64_t secondNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(firstNeighbor + 1);
141 uint_fast64_t previousVertex = vertices[firstNeighbor].back() <= vertices[secondNeighbor].back() ? firstNeighbor : secondNeighbor;
143 unprocessedVertices.set(currentVertex,
false);
144 result.push_back(std::move(vertices[currentVertex]));
146 STORM_LOG_ASSERT(neighborsOfVertices[currentVertex].getNumberOfSetBits() == 2,
147 "For 2D Polytopes with at least 3 vertices, each vertex should have exactly 2 neighbors");
148 firstNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(0);
149 secondNeighbor = neighborsOfVertices[currentVertex].getNextSetIndex(firstNeighbor + 1);
150 uint_fast64_t nextVertex = firstNeighbor != previousVertex ? firstNeighbor : secondNeighbor;
151 previousVertex = currentVertex;
152 currentVertex = nextVertex;
153 }
while (!unprocessedVertices.empty());
159template<
typename ValueType>
161 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented.");
164 return std::vector<Point>();
167template<
typename ValueType>
170 std::vector<Point> idMatrix(b.size(),
Point(b.size(), storm::utility::zero<ValueType>()));
171 for (uint64_t
i = 0;
i < b.size(); ++
i) {
172 idMatrix[
i][
i] = storm::utility::one<ValueType>();
174 return affineTransformation(idMatrix, b);
177template<
typename ValueType>
179 std::vector<std::shared_ptr<Polytope<ValueType>>> result;
180 auto rhsHalfspaces = rhs->getHalfspaces();
181 std::shared_ptr<Polytope<ValueType>> remaining =
nullptr;
182 for (
auto const& h : rhsHalfspaces) {
185 if (!next->isEmpty()) {
186 result.push_back(next);
189 if (remaining->isEmpty()) {
196template<
typename ValueType>
198 return createDownwardClosure(this->getVertices());
201template<
typename ValueType>
203 std::string
const& namePrefix)
const {
204 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented for this polytope implementation.");
205 std::vector<storm::expressions::Variable> result;
209template<
typename ValueType>
211 std::vector<storm::expressions::Variable>
const& variables)
const {
212 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Functionality not implemented for this polytope implementation.");
213 std::vector<storm::expressions::Expression> result;
217template<
typename ValueType>
218template<
typename TargetType>
223 auto halfspaces = getHalfspaces();
224 std::vector<Halfspace<TargetType>> halfspacesPrime;
225 halfspacesPrime.reserve(halfspaces.size());
226 for (
auto const& h : halfspaces) {
227 halfspacesPrime.emplace_back(storm::utility::vector::convertNumericVector<TargetType>(h.normalVector()),
228 storm::utility::convertNumber<TargetType>(h.offset()));
234template<
typename ValueType>
236 auto halfspaces = this->getHalfspaces();
237 std::stringstream stream;
238 stream <<
"Polytope with " << halfspaces.size() <<
" Halfspaces" << (halfspaces.empty() ?
"" :
":") <<
'\n';
239 for (
auto const& h : halfspaces) {
240 stream <<
" " << h.toString(numbersAsDouble) <<
'\n';
245template<
typename ValueType>
250template<
typename ValueType>
252 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"functionality not implemented for this polytope type.");
259#ifdef STORM_HAVE_CARL
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.
size_t size() const
Retrieves the number of bits this bit vector can store.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
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.
std::shared_ptr< Polytope< TargetType > > convertNumberRepresentation() const
converts the intern number representation of the polytope to the given target type
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
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)