31 #include <agrum/tools/core/math/math_utils.h> 32 #include <agrum/BN/IBayesNet.h> 33 #include <agrum/BN/algorithms/divergence/BNdistance.h> 36 template <
typename GUM_SCALAR >
37 BNdistance< GUM_SCALAR >::BNdistance(
const IBayesNet< GUM_SCALAR >& P,
38 const IBayesNet< GUM_SCALAR >& Q) :
40 q_(Q), klPQ_(0.0), klQP_(0.0), errorPQ_(0), errorQP_(0),
41 difficulty__(Complexity::Heavy), done__(
false) {
42 checkCompatibility__();
43 GUM_CONSTRUCTOR(BNdistance);
45 double diff = p_.log10DomainSize();
47 if (diff > GAP_COMPLEXITY_KL_HEAVY_DIFFICULT)
48 difficulty__ = Complexity::Heavy;
49 else if (diff > GAP_COMPLEXITY_KL_DIFFICULT_CORRECT)
50 difficulty__ = Complexity::Difficult;
52 difficulty__ = Complexity::Correct;
55 template <
typename GUM_SCALAR >
56 BNdistance< GUM_SCALAR >::BNdistance(
const BNdistance< GUM_SCALAR >& kl) :
57 p_(kl.p_), q_(kl.q_), klPQ_(kl.klPQ_), klQP_(kl.klQP_),
58 errorPQ_(kl.errorPQ_), errorQP_(kl.errorQP_), difficulty__(kl.difficulty__),
60 GUM_CONSTRUCTOR(BNdistance);
63 template <
typename GUM_SCALAR >
64 BNdistance< GUM_SCALAR >::~BNdistance() {
65 GUM_DESTRUCTOR(BNdistance);
68 template <
typename GUM_SCALAR >
69 Complexity BNdistance< GUM_SCALAR >::difficulty()
const {
73 template <
typename GUM_SCALAR >
74 INLINE
double BNdistance< GUM_SCALAR >::klPQ() {
79 template <
typename GUM_SCALAR >
80 INLINE
double BNdistance< GUM_SCALAR >::klQP() {
85 template <
typename GUM_SCALAR >
86 INLINE
double BNdistance< GUM_SCALAR >::hellinger() {
91 template <
typename GUM_SCALAR >
92 INLINE
double BNdistance< GUM_SCALAR >::bhattacharya() {
97 template <
typename GUM_SCALAR >
98 INLINE
double BNdistance< GUM_SCALAR >::jsd() {
103 template <
typename GUM_SCALAR >
104 INLINE Size BNdistance< GUM_SCALAR >::errorPQ() {
109 template <
typename GUM_SCALAR >
110 INLINE Size BNdistance< GUM_SCALAR >::errorQP() {
115 template <
typename GUM_SCALAR >
116 INLINE
const IBayesNet< GUM_SCALAR >& BNdistance< GUM_SCALAR >::p()
const {
120 template <
typename GUM_SCALAR >
121 INLINE
const IBayesNet< GUM_SCALAR >& BNdistance< GUM_SCALAR >::q()
const {
126 template <
typename GUM_SCALAR >
127 bool BNdistance< GUM_SCALAR >::checkCompatibility__()
const {
128 for (
auto node: p_.nodes()) {
129 const DiscreteVariable& vp = p_.variable(node);
132 const DiscreteVariable& vq = q_.variableFromName(vp.name());
134 if (vp.domainSize() != vq.domainSize())
135 GUM_ERROR(OperationNotAllowed,
136 "BNdistance : the 2 BNs are not compatible " 137 "(not the same domainSize for " 140 for (Idx i = 0; i < vp.domainSize(); i++) {
145 }
catch (OutOfBounds&) {
146 GUM_ERROR(OperationNotAllowed,
147 "BNdistance : the 2 BNs are not compatible F(not the same " 152 }
catch (NotFound&) {
153 GUM_ERROR(OperationNotAllowed,
154 "BNdistance : the 2 BNs are not compatible (not the same vars : " 160 if (p_.size() != q_.size())
161 GUM_ERROR(OperationNotAllowed,
162 "BNdistance : the 2 BNs are not compatible (not the same size)");
164 if (std::fabs(p_.log10DomainSize() - q_.log10DomainSize()) > 1e-14) {
167 "BNdistance : the 2 BNs are not compatible (not the same domainSize) : p=" 168 << p_.log10DomainSize() <<
" q=" << q_.log10DomainSize() <<
" => " 169 << p_.log10DomainSize() - q_.log10DomainSize());
176 template <
typename GUM_SCALAR >
177 void BNdistance< GUM_SCALAR >::process_() {
185 template <
typename GUM_SCALAR >
186 void BNdistance< GUM_SCALAR >::computeKL_() {
187 GUM_ERROR(OperationNotAllowed,
"No default computations");