34 #include "DGtal/base/Common.h"
35 #include "DGtal/geometry/volumes/EhrhartPolynomial.h"
36 #include "DGtal/geometry/volumes/DigitalConvexity.h"
37 #include "DGtalCatch.h"
41 using namespace DGtal;
48 SCENARIO(
"EhrhartPolynomial< Z2 > unit tests",
"[ehrhart_polynomial][2d]" )
56 GIVEN(
"Simplex (0,0), (1,0), (2,1)" ) {
61 THEN(
"Its Ehrhart polynomial is 1/2( 2+ 3t+t^2) ") {
62 auto expP = mmonomial<Integer>( 2 ) + 3 * mmonomial<Integer>( 1 ) + 2;
63 REQUIRE( E.numerator() == expP );
64 REQUIRE( E.denominator() == 2 );
66 THEN(
"Its Ehrhart polynomial counts lattice points" ) {
68 auto n0 = E.count( 0 );
71 auto n1 = E.count( 1 );
74 auto n2 = E.count( 2 );
77 auto n3 = E.count( 3 );
80 THEN(
"Its Ehrhart polynomial counts interior lattice points" ) {
82 auto n1 = E.countInterior( 1 );
83 REQUIRE( P1.countInterior() == n1 );
85 auto n2 = E.countInterior( 2 );
86 REQUIRE( P2.countInterior() == n2 );
88 auto n3 = E.countInterior( 3 );
89 REQUIRE( P3.countInterior() == n3 );
91 auto n4 = E.countInterior( 4 );
92 REQUIRE( P4.countInterior() == n4 );
97 SCENARIO(
"EhrhartPolynomial< Z3 > unit tests",
"[ehrhart_polynomial][3d]" )
105 GIVEN(
"A convex polytope" ) {
106 std::vector< Point > T = {
Point(0,0,0),
Point(1,0,1),
Point(2,1,0),
Point(0,0,2),
113 THEN(
"Its Ehrhart polynomial counts lattice points" ) {
115 auto n0 = E.count( 0 );
118 auto n1 = E.count( 1 );
121 auto n2 = E.count( 2 );
124 auto n3 = E.count( 3 );
127 THEN(
"Its Ehrhart polynomial counts interior lattice points" ) {
129 auto n1 = E.countInterior( 1 );
130 REQUIRE( P1.countInterior() == n1 );
132 auto n2 = E.countInterior( 2 );
133 REQUIRE( P2.countInterior() == n2 );
135 auto n3 = E.countInterior( 3 );
136 REQUIRE( P3.countInterior() == n3 );
138 auto n4 = E.countInterior( 4 );
139 REQUIRE( P4.countInterior() == n4 );
145 SCENARIO(
"EhrhartPolynomial< Z4 > unit tests",
"[ehrhart_polynomial][4d]" )
153 GIVEN(
"A convex polytope" ) {
154 std::vector< Point > T = {
Point(0,0,0,0),
Point(1,0,1,-1),
Point(2,1,0,2),
155 Point(0,0,2,0),
Point(0,4,1,3),
Point(3,0,-1,1) };
161 THEN(
"Its Ehrhart polynomial counts lattice points" ) {
163 auto n0 = E.count( 0 );
166 auto n1 = E.count( 1 );
169 auto n2 = E.count( 2 );
172 auto n3 = E.count( 3 );
175 THEN(
"Its Ehrhart polynomial counts interior lattice points" ) {
177 auto n1 = E.countInterior( 1 );
178 REQUIRE( P1.countInterior() == n1 );
180 auto n2 = E.countInterior( 2 );
181 REQUIRE( P2.countInterior() == n2 );
183 auto n3 = E.countInterior( 3 );
184 REQUIRE( P3.countInterior() == n3 );
186 auto n4 = E.countInterior( 4 );
187 REQUIRE( P4.countInterior() == n4 );
192 SCENARIO(
"EhrhartPolynomial< Z2 > triangle tests",
"[ehrhart_polynomial][2d]" )
200 typedef Ehrhart::LatticePolytope Polytope;
201 typedef Polytope::UnitSegment UnitSegment;
206 WHEN(
"Computing all triangles in domain (0,0)-(4,4)." ) {
207 unsigned int nbsimplex = 0;
208 unsigned int nb0_ok = 0;
209 unsigned int nb1_ok = 0;
210 unsigned int nb_cvx_ok = 0;
215 if ( ! ( ( a < b ) && ( b < c ) ) )
continue;
219 const auto P0 = P + UnitSegment( 0 );
220 const auto P1 = P + UnitSegment( 1 );
221 const auto D = P.getDomain();
222 const auto W = D.upperBound() - D.lowerBound();
223 const auto E_P = Ehrhart( P );
224 const auto E_P0 = Ehrhart( P0 );
225 const auto E_P1 = Ehrhart( P1 );
226 const auto LP = E_P.numerator();
227 const auto LP0 = E_P0.numerator();
228 const auto LP1 = E_P1.numerator();
229 const auto LD = E_P.denominator();
230 const auto LD0 = E_P0.denominator();
231 const auto LD1 = E_P1.denominator();
232 const bool c2_0 = ( LP[ 2 ] +
Integer( W[ 1 ] ) * LD ) == LP0[ 2 ];
233 const bool c1_0 = ( LP[ 1 ] +
Integer( 1 ) * LD ) == LP0[ 1 ];
234 const bool c0_0 = LP[ 0 ] == LP0[ 0 ];
235 const bool d_0 = LD == LD0;
236 const bool c2_1 = ( LP[ 2 ] +
Integer( W[ 0 ] ) * LD ) == LP1[ 2 ];
237 const bool c1_1 = ( LP[ 1 ] +
Integer( 1 ) * LD ) == LP1[ 1 ];
238 const bool c0_1 = LP[ 0 ] == LP1[ 0 ];
239 const bool d_1 = LD == LD1;
240 nb0_ok += ( c2_0 && c1_0 && c0_0 && d_0 ) ? 1 : 0;
241 nb1_ok += ( c2_1 && c1_1 && c0_1 && d_1 ) ? 1 : 0;
243 nb_cvx_ok += fcvx ? 1 : 0;
244 if ( ! ( c2_0 && c1_0 && c0_0 && d_0 ) ){
245 trace.
info() <<
"------------------------------------" << std::endl;
246 trace.
info() << ( fcvx ?
"FULLCVX" :
"NOTFULLCVX" ) << a << b << c << std::endl;
247 trace.
info() <<
"W[0] = " << W[ 0 ] <<
"W[1] = " << W[ 1 ] << std::endl;
248 trace.
info() <<
"LP = (" << LP <<
")/" << E_P.denominator() << std::endl;
249 trace.
info() <<
"LP0= (" << LP0 <<
")/" << E_P0.denominator() << std::endl;
252 if ( ! ( c2_1 && c1_1 && c0_1 && d_1 ) ){
253 trace.
info() <<
"------------------------------------" << std::endl;
254 trace.
info() << ( fcvx ?
"FULLCVX" :
"NOTFULLCVX" ) << a << b << c << std::endl;
255 trace.
info() <<
"W[0] = " << W[ 0 ] <<
"W[1] = " << W[ 1 ] << std::endl;
256 trace.
info() <<
"LP = (" << LP <<
")/" << E_P.denominator() << std::endl;
257 trace.
info() <<
"LP1= (" << LP1 <<
")/" << E_P1.denominator() << std::endl;
261 THEN(
"Not all triangles are fully convex." ) {
262 REQUIRE( nb_cvx_ok < nbsimplex );
264 THEN(
"Ehrhart polynomials are predictable." ) {
266 REQUIRE( nb0_ok == nbsimplex );
267 REQUIRE( nb1_ok == nbsimplex );
static bool isSimplexFullDimensional(PointIterator itB, PointIterator itE)
static LatticePolytope makeSimplex(PointIterator itB, PointIterator itE)
bool isFullyConvex(const PointRange &X, bool convex0=false) const
LatticePolytope makePolytope(const PointRange &X, bool make_minkowski_summable=false) const
Aim: This class implements the class Ehrhart Polynomial which is related to lattice point enumeration...
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
Point::Coordinate Integer
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::int64_t int64_t
signed 94-bit integer.
GIVEN("A cubical complex with random 3-cells")
SCENARIO("EhrhartPolynomial< Z2 > unit tests", "[ehrhart_polynomial][2d]")
HyperRectDomain< Space > Domain
REQUIRE(domain.isInside(aPoint))