31 template <
typename GUM_SCALAR >
33 __state = __states::none;
47 template <
typename GUM_SCALAR >
52 template <
typename GUM_SCALAR >
57 template <
typename GUM_SCALAR >
62 template <
typename GUM_SCALAR >
67 template <
typename GUM_SCALAR >
73 "LRSWrapper< GUM_SCALAR >::getVolume () : " 74 "volume computation was not asked for this " 75 "credal set, call computeVolume() from a " 79 template <
typename GUM_SCALAR >
83 "LRSWrapper< GUM_SCALAR >::setUpH : " 84 "cardinality must be at least 2");
88 __input = std::vector< std::vector< GUM_SCALAR > >(
89 card * 2 + 2, std::vector< GUM_SCALAR >(card + 1, 0));
91 __input[card * 2] = std::vector< GUM_SCALAR >(card + 1, -1);
92 __input[card * 2][0] = 1;
94 __input[card * 2 + 1] = std::vector< GUM_SCALAR >(card + 1, 1);
95 __input[card * 2 + 1][0] = -1;
97 __output = std::vector< std::vector< GUM_SCALAR > >();
99 __vertex = std::vector< GUM_SCALAR >(card);
101 __state = __states::Hup;
103 __card = (
unsigned int)card;
106 template <
typename GUM_SCALAR >
110 "LRSWrapper< GUM_SCALAR >::setUpV : " 111 "cardinality must be at least 2");
115 "LRSWrapper< GUM_SCALAR >::setUpV : vertices " 116 "must be at least 2 to build a polytope");
120 __input = std::vector< std::vector< GUM_SCALAR > >(
121 vertices, std::vector< GUM_SCALAR >(card + 1, 1));
123 __output = std::vector< std::vector< GUM_SCALAR > >();
125 __state = __states::Vup;
127 __card = (
unsigned int)card;
128 __vertices = (
unsigned int)vertices;
131 template <
typename GUM_SCALAR >
136 __insertedModals.clear();
138 __insertedVertices.clear();
143 __state = __states::none;
151 template <
typename GUM_SCALAR >
153 __insertedModals.clear();
154 __insertedVertices.clear();
157 __vertex.resize(__card, 0);
166 if (__state == __states::H2Vready)
167 __state = __states::Hup;
168 else if (__state == __states::V2Hready) {
169 __state = __states::Vup;
172 "LRSWrapper< GUM_SCALAR >::nextHInput : only for H-representation " 173 "as input. Previous state was : " 174 << __setUpStateNames[static_cast< int >(__state)]);
177 __state = __states::none;
183 template <
typename GUM_SCALAR >
185 const GUM_SCALAR& max,
187 if (__state != __states::Hup)
190 "LRSWrapper< GUM_SCALAR >::fillH : setUpH or nextInput has not " 191 "been called or H-representation is complete, current state is : " 192 << __setUpStateNames[static_cast< int >(__state)]);
196 "LRSWrapper< GUM_SCALAR >::fillH : modality is " 197 "greater or equal than cardinality : " 198 << modal <<
" >= " << __card);
200 __input[modal * 2][0] = -min;
201 __input[modal * 2][modal + 1] = 1;
203 __input[modal * 2 + 1][0] = max;
204 __input[modal * 2 + 1][modal + 1] = -1;
206 __vertex[modal] = max;
208 __insertedModals.insert(
int(modal));
210 if (__insertedModals.size() == __card) __state = __states::H2Vready;
213 template <
typename GUM_SCALAR >
215 const std::vector< std::vector< GUM_SCALAR > >&
matrix) {
216 if (__state != __states::Hup)
219 "LRSWrapper< GUM_SCALAR >::fillH : setUpH or nextInput has not " 220 "been called or H-representation is complete, current state is : " 221 << __setUpStateNames[static_cast< int >(__state)]);
223 if (
matrix[0].size() - 1 != __card)
225 "LRSWrapper< GUM_SCALAR >::fillMatrix : size is " 226 "different than cardinality : " 227 << (
matrix[0].size() - 1) <<
" != " << __card);
231 for (
unsigned int modal = 0; modal < __card; modal++) {
232 __insertedModals.insert(modal);
235 __state = __states::H2Vready;
238 template <
typename GUM_SCALAR >
240 if (__state != __states::Vup)
243 "LRSWrapper< GUM_SCALAR >::fillV : setUpV or nextInput has not " 244 "been called or V-representation is complete, current state is : " 245 << __setUpStateNames[static_cast< int >(__state)]);
247 if (__insertedVertices.size() == __vertices)
249 "LRSWrapper< GUM_SCALAR >::fillV : input is already full with " 250 << __vertices <<
" vertices.");
254 for (
const auto& v : __insertedVertices) {
257 for (decltype(__card) mod = 0; mod < __card; mod++)
258 if (std::fabs(v[mod] - vertex[mod]) > 1e-6) {
272 auto row = __insertedVertices.size();
274 for (decltype(__card) mod = 0; mod < __card; mod++)
275 __input[row][mod + 1] = vertex[mod];
277 __insertedVertices.push_back(vertex);
279 if (__insertedVertices.size() == __vertices) __state = __states::V2Hready;
282 template <
typename GUM_SCALAR >
284 if (__state != __states::H2Vready)
286 "LRSWrapper< GUM_SCALAR >::H2V : fillH has not been called with " 287 "all modalities, current state is still : " 288 << __setUpStateNames[static_cast< int >(__state)]);
295 for (
const auto elem : __vertex)
298 if (std::fabs(sum - 1) < 1e-6) {
299 __output = std::vector< std::vector< GUM_SCALAR > >(1, __vertex);
317 std::vector< int64_t > Num;
318 std::vector< int64_t > Den;
321 for (decltype(__dic->d) col = 0, end = __dic->d; col <= end; col++)
322 if (lrs_getsolution(__dic, __dat, __lrsOutput, col)) {
325 || ((((__lrsOutput[0])[0] == 2 || (__lrsOutput[0])[0] == -2)
326 && (__lrsOutput[0])[1] == 0)
333 "LRSWrapper< GUM_SCALAR >::H2V : asked for " 334 "Q-hull computation or not reading a vertex !");
336 for (decltype(__dat->n) i = 1, end = __dat->n; i < end; i++)
337 __getLRSWrapperOutput(__lrsOutput[i], __lrsOutput[0], Num, Den);
339 }
while (lrs_getnextbasis(&__dic, __dat, 0L));
341 auto vtx = Num.size();
342 std::vector< GUM_SCALAR > vertex(__card);
344 for (decltype(vtx) i = 1; i <= vtx; i++) {
345 vertex[(i - 1) % __card] = GUM_SCALAR(Num[i - 1] * 1.0 / Den[i - 1]);
347 if (i % __card == 0) {
348 __output.push_back(vertex);
358 template <
typename GUM_SCALAR >
360 if (!__state == __states::V2Hready)
362 "LRSWrapper< GUM_SCALAR >::V2H : fillV has " 363 "not been called with all vertices, current " 365 << __setUpStateNames[__state]);
368 template <
typename GUM_SCALAR >
370 if (!__state == __states::V2Hready)
372 "LRSWrapper< GUM_SCALAR >::computeVolume : " 373 "volume is only for V-representation or " 374 "fillV has not been called with all " 375 "vertices, current state is still : " 376 << __setUpStateNames[__state]);
385 for (decltype(__dic->d) col = 0, end = __dic->d; col <= end; col++)
386 lrs_getsolution(__dic, __dat, __lrsOutput, col);
387 }
while (lrs_getnextbasis(&__dic, __dat, 0L));
390 (__dat->Nvolume[0] > 0) ? __dat->Nvolume[0] : -__dat->Nvolume[0];
392 (__dat->Dvolume[0] > 0) ? __dat->Dvolume[0] : -__dat->Dvolume[0];
394 int64_t num = 0L, den = 0L;
397 for (decltype(Nsize) i = Nsize - 1; i > 0; i--) {
398 tmp = __dat->Nvolume[i];
400 for (decltype(i) j = 1; j < i; j++)
406 for (decltype(Dsize) i = Dsize - 1; i > 0; i--) {
407 tmp = __dat->Dvolume[i];
409 for (decltype(i) j = 1; j < i; j++)
415 __volume = num * 1.0 / den;
422 template <
typename GUM_SCALAR >
424 if (__state != __states::V2Hready)
427 "LRSWrapper< GUM_SCALAR >::elimRedundVrep : only for " 428 "V-representation or fillV has not been called with all vertices, " 429 "current state is still : " 430 << __setUpStateNames[static_cast< int >(__state)]);
447 auto nlinearity = __dat->nlinearity;
448 auto lastdv = __dat->lastdv;
451 redineq = (int64_t*)calloc(std::size_t(m + 1),
sizeof(int64_t));
453 for (decltype(nlinearity) i = 0; i < nlinearity; i++)
454 redineq[__dat->linearity[i]] = 2L;
459 for (decltype(m + d) index = lastdv + 1, end = m + d; index <= end;
463 __dat->inequality[index - lastdv];
466 redineq[ineq] = checkindex(__dic, __dat, index);
472 "LRSWrapper< GUM_SCALAR >::elimRedundVrep : not " 473 "reading a vertex but a linearity !");
488 for (decltype(m) i = 1; i <= m; i++)
491 std::vector< GUM_SCALAR >(++__input[std::size_t(i - 1)].begin(),
492 __input[std::size_t(i - 1)].end()));
494 __vertices = (
unsigned int)__output.size();
501 template <
typename GUM_SCALAR >
505 std::vector< int64_t >& Num,
506 std::vector< int64_t >& Den)
const {
507 int64_t Nsize = (Nin[0] > 0) ? Nin[0] : -Nin[0];
508 int64_t Dsize = (Din[0] > 0) ? Din[0] : -Din[0];
515 for (decltype(Nsize) i = Nsize - 1; i > 0; i--) {
518 for (decltype(i) j = 1; j < i; j++)
524 if (!(Din[0] == 2L && Din[1] == 1L)) {
525 for (decltype(Dsize) i = Dsize - 1; i > 0; i--) {
528 for (decltype(i) j = 1; j < i; j++)
537 int64_t Nsign = ((Nin[0] < 0) ? -1L : 1L);
538 int64_t Dsign = ((Din[0] < 0) ? -1L : 1L);
540 if ((Nsign * Dsign) == -1L) num = -num;
560 template <
typename GUM_SCALAR >
562 std::size_t cols = __input[0].size();
564 int64_t* num =
new int64_t[cols];
566 int64_t* den =
new int64_t[cols];
568 int64_t rows = int64_t(__input.size());
570 int64_t numerator, denominator;
572 for (int64_t row = 0; row < rows; row++) {
573 for (std::size_t col = 0; col < cols; col++) {
575 numerator, denominator, __input[std::size_t(row)][col]);
577 num[col] = numerator;
578 den[col] = denominator;
595 template <
typename GUM_SCALAR >
597 if (__state != __states::H2Vready && __state != __states::V2Hready)
599 "LRSWrapper< GUM_SCALAR >::__initLrs : not ready, current state " 601 << __setUpStateNames[static_cast< int >(__state)]);
605 std::string name =
"\n*LrsWrapper:";
606 std::vector< char > chars(name.c_str(), name.c_str() + name.size() + 1u);
609 if (!lrs_init(&chars[0])) {
612 "LRSWrapper< GUM_SCALAR >::__initLrs : failed lrs_init");
615 name =
"LRSWrapper globals";
616 chars = std::vector< char >(name.c_str(), name.c_str() + name.size() + 1u);
618 __dat = lrs_alloc_dat(&chars[0]);
620 if (__dat ==
nullptr) {
623 "LRSWrapper< GUM_SCALAR >::__initLrs : failed lrs_alloc_dat");
626 __dat->n =
Size(__input[0].size());
627 __dat->m =
Size(__input.size());
629 __dat->getvolume = (__getVolume) ? 1L : 0L;
630 __dat->hull = (__hull) ? 1L : 0L;
631 __dat->polytope = (__polytope) ? 1L : 0L;
633 __lrsOutput = lrs_alloc_mp_vector(__dat->n);
635 __dic = lrs_alloc_dic(__dat);
637 if (__dic ==
nullptr) {
640 "LRSWrapper< GUM_SCALAR >::__initLrs : failed lrs_alloc_dic");
646 if (!lrs_getfirstbasis(&__dic, __dat, &__Lin, 0L)) {
650 "LRSWrapper< GUM_SCALAR >::__initLrs : failed lrs_getfirstbasis");
658 decltype(__dat->nredundcol) startcol = 0;
660 if (__dat->homogeneous && __dat->hull) {
663 if (!__dat->restart) {
666 for (decltype(__dat->nredundcol) col = startcol; col < __dat->nredundcol;
668 lrs_printoutput(__dat, __Lin[col]);
671 "LRSWrapper< GUM_SCALAR >::__initLrs : redundant columns !");
691 template <
typename GUM_SCALAR >
695 lrs_clear_mp_vector(__lrsOutput, __dat->n);
697 if (__dat->nredundcol > 0)
698 lrs_clear_mp_matrix(__Lin, __dat->nredundcol, __dat->n);
700 if (__dat->runs > 0) {
705 auto savem = __dic->m;
707 lrs_free_dic(__dic, __dat);
712 std::string name =
"LrsWrapper:";
713 std::vector< char > chars(name.c_str(), name.c_str() + name.size() + 1u);
715 lrs_close(&chars[0]);
720 template <
typename GUM_SCALAR >
724 freopen(
"NUL",
"w", stdout);
728 int new_cout = open(
"/dev/null", O_WRONLY);
734 template <
typename GUM_SCALAR >
738 freopen(
"CON",
"w", stdout);
~LRSWrapper()
Default Destructor.
void V2H()
V-representation to H-representation.
void fillMatrix(const std::vector< std::vector< GUM_SCALAR > > &matrix)
Fill the H-representation from the matrix given in argument.
void __coutOff() const
The function that redirects standard cout to /dev/null.
const GUM_SCALAR & getVolume() const
Get the volume of the polytope that has been computed.
const matrix & getInput() const
Get the intput matrix of the problem.
void __getLRSWrapperOutput(lrs_mp Nin, lrs_mp Din, std::vector< int64_t > &Num, std::vector< int64_t > &Den) const
Translate a single output from lrs.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
void __initLrs()
Initialize lrs structs and first basis according to flags.
typename std::vector< std::vector< GUM_SCALAR > > matrix
Shortcut for dynamic matrix using vectors.
void __freeLrs()
Free lrs space.
void fillV(const std::vector< GUM_SCALAR > &vertex)
Creates the V-representation of a polytope by adding a vertex to the problem input __input...
void fillH(const GUM_SCALAR &min, const GUM_SCALAR &max, const Size &modal)
Creates the H-representation of min <= p(X=modal | .) <= max and add it to the problem input __input...
Class template acting as a wrapper for Lexicographic Reverse Search by David Avis.
void setUpH(const Size &card)
Sets up an H-representation.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
void nextHInput()
Reset the wrapper for next computation for a H-representation with the same variable cardinality and ...
void tearDown()
Reset the wrapper as if it was built.
static void continuedFracFirst(int64_t &numerator, int64_t &denominator, const GUM_SCALAR &number, const double &zero=1e-6)
Find the first best rational approximation.
void __coutOn() const
The function that restores standard cout.
void setUpV(const Size &card, const Size &vertices)
Sets up a V-representation.
void H2V()
H-representation to V-representation.
void elimRedundVrep()
V-Redundancy elimination.
void __fill() const
Fill lrs_dictionnary and datas from __input using integer rationals.
const matrix & getOutput() const
Get the output matrix solution of the problem.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
LRSWrapper()
Default Constructor.
void computeVolume()
Computes a polytope ( pseudo ) volume from it's V-representation.
#define GUM_ERROR(type, msg)
const unsigned int & getVerticesNumber() const
Get the number of vertices of this polytope.