aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
GibbsKL_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49
53#include <agrum/BN/IBayesNet.h>
55
57
58#define GIBBSKL_DEFAULT_MAXITER 10000000
59#define GIBBSKL_DEFAULT_EPSILON 1e-10
60#define GIBBSKL_DEFAULT_MIN_EPSILON_RATE 1e-10
61#define GIBBSKL_DEFAULT_PERIOD_SIZE 200
62#define GIBBSKL_DEFAULT_VERBOSITY false
63#define GIBBSKL_DEFAULT_BURNIN 2000
64#define GIBBSKL_DEFAULT_TIMEOUT 6000
65
66#define GIBBSKL_POURCENT_DRAWN_SAMPLE 10 // percent drawn
67#define GIBBSKL_DRAWN_AT_RANDOM false
68
69namespace gum {
70
71
72 template < typename GUM_SCALAR >
90
91 template < typename GUM_SCALAR >
93 BNdistance< GUM_SCALAR >(kl), ApproximationScheme()
94 // Gibbs operator with 10% of nodes changes at random between each samples
95 ,
96 GibbsOperator< GUM_SCALAR >(kl.p(),
97 nullptr,
98 1 + (kl.p().size() * GIBBSKL_POURCENT_DRAWN_SAMPLE / 100),
99 true) {
100 GUM_CONSTRUCTOR(GibbsBNdistance);
101
109 }
110
111 template < typename GUM_SCALAR >
115
116 template < typename GUM_SCALAR >
118 auto Iq = q_.completeInstantiation();
121
122 // map between particle() variables and q_ variables (using name of vars)
124
125 for (Idx ite = 0; ite < I.nbrDim(); ++ite) {
126 map.insert(&I.variable(ite), &q_.variableFromName(I.variable(ite).name()));
127 }
128
129 // BURN IN
130 this->updateSamplingNodes_();
131 for (Idx i = 0; i < burnIn(); i++)
132 I = this->nextSample(I);
133
134 // SAMPLING
135 klPQ_ = klQP_ = hellinger_ = jsd_ = (GUM_SCALAR)0.0;
136 errorPQ_ = errorQP_ = 0;
138 GUM_SCALAR delta, ratio, error;
139 delta = ratio = error = (GUM_SCALAR)-1;
140 GUM_SCALAR oldPQ = 0.0;
141 GUM_SCALAR pp, pq, pmid;
142
143 do {
144 this->disableMinEpsilonRate();
145 I = this->nextSample(I);
147
148 //_p.synchroInstantiations( Ip,I);
149 Iq.setValsFrom(map, I);
150
151 pp = p_.jointProbability(I);
152 pq = q_.jointProbability(Iq);
153 pmid = (pp + pq) / 2.0;
154
155 if (pp != (GUM_SCALAR)0.0) {
156 hellinger_ += std::pow(std::sqrt(pp) - std::sqrt(pq), 2) / pp;
157
158 if (pq != (GUM_SCALAR)0.0) {
159 bhattacharya_ += std::sqrt(pq / pp); // std::sqrt(pp*pq)/pp
161 this->enableMinEpsilonRate(); // replace check_rate=true;
162 ratio = pq / pp;
163 delta = (GUM_SCALAR)std::log2(ratio);
164 klPQ_ += delta;
165
166 // pmid!=0
167 jsd_ -= std::log2(pp / pmid) + ratio * std::log2(pq / pmid);
168 } else {
169 errorPQ_++;
170 }
171 }
172
173 if (pq != (GUM_SCALAR)0.0) {
174 if (pp != (GUM_SCALAR)0.0) {
175 // if we are here, it is certain that delta and ratio have been
176 // computed
177 // further lines above. (for now #112-113)
178 klQP_ += (GUM_SCALAR)(-delta * ratio);
179 } else {
180 errorQP_++;
181 }
182 }
183
184 if (this->isEnabledMinEpsilonRate()) { // replace check_rate
185 // delta is used as a temporary variable
186 delta = klPQ_ / nbrIterations();
187 error = (GUM_SCALAR)std::abs(delta - oldPQ);
188 oldPQ = delta;
189 }
190 } while (continueApproximationScheme(error)); //
191
192 klPQ_ = -klPQ_ / (nbrIterations());
193 klQP_ = -klQP_ / (nbrIterations());
194 jsd_ = -0.5 * jsd_ / (nbrIterations());
195 hellinger_ = std::sqrt(hellinger_ / nbrIterations());
196 bhattacharya_ = -std::log(bhattacharya_ / (nbrIterations()));
197 }
198
199 template < typename GUM_SCALAR >
203
204 template < typename GUM_SCALAR >
206 return this->burn_in_;
207 }
208} // namespace gum
algorithm for approximated computation KL divergence between BNs using GIBBS sampling
#define GIBBSKL_DEFAULT_MAXITER
Definition GibbsKL_tpl.h:58
#define GIBBSKL_DEFAULT_MIN_EPSILON_RATE
Definition GibbsKL_tpl.h:60
#define GIBBSKL_DEFAULT_PERIOD_SIZE
Definition GibbsKL_tpl.h:61
#define GIBBSKL_DEFAULT_TIMEOUT
Definition GibbsKL_tpl.h:64
#define GIBBSKL_DEFAULT_BURNIN
Definition GibbsKL_tpl.h:63
#define GIBBSKL_DRAWN_AT_RANDOM
Definition GibbsKL_tpl.h:67
#define GIBBSKL_DEFAULT_VERBOSITY
Definition GibbsKL_tpl.h:62
#define GIBBSKL_POURCENT_DRAWN_SAMPLE
Definition GibbsKL_tpl.h:66
#define GIBBSKL_DEFAULT_EPSILON
Definition GibbsKL_tpl.h:59
Class representing the minimal interface for Bayesian network with no numerical data.
This file contains general scheme for iteratively convergent algorithms.
void updateApproximationScheme(unsigned int incr=1)
Update the scheme w.r.t the new error and increment steps.
void setMaxIter(Size max) override
Stopping criterion on number of iterations.
void setMaxTime(double timeout) override
Stopping criterion on timeout.
void setMinEpsilonRate(double rate) override
Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|).
void setPeriodSize(Size p) override
How many samples between two stopping is enable.
bool isEnabledMinEpsilonRate() const override
Returns true if stopping criterion on epsilon rate is enabled, false otherwise.
void disableMinEpsilonRate() override
Disable stopping criterion on epsilon rate.
ApproximationScheme(bool verbosity=false)
void initApproximationScheme()
Initialise the scheme.
Size nbrIterations() const override
Returns the number of iterations.
void enableMinEpsilonRate() override
Enable stopping criterion on epsilon rate.
bool continueApproximationScheme(double error)
Update the scheme w.r.t the new error.
Size burn_in_
Number of iterations before checking stopping criteria.
void setVerbosity(bool v) override
Set the verbosity on (true) or off (false).
void setEpsilon(double eps) override
Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)|.
GUM_SCALAR hellinger_
Definition BNdistance.h:165
GUM_SCALAR klPQ_
Definition BNdistance.h:159
BNdistance(const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
constructor must give 2 BNs
GUM_SCALAR jsd_
Definition BNdistance.h:167
GUM_SCALAR klQP_
Definition BNdistance.h:160
GUM_SCALAR bhattacharya_
Definition BNdistance.h:166
const IBayesNet< GUM_SCALAR > & q_
Definition BNdistance.h:157
const IBayesNet< GUM_SCALAR > & p() const
const IBayesNet< GUM_SCALAR > & p_
Definition BNdistance.h:156
Size burnIn() const
Returns the number of burn in.
void computeKL_() final
void setBurnIn(Size b)
Number of burn in for one iteration.
GibbsBNdistance(const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
constructor must give 2 BNs
Definition GibbsKL_tpl.h:73
~GibbsBNdistance()
destructor
Instantiation nextSample(Instantiation prev)
draws next sample of Gibbs sampling
Instantiation monteCarloSample()
draws a Monte Carlo sample
GibbsOperator(const IBayesNet< GUM_SCALAR > &BN, const NodeProperty< Idx > *hardEv, Size nbr=1, bool atRandom=false)
constructor
The class for generic Hash Tables.
Definition hashTable.h:637
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Class representing the minimal interface for Bayesian network with no numerical data.
Definition IBayesNet.h:75
Class for assigning/browsing values to tuples of discrete variables.
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Idx nbrDim() const final
Returns the number of variables in the Instantiation.
const std::string & name() const
returns the name of the variable
This file contains Gibbs sampling (for BNs) class definitions.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Class hash tables iterators.
Useful macros for maths.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46