28 #ifndef DOXYGEN_SHOULD_SKIP_THIS 30 # include <agrum/BN/learning/scores_and_tests/scoreBDeu.h> 38 template <
template <
typename >
class ALLOC >
39 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(
40 const DBRowGeneratorParser< ALLOC >& parser,
41 const Apriori< ALLOC >& apriori,
42 const std::vector< std::pair< std::size_t, std::size_t >,
43 ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
44 const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
46 const typename ScoreBDeu< ALLOC >::allocator_type& alloc) :
47 Score< ALLOC >(parser, apriori, ranges, nodeId2columns, alloc),
48 internal_apriori__(parser.database(), nodeId2columns) {
49 GUM_CONSTRUCTOR(ScoreBDeu);
54 template <
template <
typename >
class ALLOC >
55 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(
56 const DBRowGeneratorParser< ALLOC >& parser,
57 const Apriori< ALLOC >& apriori,
58 const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
60 const typename ScoreBDeu< ALLOC >::allocator_type& alloc) :
61 Score< ALLOC >(parser, apriori, nodeId2columns, alloc),
62 internal_apriori__(parser.database(), nodeId2columns) {
63 GUM_CONSTRUCTOR(ScoreBDeu);
68 template <
template <
typename >
class ALLOC >
69 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(
70 const ScoreBDeu< ALLOC >& from,
71 const typename ScoreBDeu< ALLOC >::allocator_type& alloc) :
72 Score< ALLOC >(from, alloc),
73 internal_apriori__(from.internal_apriori__, alloc),
74 gammalog2__(from.gammalog2__) {
75 GUM_CONS_CPY(ScoreBDeu);
80 template <
template <
typename >
class ALLOC >
81 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(
const ScoreBDeu< ALLOC >& from) :
82 ScoreBDeu< ALLOC >(from, from.getAllocator()) {}
86 template <
template <
typename >
class ALLOC >
87 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(
88 ScoreBDeu< ALLOC >&& from,
89 const typename ScoreBDeu< ALLOC >::allocator_type& alloc) :
90 Score< ALLOC >(std::move(from), alloc),
91 internal_apriori__(std::move(from.internal_apriori__), alloc),
92 gammalog2__(std::move(from.gammalog2__)) {
93 GUM_CONS_MOV(ScoreBDeu);
98 template <
template <
typename >
class ALLOC >
99 INLINE ScoreBDeu< ALLOC >::ScoreBDeu(ScoreBDeu< ALLOC >&& from) :
100 ScoreBDeu< ALLOC >(std::move(from), from.getAllocator()) {}
104 template <
template <
typename >
class ALLOC >
105 ScoreBDeu< ALLOC >* ScoreBDeu< ALLOC >::clone(
106 const typename ScoreBDeu< ALLOC >::allocator_type& alloc)
const {
107 ALLOC< ScoreBDeu< ALLOC > > allocator(alloc);
108 ScoreBDeu< ALLOC >* new_score = allocator.allocate(1);
110 allocator.construct(new_score, *
this, alloc);
112 allocator.deallocate(new_score, 1);
121 template <
template <
typename >
class ALLOC >
122 ScoreBDeu< ALLOC >* ScoreBDeu< ALLOC >::clone()
const {
123 return clone(
this->getAllocator());
128 template <
template <
typename >
class ALLOC >
129 ScoreBDeu< ALLOC >::~ScoreBDeu() {
130 GUM_DESTRUCTOR(ScoreBDeu);
135 template <
template <
typename >
class ALLOC >
137 ScoreBDeu< ALLOC >::operator=(
const ScoreBDeu< ALLOC >& from) {
139 Score< ALLOC >::operator=(from);
140 internal_apriori__ = from.internal_apriori__;
147 template <
template <
typename >
class ALLOC >
148 ScoreBDeu< ALLOC >& ScoreBDeu< ALLOC >::operator=(ScoreBDeu< ALLOC >&& from) {
150 Score< ALLOC >::operator=(std::move(from));
151 internal_apriori__ = std::move(from.internal_apriori__);
158 template <
template <
typename >
class ALLOC >
160 ScoreBDeu< ALLOC >::isAprioriCompatible(
const std::string& apriori_type,
163 if (apriori_type == AprioriNoAprioriType::type) {
return ""; }
166 return "The apriori is currently compatible with the BDeu score but " 167 "if you change the weight, it will become incompatible.";
171 if ((apriori_type == AprioriDirichletType::type)
172 || (apriori_type == AprioriSmoothingType::type)) {
173 return "The BDeu score already contains a different 'implicit' apriori. " 174 "Therefore, the learning will probably be biased.";
178 std::stringstream msg;
179 msg <<
"The apriori '" << apriori_type
180 <<
"' is not yet supported by method isAprioriCompatible os Score BDeu";
186 template <
template <
typename >
class ALLOC >
188 ScoreBDeu< ALLOC >::isAprioriCompatible(
const Apriori< ALLOC >& apriori) {
189 return isAprioriCompatible(apriori.getType(), apriori.weight());
194 template <
template <
typename >
class ALLOC >
195 INLINE std::string ScoreBDeu< ALLOC >::isAprioriCompatible()
const {
196 return isAprioriCompatible(*(
this->apriori_));
201 template <
template <
typename >
class ALLOC >
202 INLINE
const Apriori< ALLOC >& ScoreBDeu< ALLOC >::internalApriori()
const {
203 return internal_apriori__;
208 template <
template <
typename >
class ALLOC >
209 INLINE
void ScoreBDeu< ALLOC >::setEffectiveSampleSize(
double ess) {
211 GUM_ERROR(OutOfBounds,
212 "The effective sample size of the BDeu's " 213 "internal apriori must be positive");
215 internal_apriori__.setEffectiveSampleSize(ess);
221 template <
template <
typename >
class ALLOC >
222 double ScoreBDeu< ALLOC >::score_(
const IdCondSet< ALLOC >& idset) {
224 std::vector<
double, ALLOC<
double > > N_ijk(
225 this->counter_.counts(idset,
true));
226 const std::size_t all_size = N_ijk.size();
229 const double ess = internal_apriori__.weight();
230 const bool informative_external_apriori =
this->apriori_->isInformative();
235 if (idset.hasConditioningSet()) {
237 std::vector<
double, ALLOC<
double > > N_ij(
238 this->marginalize_(idset[0], N_ijk));
239 const std::size_t conditioning_size = N_ij.size();
240 const double ess_qi = ess / conditioning_size;
241 const double ess_riqi = ess / all_size;
243 if (informative_external_apriori) {
248 std::vector<
double, ALLOC<
double > > N_prime_ijk(all_size, 0.0);
249 this->apriori_->addAllApriori(idset, N_prime_ijk);
250 std::vector<
double, ALLOC<
double > > N_prime_ij(N_ij.size(), 0.0);
251 this->apriori_->addConditioningApriori(idset, N_prime_ij);
258 for (std::size_t j = std::size_t(0); j < conditioning_size; ++j) {
259 score += gammalog2__(N_prime_ij[j] + ess_qi)
260 - gammalog2__(N_ij[j] + N_prime_ij[j] + ess_qi);
262 for (std::size_t k = std::size_t(0); k < all_size; ++k) {
263 score += gammalog2__(N_ijk[k] + N_prime_ijk[k] + ess_riqi)
264 - gammalog2__(N_prime_ijk[k] + ess_riqi);
272 score = conditioning_size * gammalog2__(ess_qi)
273 - all_size * gammalog2__(ess_riqi);
275 for (
const auto n_ij: N_ij) {
276 score -= gammalog2__(n_ij + ess_qi);
278 for (
const auto n_ijk: N_ijk) {
279 score += gammalog2__(n_ijk + ess_riqi);
284 const double ess_ri = ess / all_size;
286 if (informative_external_apriori) {
291 std::vector<
double, ALLOC<
double > > N_prime_ijk(all_size, 0.0);
292 this->apriori_->addAllApriori(idset, N_prime_ijk);
299 double N_prime = 0.0;
300 for (std::size_t k = std::size_t(0); k < all_size; ++k) {
301 score += gammalog2__(N_ijk[k] + N_prime_ijk[k] + ess_ri)
302 - gammalog2__(N_prime_ijk[k] + ess_ri);
304 N_prime += N_prime_ijk[k];
306 score += gammalog2__(N_prime + ess) - gammalog2__(N + N_prime + ess);
313 score = gammalog2__(ess) - all_size * gammalog2__(ess_ri);
315 for (
const auto n_ijk: N_ijk) {
316 score += gammalog2__(n_ijk + ess_ri);
319 score -= gammalog2__(N + ess);