#ifndef STORM_STORAGE_GEOMETRY_NATIVEPOLYTOPE_H_ #define STORM_STORAGE_GEOMETRY_NATIVEPOLYTOPE_H_ #include "storm/storage/geometry/Polytope.h" #include "storm/storage/expressions/Expressions.h" #include "storm/adapters/EigenAdapter.h" namespace storm { namespace storage { namespace geometry { template <typename ValueType> class NativePolytope : public Polytope<ValueType> { public: typedef StormEigen::Matrix<ValueType, StormEigen::Dynamic, StormEigen::Dynamic> EigenMatrix; typedef StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1> EigenVector; enum class EmptyStatus{ Unknown, //It is unknown whether the polytope is empty or not Empty, //The polytope is empty Nonempty //the polytope is not empty }; typedef typename Polytope<ValueType>::Point Point; /*! * Creates a NativePolytope from the given halfspaces or points. * If both representations are given, one of them might be ignored */ 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 * The resulting polytope is defined as the intersection of the halfspaces. */ NativePolytope(std::vector<Halfspace<ValueType>> const& halfspaces); /*! * Creates a NativePolytope from the given points. * The resulting polytope is defined as the convex hull of the points' */ NativePolytope(std::vector<Point> const& points); /*! * Copy and move constructors */ NativePolytope(NativePolytope<ValueType> const& other); NativePolytope(NativePolytope<ValueType>&& other); /*! * Construction from intern data */ NativePolytope(EmptyStatus const& emptyStatus, EigenMatrix const& halfspaceMatrix, EigenVector const& halfspaceVector); NativePolytope(EmptyStatus&& emptyStatus, EigenMatrix&& halfspaceMatrix, EigenVector&& halfspaceVector); ~NativePolytope(); /*! * Returns the vertices of this polytope. */ virtual std::vector<Point> getVertices() const override; /*! * Returns the halfspaces of this polytope. */ virtual std::vector<Halfspace<ValueType>> getHalfspaces() const override; /*! * Returns whether this polytope is the empty set. */ virtual bool isEmpty() const override; /*! * Returns whether this polytope is universal (i.e., equals R^n). */ virtual bool isUniversal() const override; /*! * Returns true iff the given point is inside of the polytope. */ virtual bool contains(Point const& point) const override; /*! * Returns true iff the given polytope is a subset of this polytope. */ virtual bool contains(std::shared_ptr<Polytope<ValueType>> const& other) const override; /*! * Intersects this polytope with rhs and returns the result. */ virtual std::shared_ptr<Polytope<ValueType>> intersection(std::shared_ptr<Polytope<ValueType>> const& rhs) const override; virtual std::shared_ptr<Polytope<ValueType>> intersection(Halfspace<ValueType> const& halfspace) const override; /*! * Returns the convex union of this polytope and rhs. */ virtual std::shared_ptr<Polytope<ValueType>> convexUnion(std::shared_ptr<Polytope<ValueType>> const& rhs) const override; /*! * Returns the minkowskiSum of this polytope and rhs. */ virtual std::shared_ptr<Polytope<ValueType>> minkowskiSum(std::shared_ptr<Polytope<ValueType>> const& rhs) const override; /*! * Returns the affine transformation of this polytope P w.r.t. the given matrix A and vector b. * The result is the set {A*x+b | x \in P} * * @param matrix the transformation matrix, given as vector of rows * @param vector the transformation offset */ virtual std::shared_ptr<Polytope<ValueType>> affineTransformation(std::vector<Point> const& matrix, Point const& vector) const override; /*! * Finds an optimal point inside this polytope w.r.t. the given direction, i.e., * a point that maximizes dotPorduct(point, direction). * If such a point does not exist, the returned bool is false. There are two reasons for this: * - The polytope is empty * - The polytope is not bounded in the given direction */ virtual std::pair<Point, bool> optimize(Point const& direction) const override; virtual bool isNativePolytope() const override; private: // returns the vertices of this polytope as EigenVectors std::vector<EigenVector> getEigenVertices() const; // As optimize(..) but with EigenVectors std::pair<EigenVector, bool> optimize(EigenVector const& direction) const; // declares one variable for each constraint and returns the obtained variables. std::vector<storm::expressions::Variable> declareVariables(storm::expressions::ExpressionManager& manager, std::string const& namePrefix) const; // returns the constrains defined by this polytope as an expresseion storm::expressions::Expression getConstraints(storm::expressions::ExpressionManager const& manager, std::vector<storm::expressions::Variable> const& variables) const; //Stores whether the polytope is empty or not mutable EmptyStatus emptyStatus; // Intern representation of the polytope as { x | Ax<=b } EigenMatrix A; EigenVector b; }; } } } #endif /* STORM_STORAGE_GEOMETRY_NATIVEPOLYTOPE_H_ */