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), _difficulty_(Complexity::Heavy),
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_), errorPQ_(kl.errorPQ_),
58 errorQP_(kl.errorQP_), _difficulty_(kl._difficulty_), _done_(kl._done_) {
59 GUM_CONSTRUCTOR(BNdistance);
62 template <
typename GUM_SCALAR >
63 BNdistance< GUM_SCALAR >::~BNdistance() {
64 GUM_DESTRUCTOR(BNdistance);
67 template <
typename GUM_SCALAR >
68 Complexity BNdistance< GUM_SCALAR >::difficulty()
const {
72 template <
typename GUM_SCALAR >
73 INLINE
double BNdistance< GUM_SCALAR >::klPQ() {
78 template <
typename GUM_SCALAR >
79 INLINE
double BNdistance< GUM_SCALAR >::klQP() {
84 template <
typename GUM_SCALAR >
85 INLINE
double BNdistance< GUM_SCALAR >::hellinger() {
90 template <
typename GUM_SCALAR >
91 INLINE
double BNdistance< GUM_SCALAR >::bhattacharya() {
96 template <
typename GUM_SCALAR >
97 INLINE
double BNdistance< GUM_SCALAR >::jsd() {
102 template <
typename GUM_SCALAR >
103 INLINE Size BNdistance< GUM_SCALAR >::errorPQ() {
108 template <
typename GUM_SCALAR >
109 INLINE Size BNdistance< GUM_SCALAR >::errorQP() {
114 template <
typename GUM_SCALAR >
115 INLINE
const IBayesNet< GUM_SCALAR >& BNdistance< GUM_SCALAR >::p()
const {
119 template <
typename GUM_SCALAR >
120 INLINE
const IBayesNet< GUM_SCALAR >& BNdistance< GUM_SCALAR >::q()
const {
125 template <
typename GUM_SCALAR >
126 bool BNdistance< GUM_SCALAR >::_checkCompatibility_()
const {
127 for (
auto node: p_.nodes()) {
128 const DiscreteVariable& vp = p_.variable(node);
131 const DiscreteVariable& vq = q_.variableFromName(vp.name());
133 if (vp.domainSize() != vq.domainSize())
134 GUM_ERROR(OperationNotAllowed,
135 "BNdistance : the 2 BNs are not compatible " 136 "(not the same domainSize for " 139 for (Idx i = 0; i < vp.domainSize(); i++) {
144 }
catch (OutOfBounds&) {
145 GUM_ERROR(OperationNotAllowed,
146 "BNdistance : the 2 BNs are not compatible F(not the same " 151 }
catch (NotFound&) {
152 GUM_ERROR(OperationNotAllowed,
153 "BNdistance : the 2 BNs are not compatible (not the same vars : " + vp.name()
159 if (p_.size() != q_.size())
160 GUM_ERROR(OperationNotAllowed,
161 "BNdistance : the 2 BNs are not compatible (not the same size)")
163 if (std::fabs(p_.log10DomainSize() - q_.log10DomainSize()) > 1e-14) {
164 GUM_ERROR(OperationNotAllowed,
165 "BNdistance : the 2 BNs are not compatible (not the same domainSize) : p=" 166 << p_.log10DomainSize() <<
" q=" << q_.log10DomainSize() <<
" => " 167 << p_.log10DomainSize() - q_.log10DomainSize());
174 template <
typename GUM_SCALAR >
175 void BNdistance< GUM_SCALAR >::process_() {
183 template <
typename GUM_SCALAR >
184 void BNdistance< GUM_SCALAR >::computeKL_() {
185 GUM_ERROR(OperationNotAllowed,
"No default computations")