aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
GibbsKL_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@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 /**
23  * @file
24  * @brief KL divergence between BNs -- implementation using Gibbs sampling
25  *
26  * @author Paul ALAM & Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #include <agrum/tools/core/math/math_utils.h>
30 #include <agrum/BN/IBayesNet.h>
31 #include <agrum/BN/algorithms/divergence/GibbsBNdistance.h>
32 #include <agrum/BN/inference/tools/gibbsOperator.h>
33 #include <agrum/tools/core/approximations/approximationScheme.h>
34 #include <agrum/tools/core/hashTable.h>
35 
36 #define GIBBSKL_DEFAULT_MAXITER 10000000
37 #define GIBBSKL_DEFAULT_EPSILON 1e-10
38 #define GIBBSKL_DEFAULT_MIN_EPSILON_RATE 1e-10
39 #define GIBBSKL_DEFAULT_PERIOD_SIZE 200
40 #define GIBBSKL_DEFAULT_VERBOSITY false
41 #define GIBBSKL_DEFAULT_BURNIN 2000
42 #define GIBBSKL_DEFAULT_TIMEOUT 6000
43 
44 #define GIBBSKL_POURCENT_DRAWN_SAMPLE 10 // percent drawn
45 #define GIBBSKL_DRAWN_AT_RANDOM false
46 
47 namespace gum {
48 
49 
50  template < typename GUM_SCALAR >
51  GibbsBNdistance< GUM_SCALAR >::GibbsBNdistance(const IBayesNet< GUM_SCALAR >& P,
52  const IBayesNet< GUM_SCALAR >& Q) :
53  BNdistance< GUM_SCALAR >(P, Q),
54  ApproximationScheme(), GibbsOperator< GUM_SCALAR >(
55  P,
56  nullptr,
57  1 + (P.size() * GIBBSKL_POURCENT_DRAWN_SAMPLE / 100),
59  GUM_CONSTRUCTOR(GibbsBNdistance);
60 
61  setEpsilon(GIBBSKL_DEFAULT_EPSILON);
62  setMinEpsilonRate(GIBBSKL_DEFAULT_MIN_EPSILON_RATE);
63  setMaxIter(GIBBSKL_DEFAULT_MAXITER);
64  setVerbosity(GIBBSKL_DEFAULT_VERBOSITY);
65  setBurnIn(GIBBSKL_DEFAULT_BURNIN);
66  setPeriodSize(GIBBSKL_DEFAULT_PERIOD_SIZE);
67  setMaxTime(GIBBSKL_DEFAULT_TIMEOUT);
68  }
69 
70  template < typename GUM_SCALAR >
73  // Gibbs operator with 10% of nodes changes at random between each samples
74  ,
76  nullptr,
77  1 + (kl.p().size() * GIBBSKL_POURCENT_DRAWN_SAMPLE / 100),
78  true) {
80 
88  }
89 
90  template < typename GUM_SCALAR >
93  }
94 
95  template < typename GUM_SCALAR >
97  auto Iq = q_.completeInstantiation();
98 
101 
102  // map between particle() variables and q_ variables (using name of vars)
104 
105  for (Idx ite = 0; ite < I.nbrDim(); ++ite) {
107  }
108 
109  // BURN IN
110  for (Idx i = 0; i < burnIn(); i++)
111  I = this->nextSample(I);
112 
113  // SAMPLING
114  klPQ_ = klQP_ = hellinger_ = jsd_ = (GUM_SCALAR)0.0;
115  errorPQ_ = errorQP_ = 0;
116  /// bool check_rate;
118  delta = ratio = error = (GUM_SCALAR)-1;
119  GUM_SCALAR oldPQ = 0.0;
120  GUM_SCALAR pp, pq, pmid;
121 
122  do {
123  this->disableMinEpsilonRate();
124  I = this->nextSample(I);
126 
127  //_p.synchroInstantiations( Ip,I);
128  Iq.setValsFrom(map, I);
129 
130  pp = p_.jointProbability(I);
132  pmid = (pp + pq) / 2.0;
133 
134  if (pp != (GUM_SCALAR)0.0) {
135  hellinger_ += std::pow(std::sqrt(pp) - std::sqrt(pq), 2) / pp;
136 
137  if (pq != (GUM_SCALAR)0.0) {
138  bhattacharya_ += std::sqrt(pq / pp); // std::sqrt(pp*pq)/pp
139  /// check_rate=true;
140  this->enableMinEpsilonRate(); // replace check_rate=true;
141  ratio = pq / pp;
143  klPQ_ += delta;
144 
145  // pmid!=0
146  jsd_ -= std::log2(pp / pmid) + ratio * std::log2(pq / pmid);
147  } else {
148  errorPQ_++;
149  }
150  }
151 
152  if (pq != (GUM_SCALAR)0.0) {
153  if (pp != (GUM_SCALAR)0.0) {
154  // if we are here, it is certain that delta and ratio have been
155  // computed
156  // further lines above. (for now #112-113)
157  klQP_ += (GUM_SCALAR)(-delta * ratio);
158  } else {
159  errorQP_++;
160  }
161  }
162 
163  if (this->isEnabledMinEpsilonRate()) { // replace check_rate
164  // delta is used as a temporary variable
165  delta = klPQ_ / nbrIterations();
167  oldPQ = delta;
168  }
169  } while (continueApproximationScheme(error)); //
170 
171  klPQ_ = -klPQ_ / (nbrIterations());
172  klQP_ = -klQP_ / (nbrIterations());
173  jsd_ = -0.5 * jsd_ / (nbrIterations());
176  }
177 
178  template < typename GUM_SCALAR >
180  this->burn_in_ = b;
181  }
182 
183  template < typename GUM_SCALAR >
185  return this->burn_in_;
186  }
187 } // namespace gum
#define GIBBSKL_DEFAULT_TIMEOUT
Definition: GibbsKL_tpl.h:42
#define GIBBSKL_DRAWN_AT_RANDOM
Definition: GibbsKL_tpl.h:45
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
#define GIBBSKL_DEFAULT_BURNIN
Definition: GibbsKL_tpl.h:41
#define GIBBSKL_POURCENT_DRAWN_SAMPLE
Definition: GibbsKL_tpl.h:44
#define GIBBSKL_DEFAULT_EPSILON
Definition: GibbsKL_tpl.h:37
#define GIBBSKL_DEFAULT_PERIOD_SIZE
Definition: GibbsKL_tpl.h:39
#define GIBBSKL_DEFAULT_MIN_EPSILON_RATE
Definition: GibbsKL_tpl.h:38
#define GIBBSKL_DEFAULT_VERBOSITY
Definition: GibbsKL_tpl.h:40
#define GIBBSKL_DEFAULT_MAXITER
Definition: GibbsKL_tpl.h:36