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