Some improvements to jtree and regiongraph and started work on regiongraph unit tests
[libdai.git] / tests / unit / factor.cpp
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
6 *
7 * Copyright (C) 2010 Joris Mooij [joris dot mooij at libdai dot org]
8 */
9
10
11 #define BOOST_TEST_DYN_LINK
12
13
14 #include <dai/factor.h>
15 #include <strstream>
16
17
18 using namespace dai;
19
20
21 const double tol = 1e-8;
22
23
24 #define BOOST_TEST_MODULE FactorTest
25
26
27 #include <boost/test/unit_test.hpp>
28 #include <boost/test/floating_point_comparison.hpp>
29
30
31 BOOST_AUTO_TEST_CASE( ConstructorsTest ) {
32 // check constructors
33 Factor x1;
34 BOOST_CHECK_EQUAL( x1.nrStates(), 1 );
35 BOOST_CHECK( x1.p() == Prob( 1, 1.0 ) );
36 BOOST_CHECK( x1.vars() == VarSet() );
37
38 Factor x2( 5.0 );
39 BOOST_CHECK_EQUAL( x2.nrStates(), 1 );
40 BOOST_CHECK( x2.p() == Prob( 1, 5.0 ) );
41 BOOST_CHECK( x2.vars() == VarSet() );
42
43 Var v1( 0, 3 );
44 Factor x3( v1 );
45 BOOST_CHECK_EQUAL( x3.nrStates(), 3 );
46 BOOST_CHECK( x3.p() == Prob( 3, 1.0 / 3.0 ) );
47 BOOST_CHECK( x3.vars() == VarSet( v1 ) );
48 BOOST_CHECK_EQUAL( x3[0], 1.0 / 3.0 );
49 BOOST_CHECK_EQUAL( x3[1], 1.0 / 3.0 );
50 BOOST_CHECK_EQUAL( x3[2], 1.0 / 3.0 );
51
52 Var v2( 1, 2 );
53 Factor x4( VarSet( v1, v2 ) );
54 BOOST_CHECK_EQUAL( x4.nrStates(), 6 );
55 BOOST_CHECK( x4.p() == Prob( 6, 1.0 / 6.0 ) );
56 BOOST_CHECK( x4.vars() == VarSet( v1, v2 ) );
57 for( size_t i = 0; i < 6; i++ )
58 BOOST_CHECK_EQUAL( x4[i], 1.0 / 6.0 );
59
60 Factor x5( VarSet( v1, v2 ), 1.0 );
61 BOOST_CHECK_EQUAL( x5.nrStates(), 6 );
62 BOOST_CHECK( x5.p() == Prob( 6, 1.0 ) );
63 BOOST_CHECK( x5.vars() == VarSet( v1, v2 ) );
64 for( size_t i = 0; i < 6; i++ )
65 BOOST_CHECK_EQUAL( x5[i], 1.0 );
66
67 std::vector<Real> x( 6, 1.0 );
68 for( size_t i = 0; i < 6; i++ )
69 x[i] = 10.0 - i;
70 Factor x6( VarSet( v1, v2 ), x );
71 BOOST_CHECK_EQUAL( x6.nrStates(), 6 );
72 BOOST_CHECK( x6.vars() == VarSet( v1, v2 ) );
73 for( size_t i = 0; i < 6; i++ )
74 BOOST_CHECK_EQUAL( x6[i], x[i] );
75
76 x.resize( 4 );
77 BOOST_CHECK_THROW( Factor x7( VarSet( v1, v2 ), x ), Exception );
78
79 x.resize( 6 );
80 x[4] = 10.0 - 4; x[5] = 10.0 - 5;
81 Factor x8( VarSet( v2, v1 ), &(x[0]) );
82 BOOST_CHECK_EQUAL( x8.nrStates(), 6 );
83 BOOST_CHECK( x8.vars() == VarSet( v1, v2 ) );
84 for( size_t i = 0; i < 6; i++ )
85 BOOST_CHECK_EQUAL( x8[i], x[i] );
86
87 Prob xx( x );
88 Factor x9( VarSet( v2, v1 ), xx );
89 BOOST_CHECK_EQUAL( x9.nrStates(), 6 );
90 BOOST_CHECK( x9.vars() == VarSet( v1, v2 ) );
91 for( size_t i = 0; i < 6; i++ )
92 BOOST_CHECK_EQUAL( x9[i], x[i] );
93
94 xx.resize( 4 );
95 BOOST_CHECK_THROW( Factor x10( VarSet( v2, v1 ), xx ), Exception );
96
97 std::vector<Real> w;
98 w.push_back( 0.1 );
99 w.push_back( 3.5 );
100 w.push_back( 2.8 );
101 w.push_back( 6.3 );
102 w.push_back( 8.4 );
103 w.push_back( 0.0 );
104 w.push_back( 7.4 );
105 w.push_back( 2.4 );
106 w.push_back( 8.9 );
107 w.push_back( 1.3 );
108 w.push_back( 1.6 );
109 w.push_back( 2.6 );
110 Var v4( 4, 3 );
111 Var v8( 8, 2 );
112 Var v7( 7, 2 );
113 std::vector<Var> vars;
114 vars.push_back( v4 );
115 vars.push_back( v8 );
116 vars.push_back( v7 );
117 Factor x11( vars, w );
118 BOOST_CHECK_EQUAL( x11.nrStates(), 12 );
119 BOOST_CHECK( x11.vars() == VarSet( vars.begin(), vars.end() ) );
120 BOOST_CHECK_EQUAL( x11[0], 0.1 );
121 BOOST_CHECK_EQUAL( x11[1], 3.5 );
122 BOOST_CHECK_EQUAL( x11[2], 2.8 );
123 BOOST_CHECK_EQUAL( x11[3], 7.4 );
124 BOOST_CHECK_EQUAL( x11[4], 2.4 );
125 BOOST_CHECK_EQUAL( x11[5], 8.9 );
126 BOOST_CHECK_EQUAL( x11[6], 6.3 );
127 BOOST_CHECK_EQUAL( x11[7], 8.4 );
128 BOOST_CHECK_EQUAL( x11[8], 0.0 );
129 BOOST_CHECK_EQUAL( x11[9], 1.3 );
130 BOOST_CHECK_EQUAL( x11[10], 1.6 );
131 BOOST_CHECK_EQUAL( x11[11], 2.6 );
132
133 Factor x12( x11 );
134 BOOST_CHECK( x12 == x11 );
135
136 Factor x13 = x12;
137 BOOST_CHECK( x13 == x11 );
138 }
139
140
141 BOOST_AUTO_TEST_CASE( QueriesTest ) {
142 Factor x( Var( 5, 5 ), 0.0 );
143 for( size_t i = 0; i < x.nrStates(); i++ )
144 x.set( i, 2.0 - i );
145
146 // test min, max, sum, sumAbs, maxAbs
147 BOOST_CHECK_EQUAL( x.sum(), 0.0 );
148 BOOST_CHECK_EQUAL( x.max(), 2.0 );
149 BOOST_CHECK_EQUAL( x.min(), -2.0 );
150 BOOST_CHECK_EQUAL( x.sumAbs(), 6.0 );
151 BOOST_CHECK_EQUAL( x.maxAbs(), 2.0 );
152 x.set( 1, 1.0 );
153 BOOST_CHECK_EQUAL( x.maxAbs(), 2.0 );
154 x /= x.sum();
155
156 // test entropy
157 BOOST_CHECK( x.entropy() < Prob(5).entropy() );
158 for( size_t i = 1; i < 100; i++ )
159 BOOST_CHECK_CLOSE( Factor( Var(0,i) ).entropy(), std::log(i), tol );
160
161 // test hasNaNs and hasNegatives
162 BOOST_CHECK( !Factor( 0.0 ).hasNaNs() );
163 Real c = 0.0;
164 BOOST_CHECK( Factor( c / c ).hasNaNs() );
165 BOOST_CHECK( !Factor( 0.0 ).hasNegatives() );
166 BOOST_CHECK( !Factor( 1.0 ).hasNegatives() );
167 BOOST_CHECK( Factor( -1.0 ).hasNegatives() );
168 x.set( 0, 0.0 ); x.set( 1, 0.0 ); x.set( 2, -1.0 ); x.set( 3, 1.0 ); x.set( 4, 100.0 );
169 BOOST_CHECK( x.hasNegatives() );
170 x.set( 2, -INFINITY );
171 BOOST_CHECK( x.hasNegatives() );
172 x.set( 2, INFINITY );
173 BOOST_CHECK( !x.hasNegatives() );
174 x.set( 2, -1.0 );
175
176 // test strength
177 Var x0(0,2);
178 Var x1(1,2);
179 BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, 1.0 ).strength( x0, x1 ), std::tanh( 1.0 ), tol );
180 BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, -1.0 ).strength( x0, x1 ), std::tanh( 1.0 ), tol );
181 BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, 0.5 ).strength( x0, x1 ), std::tanh( 0.5 ), tol );
182
183 // test ==
184 Factor a(Var(0,3)), b(Var(0,3));
185 Factor d(Var(1,3));
186 BOOST_CHECK( !(a == d) );
187 BOOST_CHECK( !(b == d) );
188 BOOST_CHECK( a == b );
189 a.set( 0, 0.0 );
190 BOOST_CHECK( !(a == b) );
191 b.set( 2, 0.0 );
192 BOOST_CHECK( !(a == b) );
193 b.set( 0, 0.0 );
194 BOOST_CHECK( !(a == b) );
195 a.set( 1, 0.0 );
196 BOOST_CHECK( !(a == b) );
197 b.set( 1, 0.0 );
198 BOOST_CHECK( !(a == b) );
199 a.set( 2, 0.0 );
200 BOOST_CHECK( a == b );
201 }
202
203
204 BOOST_AUTO_TEST_CASE( UnaryTransformationsTest ) {
205 Var v( 0, 3 );
206 Factor x( v );
207 x.set( 0, -2.0 );
208 x.set( 1, 0.0 );
209 x.set( 2, 2.0 );
210
211 Factor y = -x;
212 BOOST_CHECK_EQUAL( y[0], 2.0 );
213 BOOST_CHECK_EQUAL( y[1], 0.0 );
214 BOOST_CHECK_EQUAL( y[2], -2.0 );
215
216 y = x.abs();
217 BOOST_CHECK_EQUAL( y[0], 2.0 );
218 BOOST_CHECK_EQUAL( y[1], 0.0 );
219 BOOST_CHECK_EQUAL( y[2], 2.0 );
220
221 y = x.exp();
222 BOOST_CHECK_CLOSE( y[0], std::exp(-2.0), tol );
223 BOOST_CHECK_EQUAL( y[1], 1.0 );
224 BOOST_CHECK_CLOSE( y[2], 1.0 / y[0], tol );
225
226 y = x.log(false);
227 BOOST_CHECK( isnan( y[0] ) );
228 BOOST_CHECK_EQUAL( y[1], -INFINITY );
229 BOOST_CHECK_CLOSE( y[2], std::log(2.0), tol );
230
231 y = x.log(true);
232 BOOST_CHECK( isnan( y[0] ) );
233 BOOST_CHECK_EQUAL( y[1], 0.0 );
234 BOOST_CHECK_EQUAL( y[2], std::log(2.0) );
235
236 y = x.inverse(false);
237 BOOST_CHECK_EQUAL( y[0], -0.5 );
238 BOOST_CHECK_EQUAL( y[1], INFINITY );
239 BOOST_CHECK_EQUAL( y[2], 0.5 );
240
241 y = x.inverse(true);
242 BOOST_CHECK_EQUAL( y[0], -0.5 );
243 BOOST_CHECK_EQUAL( y[1], 0.0 );
244 BOOST_CHECK_EQUAL( y[2], 0.5 );
245
246 x.set( 0, 2.0 );
247 y = x.normalized();
248 BOOST_CHECK_EQUAL( y[0], 0.5 );
249 BOOST_CHECK_EQUAL( y[1], 0.0 );
250 BOOST_CHECK_EQUAL( y[2], 0.5 );
251
252 y = x.normalized( NORMPROB );
253 BOOST_CHECK_EQUAL( y[0], 0.5 );
254 BOOST_CHECK_EQUAL( y[1], 0.0 );
255 BOOST_CHECK_EQUAL( y[2], 0.5 );
256
257 x.set( 0, -2.0 );
258 y = x.normalized( NORMLINF );
259 BOOST_CHECK_EQUAL( y[0], -1.0 );
260 BOOST_CHECK_EQUAL( y[1], 0.0 );
261 BOOST_CHECK_EQUAL( y[2], 1.0 );
262 }
263
264
265 BOOST_AUTO_TEST_CASE( UnaryOperationsTest ) {
266 Var v( 0, 3 );
267 Factor xorg( v );
268 xorg.set( 0, 2.0 );
269 xorg.set( 1, 0.0 );
270 xorg.set( 2, 1.0 );
271 Factor y( v );
272
273 Factor x = xorg;
274 BOOST_CHECK( x.setUniform() == Factor( v ) );
275 BOOST_CHECK( x == Factor( v ) );
276
277 y.set( 0, std::exp(2.0) );
278 y.set( 1, 1.0 );
279 y.set( 2, std::exp(1.0) );
280 x = xorg;
281 BOOST_CHECK( x.takeExp() == y );
282 BOOST_CHECK( x == y );
283
284 y.set( 0, std::log(2.0) );
285 y.set( 1, -INFINITY );
286 y.set( 2, 0.0 );
287 x = xorg;
288 BOOST_CHECK( x.takeLog() == y );
289 BOOST_CHECK( x == y );
290 x = xorg;
291 BOOST_CHECK( x.takeLog(false) == y );
292 BOOST_CHECK( x == y );
293
294 y.set( 1, 0.0 );
295 x = xorg;
296 BOOST_CHECK( x.takeLog(true) == y );
297 BOOST_CHECK( x == y );
298
299 y.set( 0, 2.0 / 3.0 );
300 y.set( 1, 0.0 / 3.0 );
301 y.set( 2, 1.0 / 3.0 );
302 x = xorg;
303 BOOST_CHECK_EQUAL( x.normalize(), 3.0 );
304 BOOST_CHECK( x == y );
305
306 x = xorg;
307 BOOST_CHECK_EQUAL( x.normalize( NORMPROB ), 3.0 );
308 BOOST_CHECK( x == y );
309
310 y.set( 0, 2.0 / 2.0 );
311 y.set( 1, 0.0 / 2.0 );
312 y.set( 2, 1.0 / 2.0 );
313 x = xorg;
314 BOOST_CHECK_EQUAL( x.normalize( NORMLINF ), 2.0 );
315 BOOST_CHECK( x == y );
316
317 xorg.set( 0, -2.0 );
318 y.set( 0, 2.0 );
319 y.set( 1, 0.0 );
320 y.set( 2, 1.0 );
321 x = xorg;
322 BOOST_CHECK( x.takeAbs() == y );
323 BOOST_CHECK( x == y );
324
325 for( size_t repeat = 0; repeat < 10000; repeat++ ) {
326 x.randomize();
327 for( size_t i = 0; i < x.nrStates(); i++ ) {
328 BOOST_CHECK( x[i] < 1.0 );
329 BOOST_CHECK( x[i] >= 0.0 );
330 }
331 }
332 }
333
334
335 BOOST_AUTO_TEST_CASE( ScalarOperationsTest ) {
336 Var v( 0, 3 );
337 Factor xorg( v ), x( v );
338 xorg.set( 0, 2.0 );
339 xorg.set( 1, 0.0 );
340 xorg.set( 2, 1.0 );
341 Factor y( v );
342
343 x = xorg;
344 BOOST_CHECK( x.fill( 1.0 ) == Factor(v, 1.0) );
345 BOOST_CHECK( x == Factor(v, 1.0) );
346 BOOST_CHECK( x.fill( 2.0 ) == Factor(v, 2.0) );
347 BOOST_CHECK( x == Factor(v, 2.0) );
348 BOOST_CHECK( x.fill( 0.0 ) == Factor(v, 0.0) );
349 BOOST_CHECK( x == Factor(v, 0.0) );
350
351 x = xorg;
352 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
353 BOOST_CHECK( (x += 1.0) == y );
354 BOOST_CHECK( x == y );
355 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
356 BOOST_CHECK( (x += -2.0) == y );
357 BOOST_CHECK( x == y );
358
359 x = xorg;
360 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
361 BOOST_CHECK( (x -= 1.0) == y );
362 BOOST_CHECK( x == y );
363 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
364 BOOST_CHECK( (x -= -2.0) == y );
365 BOOST_CHECK( x == y );
366
367 x = xorg;
368 BOOST_CHECK( (x *= 1.0) == x );
369 BOOST_CHECK( x == x );
370 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 2.0 );
371 BOOST_CHECK( (x *= 2.0) == y );
372 BOOST_CHECK( x == y );
373 y.set( 0, -1.0 ); y.set( 1, 0.0 ); y.set( 2, -0.5 );
374 BOOST_CHECK( (x *= -0.25) == y );
375 BOOST_CHECK( x == y );
376
377 x = xorg;
378 BOOST_CHECK( (x /= 1.0) == x );
379 BOOST_CHECK( x == x );
380 y.set( 0, 1.0 ); y.set( 1, 0.0 ); y.set( 2, 0.5 );
381 BOOST_CHECK( (x /= 2.0) == y );
382 BOOST_CHECK( x == y );
383 y.set( 0, -4.0 ); y.set( 1, 0.0 ); y.set( 2, -2.0 );
384 BOOST_CHECK( (x /= -0.25) == y );
385 BOOST_CHECK( x == y );
386 BOOST_CHECK( (x /= 0.0) == Factor(v, 0.0) );
387 BOOST_CHECK( x == Factor(v, 0.0) );
388
389 x = xorg;
390 BOOST_CHECK( (x ^= 1.0) == x );
391 BOOST_CHECK( x == x );
392 BOOST_CHECK( (x ^= 0.0) == Factor(v, 1.0) );
393 BOOST_CHECK( x == Factor(v, 1.0) );
394 x = xorg;
395 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
396 BOOST_CHECK( (x ^= 2.0) == y );
397 BOOST_CHECK( x == y );
398 y.set( 0, 0.5 ); y.set( 1, INFINITY ); y.set( 2, 1.0 );
399 BOOST_CHECK( (x ^= -0.5) == y );
400 BOOST_CHECK( x == y );
401 }
402
403
404 BOOST_AUTO_TEST_CASE( ScalarTransformationsTest ) {
405 Var v( 0, 3 );
406 Factor x( v );
407 x.set( 0, 2.0 );
408 x.set( 1, 0.0 );
409 x.set( 2, 1.0 );
410 Factor y( v );
411
412 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
413 BOOST_CHECK( (x + 1.0) == y );
414 y.set( 0, 0.0 ); y.set( 1, -2.0 ); y.set( 2, -1.0 );
415 BOOST_CHECK( (x + (-2.0)) == y );
416
417 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
418 BOOST_CHECK( (x - 1.0) == y );
419 y.set( 0, 4.0 ); y.set( 1, 2.0 ); y.set( 2, 3.0 );
420 BOOST_CHECK( (x - (-2.0)) == y );
421
422 BOOST_CHECK( (x * 1.0) == x );
423 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 2.0 );
424 BOOST_CHECK( (x * 2.0) == y );
425 y.set( 0, -1.0 ); y.set( 1, 0.0 ); y.set( 2, -0.5 );
426 BOOST_CHECK( (x * -0.5) == y );
427
428 BOOST_CHECK( (x / 1.0) == x );
429 y.set( 0, 1.0 ); y.set( 1, 0.0 ); y.set( 2, 0.5 );
430 BOOST_CHECK( (x / 2.0) == y );
431 y.set( 0, -4.0 ); y.set( 1, 0.0 ); y.set( 2, -2.0 );
432 BOOST_CHECK( (x / -0.5) == y );
433 BOOST_CHECK( (x / 0.0) == Factor(v, 0.0) );
434
435 BOOST_CHECK( (x ^ 1.0) == x );
436 BOOST_CHECK( (x ^ 0.0) == Factor(v, 1.0) );
437 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
438 BOOST_CHECK( (x ^ 2.0) == y );
439 y.set( 0, 1.0 / std::sqrt(2.0) ); y.set( 1, INFINITY ); y.set( 2, 1.0 );
440 Factor z = (x ^ -0.5);
441 BOOST_CHECK_CLOSE( z[0], y[0], tol );
442 BOOST_CHECK_EQUAL( z[1], y[1] );
443 BOOST_CHECK_CLOSE( z[2], y[2], tol );
444 }
445
446
447 BOOST_AUTO_TEST_CASE( SimilarFactorOperationsTest ) {
448 size_t N = 6;
449 Var v( 0, N );
450 Factor xorg( v ), x( v );
451 xorg.set( 0, 2.0 ); xorg.set( 1, 0.0 ); xorg.set( 2, 1.0 ); xorg.set( 3, 0.0 ); xorg.set( 4, 2.0 ); xorg.set( 5, 3.0 );
452 Factor y( v );
453 y.set( 0, 0.5 ); y.set( 1, -1.0 ); y.set( 2, 0.0 ); y.set( 3, 0.0 ); y.set( 4, -2.0 ); y.set( 5, 3.0 );
454 Factor z( v ), r( v );
455
456 z.set( 0, 2.5 ); z.set( 1, -1.0 ); z.set( 2, 1.0 ); z.set( 3, 0.0 ); z.set( 4, 0.0 ); z.set( 5, 6.0 );
457 x = xorg;
458 r = (x += y);
459 for( size_t i = 0; i < N; i++ )
460 BOOST_CHECK_CLOSE( r[i], z[i], tol );
461 BOOST_CHECK( x == z );
462 x = xorg;
463 BOOST_CHECK( x.binaryOp( y, std::plus<Real>() ) == z );
464 BOOST_CHECK( x == z );
465
466 z.set( 0, 1.5 ); z.set( 1, 1.0 ); z.set( 2, 1.0 ); z.set( 3, 0.0 ); z.set( 4, 4.0 ); z.set( 5, 0.0 );
467 x = xorg;
468 r = (x -= y);
469 for( size_t i = 0; i < N; i++ )
470 BOOST_CHECK_CLOSE( r[i], z[i], tol );
471 BOOST_CHECK( x == z );
472 x = xorg;
473 BOOST_CHECK( x.binaryOp( y, std::minus<Real>() ) == z );
474 BOOST_CHECK( x == z );
475
476 z.set( 0, 1.0 ); z.set( 1, 0.0 ); z.set( 2, 0.0 ); z.set( 3, 0.0 ); z.set( 4, -4.0 ); z.set( 5, 9.0 );
477 x = xorg;
478 r = (x *= y);
479 for( size_t i = 0; i < N; i++ )
480 BOOST_CHECK_CLOSE( r[i], z[i], tol );
481 BOOST_CHECK( x == z );
482 x = xorg;
483 BOOST_CHECK( x.binaryOp( y, std::multiplies<Real>() ) == z );
484 BOOST_CHECK( x == z );
485
486 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, 0.0 ); z.set( 3, 0.0 ); z.set( 4, -1.0 ); z.set( 5, 1.0 );
487 x = xorg;
488 r = (x /= y);
489 for( size_t i = 0; i < N; i++ )
490 BOOST_CHECK_CLOSE( r[i], z[i], tol );
491 BOOST_CHECK( x == z );
492 x = xorg;
493 BOOST_CHECK( x.binaryOp( y, fo_divides0<Real>() ) == z );
494 BOOST_CHECK( x == z );
495 }
496
497
498 BOOST_AUTO_TEST_CASE( SimilarFactorTransformationsTest ) {
499 size_t N = 6;
500 Var v( 0, N );
501 Factor x( v );
502 x.set( 0, 2.0 ); x.set( 1, 0.0 ); x.set( 2, 1.0 ); x.set( 3, 0.0 ); x.set( 4, 2.0 ); x.set( 5, 3.0 );
503 Factor y( v );
504 y.set( 0, 0.5 ); y.set( 1, -1.0 ); y.set( 2, 0.0 ); y.set( 3, 0.0 ); y.set( 4, -2.0 ); y.set( 5, 3.0 );
505 Factor z( v ), r( v );
506
507 z.set( 0, 2.5 ); z.set( 1, -1.0 ); z.set( 2, 1.0 ); z.set( 3, 0.0 ); z.set( 4, 0.0 ); z.set( 5, 6.0 );
508 r = x + y;
509 for( size_t i = 0; i < N; i++ )
510 BOOST_CHECK_CLOSE( r[i], z[i], tol );
511 z = x.binaryTr( y, std::plus<Real>() );
512 BOOST_CHECK( r == z );
513
514 z.set( 0, 1.5 ); z.set( 1, 1.0 ); z.set( 2, 1.0 ); z.set( 3, 0.0 ); z.set( 4, 4.0 ); z.set( 5, 0.0 );
515 r = x - y;
516 for( size_t i = 0; i < N; i++ )
517 BOOST_CHECK_CLOSE( r[i], z[i], tol );
518 z = x.binaryTr( y, std::minus<Real>() );
519 BOOST_CHECK( r == z );
520
521 z.set( 0, 1.0 ); z.set( 1, 0.0 ); z.set( 2, 0.0 ); z.set( 3, 0.0 ); z.set( 4, -4.0 ); z.set( 5, 9.0 );
522 r = x * y;
523 for( size_t i = 0; i < N; i++ )
524 BOOST_CHECK_CLOSE( r[i], z[i], tol );
525 z = x.binaryTr( y, std::multiplies<Real>() );
526 BOOST_CHECK( r == z );
527
528 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, 0.0 ); z.set( 3, 0.0 ); z.set( 4, -1.0 ); z.set( 5, 1.0 );
529 r = x / y;
530 for( size_t i = 0; i < N; i++ )
531 BOOST_CHECK_CLOSE( r[i], z[i], tol );
532 z = x.binaryTr( y, fo_divides0<Real>() );
533 BOOST_CHECK( r == z );
534 }
535
536
537 BOOST_AUTO_TEST_CASE( FactorOperationsTest ) {
538 size_t N = 9;
539 Var v1( 1, 3 );
540 Var v2( 2, 3 );
541 Factor xorg( v1 ), x( v1 );
542 xorg.set( 0, 2.0 ); xorg.set( 1, 0.0 ); xorg.set( 2, -1.0 );
543 Factor y( v2 );
544 y.set( 0, 0.5 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
545 Factor r;
546
547 Factor z( VarSet( v1, v2 ) );
548 z.set( 0, 2.5 ); z.set( 1, 0.5 ); z.set( 2, -0.5 );
549 z.set( 3, 1.0 ); z.set( 4, -1.0 ); z.set( 5, -2.0 );
550 z.set( 6, 2.0 ); z.set( 7, 0.0 ); z.set( 8, -1.0 );
551 x = xorg;
552 r = (x += y);
553 for( size_t i = 0; i < N; i++ )
554 BOOST_CHECK_CLOSE( r[i], z[i], tol );
555 BOOST_CHECK( x == z );
556 x = xorg;
557 BOOST_CHECK( x.binaryOp( y, std::plus<Real>() ) == z );
558 BOOST_CHECK( x == z );
559
560 z.set( 0, 1.5 ); z.set( 1, -0.5 ); z.set( 2, -1.5 );
561 z.set( 3, 3.0 ); z.set( 4, 1.0 ); z.set( 5, 0.0 );
562 z.set( 6, 2.0 ); z.set( 7, 0.0 ); z.set( 8, -1.0 );
563 x = xorg;
564 r = (x -= y);
565 for( size_t i = 0; i < N; i++ )
566 BOOST_CHECK_CLOSE( r[i], z[i], tol );
567 BOOST_CHECK( x == z );
568 x = xorg;
569 BOOST_CHECK( x.binaryOp( y, std::minus<Real>() ) == z );
570 BOOST_CHECK( x == z );
571
572 z.set( 0, 1.0 ); z.set( 1, 0.0 ); z.set( 2, -0.5 );
573 z.set( 3, -2.0 ); z.set( 4, 0.0 ); z.set( 5, 1.0 );
574 z.set( 6, 0.0 ); z.set( 7, 0.0 ); z.set( 8, 0.0 );
575 x = xorg;
576 r = (x *= y);
577 for( size_t i = 0; i < N; i++ )
578 BOOST_CHECK_CLOSE( r[i], z[i], tol );
579 BOOST_CHECK( x == z );
580 x = xorg;
581 BOOST_CHECK( x.binaryOp( y, std::multiplies<Real>() ) == z );
582 BOOST_CHECK( x == z );
583
584 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, -2.0 );
585 z.set( 3, -2.0 ); z.set( 4, 0.0 ); z.set( 5, 1.0 );
586 z.set( 6, 0.0 ); z.set( 7, 0.0 ); z.set( 8, 0.0 );
587 x = xorg;
588 r = (x /= y);
589 for( size_t i = 0; i < N; i++ )
590 BOOST_CHECK_CLOSE( r[i], z[i], tol );
591 BOOST_CHECK( x == z );
592 x = xorg;
593 BOOST_CHECK( x.binaryOp( y, fo_divides0<Real>() ) == z );
594 BOOST_CHECK( x == z );
595 }
596
597
598 BOOST_AUTO_TEST_CASE( FactorTransformationsTest ) {
599 size_t N = 9;
600 Var v1( 1, 3 );
601 Var v2( 2, 3 );
602 Factor x( v1 );
603 x.set( 0, 2.0 ); x.set( 1, 0.0 ); x.set( 2, -1.0 );
604 Factor y( v2 );
605 y.set( 0, 0.5 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
606 Factor r;
607
608 Factor z( VarSet( v1, v2 ) );
609 z.set( 0, 2.5 ); z.set( 1, 0.5 ); z.set( 2, -0.5 );
610 z.set( 3, 1.0 ); z.set( 4, -1.0 ); z.set( 5, -2.0 );
611 z.set( 6, 2.0 ); z.set( 7, 0.0 ); z.set( 8, -1.0 );
612 r = x + y;
613 for( size_t i = 0; i < N; i++ )
614 BOOST_CHECK_CLOSE( r[i], z[i], tol );
615 BOOST_CHECK( r == z );
616 z = x.binaryTr( y, std::plus<Real>() );
617 BOOST_CHECK( r == z );
618
619 z.set( 0, 1.5 ); z.set( 1, -0.5 ); z.set( 2, -1.5 );
620 z.set( 3, 3.0 ); z.set( 4, 1.0 ); z.set( 5, 0.0 );
621 z.set( 6, 2.0 ); z.set( 7, 0.0 ); z.set( 8, -1.0 );
622 r = x - y;
623 for( size_t i = 0; i < N; i++ )
624 BOOST_CHECK_CLOSE( r[i], z[i], tol );
625 BOOST_CHECK( r == z );
626 z = x.binaryTr( y, std::minus<Real>() );
627 BOOST_CHECK( r == z );
628
629 z.set( 0, 1.0 ); z.set( 1, 0.0 ); z.set( 2, -0.5 );
630 z.set( 3, -2.0 ); z.set( 4, 0.0 ); z.set( 5, 1.0 );
631 z.set( 6, 0.0 ); z.set( 7, 0.0 ); z.set( 8, 0.0 );
632 r = x * y;
633 for( size_t i = 0; i < N; i++ )
634 BOOST_CHECK_CLOSE( r[i], z[i], tol );
635 BOOST_CHECK( r == z );
636 z = x.binaryTr( y, std::multiplies<Real>() );
637 BOOST_CHECK( r == z );
638
639 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, -2.0 );
640 z.set( 3, -2.0 ); z.set( 4, 0.0 ); z.set( 5, 1.0 );
641 z.set( 6, 0.0 ); z.set( 7, 0.0 ); z.set( 8, 0.0 );
642 r = x / y;
643 for( size_t i = 0; i < N; i++ )
644 BOOST_CHECK_CLOSE( r[i], z[i], tol );
645 BOOST_CHECK( r == z );
646 z = x.binaryOp( y, fo_divides0<Real>() );
647 BOOST_CHECK( r == z );
648 }
649
650
651 BOOST_AUTO_TEST_CASE( MiscOperationsTest ) {
652 Var v1(1, 2);
653 Var v2(2, 3);
654 Factor x( VarSet( v1, v2 ) );
655 x.randomize();
656
657 // slice
658 Factor y = x.slice( v1, 0 );
659 BOOST_CHECK( y.vars() == VarSet( v2 ) );
660 BOOST_CHECK_EQUAL( y.nrStates(), 3 );
661 BOOST_CHECK_EQUAL( y[0], x[0] );
662 BOOST_CHECK_EQUAL( y[1], x[2] );
663 BOOST_CHECK_EQUAL( y[2], x[4] );
664 y = x.slice( v1, 1 );
665 BOOST_CHECK( y.vars() == VarSet( v2 ) );
666 BOOST_CHECK_EQUAL( y.nrStates(), 3 );
667 BOOST_CHECK_EQUAL( y[0], x[1] );
668 BOOST_CHECK_EQUAL( y[1], x[3] );
669 BOOST_CHECK_EQUAL( y[2], x[5] );
670 y = x.slice( v2, 0 );
671 BOOST_CHECK( y.vars() == VarSet( v1 ) );
672 BOOST_CHECK_EQUAL( y.nrStates(), 2 );
673 BOOST_CHECK_EQUAL( y[0], x[0] );
674 BOOST_CHECK_EQUAL( y[1], x[1] );
675 y = x.slice( v2, 1 );
676 BOOST_CHECK( y.vars() == VarSet( v1 ) );
677 BOOST_CHECK_EQUAL( y.nrStates(), 2 );
678 BOOST_CHECK_EQUAL( y[0], x[2] );
679 BOOST_CHECK_EQUAL( y[1], x[3] );
680 y = x.slice( v2, 2 );
681 BOOST_CHECK( y.vars() == VarSet( v1 ) );
682 BOOST_CHECK_EQUAL( y.nrStates(), 2 );
683 BOOST_CHECK_EQUAL( y[0], x[4] );
684 BOOST_CHECK_EQUAL( y[1], x[5] );
685 for( size_t i = 0; i < x.nrStates(); i++ ) {
686 y = x.slice( VarSet( v1, v2 ), 0 );
687 BOOST_CHECK( y.vars() == VarSet() );
688 BOOST_CHECK_EQUAL( y.nrStates(), 1 );
689 BOOST_CHECK_EQUAL( y[0], x[0] );
690 }
691 y = x.slice( VarSet(), 0 );
692 BOOST_CHECK_EQUAL( y, x );
693
694 // embed
695 Var v3(3, 4);
696 BOOST_CHECK_THROW( x.embed( VarSet( v3 ) ), Exception );
697 BOOST_CHECK_THROW( x.embed( VarSet( v3, v2 ) ), Exception );
698 y = x.embed( VarSet( v3, v2 ) | v1 );
699 for( size_t i = 0; i < y.nrStates(); i++ )
700 BOOST_CHECK_EQUAL( y[i], x[i % 6] );
701 y = x.embed( VarSet( v1, v2 ) );
702 BOOST_CHECK_EQUAL( x, y );
703
704 // marginal
705 y = x.marginal( v1 );
706 BOOST_CHECK( y.vars() == VarSet( v1 ) );
707 BOOST_CHECK_EQUAL( y[0], (x[0] + x[2] + x[4]) / x.sum() );
708 BOOST_CHECK_EQUAL( y[1], (x[1] + x[3] + x[5]) / x.sum() );
709 y = x.marginal( v2 );
710 BOOST_CHECK( y.vars() == VarSet( v2 ) );
711 BOOST_CHECK_CLOSE( y[0], (x[0] + x[1]) / x.sum(), tol );
712 BOOST_CHECK_CLOSE( y[1], (x[2] + x[3]) / x.sum(), tol );
713 BOOST_CHECK_CLOSE( y[2], (x[4] + x[5]) / x.sum(), tol );
714 y = x.marginal( VarSet() );
715 BOOST_CHECK( y.vars() == VarSet() );
716 BOOST_CHECK_EQUAL( y[0], 1.0 );
717 y = x.marginal( VarSet( v1, v2 ) );
718 BOOST_CHECK( y == x.normalized() );
719
720 y = x.marginal( v1, true );
721 BOOST_CHECK( y.vars() == VarSet( v1 ) );
722 BOOST_CHECK_EQUAL( y[0], (x[0] + x[2] + x[4]) / x.sum() );
723 BOOST_CHECK_EQUAL( y[1], (x[1] + x[3] + x[5]) / x.sum() );
724 y = x.marginal( v2, true );
725 BOOST_CHECK( y.vars() == VarSet( v2 ) );
726 BOOST_CHECK_CLOSE( y[0], (x[0] + x[1]) / x.sum(), tol );
727 BOOST_CHECK_CLOSE( y[1], (x[2] + x[3]) / x.sum(), tol );
728 BOOST_CHECK_CLOSE( y[2], (x[4] + x[5]) / x.sum(), tol );
729 y = x.marginal( VarSet(), true );
730 BOOST_CHECK( y.vars() == VarSet() );
731 BOOST_CHECK_EQUAL( y[0], 1.0 );
732 y = x.marginal( VarSet( v1, v2 ), true );
733 BOOST_CHECK( y == x.normalized() );
734
735 y = x.marginal( v1, false );
736 BOOST_CHECK( y.vars() == VarSet( v1 ) );
737 BOOST_CHECK_EQUAL( y[0], x[0] + x[2] + x[4] );
738 BOOST_CHECK_EQUAL( y[1], x[1] + x[3] + x[5] );
739 y = x.marginal( v2, false );
740 BOOST_CHECK( y.vars() == VarSet( v2 ) );
741 BOOST_CHECK_EQUAL( y[0], x[0] + x[1] );
742 BOOST_CHECK_EQUAL( y[1], x[2] + x[3] );
743 BOOST_CHECK_EQUAL( y[2], x[4] + x[5] );
744 y = x.marginal( VarSet(), false );
745 BOOST_CHECK( y.vars() == VarSet() );
746 BOOST_CHECK_EQUAL( y[0], x.sum() );
747 y = x.marginal( VarSet( v1, v2 ), false );
748 BOOST_CHECK( y == x );
749
750 // maxMarginal
751 y = x.maxMarginal( v1 );
752 BOOST_CHECK( y.vars() == VarSet( v1 ) );
753 BOOST_CHECK_EQUAL( y[0], x.slice( v1, 0 ).max() / (x.slice( v1, 0 ).max() + x.slice( v1, 1 ).max()) );
754 BOOST_CHECK_EQUAL( y[1], x.slice( v1, 1 ).max() / (x.slice( v1, 0 ).max() + x.slice( v1, 1 ).max()) );
755 y = x.maxMarginal( v2 );
756 BOOST_CHECK( y.vars() == VarSet( v2 ) );
757 BOOST_CHECK_EQUAL( y[0], x.slice( v2, 0 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
758 BOOST_CHECK_EQUAL( y[1], x.slice( v2, 1 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
759 BOOST_CHECK_EQUAL( y[2], x.slice( v2, 2 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
760 y = x.maxMarginal( VarSet() );
761 BOOST_CHECK( y.vars() == VarSet() );
762 BOOST_CHECK_EQUAL( y[0], 1.0 );
763 y = x.maxMarginal( VarSet( v1, v2 ) );
764 BOOST_CHECK( y == x.normalized() );
765
766 y = x.maxMarginal( v1, true );
767 BOOST_CHECK( y.vars() == VarSet( v1 ) );
768 BOOST_CHECK_EQUAL( y[0], x.slice( v1, 0 ).max() / (x.slice( v1, 0 ).max() + x.slice( v1, 1 ).max()) );
769 BOOST_CHECK_EQUAL( y[1], x.slice( v1, 1 ).max() / (x.slice( v1, 0 ).max() + x.slice( v1, 1 ).max()) );
770 y = x.maxMarginal( v2, true );
771 BOOST_CHECK( y.vars() == VarSet( v2 ) );
772 BOOST_CHECK_EQUAL( y[0], x.slice( v2, 0 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
773 BOOST_CHECK_EQUAL( y[1], x.slice( v2, 1 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
774 BOOST_CHECK_EQUAL( y[2], x.slice( v2, 2 ).max() / (x.slice( v2, 0 ).max() + x.slice( v2, 1 ).max() + x.slice( v2, 2 ).max()) );
775 y = x.maxMarginal( VarSet(), true );
776 BOOST_CHECK( y.vars() == VarSet() );
777 BOOST_CHECK_EQUAL( y[0], 1.0 );
778 y = x.maxMarginal( VarSet( v1, v2 ), true );
779 BOOST_CHECK( y == x.normalized() );
780
781 y = x.maxMarginal( v1, false );
782 BOOST_CHECK( y.vars() == VarSet( v1 ) );
783 BOOST_CHECK_EQUAL( y[0], x.slice( v1, 0 ).max() );
784 BOOST_CHECK_EQUAL( y[1], x.slice( v1, 1 ).max() );
785 y = x.maxMarginal( v2, false );
786 BOOST_CHECK( y.vars() == VarSet( v2 ) );
787 BOOST_CHECK_EQUAL( y[0], x.slice( v2, 0 ).max() );
788 BOOST_CHECK_EQUAL( y[1], x.slice( v2, 1 ).max() );
789 BOOST_CHECK_EQUAL( y[2], x.slice( v2, 2 ).max() );
790 y = x.maxMarginal( VarSet(), false );
791 BOOST_CHECK( y.vars() == VarSet() );
792 BOOST_CHECK_EQUAL( y[0], x.max() );
793 y = x.maxMarginal( VarSet( v1, v2 ), false );
794 BOOST_CHECK( y == x );
795 }
796
797
798 BOOST_AUTO_TEST_CASE( RelatedFunctionsTest ) {
799 Var v( 0, 3 );
800 Factor x(v), y(v), z(v);
801 x.set( 0, 0.2 );
802 x.set( 1, 0.8 );
803 x.set( 2, 0.0 );
804 y.set( 0, 0.0 );
805 y.set( 1, 0.6 );
806 y.set( 2, 0.4 );
807
808 z = min( x, y );
809 BOOST_CHECK_EQUAL( z[0], 0.0 );
810 BOOST_CHECK_EQUAL( z[1], 0.6 );
811 BOOST_CHECK_EQUAL( z[2], 0.0 );
812 z = max( x, y );
813 BOOST_CHECK_EQUAL( z[0], 0.2 );
814 BOOST_CHECK_EQUAL( z[1], 0.8 );
815 BOOST_CHECK_EQUAL( z[2], 0.4 );
816
817 BOOST_CHECK_EQUAL( dist( x, x, DISTL1 ), 0.0 );
818 BOOST_CHECK_EQUAL( dist( y, y, DISTL1 ), 0.0 );
819 BOOST_CHECK_EQUAL( dist( x, y, DISTL1 ), 0.2 + 0.2 + 0.4 );
820 BOOST_CHECK_EQUAL( dist( y, x, DISTL1 ), 0.2 + 0.2 + 0.4 );
821 BOOST_CHECK_EQUAL( dist( x, x, DISTLINF ), 0.0 );
822 BOOST_CHECK_EQUAL( dist( y, y, DISTLINF ), 0.0 );
823 BOOST_CHECK_EQUAL( dist( x, y, DISTLINF ), 0.4 );
824 BOOST_CHECK_EQUAL( dist( y, x, DISTLINF ), 0.4 );
825 BOOST_CHECK_EQUAL( dist( x, x, DISTTV ), 0.0 );
826 BOOST_CHECK_EQUAL( dist( y, y, DISTTV ), 0.0 );
827 BOOST_CHECK_EQUAL( dist( x, y, DISTTV ), 0.5 * (0.2 + 0.2 + 0.4) );
828 BOOST_CHECK_EQUAL( dist( y, x, DISTTV ), 0.5 * (0.2 + 0.2 + 0.4) );
829 BOOST_CHECK_EQUAL( dist( x, x, DISTKL ), 0.0 );
830 BOOST_CHECK_EQUAL( dist( y, y, DISTKL ), 0.0 );
831 BOOST_CHECK_EQUAL( dist( x, y, DISTKL ), INFINITY );
832 BOOST_CHECK_EQUAL( dist( y, x, DISTKL ), INFINITY );
833 BOOST_CHECK_EQUAL( dist( x, x, DISTHEL ), 0.0 );
834 BOOST_CHECK_EQUAL( dist( y, y, DISTHEL ), 0.0 );
835 BOOST_CHECK_EQUAL( dist( x, y, DISTHEL ), 0.5 * (0.2 + std::pow(std::sqrt(0.8) - std::sqrt(0.6), 2.0) + 0.4) );
836 BOOST_CHECK_EQUAL( dist( y, x, DISTHEL ), 0.5 * (0.2 + std::pow(std::sqrt(0.8) - std::sqrt(0.6), 2.0) + 0.4) );
837 x.set( 1, 0.7 ); x.set( 2, 0.1 );
838 y.set( 0, 0.1 ); y.set( 1, 0.5 );
839 BOOST_CHECK_CLOSE( dist( x, y, DISTKL ), 0.2 * std::log(0.2 / 0.1) + 0.7 * std::log(0.7 / 0.5) + 0.1 * std::log(0.1 / 0.4), tol );
840 BOOST_CHECK_CLOSE( dist( y, x, DISTKL ), 0.1 * std::log(0.1 / 0.2) + 0.5 * std::log(0.5 / 0.7) + 0.4 * std::log(0.4 / 0.1), tol );
841
842 std::stringstream ss;
843 ss << x;
844 std::string s;
845 std::getline( ss, s );
846 BOOST_CHECK_EQUAL( s, std::string("({x0}, (0.2, 0.7, 0.1))") );
847 std::stringstream ss2;
848 ss2 << y;
849 std::getline( ss2, s );
850 BOOST_CHECK_EQUAL( s, std::string("({x0}, (0.1, 0.5, 0.4))") );
851
852 z = min( x, y );
853 BOOST_CHECK_EQUAL( z[0], 0.1 );
854 BOOST_CHECK_EQUAL( z[1], 0.5 );
855 BOOST_CHECK_EQUAL( z[2], 0.1 );
856 z = max( x, y );
857 BOOST_CHECK_EQUAL( z[0], 0.2 );
858 BOOST_CHECK_EQUAL( z[1], 0.7 );
859 BOOST_CHECK_EQUAL( z[2], 0.4 );
860
861 for( double J = -1.0; J <= 1.01; J += 0.1 ) {
862 Factor x = createFactorIsing( Var(0,2), Var(1,2), J ).normalized();
863 BOOST_CHECK_CLOSE( x[0], std::exp(J) / (4.0 * std::cosh(J)), tol );
864 BOOST_CHECK_CLOSE( x[1], std::exp(-J) / (4.0 * std::cosh(J)), tol );
865 BOOST_CHECK_CLOSE( x[2], std::exp(-J) / (4.0 * std::cosh(J)), tol );
866 BOOST_CHECK_CLOSE( x[3], std::exp(J) / (4.0 * std::cosh(J)), tol );
867 BOOST_CHECK_SMALL( MutualInfo( x ) - (J * std::tanh(J) - std::log(std::cosh(J))), tol );
868 }
869 Var v1( 1, 3 );
870 Var v2( 2, 4 );
871 BOOST_CHECK_SMALL( MutualInfo( (Factor(v1).randomize() * Factor(v2).randomize()).normalized() ), tol );
872 BOOST_CHECK_THROW( MutualInfo( createFactorIsing( Var(0,2), 1.0 ).normalized() ), Exception );
873 BOOST_CHECK_THROW( createFactorIsing( v1, 0.0 ), Exception );
874 BOOST_CHECK_THROW( createFactorIsing( v1, v2, 0.0 ), Exception );
875 for( double J = -1.0; J <= 1.01; J += 0.1 ) {
876 Factor x = createFactorIsing( Var(0,2), J ).normalized();
877 BOOST_CHECK_CLOSE( x[0], std::exp(-J) / (2.0 * std::cosh(J)), tol );
878 BOOST_CHECK_CLOSE( x[1], std::exp(J) / (2.0 * std::cosh(J)), tol );
879 BOOST_CHECK_SMALL( x.entropy() - (-J * std::tanh(J) + std::log(2.0 * std::cosh(J))), tol );
880 }
881
882 x = createFactorDelta( v1, 2 );
883 BOOST_CHECK_EQUAL( x[0], 0.0 );
884 BOOST_CHECK_EQUAL( x[1], 0.0 );
885 BOOST_CHECK_EQUAL( x[2], 1.0 );
886 x = createFactorDelta( v1, 1 );
887 BOOST_CHECK_EQUAL( x[0], 0.0 );
888 BOOST_CHECK_EQUAL( x[1], 1.0 );
889 BOOST_CHECK_EQUAL( x[2], 0.0 );
890 x = createFactorDelta( v1, 0 );
891 BOOST_CHECK_EQUAL( x[0], 1.0 );
892 BOOST_CHECK_EQUAL( x[1], 0.0 );
893 BOOST_CHECK_EQUAL( x[2], 0.0 );
894 BOOST_CHECK_THROW( createFactorDelta( v1, 4 ), Exception );
895 }