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