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