aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
LrsWrapper_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4
* info_at_agrum_dot_org
5
*
6
* This library is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
*
19
*/
20
21
22
#
include
<
string
.
h
>
23
24
#
include
<
agrum
/
CN
/
polytope
/
LrsWrapper
.
h
>
25
#
include
<
agrum
/
agrum
.
h
>
26
27
namespace
gum
{
28
namespace
credal
{
29
30
template
<
typename
GUM_SCALAR >
31
LRSWrapper< GUM_SCALAR >::LRSWrapper() {
32
state__ = states__::none;
33
34
vertices__ = 0;
35
card__ = 0;
36
37
volume__ = 0;
38
39
getVolume__ =
false
;
40
hull__ =
false
;
41
polytope__ =
false
;
42
43
GUM_CONSTRUCTOR(LRSWrapper);
44
}
45
46
template
<
typename
GUM_SCALAR
>
47
LRSWrapper
<
GUM_SCALAR
>::~
LRSWrapper
() {
48
GUM_DESTRUCTOR
(
LRSWrapper
);
49
}
50
51
template
<
typename
GUM_SCALAR
>
52
auto
LRSWrapper
<
GUM_SCALAR
>::
getInput
()
const
->
const
matrix
& {
53
return
input__
;
54
}
55
56
template
<
typename
GUM_SCALAR
>
57
auto
LRSWrapper
<
GUM_SCALAR
>::
getOutput
()
const
->
const
matrix
& {
58
return
output__
;
59
}
60
61
template
<
typename
GUM_SCALAR
>
62
const
unsigned
int
&
LRSWrapper
<
GUM_SCALAR
>::
getVerticesNumber
()
const
{
63
return
vertices__
;
64
}
65
66
template
<
typename
GUM_SCALAR
>
67
const
GUM_SCALAR
&
LRSWrapper
<
GUM_SCALAR
>::
getVolume
()
const
{
68
if
(
volume__
!= 0)
69
return
volume__
;
70
else
71
GUM_ERROR
(
OperationNotAllowed
,
72
"LRSWrapper< GUM_SCALAR >::getVolume () : "
73
"volume computation was not asked for this "
74
"credal set, call computeVolume() from a "
75
"V-representation."
);
76
}
77
78
template
<
typename
GUM_SCALAR
>
79
void
LRSWrapper
<
GUM_SCALAR
>::
setUpH
(
const
Size
&
card
) {
80
if
(
card
< 2)
81
GUM_ERROR
(
OperationNotAllowed
,
82
"LRSWrapper< GUM_SCALAR >::setUpH : "
83
"cardinality must be at least 2"
);
84
85
tearDown
();
86
87
input__
=
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >(
88
card
* 2 + 2,
89
std
::
vector
<
GUM_SCALAR
>(
card
+ 1, 0));
90
91
input__
[
card
* 2] =
std
::
vector
<
GUM_SCALAR
>(
card
+ 1, -1);
92
input__
[
card
* 2][0] = 1;
93
94
input__
[
card
* 2 + 1] =
std
::
vector
<
GUM_SCALAR
>(
card
+ 1, 1);
95
input__
[
card
* 2 + 1][0] = -1;
96
97
output__
=
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >();
98
99
vertex__
=
std
::
vector
<
GUM_SCALAR
>(
card
);
100
101
state__
=
states__
::
Hup
;
102
103
card__
= (
unsigned
int
)
card
;
104
}
105
106
template
<
typename
GUM_SCALAR
>
107
void
LRSWrapper
<
GUM_SCALAR
>::
setUpV
(
const
Size
&
card
,
const
Size
&
vertices
) {
108
if
(
card
< 2)
109
GUM_ERROR
(
OperationNotAllowed
,
110
"LRSWrapper< GUM_SCALAR >::setUpV : "
111
"cardinality must be at least 2"
);
112
113
if
(
vertices
< 2)
114
GUM_ERROR
(
OperationNotAllowed
,
115
"LRSWrapper< GUM_SCALAR >::setUpV : vertices "
116
"must be at least 2 to build a polytope"
);
117
118
tearDown
();
119
120
input__
=
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >(
121
vertices
,
122
std
::
vector
<
GUM_SCALAR
>(
card
+ 1, 1));
123
124
output__
=
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >();
125
126
state__
=
states__
::
Vup
;
127
128
card__
= (
unsigned
int
)
card
;
129
vertices__
= (
unsigned
int
)
vertices
;
130
}
131
132
template
<
typename
GUM_SCALAR
>
133
void
LRSWrapper
<
GUM_SCALAR
>::
tearDown
() {
134
input__
.
clear
();
135
output__
.
clear
();
136
vertex__
.
clear
();
137
insertedModals__
.
clear
();
138
139
insertedVertices__
.
clear
();
140
vertices__
= 0;
141
142
volume__
= 0;
143
144
state__
=
states__
::
none
;
145
card__
= 0;
146
147
getVolume__
=
false
;
148
hull__
=
false
;
149
polytope__
=
false
;
150
}
151
152
template
<
typename
GUM_SCALAR
>
153
void
LRSWrapper
<
GUM_SCALAR
>::
nextHInput
() {
154
insertedModals__
.
clear
();
155
insertedVertices__
.
clear
();
156
output__
.
clear
();
157
vertex__
.
clear
();
158
vertex__
.
resize
(
card__
, 0);
159
160
volume__
= 0;
161
vertices__
= 0;
162
163
getVolume__
=
false
;
164
hull__
=
false
;
165
polytope__
=
false
;
166
167
if
(
state__
==
states__
::
H2Vready
)
168
state__
=
states__
::
Hup
;
169
else
if
(
state__
==
states__
::
V2Hready
) {
170
state__
=
states__
::
Vup
;
171
GUM_ERROR
(
172
OperationNotAllowed
,
173
"LRSWrapper< GUM_SCALAR >::nextHInput : only for H-representation "
174
"as input. Previous state was : "
175
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
176
}
else
{
177
input__
.
clear
();
178
state__
=
states__
::
none
;
179
card__
= 0;
180
vertex__
.
clear
();
181
}
182
}
183
184
template
<
typename
GUM_SCALAR
>
185
void
LRSWrapper
<
GUM_SCALAR
>::
fillH
(
const
GUM_SCALAR
&
min
,
186
const
GUM_SCALAR
&
max
,
187
const
Size
&
modal
) {
188
if
(
state__
!=
states__
::
Hup
)
189
GUM_ERROR
(
190
OperationNotAllowed
,
191
"LRSWrapper< GUM_SCALAR >::fillH : setUpH or nextInput has not "
192
"been called or H-representation is complete, current state is : "
193
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
194
195
if
(
modal
>=
card__
)
196
GUM_ERROR
(
OutOfBounds
,
197
"LRSWrapper< GUM_SCALAR >::fillH : modality is "
198
"greater or equal than cardinality : "
199
<<
modal
<<
" >= "
<<
card__
);
200
201
input__
[
modal
* 2][0] = -
min
;
202
input__
[
modal
* 2][
modal
+ 1] = 1;
203
204
input__
[
modal
* 2 + 1][0] =
max
;
205
input__
[
modal
* 2 + 1][
modal
+ 1] = -1;
206
207
vertex__
[
modal
] =
max
;
208
209
insertedModals__
.
insert
(
int
(
modal
));
210
211
if
(
insertedModals__
.
size
() ==
card__
)
state__
=
states__
::
H2Vready
;
212
}
213
214
template
<
typename
GUM_SCALAR
>
215
void
LRSWrapper
<
GUM_SCALAR
>::
fillMatrix
(
216
const
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >&
matrix
) {
217
if
(
state__
!=
states__
::
Hup
)
218
GUM_ERROR
(
219
OperationNotAllowed
,
220
"LRSWrapper< GUM_SCALAR >::fillH : setUpH or nextInput has not "
221
"been called or H-representation is complete, current state is : "
222
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
223
224
if
(
matrix
[0].
size
() - 1 !=
card__
)
225
GUM_ERROR
(
OutOfBounds
,
226
"LRSWrapper< GUM_SCALAR >::fillMatrix : size is "
227
"different than cardinality : "
228
<< (
matrix
[0].
size
() - 1) <<
" != "
<<
card__
);
229
230
input__
=
matrix
;
231
232
for
(
unsigned
int
modal
= 0;
modal
<
card__
;
modal
++) {
233
insertedModals__
.
insert
(
modal
);
234
}
235
236
state__
=
states__
::
H2Vready
;
237
}
238
239
template
<
typename
GUM_SCALAR
>
240
void
LRSWrapper
<
GUM_SCALAR
>::
fillV
(
const
std
::
vector
<
GUM_SCALAR
>&
vertex
) {
241
if
(
state__
!=
states__
::
Vup
)
242
GUM_ERROR
(
243
OperationNotAllowed
,
244
"LRSWrapper< GUM_SCALAR >::fillV : setUpV or nextInput has not "
245
"been called or V-representation is complete, current state is : "
246
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
247
248
if
(
insertedVertices__
.
size
() ==
vertices__
)
249
GUM_ERROR
(
OutOfBounds
,
250
"LRSWrapper< GUM_SCALAR >::fillV : input is already full with "
251
<<
vertices__
<<
" vertices."
);
252
253
bool
eq
=
true
;
254
255
for
(
const
auto
&
v
:
insertedVertices__
) {
256
eq
=
true
;
257
258
for
(
decltype
(
card__
)
mod
= 0;
mod
<
card__
;
mod
++)
259
if
(
std
::
fabs
(
v
[
mod
] -
vertex
[
mod
]) > 1e-6) {
260
eq
=
false
;
261
break
;
262
}
263
264
if
(
eq
) {
265
vertices__
--;
266
return
;
267
// GUM_ERROR ( DuplicateElement, "LRSWrapper< GUM_SCALAR >::fillV :
268
// vertex
269
// already present : " << vertex );
270
}
271
}
272
273
auto
row
=
insertedVertices__
.
size
();
274
275
for
(
decltype
(
card__
)
mod
= 0;
mod
<
card__
;
mod
++)
276
input__
[
row
][
mod
+ 1] =
vertex
[
mod
];
277
278
insertedVertices__
.
push_back
(
vertex
);
279
280
if
(
insertedVertices__
.
size
() ==
vertices__
)
state__
=
states__
::
V2Hready
;
281
}
282
283
template
<
typename
GUM_SCALAR
>
284
void
LRSWrapper
<
GUM_SCALAR
>::
H2V
() {
285
if
(
state__
!=
states__
::
H2Vready
)
286
GUM_ERROR
(
OperationNotAllowed
,
287
"LRSWrapper< GUM_SCALAR >::H2V : fillH has not been called with "
288
"all modalities, current state is still : "
289
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
290
291
// check that we have a credal set and not a precise point probability,
292
// i.e.
293
// sum of vertex elements is close to one ( floating type precision )
294
GUM_SCALAR
sum
= 0;
295
296
for
(
const
auto
elem
:
vertex__
)
297
sum
+=
elem
;
298
299
if
(
std
::
fabs
(
sum
- 1) < 1e-6) {
300
output__
=
std
::
vector
<
std
::
vector
<
GUM_SCALAR
> >(1,
vertex__
);
301
return
;
302
}
303
304
// not precise point probability, initialize lrs
305
306
// coutOff__();
307
308
initLrs__
();
309
310
/* We initiate reverse search from this dictionary */
311
/* getting new dictionaries until the search is complete */
312
/* User can access each output line from output which is */
313
/* vertex/ray/facet from the lrs_mp_vector output */
314
/* prune is TRUE if tree should be pruned at current node */
315
316
// pruning is not used
317
318
std
::
vector
<
int64_t
>
Num
;
/* numerators of all vertices */
319
std
::
vector
<
int64_t
>
Den
;
/* denominators of all vertices */
320
321
do
{
322
for
(
decltype
(
dic__
->
d
)
col
= 0,
end
=
dic__
->
d
;
col
<=
end
;
col
++)
323
if
(
lrs_getsolution
(
dic__
,
dat__
,
lrsOutput__
,
col
)) {
324
// iszero macro could be used here for the test on right
325
if
(
dat__
->
hull
326
|| ((((
lrsOutput__
[0])[0] == 2 || (
lrsOutput__
[0])[0] == -2)
327
&& (
lrsOutput__
[0])[1] == 0)
328
? 1L
329
: 0L)) {
330
// coutOn__();
331
/*for ( decltype(Q->n) i = 0; i < Q->n; i++ )
332
pmp ("", output[i]);*/
333
GUM_ERROR
(
FatalError
,
334
"LRSWrapper< GUM_SCALAR >::H2V : asked for "
335
"Q-hull computation or not reading a vertex !"
);
336
}
else
337
for
(
decltype
(
dat__
->
n
)
i
= 1,
end
=
dat__
->
n
;
i
<
end
;
i
++)
338
getLRSWrapperOutput__
(
lrsOutput__
[
i
],
lrsOutput__
[0],
Num
,
Den
);
339
}
340
}
while
(
lrs_getnextbasis
(&
dic__
,
dat__
, 0L));
341
342
auto
vtx
=
Num
.
size
();
343
std
::
vector
<
GUM_SCALAR
>
vertex
(
card__
);
344
345
for
(
decltype
(
vtx
)
i
= 1;
i
<=
vtx
;
i
++) {
346
vertex
[(
i
- 1) %
card__
] =
GUM_SCALAR
(
Num
[
i
- 1] * 1.0 /
Den
[
i
- 1]);
347
348
if
(
i
%
card__
== 0) {
349
output__
.
push_back
(
vertex
);
350
vertices__
++;
351
}
352
}
353
354
freeLrs__
();
355
356
// coutOn__();
357
}
358
359
template
<
typename
GUM_SCALAR
>
360
void
LRSWrapper
<
GUM_SCALAR
>::
V2H
() {
361
if
(!
state__
==
states__
::
V2Hready
)
362
GUM_ERROR
(
OperationNotAllowed
,
363
"LRSWrapper< GUM_SCALAR >::V2H : fillV has "
364
"not been called with all vertices, current "
365
"state is still : "
366
<<
setUpStateNames__
[
state__
]);
367
}
368
369
template
<
typename
GUM_SCALAR
>
370
void
LRSWrapper
<
GUM_SCALAR
>::
computeVolume
() {
371
if
(!
state__
==
states__
::
V2Hready
)
372
GUM_ERROR
(
OperationNotAllowed
,
373
"LRSWrapper< GUM_SCALAR >::computeVolume : "
374
"volume is only for V-representation or "
375
"fillV has not been called with all "
376
"vertices, current state is still : "
377
<<
setUpStateNames__
[
state__
]);
378
379
// coutOff__();
380
381
getVolume__
=
true
;
382
383
initLrs__
();
384
385
do
{
386
for
(
decltype
(
dic__
->
d
)
col
= 0,
end
=
dic__
->
d
;
col
<=
end
;
col
++)
387
lrs_getsolution
(
dic__
,
dat__
,
lrsOutput__
,
col
);
388
}
while
(
lrs_getnextbasis
(&
dic__
,
dat__
, 0L));
389
390
int64_t
Nsize
391
= (
dat__
->
Nvolume
[0] > 0) ?
dat__
->
Nvolume
[0] : -
dat__
->
Nvolume
[0];
392
int64_t
Dsize
393
= (
dat__
->
Dvolume
[0] > 0) ?
dat__
->
Dvolume
[0] : -
dat__
->
Dvolume
[0];
394
395
int64_t
num
= 0L,
den
= 0L;
396
int64_t
tmp
;
397
398
for
(
decltype
(
Nsize
)
i
=
Nsize
- 1;
i
> 0;
i
--) {
399
tmp
=
dat__
->
Nvolume
[
i
];
400
401
for
(
decltype
(
i
)
j
= 1;
j
<
i
;
j
++)
402
tmp
*=
BASE
;
403
404
num
+=
tmp
;
405
}
406
407
for
(
decltype
(
Dsize
)
i
=
Dsize
- 1;
i
> 0;
i
--) {
408
tmp
=
dat__
->
Dvolume
[
i
];
409
410
for
(
decltype
(
i
)
j
= 1;
j
<
i
;
j
++)
411
tmp
*=
BASE
;
412
413
den
+=
tmp
;
414
}
415
416
volume__
=
num
* 1.0 /
den
;
417
418
freeLrs__
();
419
420
// coutOn__();
421
}
422
423
template
<
typename
GUM_SCALAR
>
424
void
LRSWrapper
<
GUM_SCALAR
>::
elimRedundVrep
() {
425
if
(
state__
!=
states__
::
V2Hready
)
426
GUM_ERROR
(
427
OperationNotAllowed
,
428
"LRSWrapper< GUM_SCALAR >::elimRedundVrep : only for "
429
"V-representation or fillV has not been called with all vertices, "
430
"current state is still : "
431
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
432
433
// coutOff__();
434
435
initLrs__
();
436
437
int64_t
*
redineq
;
/* redineq[i]=0 if ineq i non-red,1 if red,2 linearity */
438
439
/*********************************************************************************/
440
/* Test each row of the dictionary to see if it is redundant */
441
/*********************************************************************************/
442
443
/* note some of these may have been changed in getting initial dictionary
444
*/
445
auto
m
=
dic__
->
m_A
;
446
auto
d
=
dic__
->
d
;
447
/* number of linearities in input */
/* should be 0 ! */
448
auto
nlinearity
=
dat__
->
nlinearity
;
449
auto
lastdv
=
dat__
->
lastdv
;
450
451
/* linearities are not considered for redundancy */
452
redineq
= (
int64_t
*)
calloc
(
std
::
size_t
(
m
+ 1),
sizeof
(
int64_t
));
453
454
for
(
decltype
(
nlinearity
)
i
= 0;
i
<
nlinearity
;
i
++)
455
redineq
[
dat__
->
linearity
[
i
]] = 2L;
456
457
/* rows 0..lastdv are cost, decision variables, or linearities */
458
/* other rows need to be tested */
459
460
for
(
decltype
(
m
+
d
)
index
=
lastdv
+ 1,
end
=
m
+
d
;
index
<=
end
;
461
index
++) {
462
/* input inequality number of current index */
463
auto
ineq
464
=
dat__
->
inequality
[
index
-
lastdv
];
/* the input inequality number
465
corr. to this index */
466
467
redineq
[
ineq
] =
checkindex
(
dic__
,
dat__
,
index
);
468
}
469
470
/* linearities */
471
if
(
nlinearity
> 0)
472
GUM_ERROR
(
FatalError
,
473
"LRSWrapper< GUM_SCALAR >::elimRedundVrep : not "
474
"reading a vertex but a linearity !"
);
475
476
/* count number of non-redundant inequalities */
477
/*
478
auto nredund = nlinearity;
479
for ( decltype ( m ) i = 1; i <= m; i++ )
480
if ( redineq[ i ] == 0 )
481
nredund++;
482
*/
483
484
//__vertices = nredund;
485
//__output = std::vector< std::vector< GUM_SCALAR > > ( nredund,
486
// std::vector<
487
// GUM_SCALAR > ( dat__->n - 1 ) );
488
489
for
(
decltype
(
m
)
i
= 1;
i
<=
m
;
i
++)
490
if
(
redineq
[
i
] == 0)
491
output__
.
push_back
(
492
std
::
vector
<
GUM_SCALAR
>(++
input__
[
std
::
size_t
(
i
- 1)].
begin
(),
493
input__
[
std
::
size_t
(
i
- 1)].
end
()));
494
495
vertices__
= (
unsigned
int
)
output__
.
size
();
496
497
freeLrs__
();
498
499
// coutOn__();
500
}
501
502
template
<
typename
GUM_SCALAR
>
503
void
LRSWrapper
<
GUM_SCALAR
>::
getLRSWrapperOutput__
(
504
lrs_mp
Nin
,
505
lrs_mp
Din
,
506
std
::
vector
<
int64_t
>&
Num
,
507
std
::
vector
<
int64_t
>&
Den
)
const
{
508
int64_t
Nsize
= (
Nin
[0] > 0) ?
Nin
[0] : -
Nin
[0];
509
int64_t
Dsize
= (
Din
[0] > 0) ?
Din
[0] : -
Din
[0];
510
511
int64_t
num
= 0L;
512
int64_t
den
= 0L;
513
514
int64_t
tmp
;
515
516
for
(
decltype
(
Nsize
)
i
=
Nsize
- 1;
i
> 0;
i
--) {
517
tmp
=
Nin
[
i
];
518
519
for
(
decltype
(
i
)
j
= 1;
j
<
i
;
j
++)
520
tmp
*=
BASE
;
521
522
num
+=
tmp
;
523
}
524
525
if
(!(
Din
[0] == 2L &&
Din
[1] == 1L)) {
/* rational */
526
for
(
decltype
(
Dsize
)
i
=
Dsize
- 1;
i
> 0;
i
--) {
527
tmp
=
Din
[
i
];
528
529
for
(
decltype
(
i
)
j
= 1;
j
<
i
;
j
++)
530
tmp
*=
BASE
;
531
532
den
+=
tmp
;
533
}
534
}
else
{
535
den
= 1L;
536
}
537
538
int64_t
Nsign
= ((
Nin
[0] < 0) ? -1L : 1L);
539
int64_t
Dsign
= ((
Din
[0] < 0) ? -1L : 1L);
540
541
if
((
Nsign
*
Dsign
) == -1L)
num
= -
num
;
542
543
Num
.
push_back
(
num
);
544
Den
.
push_back
(
den
);
545
}
546
547
/*
548
void pmp (char name[], lrs_mp a) {
549
int64_t i;
550
fprintf (lrs_ofp, "%s", name);
551
if (sign (a) == NEG)
552
fprintf (lrs_ofp, "-");
553
else
554
fprintf (lrs_ofp, " ");
555
fprintf (lrs_ofp, "%lu", a[length (a) - 1]);
556
for (i = length (a) - 2; i >= 1; i--)
557
fprintf (lrs_ofp, FORMAT, a[i]);
558
fprintf (lrs_ofp, " ");
559
}*/
560
561
template
<
typename
GUM_SCALAR
>
562
void
LRSWrapper
<
GUM_SCALAR
>::
fill__
()
const
{
563
std
::
size_t
cols
=
input__
[0].
size
();
564
565
int64_t
*
num
=
new
int64_t
[
cols
];
// ISO C++ forbids variable length array,
566
// we need to do this instead
567
int64_t
*
den
=
new
int64_t
[
cols
];
568
569
int64_t
rows
=
int64_t
(
input__
.
size
());
570
571
int64_t
numerator
,
denominator
;
572
573
for
(
int64_t
row
= 0;
row
<
rows
;
row
++) {
574
for
(
std
::
size_t
col
= 0;
col
<
cols
;
col
++) {
575
Rational
<
GUM_SCALAR
>::
continuedFracFirst
(
576
numerator
,
577
denominator
,
578
input__
[
std
::
size_t
(
row
)][
col
]);
579
580
num
[
col
] =
numerator
;
581
den
[
col
] =
denominator
;
582
}
583
584
/* GE is inequality, EQ is equation */
585
/* 1L, 0L respectively */
586
lrs_set_row
(
dic__
,
587
dat__
,
588
int64_t
(
row
+ 1),
589
num
,
590
den
,
591
1L);
// do NOT forget this + 1 on row
592
}
593
594
delete
[]
num
;
595
delete
[]
den
;
596
}
597
598
template
<
typename
GUM_SCALAR
>
599
void
LRSWrapper
<
GUM_SCALAR
>::
initLrs__
() {
600
if
(
state__
!=
states__
::
H2Vready
&&
state__
!=
states__
::
V2Hready
)
601
GUM_ERROR
(
OperationNotAllowed
,
602
"LRSWrapper< GUM_SCALAR >::initLrs__ : not ready, current state "
603
"is still : "
604
<<
setUpStateNames__
[
static_cast
<
int
>(
state__
)]);
605
606
//__coutOff();
607
608
std
::
string
name
=
"\n*LrsWrapper:"
;
609
std
::
vector
<
char
>
chars
(
name
.
c_str
(),
name
.
c_str
() +
name
.
size
() + 1u);
610
// use &chars[0] as a char*
611
612
if
(!
lrs_init
(&
chars
[0])) {
613
// coutOn__();
614
GUM_ERROR
(
FatalError
,
615
"LRSWrapper< GUM_SCALAR >::initLrs__ : failed lrs_init"
);
616
}
617
618
name
=
"LRSWrapper globals"
;
619
chars
=
std
::
vector
<
char
>(
name
.
c_str
(),
name
.
c_str
() +
name
.
size
() + 1u);
620
621
dat__
=
lrs_alloc_dat
(&
chars
[0]);
622
623
if
(
dat__
==
nullptr
) {
624
// coutOn__();
625
GUM_ERROR
(
FatalError
,
626
"LRSWrapper< GUM_SCALAR >::initLrs__ : failed lrs_alloc_dat"
);
627
}
628
629
dat__
->
n
=
Size
(
input__
[0].
size
());
630
dat__
->
m
=
Size
(
input__
.
size
());
631
632
dat__
->
getvolume
= (
getVolume__
) ? 1L : 0L;
633
dat__
->
hull
= (
hull__
) ? 1L : 0L;
634
dat__
->
polytope
= (
polytope__
) ? 1L : 0L;
635
636
lrsOutput__
=
lrs_alloc_mp_vector
(
dat__
->
n
);
637
638
dic__
=
lrs_alloc_dic
(
dat__
);
639
640
if
(
dic__
==
nullptr
) {
641
// coutOn__();
642
GUM_ERROR
(
FatalError
,
643
"LRSWrapper< GUM_SCALAR >::initLrs__ : failed lrs_alloc_dic"
);
644
}
645
646
fill__
();
647
648
/* Pivot to a starting dictionary */
649
if
(!
lrs_getfirstbasis
(&
dic__
,
dat__
, &
Lin__
, 0L)) {
650
// coutOn__();
651
GUM_ERROR
(
652
FatalError
,
653
"LRSWrapper< GUM_SCALAR >::initLrs__ : failed lrs_getfirstbasis"
);
654
}
655
656
/* There may have been column redundancy */
657
/* If so the linearity space is obtained and redundant */
658
/* columns are removed. User can access linearity space */
659
/* from lrs_mp_matrix Lin dimensions nredundcol x d+1 */
660
661
decltype
(
dat__
->
nredundcol
)
startcol
= 0;
662
663
if
(
dat__
->
homogeneous
&&
dat__
->
hull
) {
664
startcol
++;
/* col zero not treated as redundant */
665
666
if
(!
dat__
->
restart
) {
667
// coutOn__();
668
669
for
(
decltype
(
dat__
->
nredundcol
)
col
=
startcol
;
col
<
dat__
->
nredundcol
;
670
col
++)
671
lrs_printoutput
(
dat__
,
Lin__
[
col
]);
672
673
GUM_ERROR
(
FatalError
,
674
"LRSWrapper< GUM_SCALAR >::initLrs__ : redundant columns !"
);
675
}
676
}
677
/*
678
if ( dat__->nredundcol > 0 ) {
679
coutOn__();
680
681
for ( decltype( dat__->nredundcol ) col = 0, end =
682
dat__->nredundcol;
683
col < end;
684
col++ )
685
lrs_printoutput( dat__, Lin__[col] );
686
687
GUM_ERROR(
688
FatalError,
689
"LRSWrapper< GUM_SCALAR >::initLrs__ : redundant columns !" );
690
}
691
*/
692
}
693
694
template
<
typename
GUM_SCALAR
>
695
void
LRSWrapper
<
GUM_SCALAR
>::
freeLrs__
() {
696
/* free space : do not change order of next lines! */
697
698
lrs_clear_mp_vector
(
lrsOutput__
,
dat__
->
n
);
699
700
if
(
dat__
->
nredundcol
> 0)
701
lrs_clear_mp_matrix
(
Lin__
,
dat__
->
nredundcol
,
dat__
->
n
);
702
703
if
(
dat__
->
runs
> 0) {
704
free
(
dat__
->
isave
);
705
free
(
dat__
->
jsave
);
706
}
707
708
auto
savem
=
dic__
->
m
;
/* need this to clear dat__*/
709
710
lrs_free_dic
(
dic__
,
dat__
);
/* deallocate lrs_dic */
711
712
dat__
->
m
=
savem
;
713
lrs_free_dat
(
dat__
);
714
715
std
::
string
name
=
"LrsWrapper:"
;
716
std
::
vector
<
char
>
chars
(
name
.
c_str
(),
name
.
c_str
() +
name
.
size
() + 1u);
717
718
lrs_close
(&
chars
[0]);
719
720
// coutOn__();
721
}
722
723
template
<
typename
GUM_SCALAR
>
724
void
LRSWrapper
<
GUM_SCALAR
>::
coutOff__
()
const
{
725
fflush
(
stdout
);
726
#
ifdef
_MSC_VER
727
freopen
(
"NUL"
,
"w"
,
stdout
);
728
#
else
// _MSC_VER
729
oldCout__
=
dup
(1);
730
731
int
new_cout
=
open
(
"/dev/null"
,
O_WRONLY
);
732
dup2
(
new_cout
, 1);
733
close
(
new_cout
);
734
#
endif
// _MSC_VER
735
}
736
737
template
<
typename
GUM_SCALAR
>
738
void
LRSWrapper
<
GUM_SCALAR
>::
coutOn__
()
const
{
739
fflush
(
stdout
);
740
#
ifdef
_MSC_VER
741
freopen
(
"CON"
,
"w"
,
stdout
);
742
#
else
// _MSC_VER
743
dup2
(
oldCout__
, 1);
744
close
(
oldCout__
);
745
#
endif
// _MSC_VER
746
}
747
748
}
// namespace credal
749
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669
gum::credal
namespace for all credal networks entities
Definition:
LpInterface.cpp:37