1 /** 2 * 3 * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_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 <gumtest/AgrumTestSuite.h> 23 #include <gumtest/testsuite_utils.h> 24 #include <iostream> 25 26 #include <agrum/tools/core/math/gammaLog2.h> 27 #include <agrum/tools/database/DBTranslator4LabelizedVariable.h> 28 #include <agrum/tools/database/DBTranslatorSet.h> 29 #include <agrum/BN/learning/aprioris/aprioriNoApriori.h> 30 #include <agrum/BN/learning/scores_and_tests/scoreK2.h> 31 32 namespace gum_tests { 33 34 class ScoreK2TestSuite: public CxxTest::TestSuite { 35 private: 36 gum::GammaLog2 _gammalog2_; 37 bool _gum_destructor_increased_{false}; 38 setUp()39 void setUp() {} 40 tearDown()41 void tearDown() { 42 if (!_gum_destructor_increased_) { 43 GUM_DESTRUCTOR(GammaLog2); 44 _gum_destructor_increased_ = true; 45 } 46 } 47 _score_(const std::vector<double> & N_ijk,const std::vector<double> & N_ij)48 double _score_(const std::vector< double >& N_ijk, const std::vector< double >& N_ij) const { 49 double score = 0.0; 50 51 if (!N_ij.empty()) { 52 const double ri = double(N_ijk.size() / N_ij.size()); 53 score = N_ij.size() * _gammalog2_(ri); 54 55 for (const auto n_ij: N_ij) { 56 score -= _gammalog2_(n_ij + ri); 57 } 58 for (const auto n_ijk: N_ijk) { 59 score += _gammalog2_(n_ijk + 1); 60 } 61 } else { 62 const double ri = double(N_ijk.size()); 63 score = _gammalog2_(ri); 64 double N = 0; 65 for (const auto n_ijk: N_ijk) { 66 score += _gammalog2_(n_ijk + 1); 67 N += n_ijk; 68 } 69 score -= _gammalog2_(N + ri); 70 } 71 72 return score; 73 } 74 75 _equal_(const double x,const double y)76 bool _equal_(const double x, const double y) const { 77 double dev = x >= y ? (x - y) / x : (y - x) / y; 78 if (dev < 0) dev = -dev; 79 return dev <= TS_GUM_SMALL_ERROR; 80 } 81 82 83 public: _test_no_range_no_nodeId2col()84 void _test_no_range_no_nodeId2col() { 85 // create the translator set 86 gum::LabelizedVariable var("X1", "", 0); 87 var.addLabel("0"); 88 var.addLabel("1"); 89 var.addLabel("2"); 90 91 gum::learning::DBTranslatorSet<> trans_set; 92 { 93 const std::vector< std::string > miss; 94 gum::learning::DBTranslator4LabelizedVariable<> translator(var, miss); 95 std::vector< std::string > names{"A", "B", "C", "D", "E", "F"}; 96 97 for (std::size_t i = std::size_t(0); i < names.size(); ++i) { 98 translator.setVariableName(names[i]); 99 trans_set.insertTranslator(translator, i); 100 } 101 } 102 103 // create the database 104 gum::learning::DatabaseTable<> database(trans_set); 105 std::vector< std::string > row0{"0", "1", "0", "2", "1", "1"}; 106 std::vector< std::string > row1{"1", "2", "0", "1", "2", "2"}; 107 std::vector< std::string > row2{"2", "1", "0", "1", "1", "0"}; 108 std::vector< std::string > row3{"1", "0", "0", "0", "0", "0"}; 109 std::vector< std::string > row4{"0", "0", "0", "1", "1", "1"}; 110 for (int i = 0; i < 1000; ++i) 111 database.insertRow(row0); 112 for (int i = 0; i < 50; ++i) 113 database.insertRow(row1); 114 for (int i = 0; i < 75; ++i) 115 database.insertRow(row2); 116 for (int i = 0; i < 75; ++i) 117 database.insertRow(row3); 118 for (int i = 0; i < 200; ++i) 119 database.insertRow(row4); 120 121 // create the parser 122 gum::learning::DBRowGeneratorSet<> genset; 123 gum::learning::DBRowGeneratorParser<> parser(database.handler(), genset); 124 125 gum::learning::AprioriNoApriori<> apriori(database); 126 gum::learning::ScoreK2<> score(parser, apriori); 127 128 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible( 129 gum::learning::AprioriNoApriori<>::type::type)); 130 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible(apriori)); 131 TS_GUM_ASSERT_THROWS_NOTHING( 132 score.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 133 TS_GUM_ASSERT_THROWS_NOTHING(score.isAprioriCompatible(apriori)); 134 135 gum::NodeId node0 = 0; 136 gum::NodeId node1 = 1; 137 gum::NodeId node3 = 3; 138 std::vector< gum::NodeId > cond_empty; 139 std::vector< gum::NodeId > cond2{node1}; 140 std::vector< gum::NodeId > cond3{node3}; 141 142 gum::learning::IdCondSet<> idset1(node0, cond_empty); // #3,#0 143 gum::learning::IdCondSet<> idset2(node0, cond2, true); // #9,#3 144 gum::learning::IdCondSet<> idset3(node0, cond3, true); // #9,#3 145 146 // idset1: node0 | emptyset 147 std::vector< double > N_ijk_1{1200.0, 125.0, 75.0}; 148 std::vector< double > N_ij_1; 149 double xscore_1 = _score_(N_ijk_1, N_ij_1); 150 TS_ASSERT(_equal_(xscore_1, score.score(node0))) 151 152 // idset2: node0 | node1 153 std::vector< double > N_ijk_2{200, 75, 0, 1000, 0, 75, 0, 50, 0}; 154 std::vector< double > N_ij_2{275, 1075, 50}; 155 double xscore_2 = _score_(N_ijk_2, N_ij_2); 156 TS_ASSERT(_equal_(xscore_2, score.score(node0, cond2))) 157 158 // idset3: node0 | node3 159 std::vector< double > N_ijk_3{0, 75, 0, 200, 50, 75, 1000, 0, 0}; 160 std::vector< double > N_ij_3{75, 325, 1000}; 161 double xscore_3 = _score_(N_ijk_3, N_ij_3); 162 TS_ASSERT(_equal_(xscore_3, score.score(node0, cond3))) 163 164 gum::learning::ScoreK2<> score2(score); 165 TS_GUM_ASSERT_THROWS_NOTHING( 166 score2.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 167 TS_GUM_ASSERT_THROWS_NOTHING(score2.isAprioriCompatible(apriori)); 168 169 TS_ASSERT(_equal_(xscore_1, score2.score(node0))) 170 TS_ASSERT(_equal_(xscore_2, score2.score(node0, cond2))) 171 TS_ASSERT(_equal_(xscore_3, score2.score(node0, cond3))) 172 173 gum::learning::ScoreK2<> score3(std::move(score2)); 174 TS_GUM_ASSERT_THROWS_NOTHING( 175 score3.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 176 TS_GUM_ASSERT_THROWS_NOTHING(score3.isAprioriCompatible(apriori)); 177 178 TS_ASSERT(_equal_(xscore_1, score3.score(node0))) 179 TS_ASSERT(_equal_(xscore_2, score3.score(node0, cond2))) 180 TS_ASSERT(_equal_(xscore_3, score3.score(node0, cond3))) 181 182 gum::learning::ScoreK2<>* score4 = score3.clone(); 183 TS_GUM_ASSERT_THROWS_NOTHING( 184 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 185 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 186 187 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 188 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 189 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 190 191 score4->operator=(score); 192 TS_GUM_ASSERT_THROWS_NOTHING( 193 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 194 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 195 196 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 197 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 198 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 199 200 score4->operator=(std::move(score)); 201 TS_GUM_ASSERT_THROWS_NOTHING( 202 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 203 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 204 205 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 206 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 207 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 208 209 delete score4; 210 } 211 212 _test_no_range_has_nodeId2col()213 void _test_no_range_has_nodeId2col() { 214 // create the translator set 215 gum::LabelizedVariable var("X1", "", 0); 216 var.addLabel("0"); 217 var.addLabel("1"); 218 var.addLabel("2"); 219 220 gum::learning::DBTranslatorSet<> trans_set; 221 { 222 const std::vector< std::string > miss; 223 gum::learning::DBTranslator4LabelizedVariable<> translator(var, miss); 224 std::vector< std::string > names{"A", "B", "C", "D", "E", "F"}; 225 226 for (std::size_t i = std::size_t(0); i < names.size(); ++i) { 227 translator.setVariableName(names[i]); 228 trans_set.insertTranslator(translator, i); 229 } 230 } 231 232 // create the database 233 gum::learning::DatabaseTable<> database(trans_set); 234 std::vector< std::string > row0{"0", "1", "0", "2", "1", "1"}; 235 std::vector< std::string > row1{"1", "2", "0", "1", "2", "2"}; 236 std::vector< std::string > row2{"2", "1", "0", "1", "1", "0"}; 237 std::vector< std::string > row3{"1", "0", "0", "0", "0", "0"}; 238 std::vector< std::string > row4{"0", "0", "0", "1", "1", "1"}; 239 for (int i = 0; i < 1000; ++i) 240 database.insertRow(row0); 241 for (int i = 0; i < 50; ++i) 242 database.insertRow(row1); 243 for (int i = 0; i < 75; ++i) 244 database.insertRow(row2); 245 for (int i = 0; i < 75; ++i) 246 database.insertRow(row3); 247 for (int i = 0; i < 200; ++i) 248 database.insertRow(row4); 249 250 // create the parser 251 gum::learning::DBRowGeneratorSet<> genset; 252 gum::learning::DBRowGeneratorParser<> parser(database.handler(), genset); 253 254 gum::Bijection< gum::NodeId, std::size_t > nodeId2columns; 255 gum::NodeId node0 = 0; 256 gum::NodeId node1 = 1; 257 gum::NodeId node2 = 2; 258 gum::NodeId node3 = 3; 259 gum::NodeId node4 = 4; 260 gum::NodeId node5 = 5; 261 nodeId2columns.insert(node0, std::size_t(4)); 262 nodeId2columns.insert(node1, std::size_t(3)); 263 nodeId2columns.insert(node2, std::size_t(0)); 264 nodeId2columns.insert(node3, std::size_t(2)); 265 nodeId2columns.insert(node4, std::size_t(5)); 266 nodeId2columns.insert(node5, std::size_t(1)); 267 268 gum::learning::AprioriNoApriori<> apriori(database, nodeId2columns); 269 gum::learning::ScoreK2<> score(parser, apriori, nodeId2columns); 270 271 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible( 272 gum::learning::AprioriNoApriori<>::type::type)); 273 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible(apriori)); 274 TS_GUM_ASSERT_THROWS_NOTHING( 275 score.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 276 TS_GUM_ASSERT_THROWS_NOTHING(score.isAprioriCompatible(apriori)); 277 278 std::vector< gum::NodeId > cond_empty; 279 std::vector< gum::NodeId > cond2{node5}; 280 std::vector< gum::NodeId > cond3{node1}; 281 282 gum::learning::IdCondSet<> idset1(node2, cond_empty); // #3,#0 283 gum::learning::IdCondSet<> idset2(node2, cond2, true); // #9,#3 284 gum::learning::IdCondSet<> idset3(node2, cond3, true); // #9,#3 285 286 // idset1: node2 | emptyset 287 std::vector< double > N_ijk_1{1200.0, 125.0, 75.0}; 288 std::vector< double > N_ij_1; 289 double xscore_1 = _score_(N_ijk_1, N_ij_1); 290 TS_ASSERT(_equal_(xscore_1, score.score(node2))) 291 292 293 // idset2: node2 | node5 294 std::vector< double > N_ijk_2{200, 75, 0, 1000, 0, 75, 0, 50, 0}; 295 std::vector< double > N_ij_2{275, 1075, 50}; 296 double xscore_2 = _score_(N_ijk_2, N_ij_2); 297 TS_ASSERT(_equal_(xscore_2, score.score(node2, cond2))) 298 299 // idset3: node2 | node1 300 std::vector< double > N_ijk_3{0, 75, 0, 200, 50, 75, 1000, 0, 0}; 301 std::vector< double > N_ij_3{75, 325, 1000}; 302 double xscore_3 = _score_(N_ijk_3, N_ij_3); 303 TS_ASSERT(_equal_(xscore_3, score.score(node2, cond3))) 304 305 306 gum::learning::ScoreK2<> score2(score); 307 TS_GUM_ASSERT_THROWS_NOTHING( 308 score2.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 309 TS_GUM_ASSERT_THROWS_NOTHING(score2.isAprioriCompatible(apriori)); 310 311 TS_ASSERT(_equal_(xscore_1, score2.score(node2))) 312 TS_ASSERT(_equal_(xscore_2, score2.score(node2, cond2))) 313 TS_ASSERT(_equal_(xscore_3, score2.score(node2, cond3))) 314 315 gum::learning::ScoreK2<> score3(std::move(score2)); 316 TS_GUM_ASSERT_THROWS_NOTHING( 317 score3.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 318 TS_GUM_ASSERT_THROWS_NOTHING(score3.isAprioriCompatible(apriori)); 319 320 TS_ASSERT(_equal_(xscore_1, score3.score(node2))) 321 TS_ASSERT(_equal_(xscore_2, score3.score(node2, cond2))) 322 TS_ASSERT(_equal_(xscore_3, score3.score(node2, cond3))) 323 324 gum::learning::ScoreK2<>* score4 = score3.clone(); 325 TS_GUM_ASSERT_THROWS_NOTHING( 326 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 327 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 328 329 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 330 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 331 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 332 333 score4->operator=(score); 334 TS_GUM_ASSERT_THROWS_NOTHING( 335 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 336 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 337 338 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 339 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 340 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 341 342 score4->operator=(std::move(score)); 343 TS_GUM_ASSERT_THROWS_NOTHING( 344 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 345 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 346 347 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 348 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 349 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 350 351 delete score4; 352 } 353 354 _test_has_range_no_nodeId2col()355 void _test_has_range_no_nodeId2col() { 356 // create the translator set 357 gum::LabelizedVariable var("X1", "", 0); 358 var.addLabel("0"); 359 var.addLabel("1"); 360 var.addLabel("2"); 361 362 gum::learning::DBTranslatorSet<> trans_set; 363 { 364 const std::vector< std::string > miss; 365 gum::learning::DBTranslator4LabelizedVariable<> translator(var, miss); 366 std::vector< std::string > names{"A", "B", "C", "D", "E", "F"}; 367 368 for (std::size_t i = std::size_t(0); i < names.size(); ++i) { 369 translator.setVariableName(names[i]); 370 trans_set.insertTranslator(translator, i); 371 } 372 } 373 374 // create the database 375 gum::learning::DatabaseTable<> database(trans_set); 376 std::vector< std::string > row0{"0", "1", "0", "2", "1", "1"}; 377 std::vector< std::string > row1{"1", "2", "0", "1", "2", "2"}; 378 std::vector< std::string > row2{"2", "1", "0", "1", "1", "0"}; 379 std::vector< std::string > row3{"1", "0", "0", "0", "0", "0"}; 380 std::vector< std::string > row4{"0", "0", "0", "1", "1", "1"}; 381 for (int i = 0; i < 1000; ++i) 382 database.insertRow(row0); 383 for (int i = 0; i < 50; ++i) 384 database.insertRow(row1); 385 for (int i = 0; i < 75; ++i) 386 database.insertRow(row2); 387 for (int i = 0; i < 75; ++i) 388 database.insertRow(row3); 389 for (int i = 0; i < 200; ++i) 390 database.insertRow(row4); 391 392 // create the parser 393 gum::learning::DBRowGeneratorSet<> genset; 394 gum::learning::DBRowGeneratorParser<> parser(database.handler(), genset); 395 396 std::vector< std::pair< std::size_t, std::size_t > > ranges{{800, 1000}, {1050, 1400}}; 397 398 gum::learning::AprioriNoApriori<> apriori(database); 399 gum::learning::ScoreK2<> score(parser, apriori, ranges); 400 401 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible( 402 gum::learning::AprioriNoApriori<>::type::type)); 403 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible(apriori)); 404 TS_GUM_ASSERT_THROWS_NOTHING( 405 score.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 406 TS_GUM_ASSERT_THROWS_NOTHING(score.isAprioriCompatible(apriori)); 407 408 gum::NodeId node0 = 0; 409 gum::NodeId node1 = 1; 410 gum::NodeId node3 = 3; 411 std::vector< gum::NodeId > cond_empty; 412 std::vector< gum::NodeId > cond2{node1}; 413 std::vector< gum::NodeId > cond3{node3}; 414 415 gum::learning::IdCondSet<> idset1(node0, cond_empty); // #3,#0 416 gum::learning::IdCondSet<> idset2(node0, cond2, true); // #9,#3 417 gum::learning::IdCondSet<> idset3(node0, cond3, true); // #9,#3 418 419 // idset1: node0 | emptyset 420 std::vector< double > N_ijk_1{400.0, 75.0, 75.0}; 421 std::vector< double > N_ij_1; 422 double xscore_1 = _score_(N_ijk_1, N_ij_1); 423 TS_ASSERT(_equal_(xscore_1, score.score(node0))) 424 425 // idset2: node0 | node1 426 std::vector< double > N_ijk_2{200, 75, 0, 200, 0, 75, 0, 0, 0}; 427 std::vector< double > N_ij_2{275, 275, 0}; 428 double xscore_2 = _score_(N_ijk_2, N_ij_2); 429 TS_ASSERT(_equal_(xscore_2, score.score(node0, cond2))) 430 431 // idset3: node0 | node3 432 std::vector< double > N_ijk_3{0, 75, 0, 200, 0, 75, 200, 0, 0}; 433 std::vector< double > N_ij_3{75, 275, 200}; 434 double xscore_3 = _score_(N_ijk_3, N_ij_3); 435 TS_ASSERT(_equal_(xscore_3, score.score(node0, cond3))) 436 437 gum::learning::ScoreK2<> score2(score); 438 TS_GUM_ASSERT_THROWS_NOTHING( 439 score2.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 440 TS_GUM_ASSERT_THROWS_NOTHING(score2.isAprioriCompatible(apriori)); 441 442 TS_ASSERT(_equal_(xscore_1, score2.score(node0))) 443 TS_ASSERT(_equal_(xscore_2, score2.score(node0, cond2))) 444 TS_ASSERT(_equal_(xscore_3, score2.score(node0, cond3))) 445 446 gum::learning::ScoreK2<> score3(std::move(score2)); 447 TS_GUM_ASSERT_THROWS_NOTHING( 448 score3.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 449 TS_GUM_ASSERT_THROWS_NOTHING(score3.isAprioriCompatible(apriori)); 450 451 TS_ASSERT(_equal_(xscore_1, score3.score(node0))) 452 TS_ASSERT(_equal_(xscore_2, score3.score(node0, cond2))) 453 TS_ASSERT(_equal_(xscore_3, score3.score(node0, cond3))) 454 455 gum::learning::ScoreK2<>* score4 = score3.clone(); 456 TS_GUM_ASSERT_THROWS_NOTHING( 457 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 458 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 459 460 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 461 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 462 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 463 464 score4->operator=(score); 465 TS_GUM_ASSERT_THROWS_NOTHING( 466 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 467 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 468 469 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 470 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 471 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 472 473 score4->operator=(std::move(score)); 474 TS_GUM_ASSERT_THROWS_NOTHING( 475 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 476 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 477 478 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 479 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 480 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 481 482 delete score4; 483 } 484 485 _test_has_range_has_nodeId2col()486 void _test_has_range_has_nodeId2col() { 487 // create the translator set 488 gum::LabelizedVariable var("X1", "", 0); 489 var.addLabel("0"); 490 var.addLabel("1"); 491 var.addLabel("2"); 492 493 gum::learning::DBTranslatorSet<> trans_set; 494 { 495 const std::vector< std::string > miss; 496 gum::learning::DBTranslator4LabelizedVariable<> translator(var, miss); 497 std::vector< std::string > names{"A", "B", "C", "D", "E", "F"}; 498 499 for (std::size_t i = std::size_t(0); i < names.size(); ++i) { 500 translator.setVariableName(names[i]); 501 trans_set.insertTranslator(translator, i); 502 } 503 } 504 505 // create the database 506 gum::learning::DatabaseTable<> database(trans_set); 507 std::vector< std::string > row0{"0", "1", "0", "2", "1", "1"}; 508 std::vector< std::string > row1{"1", "2", "0", "1", "2", "2"}; 509 std::vector< std::string > row2{"2", "1", "0", "1", "1", "0"}; 510 std::vector< std::string > row3{"1", "0", "0", "0", "0", "0"}; 511 std::vector< std::string > row4{"0", "0", "0", "1", "1", "1"}; 512 for (int i = 0; i < 1000; ++i) 513 database.insertRow(row0); 514 for (int i = 0; i < 50; ++i) 515 database.insertRow(row1); 516 for (int i = 0; i < 75; ++i) 517 database.insertRow(row2); 518 for (int i = 0; i < 75; ++i) 519 database.insertRow(row3); 520 for (int i = 0; i < 200; ++i) 521 database.insertRow(row4); 522 523 // create the parser 524 gum::learning::DBRowGeneratorSet<> genset; 525 gum::learning::DBRowGeneratorParser<> parser(database.handler(), genset); 526 527 std::vector< std::pair< std::size_t, std::size_t > > ranges{{800, 1000}, {1050, 1400}}; 528 529 gum::Bijection< gum::NodeId, std::size_t > nodeId2columns; 530 gum::NodeId node0 = 0; 531 gum::NodeId node1 = 1; 532 gum::NodeId node2 = 2; 533 gum::NodeId node3 = 3; 534 gum::NodeId node4 = 4; 535 gum::NodeId node5 = 5; 536 nodeId2columns.insert(node0, std::size_t(4)); 537 nodeId2columns.insert(node1, std::size_t(3)); 538 nodeId2columns.insert(node2, std::size_t(0)); 539 nodeId2columns.insert(node3, std::size_t(2)); 540 nodeId2columns.insert(node4, std::size_t(5)); 541 nodeId2columns.insert(node5, std::size_t(1)); 542 543 gum::learning::AprioriNoApriori<> apriori(database, nodeId2columns); 544 gum::learning::ScoreK2<> score(parser, apriori, ranges, nodeId2columns); 545 546 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible( 547 gum::learning::AprioriNoApriori<>::type::type)); 548 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible(apriori)); 549 TS_GUM_ASSERT_THROWS_NOTHING( 550 score.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 551 TS_GUM_ASSERT_THROWS_NOTHING(score.isAprioriCompatible(apriori)); 552 553 std::vector< gum::NodeId > cond_empty; 554 std::vector< gum::NodeId > cond2{node5}; 555 std::vector< gum::NodeId > cond3{node1}; 556 557 gum::learning::IdCondSet<> idset1(node2, cond_empty); // #3,#0 558 gum::learning::IdCondSet<> idset2(node2, cond2, true); // #9,#3 559 gum::learning::IdCondSet<> idset3(node2, cond3, true); // #9,#3 560 561 // idset1: node2 | emptyset 562 std::vector< double > N_ijk_1{400.0, 75.0, 75.0}; 563 std::vector< double > N_ij_1; 564 double xscore_1 = _score_(N_ijk_1, N_ij_1); 565 TS_ASSERT(_equal_(xscore_1, score.score(node2))) 566 567 568 // idset2: node2 | node5 569 std::vector< double > N_ijk_2{200, 75, 0, 200, 0, 75, 0, 0, 0}; 570 std::vector< double > N_ij_2{275, 275, 0}; 571 double xscore_2 = _score_(N_ijk_2, N_ij_2); 572 TS_ASSERT(_equal_(xscore_2, score.score(node2, cond2))) 573 574 // idset3: node2 | node1 575 std::vector< double > N_ijk_3{0, 75, 0, 200, 0, 75, 200, 0, 0}; 576 std::vector< double > N_ij_3{75, 275, 200}; 577 double xscore_3 = _score_(N_ijk_3, N_ij_3); 578 TS_ASSERT(_equal_(xscore_3, score.score(node2, cond3))) 579 580 581 gum::learning::ScoreK2<> score2(score); 582 TS_GUM_ASSERT_THROWS_NOTHING( 583 score2.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 584 TS_GUM_ASSERT_THROWS_NOTHING(score2.isAprioriCompatible(apriori)); 585 586 TS_ASSERT(_equal_(xscore_1, score2.score(node2))) 587 TS_ASSERT(_equal_(xscore_2, score2.score(node2, cond2))) 588 TS_ASSERT(_equal_(xscore_3, score2.score(node2, cond3))) 589 590 gum::learning::ScoreK2<> score3(std::move(score2)); 591 TS_GUM_ASSERT_THROWS_NOTHING( 592 score3.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 593 TS_GUM_ASSERT_THROWS_NOTHING(score3.isAprioriCompatible(apriori)); 594 595 TS_ASSERT(_equal_(xscore_1, score3.score(node2))) 596 TS_ASSERT(_equal_(xscore_2, score3.score(node2, cond2))) 597 TS_ASSERT(_equal_(xscore_3, score3.score(node2, cond3))) 598 599 gum::learning::ScoreK2<>* score4 = score3.clone(); 600 TS_GUM_ASSERT_THROWS_NOTHING( 601 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 602 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 603 604 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 605 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 606 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 607 608 score4->operator=(score); 609 TS_GUM_ASSERT_THROWS_NOTHING( 610 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 611 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 612 613 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 614 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 615 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 616 617 score4->operator=(std::move(score)); 618 TS_GUM_ASSERT_THROWS_NOTHING( 619 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 620 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 621 622 TS_ASSERT(_equal_(xscore_1, score4->score(node2))) 623 TS_ASSERT(_equal_(xscore_2, score4->score(node2, cond2))) 624 TS_ASSERT(_equal_(xscore_3, score4->score(node2, cond3))) 625 626 delete score4; 627 } 628 629 test_multicore()630 void test_multicore() { 631 // create the translator set 632 gum::LabelizedVariable var("X1", "", 0); 633 var.addLabel("0"); 634 var.addLabel("1"); 635 var.addLabel("2"); 636 637 gum::learning::DBTranslatorSet<> trans_set; 638 { 639 const std::vector< std::string > miss; 640 gum::learning::DBTranslator4LabelizedVariable<> translator(var, miss); 641 std::vector< std::string > names{"A", "B", "C", "D", "E", "F"}; 642 643 for (std::size_t i = std::size_t(0); i < names.size(); ++i) { 644 translator.setVariableName(names[i]); 645 trans_set.insertTranslator(translator, i); 646 } 647 } 648 649 // create the database 650 gum::learning::DatabaseTable<> database(trans_set); 651 std::vector< std::string > row0{"0", "1", "0", "2", "1", "1"}; 652 std::vector< std::string > row1{"1", "2", "0", "1", "2", "2"}; 653 std::vector< std::string > row2{"2", "1", "0", "1", "1", "0"}; 654 std::vector< std::string > row3{"1", "0", "0", "0", "0", "0"}; 655 std::vector< std::string > row4{"0", "0", "0", "1", "1", "1"}; 656 for (int i = 0; i < 1000; ++i) 657 database.insertRow(row0); 658 for (int i = 0; i < 50; ++i) 659 database.insertRow(row1); 660 for (int i = 0; i < 75; ++i) 661 database.insertRow(row2); 662 for (int i = 0; i < 75; ++i) 663 database.insertRow(row3); 664 for (int i = 0; i < 200; ++i) 665 database.insertRow(row4); 666 667 // create the parser 668 gum::learning::DBRowGeneratorSet<> genset; 669 gum::learning::DBRowGeneratorParser<> parser(database.handler(), genset); 670 671 std::vector< std::pair< std::size_t, std::size_t > > ranges{{800, 1000}, {1050, 1400}}; 672 673 gum::learning::AprioriNoApriori<> apriori(database); 674 for (std::size_t i = std::size_t(1); i < std::size_t(24); ++i) { 675 gum::learning::ScoreK2<> score(parser, apriori, ranges); 676 score.setMaxNbThreads(i); 677 678 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible( 679 gum::learning::AprioriNoApriori<>::type::type)); 680 TS_GUM_ASSERT_THROWS_NOTHING(gum::learning::ScoreK2<>::isAprioriCompatible(apriori)); 681 TS_GUM_ASSERT_THROWS_NOTHING( 682 score.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 683 TS_GUM_ASSERT_THROWS_NOTHING(score.isAprioriCompatible(apriori)); 684 685 gum::NodeId node0 = 0; 686 gum::NodeId node1 = 1; 687 gum::NodeId node3 = 3; 688 std::vector< gum::NodeId > cond_empty; 689 std::vector< gum::NodeId > cond2{node1}; 690 std::vector< gum::NodeId > cond3{node3}; 691 692 gum::learning::IdCondSet<> idset1(node0, cond_empty); // #3,#0 693 gum::learning::IdCondSet<> idset2(node0, cond2, true); // #9,#3 694 gum::learning::IdCondSet<> idset3(node0, cond3, true); // #9,#3 695 696 // idset1: node0 | emptyset 697 std::vector< double > N_ijk_1{400.0, 75.0, 75.0}; 698 std::vector< double > N_ij_1; 699 double xscore_1 = _score_(N_ijk_1, N_ij_1); 700 TS_ASSERT(_equal_(xscore_1, score.score(node0))) 701 702 // idset2: node0 | node1 703 std::vector< double > N_ijk_2{200, 75, 0, 200, 0, 75, 0, 0, 0}; 704 std::vector< double > N_ij_2{275, 275, 0}; 705 double xscore_2 = _score_(N_ijk_2, N_ij_2); 706 TS_ASSERT(_equal_(xscore_2, score.score(node0, cond2))) 707 708 // idset3: node0 | node3 709 std::vector< double > N_ijk_3{0, 75, 0, 200, 0, 75, 200, 0, 0}; 710 std::vector< double > N_ij_3{75, 275, 200}; 711 double xscore_3 = _score_(N_ijk_3, N_ij_3); 712 TS_ASSERT(_equal_(xscore_3, score.score(node0, cond3))) 713 714 gum::learning::ScoreK2<> score2(score); 715 TS_GUM_ASSERT_THROWS_NOTHING( 716 score2.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 717 TS_GUM_ASSERT_THROWS_NOTHING(score2.isAprioriCompatible(apriori)); 718 719 TS_ASSERT(_equal_(xscore_1, score2.score(node0))) 720 TS_ASSERT(_equal_(xscore_2, score2.score(node0, cond2))) 721 TS_ASSERT(_equal_(xscore_3, score2.score(node0, cond3))) 722 723 gum::learning::ScoreK2<> score3(std::move(score2)); 724 TS_GUM_ASSERT_THROWS_NOTHING( 725 score3.isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 726 TS_GUM_ASSERT_THROWS_NOTHING(score3.isAprioriCompatible(apriori)); 727 728 TS_ASSERT(_equal_(xscore_1, score3.score(node0))) 729 TS_ASSERT(_equal_(xscore_2, score3.score(node0, cond2))) 730 TS_ASSERT(_equal_(xscore_3, score3.score(node0, cond3))) 731 732 gum::learning::ScoreK2<>* score4 = score3.clone(); 733 TS_GUM_ASSERT_THROWS_NOTHING( 734 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 735 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 736 737 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 738 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 739 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 740 741 score4->operator=(score); 742 TS_GUM_ASSERT_THROWS_NOTHING( 743 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 744 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 745 746 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 747 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 748 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 749 750 score4->operator=(std::move(score)); 751 TS_GUM_ASSERT_THROWS_NOTHING( 752 score4->isAprioriCompatible(gum::learning::AprioriNoApriori<>::type::type)); 753 TS_GUM_ASSERT_THROWS_NOTHING(score4->isAprioriCompatible(apriori)); 754 755 TS_ASSERT(_equal_(xscore_1, score4->score(node0))) 756 TS_ASSERT(_equal_(xscore_2, score4->score(node0, cond2))) 757 TS_ASSERT(_equal_(xscore_3, score4->score(node0, cond3))) 758 759 delete score4; 760 } 761 } 762 }; 763 764 765 } /* namespace gum_tests */ 766