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