aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
GibbsKL_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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(
52  const IBayesNet< GUM_SCALAR >& P,
53  const IBayesNet< GUM_SCALAR >& Q) :
54  BNdistance< GUM_SCALAR >(P, Q),
55  ApproximationScheme(),
56  GibbsOperator< GUM_SCALAR >(
57  P,
58  nullptr,
59  1 + (P.size() * GIBBSKL_POURCENT_DRAWN_SAMPLE / 100),
61  GUM_CONSTRUCTOR(GibbsBNdistance);
62 
63  setEpsilon(GIBBSKL_DEFAULT_EPSILON);
64  setMinEpsilonRate(GIBBSKL_DEFAULT_MIN_EPSILON_RATE);
65  setMaxIter(GIBBSKL_DEFAULT_MAXITER);
66  setVerbosity(GIBBSKL_DEFAULT_VERBOSITY);
67  setBurnIn(GIBBSKL_DEFAULT_BURNIN);
68  setPeriodSize(GIBBSKL_DEFAULT_PERIOD_SIZE);
69  setMaxTime(GIBBSKL_DEFAULT_TIMEOUT);
70  }
71 
72  template < typename GUM_SCALAR >
74  const BNdistance< GUM_SCALAR >& kl) :
77  // Gibbs operator with 10% of nodes changes at random between each samples
78  ,
80  kl.p(),
81  nullptr,
82  1 + (kl.p().size() * GIBBSKL_POURCENT_DRAWN_SAMPLE / 100),
83  true) {
85 
93  }
94 
95  template < typename GUM_SCALAR >
98  }
99 
100  template < typename GUM_SCALAR >
102  auto Iq = q_.completeInstantiation();
103 
104  gum::Instantiation I = this->monteCarloSample();
106 
107  // map between particle() variables and q_ variables (using name of vars)
109 
110  for (Idx ite = 0; ite < I.nbrDim(); ++ite) {
112  }
113 
114  // BURN IN
115  for (Idx i = 0; i < burnIn(); i++)
116  I = this->nextSample(I);
117 
118  // SAMPLING
119  klPQ_ = klQP_ = hellinger_ = jsd_ = (GUM_SCALAR)0.0;
120  errorPQ_ = errorQP_ = 0;
121  /// bool check_rate;
123  delta = ratio = error = (GUM_SCALAR)-1;
124  GUM_SCALAR oldPQ = 0.0;
125  GUM_SCALAR pp, pq, pmid;
126 
127  do {
128  this->disableMinEpsilonRate();
129  I = this->nextSample(I);
131 
132  //_p.synchroInstantiations( Ip,I);
133  Iq.setValsFrom(map, I);
134 
135  pp = p_.jointProbability(I);
137  pmid = (pp + pq) / 2.0;
138 
139  if (pp != (GUM_SCALAR)0.0) {
140  hellinger_ += std::pow(std::sqrt(pp) - std::sqrt(pq), 2) / pp;
141 
142  if (pq != (GUM_SCALAR)0.0) {
143  bhattacharya_ += std::sqrt(pq / pp); // std::sqrt(pp*pq)/pp
144  /// check_rate=true;
145  this->enableMinEpsilonRate(); // replace check_rate=true;
146  ratio = pq / pp;
148  klPQ_ += delta;
149 
150  // pmid!=0
151  jsd_ -= std::log2(pp / pmid) + ratio * std::log2(pq / pmid);
152  } else {
153  errorPQ_++;
154  }
155  }
156 
157  if (pq != (GUM_SCALAR)0.0) {
158  if (pp != (GUM_SCALAR)0.0) {
159  // if we are here, it is certain that delta and ratio have been
160  // computed
161  // further lines above. (for now #112-113)
162  klQP_ += (GUM_SCALAR)(-delta * ratio);
163  } else {
164  errorQP_++;
165  }
166  }
167 
168  if (this->isEnabledMinEpsilonRate()) { // replace check_rate
169  // delta is used as a temporary variable
170  delta = klPQ_ / nbrIterations();
172  oldPQ = delta;
173  }
174  } while (continueApproximationScheme(error)); //
175 
176  klPQ_ = -klPQ_ / (nbrIterations());
177  klQP_ = -klQP_ / (nbrIterations());
178  jsd_ = -0.5 * jsd_ / (nbrIterations());
181  }
182 
183  template < typename GUM_SCALAR >
185  this->burn_in_ = b;
186  }
187 
188  template < typename GUM_SCALAR >
190  return this->burn_in_;
191  }
192 } // 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:669
#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