Merge branch 'master' of git.tuebingen.mpg.de:libdai
[libdai.git] / tests / unit / prob_test.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 #include <dai/util.h>
12 #include <dai/prob.h>
13 #include <strstream>
14
15
16 using namespace dai;
17
18
19 const Real tol = 1e-8;
20
21
22 #define BOOST_TEST_MODULE ProbTest
23
24
25 #include <boost/test/unit_test.hpp>
26 #include <boost/test/floating_point_comparison.hpp>
27
28
29 BOOST_AUTO_TEST_CASE( ConstructorsTest ) {
30 // check constructors
31 Prob x1;
32 BOOST_CHECK_EQUAL( x1.size(), 0U );
33 BOOST_CHECK( x1.p() == Prob::container_type() );
34
35 Prob x2( 3 );
36 BOOST_CHECK_EQUAL( x2.size(), 3 );
37 BOOST_CHECK_CLOSE( x2[0], (Real)(1.0 / 3.0), tol );
38 BOOST_CHECK_CLOSE( x2[1], (Real)(1.0 / 3.0), tol );
39 BOOST_CHECK_CLOSE( x2[2], (Real)(1.0 / 3.0), tol );
40
41 Prob x3( 4, (Real)1.0 );
42 BOOST_CHECK_EQUAL( x3.size(), 4 );
43 BOOST_CHECK( x3.p() == Prob::container_type( 4, (Real)1.0 ) );
44 BOOST_CHECK_EQUAL( x3[0], (Real)1.0 );
45 BOOST_CHECK_EQUAL( x3[1], (Real)1.0 );
46 BOOST_CHECK_EQUAL( x3[2], (Real)1.0 );
47 BOOST_CHECK_EQUAL( x3[3], (Real)1.0 );
48 x3.set( 0, 0.5 );
49 x3.set( 1, 1.0 );
50 x3.set( 2, 2.0 );
51 x3.set( 3, 4.0 );
52
53 std::vector<Real> v;
54 v.push_back( 0.5 );
55 v.push_back( 1.0 );
56 v.push_back( 2.0 );
57 v.push_back( 4.0 );
58 Prob x4( v.begin(), v.end(), 0 );
59 BOOST_CHECK_EQUAL( x4.size(), 4 );
60 BOOST_CHECK( x4.p() == x3.p() );
61 BOOST_CHECK( x4 == x3 );
62 BOOST_CHECK_EQUAL( x4[0], (Real)0.5 );
63 BOOST_CHECK_EQUAL( x4[1], (Real)1.0 );
64 BOOST_CHECK_EQUAL( x4[2], (Real)2.0 );
65 BOOST_CHECK_EQUAL( x4[3], (Real)4.0 );
66
67 Prob x5( v.begin(), v.end(), v.size() );
68 BOOST_CHECK_EQUAL( x5.size(), 4 );
69 BOOST_CHECK( x5.p() == x3.p() );
70 BOOST_CHECK( x5 == x3 );
71 BOOST_CHECK_EQUAL( x5[0], (Real)0.5 );
72 BOOST_CHECK_EQUAL( x5[1], (Real)1.0 );
73 BOOST_CHECK_EQUAL( x5[2], (Real)2.0 );
74 BOOST_CHECK_EQUAL( x5[3], (Real)4.0 );
75
76 std::vector<int> y( 3, 2 );
77 Prob x6( y );
78 BOOST_CHECK_EQUAL( x6.size(), 3 );
79 BOOST_CHECK_EQUAL( x6[0], (Real)2.0 );
80 BOOST_CHECK_EQUAL( x6[1], (Real)2.0 );
81 BOOST_CHECK_EQUAL( x6[2], (Real)2.0 );
82
83 Prob x7( x6 );
84 BOOST_CHECK( x7 == x6 );
85
86 Prob x8 = x6;
87 BOOST_CHECK( x8 == x6 );
88
89 x7.resize( 5 );
90 BOOST_CHECK_EQUAL( x7.size(), 5 );
91 BOOST_CHECK_EQUAL( x7[0], (Real)2.0 );
92 BOOST_CHECK_EQUAL( x7[1], (Real)2.0 );
93 BOOST_CHECK_EQUAL( x7[2], (Real)2.0 );
94 BOOST_CHECK_EQUAL( x7[3], (Real)0.0 );
95 BOOST_CHECK_EQUAL( x7[4], (Real)0.0 );
96
97 x8.resize( 1 );
98 BOOST_CHECK_EQUAL( x8.size(), 1 );
99 BOOST_CHECK_EQUAL( x8[0], (Real)2.0 );
100 }
101
102
103 #ifndef DAI_SPARSE
104 BOOST_AUTO_TEST_CASE( IteratorTest ) {
105 Prob x( 5, 0.0 );
106 size_t i;
107 for( i = 0; i < x.size(); i++ )
108 x.set( i, (Real)i );
109
110 i = 0;
111 for( Prob::const_iterator cit = x.begin(); cit != x.end(); cit++, i++ )
112 BOOST_CHECK_EQUAL( *cit, (Real)i );
113
114 i = 0;
115 for( Prob::iterator it = x.begin(); it != x.end(); it++, i++ )
116 *it = (Real)(4 - i);
117
118 i = 0;
119 for( Prob::const_iterator it = x.begin(); it != x.end(); it++, i++ )
120 BOOST_CHECK_EQUAL( *it, (Real)(4 - i) );
121
122 i = 0;
123 for( Prob::const_reverse_iterator crit = x.rbegin(); crit != static_cast<Prob::const_reverse_iterator>(x.rend()); crit++, i++ )
124 BOOST_CHECK_EQUAL( *crit, (Real)i );
125
126 i = 0;
127 for( Prob::reverse_iterator rit = x.rbegin(); rit != x.rend(); rit++, i++ )
128 *rit = (Real)(2 * i);
129
130 i = 0;
131 for( Prob::const_reverse_iterator crit = x.rbegin(); crit != static_cast<Prob::const_reverse_iterator>(x.rend()); crit++, i++ )
132 BOOST_CHECK_EQUAL( *crit, (Real)2 * i );
133 }
134 #endif
135
136
137 BOOST_AUTO_TEST_CASE( QueriesTest ) {
138 Prob x( 5, 0.0 );
139 for( size_t i = 0; i < x.size(); i++ )
140 x.set( i, 2.0 - i );
141
142 // test accumulate, min, max, sum, sumAbs, maxAbs
143 BOOST_CHECK_CLOSE( x.sum(), (Real)0.0, tol );
144 BOOST_CHECK_CLOSE( x.accumulateSum( 0.0, fo_id<Real>() ), (Real)0.0, tol );
145 BOOST_CHECK_CLOSE( x.accumulateSum( 1.0, fo_id<Real>() ), (Real)1.0, tol );
146 BOOST_CHECK_CLOSE( x.accumulateSum( -1.0, fo_id<Real>() ), (Real)-1.0, tol );
147 BOOST_CHECK_CLOSE( x.max(), (Real)2.0, tol );
148 BOOST_CHECK_CLOSE( x.accumulateMax( -INFINITY, fo_id<Real>(), false ), (Real)2.0, tol );
149 BOOST_CHECK_CLOSE( x.accumulateMax( 3.0, fo_id<Real>(), false ), (Real)3.0, tol );
150 BOOST_CHECK_CLOSE( x.accumulateMax( -5.0, fo_id<Real>(), false ), (Real)2.0, tol );
151 BOOST_CHECK_CLOSE( x.min(), (Real)-2.0, tol );
152 BOOST_CHECK_CLOSE( x.accumulateMax( INFINITY, fo_id<Real>(), true ), (Real)-2.0, tol );
153 BOOST_CHECK_CLOSE( x.accumulateMax( -3.0, fo_id<Real>(), true ), (Real)-3.0, tol );
154 BOOST_CHECK_CLOSE( x.accumulateMax( 5.0, fo_id<Real>(), true ), (Real)-2.0, tol );
155 BOOST_CHECK_CLOSE( x.sumAbs(), (Real)6.0, tol );
156 BOOST_CHECK_CLOSE( x.accumulateSum( 0.0, fo_abs<Real>() ), (Real)6.0, tol );
157 BOOST_CHECK_CLOSE( x.accumulateSum( 1.0, fo_abs<Real>() ), (Real)7.0, tol );
158 BOOST_CHECK_CLOSE( x.accumulateSum( -1.0, fo_abs<Real>() ), (Real)7.0, tol );
159 BOOST_CHECK_CLOSE( x.maxAbs(), (Real)2.0, tol );
160 BOOST_CHECK_CLOSE( x.accumulateMax( 0.0, fo_abs<Real>(), false ), (Real)2.0, tol );
161 BOOST_CHECK_CLOSE( x.accumulateMax( 1.0, fo_abs<Real>(), false ), (Real)2.0, tol );
162 BOOST_CHECK_CLOSE( x.accumulateMax( -1.0, fo_abs<Real>(), false ), (Real)2.0, tol );
163 BOOST_CHECK_CLOSE( x.accumulateMax( 3.0, fo_abs<Real>(), false ), (Real)3.0, tol );
164 BOOST_CHECK_CLOSE( x.accumulateMax( -3.0, fo_abs<Real>(), false ), (Real)3.0, tol );
165 x.set( 1, 1.0 );
166 BOOST_CHECK_CLOSE( x.maxAbs(), (Real)2.0, tol );
167 BOOST_CHECK_CLOSE( x.accumulateMax( 0.0, fo_abs<Real>(), false ), (Real)2.0, tol );
168 BOOST_CHECK_CLOSE( x.accumulateMax( 1.0, fo_abs<Real>(), false ), (Real)2.0, tol );
169 BOOST_CHECK_CLOSE( x.accumulateMax( -1.0, fo_abs<Real>(), false ), (Real)2.0, tol );
170 BOOST_CHECK_CLOSE( x.accumulateMax( 3.0, fo_abs<Real>(), false ), (Real)3.0, tol );
171 BOOST_CHECK_CLOSE( x.accumulateMax( -3.0, fo_abs<Real>(), false ), (Real)3.0, tol );
172 for( size_t i = 0; i < x.size(); i++ )
173 x.set( i, i ? (1.0 / i) : 0.0 );
174 BOOST_CHECK_CLOSE( x.accumulateSum( 0.0, fo_inv0<Real>() ), (Real)10.0, tol );
175 x /= x.sum();
176
177 // test entropy
178 BOOST_CHECK( x.entropy() < Prob(5).entropy() );
179 for( size_t i = 1; i < 100; i++ )
180 BOOST_CHECK_CLOSE( Prob(i).entropy(), dai::log((Real)i), tol );
181
182 // test hasNaNs and hasNegatives
183 BOOST_CHECK( !Prob( 3, 0.0 ).hasNaNs() );
184 Real c = 0.0;
185 BOOST_CHECK( Prob( 3, c / c ).hasNaNs() );
186 BOOST_CHECK( !Prob( 3, 0.0 ).hasNegatives() );
187 BOOST_CHECK( !Prob( 3, 1.0 ).hasNegatives() );
188 BOOST_CHECK( Prob( 3, -1.0 ).hasNegatives() );
189 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 );
190 BOOST_CHECK( x.hasNegatives() );
191 x.set( 2, -INFINITY );
192 BOOST_CHECK( x.hasNegatives() );
193 x.set( 2, INFINITY );
194 BOOST_CHECK( !x.hasNegatives() );
195 x.set( 2, -1.0 );
196
197 // test argmax
198 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)100.0 ) );
199 x.set( 4, 0.5 );
200 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)3, (Real)1.0 ) );
201 x.set( 3, -2.0 );
202 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)0.5 ) );
203 x.set( 4, -1.0 );
204 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)0, (Real)0.0 ) );
205 x.set( 0, -2.0 );
206 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)1, (Real)0.0 ) );
207 x.set( 1, -3.0 );
208 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)2, (Real)-1.0 ) );
209 x.set( 2, -2.0 );
210 BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)-1.0 ) );
211
212 // test draw
213 for( size_t i = 0; i < x.size(); i++ )
214 x.set( i, i ? (1.0 / i) : 0.0 );
215 for( size_t repeat = 0; repeat < 10000; repeat++ ) {
216 BOOST_CHECK( x.draw() < x.size() );
217 BOOST_CHECK( x.draw() != 0 );
218 }
219 x.set( 2, 0.0 );
220 for( size_t repeat = 0; repeat < 10000; repeat++ ) {
221 BOOST_CHECK( x.draw() < x.size() );
222 BOOST_CHECK( x.draw() != 0 );
223 BOOST_CHECK( x.draw() != 2 );
224 }
225 x.set( 4, 0.0 );
226 for( size_t repeat = 0; repeat < 10000; repeat++ ) {
227 BOOST_CHECK( x.draw() < x.size() );
228 BOOST_CHECK( x.draw() != 0 );
229 BOOST_CHECK( x.draw() != 2 );
230 BOOST_CHECK( x.draw() != 4 );
231 }
232 x.set( 1, 0.0 );
233 for( size_t repeat = 0; repeat < 10000; repeat++ )
234 BOOST_CHECK( x.draw() == 3 );
235
236 // test <, ==
237 Prob a(3, 1.0), b(3, 1.0);
238 BOOST_CHECK( !(a < b) );
239 BOOST_CHECK( !(b < a) );
240 BOOST_CHECK( a == b );
241 a.set( 0, 0.0 );
242 BOOST_CHECK( a < b );
243 BOOST_CHECK( !(b < a) );
244 BOOST_CHECK( !(a == b) );
245 b.set( 2, 0.0 );
246 BOOST_CHECK( a < b );
247 BOOST_CHECK( !(b < a) );
248 BOOST_CHECK( !(a == b) );
249 b.set( 0, 0.0 );
250 BOOST_CHECK( !(a < b) );
251 BOOST_CHECK( b < a );
252 BOOST_CHECK( !(a == b) );
253 a.set( 1, 0.0 );
254 BOOST_CHECK( a < b );
255 BOOST_CHECK( !(b < a) );
256 BOOST_CHECK( !(a == b) );
257 b.set( 1, 0.0 );
258 BOOST_CHECK( !(a < b) );
259 BOOST_CHECK( b < a );
260 BOOST_CHECK( !(a == b) );
261 a.set( 2, 0.0 );
262 BOOST_CHECK( !(a < b) );
263 BOOST_CHECK( !(b < a) );
264 BOOST_CHECK( a == b );
265 }
266
267
268 BOOST_AUTO_TEST_CASE( UnaryTransformationsTest ) {
269 Prob x( 3 );
270 x.set( 0, -2.0 );
271 x.set( 1, 0.0 );
272 x.set( 2, 2.0 );
273
274 Prob y = -x;
275 Prob z = x.pwUnaryTr( std::negate<Real>() );
276 BOOST_CHECK_CLOSE( y[0], (Real)2.0, tol );
277 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
278 BOOST_CHECK_CLOSE( y[2], (Real)-2.0, tol );
279 BOOST_CHECK( y == z );
280
281 y = x.abs();
282 z = x.pwUnaryTr( fo_abs<Real>() );
283 BOOST_CHECK_CLOSE( y[0], (Real)2.0, tol );
284 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
285 BOOST_CHECK_CLOSE( y[2], (Real)2.0, tol );
286 BOOST_CHECK( y == z );
287
288 y = x.exp();
289 z = x.pwUnaryTr( fo_exp<Real>() );
290 BOOST_CHECK_CLOSE( y[0], dai::exp((Real)-2.0), tol );
291 BOOST_CHECK_CLOSE( y[1], (Real)1.0, tol );
292 BOOST_CHECK_CLOSE( y[2], (Real)1.0 / y[0], tol );
293 BOOST_CHECK( y == z );
294
295 y = x.log(false);
296 z = x.pwUnaryTr( fo_log<Real>() );
297 BOOST_CHECK( dai::isnan( y[0] ) );
298 BOOST_CHECK_EQUAL( y[1], -INFINITY );
299 BOOST_CHECK_CLOSE( y[2], dai::log((Real)2.0), tol );
300 BOOST_CHECK( !(y == z) );
301 y.set( 0, 0.0 );
302 z.set( 0, 0.0 );
303 BOOST_CHECK( y == z );
304
305 y = x.log(true);
306 z = x.pwUnaryTr( fo_log0<Real>() );
307 BOOST_CHECK( dai::isnan( y[0] ) );
308 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
309 BOOST_CHECK_CLOSE( y[2], dai::log((Real)2.0), tol );
310 BOOST_CHECK( !(y == z) );
311 y.set( 0, 0.0 );
312 z.set( 0, 0.0 );
313 BOOST_CHECK( y == z );
314
315 y = x.inverse(false);
316 z = x.pwUnaryTr( fo_inv<Real>() );
317 BOOST_CHECK_CLOSE( y[0], (Real)-0.5, tol );
318 BOOST_CHECK_EQUAL( y[1], INFINITY );
319 BOOST_CHECK_CLOSE( y[2], (Real)0.5, tol );
320 BOOST_CHECK( y == z );
321
322 y = x.inverse(true);
323 z = x.pwUnaryTr( fo_inv0<Real>() );
324 BOOST_CHECK_CLOSE( y[0], (Real)-0.5, tol );
325 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
326 BOOST_CHECK_CLOSE( y[2], (Real)0.5, tol );
327 BOOST_CHECK( y == z );
328
329 x.set( 0, 2.0 );
330 y = x.normalized();
331 BOOST_CHECK_CLOSE( y[0], (Real)0.5, tol );
332 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
333 BOOST_CHECK_CLOSE( y[2], (Real)0.5, tol );
334
335 y = x.normalized( NORMPROB );
336 BOOST_CHECK_CLOSE( y[0], (Real)0.5, tol );
337 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
338 BOOST_CHECK_CLOSE( y[2], (Real)0.5, tol );
339
340 x.set( 0, -2.0 );
341 y = x.normalized( NORMLINF );
342 BOOST_CHECK_CLOSE( y[0], (Real)-1.0, tol );
343 BOOST_CHECK_CLOSE( y[1], (Real)0.0, tol );
344 BOOST_CHECK_CLOSE( y[2], (Real)1.0, tol );
345 }
346
347
348 BOOST_AUTO_TEST_CASE( UnaryOperationsTest ) {
349 Prob xorg(3);
350 xorg.set( 0, 2.0 );
351 xorg.set( 1, 0.0 );
352 xorg.set( 2, 1.0 );
353 Prob y(3);
354
355 Prob x = xorg;
356 BOOST_CHECK( x.setUniform() == Prob(3) );
357 BOOST_CHECK( x == Prob(3) );
358
359 y.set( 0, dai::exp(2.0) );
360 y.set( 1, 1.0 );
361 y.set( 2, dai::exp(1.0) );
362 x = xorg;
363 BOOST_CHECK_SMALL( dist( x.takeExp(), y, DISTL1 ), tol );
364 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
365 x = xorg;
366 BOOST_CHECK_SMALL( dist( x.pwUnaryOp( fo_exp<Real>() ), y, DISTL1 ), tol );
367 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
368
369 y.set( 0, dai::log(2.0) );
370 y.set( 1, -INFINITY );
371 y.set( 2, 0.0 );
372 x = xorg;
373 Prob z = x.takeLog();
374 BOOST_CHECK_CLOSE( z[0], y[0], tol );
375 // BOOST_CHECK_CLOSE( z[1], y[1], tol );
376 BOOST_CHECK_CLOSE( z[2], y[2], tol );
377 BOOST_CHECK( x == z );
378 x = xorg;
379 z = x.takeLog(false);
380 BOOST_CHECK_CLOSE( z[0], y[0], tol );
381 // BOOST_CHECK_CLOSE( z[1], y[1], tol );
382 BOOST_CHECK_CLOSE( z[2], y[2], tol );
383 BOOST_CHECK( x == z );
384 x = xorg;
385 z = x.pwUnaryOp( fo_log<Real>() );
386 BOOST_CHECK_CLOSE( z[0], y[0], tol );
387 // BOOST_CHECK_CLOSE( z[1], y[1], tol );
388 BOOST_CHECK_CLOSE( z[2], y[2], tol );
389 BOOST_CHECK( x == z );
390
391 y.set( 1, 0.0 );
392 x = xorg;
393 BOOST_CHECK_SMALL( dist( x.takeLog(true), y, DISTL1 ), tol );
394 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
395 x = xorg;
396 BOOST_CHECK_SMALL( dist( x.pwUnaryOp( fo_log0<Real>() ), y, DISTL1 ), tol );
397 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
398
399 y.set( 0, 2.0 / 3.0 );
400 y.set( 1, 0.0 / 3.0 );
401 y.set( 2, 1.0 / 3.0 );
402 x = xorg;
403 BOOST_CHECK_CLOSE( x.normalize(), (Real)3.0, tol );
404 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
405
406 x = xorg;
407 BOOST_CHECK_CLOSE( x.normalize( NORMPROB ), (Real)3.0, tol );
408 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
409
410 y.set( 0, 2.0 / 2.0 );
411 y.set( 1, 0.0 / 2.0 );
412 y.set( 2, 1.0 / 2.0 );
413 x = xorg;
414 BOOST_CHECK_CLOSE( x.normalize( NORMLINF ), (Real)2.0, tol );
415 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
416
417 xorg.set( 0, -2.0 );
418 y.set( 0, 2.0 );
419 y.set( 1, 0.0 );
420 y.set( 2, 1.0 );
421 x = xorg;
422 BOOST_CHECK( x.takeAbs() == y );
423 BOOST_CHECK( x == y );
424
425 for( size_t repeat = 0; repeat < 10000; repeat++ ) {
426 x.randomize();
427 for( size_t i = 0; i < x.size(); i++ ) {
428 BOOST_CHECK( x[i] < (Real)1.0 );
429 BOOST_CHECK( x[i] >= (Real)0.0 );
430 }
431 }
432 }
433
434
435 BOOST_AUTO_TEST_CASE( ScalarTransformationsTest ) {
436 Prob x(3);
437 x.set( 0, 2.0 );
438 x.set( 1, 0.0 );
439 x.set( 2, 1.0 );
440 Prob y(3);
441
442 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
443 BOOST_CHECK_SMALL( dist( (x + 1.0), y, DISTL1 ), tol );
444 y.set( 0, 0.0 ); y.set( 1, -2.0 ); y.set( 2, -1.0 );
445 BOOST_CHECK_SMALL( dist( (x + (-2.0)), y, DISTL1 ), tol );
446
447 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
448 BOOST_CHECK_SMALL( dist( (x - 1.0), y, DISTL1 ), tol );
449 y.set( 0, 4.0 ); y.set( 1, 2.0 ); y.set( 2, 3.0 );
450 BOOST_CHECK_SMALL( dist( (x - (-2.0)), y, DISTL1 ), tol );
451
452 BOOST_CHECK_SMALL( dist( (x * 1.0), x, DISTL1 ), tol );
453 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 2.0 );
454 BOOST_CHECK_SMALL( dist( (x * 2.0), y, DISTL1 ), tol );
455 y.set( 0, -1.0 ); y.set( 1, 0.0 ); y.set( 2, -0.5 );
456 BOOST_CHECK_SMALL( dist( (x * -0.5), y, DISTL1 ), tol );
457
458 BOOST_CHECK_SMALL( dist( (x / 1.0), x, DISTL1 ), tol );
459 y.set( 0, 1.0 ); y.set( 1, 0.0 ); y.set( 2, 0.5 );
460 BOOST_CHECK_SMALL( dist( (x / 2.0), y, DISTL1 ), tol );
461 y.set( 0, -4.0 ); y.set( 1, 0.0 ); y.set( 2, -2.0 );
462 BOOST_CHECK_SMALL( dist( (x / -0.5), y, DISTL1 ), tol );
463 BOOST_CHECK( (x / 0.0) == Prob(3, 0.0) );
464
465 BOOST_CHECK( (x ^ 1.0) == x );
466 BOOST_CHECK( (x ^ 0.0) == Prob(3, 1.0) );
467 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
468 BOOST_CHECK_SMALL( dist( (x ^ 2.0), y, DISTL1 ), tol );
469 y.set( 0, std::sqrt(2.0) ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
470 BOOST_CHECK_SMALL( dist( (x ^ 0.5), y, DISTL1 ), tol );
471 }
472
473
474 BOOST_AUTO_TEST_CASE( ScalarOperationsTest ) {
475 Prob xorg(3), x(3);
476 xorg.set( 0, 2.0 );
477 xorg.set( 1, 0.0 );
478 xorg.set( 2, 1.0 );
479 Prob y(3);
480
481 x = xorg;
482 BOOST_CHECK( x.fill( 1.0 ) == Prob(3, 1.0) );
483 BOOST_CHECK( x == Prob(3, 1.0) );
484 BOOST_CHECK( x.fill( 2.0 ) == Prob(3, 2.0) );
485 BOOST_CHECK( x == Prob(3, 2.0) );
486 BOOST_CHECK( x.fill( 0.0 ) == Prob(3, 0.0) );
487 BOOST_CHECK( x == Prob(3, 0.0) );
488
489 x = xorg;
490 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
491 BOOST_CHECK_SMALL( dist( (x += 1.0), y, DISTL1 ), tol );
492 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
493 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
494 BOOST_CHECK_SMALL( dist( (x += -2.0), y, DISTL1 ), tol );
495 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
496
497 x = xorg;
498 y.set( 0, 1.0 ); y.set( 1, -1.0 ); y.set( 2, 0.0 );
499 BOOST_CHECK_SMALL( dist( (x -= 1.0), y, DISTL1 ), tol );
500 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
501 y.set( 0, 3.0 ); y.set( 1, 1.0 ); y.set( 2, 2.0 );
502 BOOST_CHECK_SMALL( dist( (x -= -2.0), y, DISTL1 ), tol );
503 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
504
505 x = xorg;
506 BOOST_CHECK_SMALL( dist( (x *= 1.0), x, DISTL1 ), tol );
507 BOOST_CHECK_SMALL( dist( x, x, DISTL1 ), tol );
508 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 2.0 );
509 BOOST_CHECK_SMALL( dist( (x *= 2.0), y, DISTL1 ), tol );
510 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
511 y.set( 0, -1.0 ); y.set( 1, 0.0 ); y.set( 2, -0.5 );
512 BOOST_CHECK_SMALL( dist( (x *= -0.25), y, DISTL1 ), tol );
513 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
514
515 x = xorg;
516 BOOST_CHECK_SMALL( dist( (x /= 1.0), x, DISTL1 ), tol );
517 BOOST_CHECK_SMALL( dist( x, x, DISTL1 ), tol );
518 y.set( 0, 1.0 ); y.set( 1, 0.0 ); y.set( 2, 0.5 );
519 BOOST_CHECK_SMALL( dist( (x /= 2.0), y, DISTL1 ), tol );
520 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
521 y.set( 0, -4.0 ); y.set( 1, 0.0 ); y.set( 2, -2.0 );
522 BOOST_CHECK_SMALL( dist( (x /= -0.25), y, DISTL1 ), tol );
523 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
524 BOOST_CHECK( (x /= 0.0) == Prob(3, 0.0) );
525 BOOST_CHECK( x == Prob(3, 0.0) );
526
527 x = xorg;
528 BOOST_CHECK( (x ^= 1.0) == x );
529 BOOST_CHECK( x == x );
530 BOOST_CHECK( (x ^= 0.0) == Prob(3, 1.0) );
531 BOOST_CHECK( x == Prob(3, 1.0) );
532 x = xorg;
533 y.set( 0, 4.0 ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
534 BOOST_CHECK_SMALL( dist( (x ^= 2.0), y, DISTL1 ), tol );
535 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
536 y.set( 0, 2.0 ); y.set( 1, 0.0 ); y.set( 2, 1.0 );
537 BOOST_CHECK_SMALL( dist( (x ^= 0.5), y, DISTL1 ), tol );
538 BOOST_CHECK_SMALL( dist( x, y, DISTL1 ), tol );
539 }
540
541
542 BOOST_AUTO_TEST_CASE( VectorOperationsTest ) {
543 size_t N = 6;
544 Prob xorg(N), x(N);
545 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 );
546 Prob y(N);
547 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 );
548 Prob z(N), r(N);
549
550 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 );
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_SMALL( dist( x, z, DISTL1 ), tol );
556 x = xorg;
557 BOOST_CHECK( x.pwBinaryOp( y, std::plus<Real>() ) == r );
558 BOOST_CHECK( x == r );
559
560 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 );
561 x = xorg;
562 r = (x -= y);
563 for( size_t i = 0; i < N; i++ )
564 BOOST_CHECK_CLOSE( r[i], z[i], tol );
565 BOOST_CHECK_SMALL( dist( x, z, DISTL1 ), tol );
566 x = xorg;
567 BOOST_CHECK( x.pwBinaryOp( y, std::minus<Real>() ) == r );
568 BOOST_CHECK( x == r );
569
570 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 );
571 x = xorg;
572 r = (x *= y);
573 for( size_t i = 0; i < N; i++ )
574 BOOST_CHECK_CLOSE( r[i], z[i], tol );
575 BOOST_CHECK_SMALL( dist( x, z, DISTL1 ), tol );
576 x = xorg;
577 BOOST_CHECK( x.pwBinaryOp( y, std::multiplies<Real>() ) == r );
578 BOOST_CHECK( x == r );
579
580 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 );
581 x = xorg;
582 r = (x /= y);
583 for( size_t i = 0; i < N; i++ )
584 BOOST_CHECK_CLOSE( r[i], z[i], tol );
585 BOOST_CHECK_SMALL( dist( x, z, DISTL1 ), tol );
586 x = xorg;
587 BOOST_CHECK( x.pwBinaryOp( y, fo_divides0<Real>() ) == r );
588 BOOST_CHECK( x == r );
589
590 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, INFINITY ); /*z.set( 3, INFINITY );*/ z.set( 4, -1.0 ); z.set( 5, 1.0 );
591 x = xorg;
592 r = (x.divide( y ));
593 BOOST_CHECK_CLOSE( r[0], z[0], tol );
594 BOOST_CHECK_CLOSE( r[1], z[1], tol );
595 BOOST_CHECK_EQUAL( r[2], z[2] );
596 BOOST_CHECK( dai::isnan(r[3]) );
597 BOOST_CHECK_CLOSE( r[4], z[4], tol );
598 BOOST_CHECK_CLOSE( r[5], z[5], tol );
599 x.set( 3, 0.0 ); r.set( 3, 0.0 );
600 BOOST_CHECK( x == r );
601 x = xorg;
602 r = x.pwBinaryOp( y, std::divides<Real>() );
603 BOOST_CHECK_CLOSE( r[0], z[0], tol );
604 BOOST_CHECK_CLOSE( r[1], z[1], tol );
605 BOOST_CHECK_EQUAL( r[2], z[2] );
606 BOOST_CHECK( dai::isnan(r[3]) );
607 BOOST_CHECK_CLOSE( r[4], z[4], tol );
608 BOOST_CHECK_CLOSE( r[5], z[5], tol );
609 x.set( 3, 0.0 ); r.set( 3, 0.0 );
610 BOOST_CHECK( x == r );
611
612 z.set( 0, std::sqrt(2.0) ); z.set( 1, 0.0 ); z.set( 2, 1.0 ); z.set( 3, 1.0 ); z.set( 4, 0.25 ); z.set( 5, 27.0 );
613 x = xorg;
614 r = (x ^= y);
615 for( size_t i = 0; i < 6; i++ )
616 BOOST_CHECK_CLOSE( r[i], z[i], tol );
617 BOOST_CHECK( x == r );
618 x = xorg;
619 r = x.pwBinaryOp( y, fo_pow<Real>() );
620 for( size_t i = 0; i < 6; i++ )
621 BOOST_CHECK_CLOSE( r[i], z[i], tol );
622 BOOST_CHECK( x == r );
623 }
624
625
626 BOOST_AUTO_TEST_CASE( VectorTransformationsTest ) {
627 size_t N = 6;
628 Prob x(N);
629 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 );
630 Prob y(N);
631 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 );
632 Prob z(N), r(N);
633
634 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 );
635 r = x + y;
636 for( size_t i = 0; i < N; i++ )
637 BOOST_CHECK_CLOSE( r[i], z[i], tol );
638 z = x.pwBinaryTr( y, std::plus<Real>() );
639 BOOST_CHECK( r == z );
640
641 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 );
642 r = x - y;
643 for( size_t i = 0; i < N; i++ )
644 BOOST_CHECK_CLOSE( r[i], z[i], tol );
645 z = x.pwBinaryTr( y, std::minus<Real>() );
646 BOOST_CHECK( r == z );
647
648 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 );
649 r = x * y;
650 for( size_t i = 0; i < N; i++ )
651 BOOST_CHECK_CLOSE( r[i], z[i], tol );
652 z = x.pwBinaryTr( y, std::multiplies<Real>() );
653 BOOST_CHECK( r == z );
654
655 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 );
656 r = x / y;
657 for( size_t i = 0; i < N; i++ )
658 BOOST_CHECK_CLOSE( r[i], z[i], tol );
659 z = x.pwBinaryTr( y, fo_divides0<Real>() );
660 BOOST_CHECK( r == z );
661
662 z.set( 0, 4.0 ); z.set( 1, 0.0 ); z.set( 2, INFINITY ); /*z.set( 3, INFINITY );*/ z.set( 4, -1.0 ); z.set( 5, 1.0 );
663 r = x.divided_by( y );
664 BOOST_CHECK_CLOSE( r[0], z[0], tol );
665 BOOST_CHECK_CLOSE( r[1], z[1], tol );
666 BOOST_CHECK_EQUAL( r[2], z[2] );
667 BOOST_CHECK( dai::isnan(r[3]) );
668 BOOST_CHECK_CLOSE( r[4], z[4], tol );
669 BOOST_CHECK_CLOSE( r[5], z[5], tol );
670 z = x.pwBinaryTr( y, std::divides<Real>() );
671 BOOST_CHECK_CLOSE( r[0], z[0], tol );
672 BOOST_CHECK_CLOSE( r[1], z[1], tol );
673 BOOST_CHECK_EQUAL( r[2], z[2] );
674 BOOST_CHECK( dai::isnan(r[3]) );
675 BOOST_CHECK_CLOSE( r[4], z[4], tol );
676 BOOST_CHECK_CLOSE( r[5], z[5], tol );
677
678 z.set( 0, std::sqrt(2.0) ); z.set( 1, 0.0 ); z.set( 2, 1.0 ); z.set( 3, 1.0 ); z.set( 4, 0.25 ); z.set( 5, 27.0 );
679 r = x ^ y;
680 BOOST_CHECK_CLOSE( r[0], z[0], tol );
681 BOOST_CHECK_CLOSE( r[1], z[1], tol );
682 BOOST_CHECK_CLOSE( r[2], z[2], tol );
683 BOOST_CHECK_CLOSE( r[3], z[3], tol );
684 BOOST_CHECK_CLOSE( r[4], z[4], tol );
685 BOOST_CHECK_CLOSE( r[5], z[5], tol );
686 z = x.pwBinaryTr( y, fo_pow<Real>() );
687 BOOST_CHECK( r == z );
688 }
689
690
691 BOOST_AUTO_TEST_CASE( RelatedFunctionsTest ) {
692 Prob x(3), y(3), z(3);
693 x.set( 0, 0.2 );
694 x.set( 1, 0.8 );
695 x.set( 2, 0.0 );
696 y.set( 0, 0.0 );
697 y.set( 1, 0.6 );
698 y.set( 2, 0.4 );
699
700 z = min( x, y );
701 BOOST_CHECK_EQUAL( z[0], (Real)0.0 );
702 BOOST_CHECK_EQUAL( z[1], (Real)0.6 );
703 BOOST_CHECK_EQUAL( z[2], (Real)0.0 );
704 z = max( x, y );
705 BOOST_CHECK_EQUAL( z[0], (Real)0.2 );
706 BOOST_CHECK_EQUAL( z[1], (Real)0.8 );
707 BOOST_CHECK_EQUAL( z[2], (Real)0.4 );
708
709 BOOST_CHECK_CLOSE( dist( x, x, DISTL1 ), (Real)0.0, tol );
710 BOOST_CHECK_CLOSE( dist( y, y, DISTL1 ), (Real)0.0, tol );
711 BOOST_CHECK_CLOSE( dist( x, y, DISTL1 ), (Real)(0.2 + 0.2 + 0.4), tol );
712 BOOST_CHECK_CLOSE( dist( y, x, DISTL1 ), (Real)(0.2 + 0.2 + 0.4), tol );
713 BOOST_CHECK_CLOSE( dist( x, y, DISTL1 ), x.innerProduct( y, 0.0, std::plus<Real>(), fo_absdiff<Real>() ), tol );
714 BOOST_CHECK_CLOSE( dist( y, x, DISTL1 ), y.innerProduct( x, 0.0, std::plus<Real>(), fo_absdiff<Real>() ), tol );
715 BOOST_CHECK_CLOSE( dist( x, x, DISTLINF ), (Real)0.0, tol );
716 BOOST_CHECK_CLOSE( dist( y, y, DISTLINF ), (Real)0.0, tol );
717 BOOST_CHECK_CLOSE( dist( x, y, DISTLINF ), (Real)0.4, tol );
718 BOOST_CHECK_CLOSE( dist( y, x, DISTLINF ), (Real)0.4, tol );
719 BOOST_CHECK_CLOSE( dist( x, y, DISTLINF ), x.innerProduct( y, 0.0, fo_max<Real>(), fo_absdiff<Real>() ), tol );
720 BOOST_CHECK_CLOSE( dist( y, x, DISTLINF ), y.innerProduct( x, 0.0, fo_max<Real>(), fo_absdiff<Real>() ), tol );
721 BOOST_CHECK_CLOSE( dist( x, x, DISTTV ), (Real)0.0, tol );
722 BOOST_CHECK_CLOSE( dist( y, y, DISTTV ), (Real)0.0, tol );
723 BOOST_CHECK_CLOSE( dist( x, y, DISTTV ), (Real)(0.5 * (0.2 + 0.2 + 0.4)), tol );
724 BOOST_CHECK_CLOSE( dist( y, x, DISTTV ), (Real)(0.5 * (0.2 + 0.2 + 0.4)), tol );
725 BOOST_CHECK_CLOSE( dist( x, y, DISTTV ), x.innerProduct( y, 0.0, std::plus<Real>(), fo_absdiff<Real>() ) / 2.0, tol );
726 BOOST_CHECK_CLOSE( dist( y, x, DISTTV ), y.innerProduct( x, 0.0, std::plus<Real>(), fo_absdiff<Real>() ) / 2.0, tol );
727 BOOST_CHECK_CLOSE( dist( x, x, DISTKL ), (Real)0.0, tol );
728 BOOST_CHECK_CLOSE( dist( y, y, DISTKL ), (Real)0.0, tol );
729 BOOST_CHECK_EQUAL( dist( x, y, DISTKL ), INFINITY );
730 BOOST_CHECK_EQUAL( dist( y, x, DISTKL ), INFINITY );
731 BOOST_CHECK_EQUAL( dist( x, y, DISTKL ), x.innerProduct( y, 0.0, std::plus<Real>(), fo_KL<Real>() ) );
732 BOOST_CHECK_EQUAL( dist( y, x, DISTKL ), y.innerProduct( x, 0.0, std::plus<Real>(), fo_KL<Real>() ) );
733 BOOST_CHECK_CLOSE( dist( x, x, DISTHEL ), (Real)0.0, tol );
734 BOOST_CHECK_CLOSE( dist( y, y, DISTHEL ), (Real)0.0, tol );
735 BOOST_CHECK_CLOSE( dist( x, y, DISTHEL ), (Real)(0.5 * (0.2 + dai::pow(std::sqrt(0.8) - std::sqrt(0.6), 2.0) + 0.4)), tol );
736 BOOST_CHECK_CLOSE( dist( y, x, DISTHEL ), (Real)(0.5 * (0.2 + dai::pow(std::sqrt(0.8) - std::sqrt(0.6), 2.0) + 0.4)), tol );
737 BOOST_CHECK_CLOSE( dist( x, y, DISTHEL ), x.innerProduct( y, 0.0, std::plus<Real>(), fo_Hellinger<Real>() ) / 2.0, tol );
738 BOOST_CHECK_CLOSE( dist( y, x, DISTHEL ), y.innerProduct( x, 0.0, std::plus<Real>(), fo_Hellinger<Real>() ) / 2.0, tol );
739 x.set( 1, 0.7 ); x.set( 2, 0.1 );
740 y.set( 0, 0.1 ); y.set( 1, 0.5 );
741 BOOST_CHECK_CLOSE( dist( x, y, DISTKL ), (Real)(0.2 * dai::log(0.2 / 0.1) + 0.7 * dai::log(0.7 / 0.5) + 0.1 * dai::log(0.1 / 0.4)), tol );
742 BOOST_CHECK_CLOSE( dist( y, x, DISTKL ), (Real)(0.1 * dai::log(0.1 / 0.2) + 0.5 * dai::log(0.5 / 0.7) + 0.4 * dai::log(0.4 / 0.1)), tol );
743 BOOST_CHECK_CLOSE( dist( x, y, DISTKL ), x.innerProduct( y, 0.0, std::plus<Real>(), fo_KL<Real>() ), tol );
744 BOOST_CHECK_CLOSE( dist( y, x, DISTKL ), y.innerProduct( x, 0.0, std::plus<Real>(), fo_KL<Real>() ), tol );
745
746 Prob xx(4), yy(4);
747 for( size_t i = 0; i < 3; i++ ) {
748 xx.set( i, x[i] );
749 yy.set( i, y[i] );
750 }
751 std::stringstream ss;
752 ss << xx;
753 std::string s;
754 std::getline( ss, s );
755 #ifdef DAI_SPARSE
756 BOOST_CHECK_EQUAL( s, std::string("(size:4, def:0.25, 0:0.2, 1:0.7, 2:0.1)") );
757 #else
758 BOOST_CHECK_EQUAL( s, std::string("(0.2, 0.7, 0.1, 0.25)") );
759 #endif
760 std::stringstream ss2;
761 ss2 << yy;
762 std::getline( ss2, s );
763 #ifdef DAI_SPARSE
764 BOOST_CHECK_EQUAL( s, std::string("(size:4, def:0.25, 0:0.1, 1:0.5, 2:0.4)") );
765 #else
766 BOOST_CHECK_EQUAL( s, std::string("(0.1, 0.5, 0.4, 0.25)") );
767 #endif
768
769 z = min( x, y );
770 BOOST_CHECK_EQUAL( z[0], (Real)0.1 );
771 BOOST_CHECK_EQUAL( z[1], (Real)0.5 );
772 BOOST_CHECK_EQUAL( z[2], (Real)0.1 );
773 z = max( x, y );
774 BOOST_CHECK_EQUAL( z[0], (Real)0.2 );
775 BOOST_CHECK_EQUAL( z[1], (Real)0.7 );
776 BOOST_CHECK_EQUAL( z[2], (Real)0.4 );
777
778 BOOST_CHECK_CLOSE( x.innerProduct( y, 0.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
779 BOOST_CHECK_CLOSE( y.innerProduct( x, 0.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
780 BOOST_CHECK_CLOSE( x.innerProduct( y, 1.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(1.0 + 0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
781 BOOST_CHECK_CLOSE( y.innerProduct( x, 1.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(1.0 + 0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
782 BOOST_CHECK_CLOSE( x.innerProduct( y, -1.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(-1.0 + 0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
783 BOOST_CHECK_CLOSE( y.innerProduct( x, -1.0, std::plus<Real>(), std::multiplies<Real>() ), (Real)(-1.0 + 0.2*0.1 + 0.7*0.5 + 0.1*0.4), tol );
784 }