aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
gum::ExactBNdistance< GUM_SCALAR > Class Template Reference

ExactBNdistance computes exactly the KL divergence betweens 2 BNs. More...

#include <exactBNdistance.h>

Inheritance diagram for gum::ExactBNdistance< GUM_SCALAR >:
Collaboration diagram for gum::ExactBNdistance< GUM_SCALAR >:

Public Member Functions

 ExactBNdistance (const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
 constructor must give 2 BNs
 ExactBNdistance (const BNdistance< GUM_SCALAR > &kl)
 copy constructor
virtual ~ExactBNdistance ()
 destructor
Complexity difficulty () const
 return KL::Complexity::Heavy,KL::Complexity::Difficult,KL::Complexity::Correct depending on the BNs p and q
Accessors to results. The first call do the computations. The

others do not.

double klPQ ()
Size errorPQ ()
double klQP ()
Size errorQP ()
double hellinger ()
double bhattacharya ()
double jsd ()
const IBayesNet< GUM_SCALAR > & p () const
const IBayesNet< GUM_SCALAR > & q () const

Protected Member Functions

void computeKL_ () final
void process_ ()

Protected Attributes

const IBayesNet< GUM_SCALAR > & p_
const IBayesNet< GUM_SCALAR > & q_
GUM_SCALAR klPQ_
GUM_SCALAR klQP_
Size errorPQ_
Size errorQP_
GUM_SCALAR hellinger_
GUM_SCALAR bhattacharya_
GUM_SCALAR jsd_

Private Member Functions

bool _checkCompatibility_ () const

Private Attributes

Complexity _difficulty_
bool _done_

Detailed Description

template<typename GUM_SCALAR>
class gum::ExactBNdistance< GUM_SCALAR >

ExactBNdistance computes exactly the KL divergence betweens 2 BNs.

ExactBNdistance should be used only if difficulty() gives an estimation ( KL_CORRECT ) of the needed time. KL.process() computes KL(P||Q) using klPQ() and KL(Q||P) using klQP(). The computations are made once. The second is for free :) ExactBNdistance allows as well to compute in the same time the Hellinger distance ( \(*\sqrt{\sum_i (\sqrt{p_i}-\sqrt{q_i})^2}\)) (Kokolakis and Nanopoulos, 2001).

It may happen that P*ln(P/Q) is not computable (Q=0 and P!=0). In such a case, KL keeps working but trace this error (errorPQ() and errorQP())? *

Warning
This ExactBNdistance should be use only if difficulty()==complexity::CORRECT or at most complexity::DIFFICULT ... snippets :
gum::KL base_kl(net1,net2);
if (base_kl.difficulty()!=KL::HEAVY) {
gum::ExactBNdistance kl(base_kl);
std::cout<<"KL net1||net2 :"<<kl.klPQ()<<std::endl;
} else {
gum::GibbsKL kl(base_kl);
std::cout<<"KL net1||net2 :"<<kl.klPQ()<<std::endl;
}
ExactBNdistance computes exactly the KL divergence betweens 2 BNs.

Definition at line 89 of file exactBNdistance.h.

Constructor & Destructor Documentation

◆ ExactBNdistance() [1/2]

template<typename GUM_SCALAR>
gum::ExactBNdistance< GUM_SCALAR >::ExactBNdistance ( const IBayesNet< GUM_SCALAR > & P,
const IBayesNet< GUM_SCALAR > & Q )

constructor must give 2 BNs

Exceptions
gum::OperationNotAllowedif the 2 BNs have not the same domainSize or compatible node sets.

Definition at line 58 of file exactBNdistance_tpl.h.

59 :
62 }
BNdistance(const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
constructor must give 2 BNs
ExactBNdistance(const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
constructor must give 2 BNs

References gum::BNdistance< GUM_SCALAR >::BNdistance(), and ExactBNdistance().

Referenced by ExactBNdistance(), ExactBNdistance(), and ~ExactBNdistance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ExactBNdistance() [2/2]

template<typename GUM_SCALAR>
gum::ExactBNdistance< GUM_SCALAR >::ExactBNdistance ( const BNdistance< GUM_SCALAR > & kl)
explicit

copy constructor

Definition at line 65 of file exactBNdistance_tpl.h.

References gum::BNdistance< GUM_SCALAR >::BNdistance(), and ExactBNdistance().

Here is the call graph for this function:

◆ ~ExactBNdistance()

template<typename GUM_SCALAR>
gum::ExactBNdistance< GUM_SCALAR >::~ExactBNdistance ( )
virtual

destructor

Definition at line 71 of file exactBNdistance_tpl.h.

References ExactBNdistance().

Here is the call graph for this function:

Member Function Documentation

◆ _checkCompatibility_()

template<typename GUM_SCALAR>
bool gum::BNdistance< GUM_SCALAR >::_checkCompatibility_ ( ) const
privateinherited

Definition at line 144 of file BNdistance_tpl.h.

144 {
145 // should not be used
146 if (p_.size() != q_.size())
148 "BNdistance : the 2 BNs are not compatible (not the same size)")
149
150 for (auto node: p_.nodes()) {
151 const DiscreteVariable& vp = p_.variable(node);
152 try {
153 const DiscreteVariable& vq = q_.variableFromName(vp.name());
154 if (vp != vq)
156 "BNdistance : the 2 BNs are not compatible "
157 "(not the same variable for the same name : "
158 + vp.toString() + "and " + vq.toString() + ")");
159 } catch (NotFound const&) {
161 "BNdistance : the 2 BNs are not compatible (variable : " + vp.name() + ")");
162 }
163 }
164
165 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());
170 }
171
172 return true;
173 }
const IBayesNet< GUM_SCALAR > & q_
Definition BNdistance.h:157
const IBayesNet< GUM_SCALAR > & p_
Definition BNdistance.h:156
#define GUM_ERROR(type, msg)
Definition exceptions.h:72

References GUM_ERROR, gum::Variable::name(), p_, q_, and gum::DiscreteVariable::toString().

Referenced by BNdistance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bhattacharya()

template<typename GUM_SCALAR>
INLINE double gum::BNdistance< GUM_SCALAR >::bhattacharya ( )
inherited
Returns
Bhattacharya distance (
See also
http://en.wikipedia.org/wiki/Bhattacharya_distance)

Definition at line 109 of file BNdistance_tpl.h.

109 {
110 process_();
111 return bhattacharya_;
112 }
GUM_SCALAR bhattacharya_
Definition BNdistance.h:166

References bhattacharya_, and process_().

Here is the call graph for this function:

◆ computeKL_()

template<typename GUM_SCALAR>
void gum::ExactBNdistance< GUM_SCALAR >::computeKL_ ( )
finalprotectedvirtual

Reimplemented from gum::BNdistance< GUM_SCALAR >.

Definition at line 76 of file exactBNdistance_tpl.h.

76 {
78 errorPQ_ = errorQP_ = 0;
79
80 auto Ip = p_.completeInstantiation();
81 auto Iq = q_.completeInstantiation();
82
83 // map between p_ variables and q_ variables (using name of vars)
85
86 for (Idx ite = 0; ite < Ip.nbrDim(); ++ite) {
87 map.insert(&Ip.variable(ite), &q_.variableFromName(Ip.variable(ite).name()));
88 }
90 for (Ip.setFirst(); !Ip.end(); ++Ip) {
91 Iq.setValsFrom(map, Ip);
92 pp = p_.jointProbability(Ip);
93 pq = q_.jointProbability(Iq);
94 pmid = (pp + pq) / 2.0;
98
99
102
103 if (pp != (GUM_SCALAR)0.0) {
104 if (pq != (GUM_SCALAR)0.0) {
105 klPQ_ -= pp * (lpq - lpp); // log2(pq / pp);
106 } else {
107 errorPQ_++;
108 }
109 }
110
111 if (pq != (GUM_SCALAR)0.0) {
112 if (pp != (GUM_SCALAR)0.0) {
113 klQP_ -= pq * (lpp - lpq); // log2(pp / pq);
114 } else {
115 errorQP_++;
116 }
117 }
118 if (pmid != (GUM_SCALAR)0.0) {
119 jsd_ += pp * lpp + pq * lpq
120 - (pp + pq) * lpmid; // pp* log2(pp / pmid) + pq * log2(pq / pmid);
121 }
122 }
123 jsd_ /= 2.0;
126 }
GUM_SCALAR hellinger_
Definition BNdistance.h:165
GUM_SCALAR klPQ_
Definition BNdistance.h:159
GUM_SCALAR jsd_
Definition BNdistance.h:167
GUM_SCALAR klQP_
Definition BNdistance.h:160
#define GUM_LOG2_OR_0(x)
Definition math_utils.h:70

References gum::BNdistance< GUM_SCALAR >::bhattacharya_, gum::BNdistance< GUM_SCALAR >::errorPQ_, gum::BNdistance< GUM_SCALAR >::errorQP_, GUM_LOG2_OR_0, gum::BNdistance< GUM_SCALAR >::hellinger_, gum::HashTable< Key, Val >::insert(), gum::BNdistance< GUM_SCALAR >::jsd_, gum::BNdistance< GUM_SCALAR >::klPQ_, gum::BNdistance< GUM_SCALAR >::klQP_, gum::BNdistance< GUM_SCALAR >::p_, and gum::BNdistance< GUM_SCALAR >::q_.

Here is the call graph for this function:

◆ difficulty()

template<typename GUM_SCALAR>
Complexity gum::BNdistance< GUM_SCALAR >::difficulty ( ) const
inherited

return KL::Complexity::Heavy,KL::Complexity::Difficult,KL::Complexity::Correct depending on the BNs p and q

Definition at line 86 of file BNdistance_tpl.h.

86 {
87 return _difficulty_;
88 }
Complexity _difficulty_
Definition BNdistance.h:171

References _difficulty_.

◆ errorPQ()

template<typename GUM_SCALAR>
INLINE Size gum::BNdistance< GUM_SCALAR >::errorPQ ( )
inherited
Returns
the number of errors while processing divergence KL(P||Q)

Definition at line 121 of file BNdistance_tpl.h.

121 {
122 process_();
123 return errorPQ_;
124 }

References errorPQ_, and process_().

Here is the call graph for this function:

◆ errorQP()

template<typename GUM_SCALAR>
INLINE Size gum::BNdistance< GUM_SCALAR >::errorQP ( )
inherited
Returns
the number of errors while processing divergence KL(Q||P)

Definition at line 127 of file BNdistance_tpl.h.

127 {
128 process_();
129 return errorQP_;
130 }

References errorQP_, and process_().

Here is the call graph for this function:

◆ hellinger()

template<typename GUM_SCALAR>
INLINE double gum::BNdistance< GUM_SCALAR >::hellinger ( )
inherited
Returns
hellinger distance (
See also
http://en.wikipedia.org/wiki/Hellinger_distance)

Definition at line 103 of file BNdistance_tpl.h.

103 {
104 process_();
105 return hellinger_;
106 }

References hellinger_, and process_().

Here is the call graph for this function:

◆ jsd()

template<typename GUM_SCALAR>
INLINE double gum::BNdistance< GUM_SCALAR >::jsd ( )
inherited
Returns
Jensen-Shannon divergence(
See also
https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence)

Definition at line 115 of file BNdistance_tpl.h.

115 {
116 process_();
117 return jsd_;
118 }

References jsd_, and process_().

Here is the call graph for this function:

◆ klPQ()

template<typename GUM_SCALAR>
INLINE double gum::BNdistance< GUM_SCALAR >::klPQ ( )
inherited
Returns
divergence KL(P||Q)

Definition at line 91 of file BNdistance_tpl.h.

91 {
92 process_();
93 return klPQ_;
94 }

References klPQ_, and process_().

Here is the call graph for this function:

◆ klQP()

template<typename GUM_SCALAR>
INLINE double gum::BNdistance< GUM_SCALAR >::klQP ( )
inherited
Returns
divergence KL(Q||P)

Definition at line 97 of file BNdistance_tpl.h.

97 {
98 process_();
99 return klQP_;
100 }

References klQP_, and process_().

Here is the call graph for this function:

◆ p()

template<typename GUM_SCALAR>
INLINE const IBayesNet< GUM_SCALAR > & gum::BNdistance< GUM_SCALAR >::p ( ) const
inherited
Returns
p

Definition at line 133 of file BNdistance_tpl.h.

133 {
134 return p_;
135 }

References p_.

Referenced by gum::GibbsBNdistance< GUM_SCALAR >::GibbsBNdistance().

Here is the caller graph for this function:

◆ process_()

template<typename GUM_SCALAR>
void gum::BNdistance< GUM_SCALAR >::process_ ( )
protectedinherited

Definition at line 177 of file BNdistance_tpl.h.

177 {
178 if (!_done_) {
179 computeKL_();
180 _done_ = true;
181 }
182 }
virtual void computeKL_()

References _done_, and computeKL_().

Referenced by bhattacharya(), errorPQ(), errorQP(), hellinger(), jsd(), klPQ(), and klQP().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ q()

template<typename GUM_SCALAR>
INLINE const IBayesNet< GUM_SCALAR > & gum::BNdistance< GUM_SCALAR >::q ( ) const
inherited
Returns
q

Definition at line 138 of file BNdistance_tpl.h.

138 {
139 return q_;
140 }

References q_.

Member Data Documentation

◆ _difficulty_

template<typename GUM_SCALAR>
Complexity gum::BNdistance< GUM_SCALAR >::_difficulty_
privateinherited

Definition at line 171 of file BNdistance.h.

Referenced by BNdistance(), BNdistance(), and difficulty().

◆ _done_

template<typename GUM_SCALAR>
bool gum::BNdistance< GUM_SCALAR >::_done_
privateinherited

Definition at line 172 of file BNdistance.h.

Referenced by BNdistance(), BNdistance(), and process_().

◆ bhattacharya_

template<typename GUM_SCALAR>
GUM_SCALAR gum::BNdistance< GUM_SCALAR >::bhattacharya_
protectedinherited

◆ errorPQ_

template<typename GUM_SCALAR>
Size gum::BNdistance< GUM_SCALAR >::errorPQ_
protectedinherited

◆ errorQP_

template<typename GUM_SCALAR>
Size gum::BNdistance< GUM_SCALAR >::errorQP_
protectedinherited

◆ hellinger_

template<typename GUM_SCALAR>
GUM_SCALAR gum::BNdistance< GUM_SCALAR >::hellinger_
protectedinherited

◆ jsd_

template<typename GUM_SCALAR>
GUM_SCALAR gum::BNdistance< GUM_SCALAR >::jsd_
protectedinherited

◆ klPQ_

template<typename GUM_SCALAR>
GUM_SCALAR gum::BNdistance< GUM_SCALAR >::klPQ_
protectedinherited

◆ klQP_

template<typename GUM_SCALAR>
GUM_SCALAR gum::BNdistance< GUM_SCALAR >::klQP_
protectedinherited

◆ p_

template<typename GUM_SCALAR>
const IBayesNet< GUM_SCALAR >& gum::BNdistance< GUM_SCALAR >::p_
protectedinherited

◆ q_

template<typename GUM_SCALAR>
const IBayesNet< GUM_SCALAR >& gum::BNdistance< GUM_SCALAR >::q_
protectedinherited

The documentation for this class was generated from the following files: