aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
MCBNDistance_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-2026 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-2026 *
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
41#pragma once
42
43
51
55#include <agrum/BN/IBayesNet.h>
56
58
59#define MCBNDISTANCE_DEFAULT_MAXITER 10000000
60#define MCBNDISTANCE_DEFAULT_EPSILON 1e-10
61#define MCBNDISTANCE_DEFAULT_MIN_EPSILON_RATE 1e-10
62#define MCBNDISTANCE_DEFAULT_PERIOD_SIZE 200
63#define MCBNDISTANCE_DEFAULT_VERBOSITY false
64#define MCBNDISTANCE_DEFAULT_TIMEOUT 6000
65
66namespace gum {
67
68 template < GUM_Numeric GUM_SCALAR >
81
82 template < GUM_Numeric GUM_SCALAR >
94
95 template < GUM_Numeric GUM_SCALAR >
99
100 template < GUM_Numeric GUM_SCALAR >
103
104 for (const auto nod: topoOrder) {
105 I.add(p_.variable(nod));
106 gum::Instantiation Itop(I);
107 Itop.erase(p_.variable(nod));
108 I.chgVal(p_.variable(nod), p_.cpt(nod).extract(Itop).draw());
109 }
110 return I;
111 }
112
113 template < GUM_Numeric GUM_SCALAR >
115 auto Iq = q_.completeInstantiation();
116 const auto topoOrder = p_.topologicalOrder();
118
119 // map between drawSample_() variables and q_ variables (using name of vars)
121 {
122 auto Ip = p_.completeInstantiation();
123 for (Idx ite = 0; ite < Ip.nbrDim(); ++ite) {
124 map.insert(&Ip.variable(ite), &q_.variableFromName(Ip.variable(ite).name()));
125 }
126 }
127
128 klPQ_ = klQP_ = hellinger_ = jsd_ = (GUM_SCALAR)0.0;
129 errorPQ_ = errorQP_ = 0;
130 GUM_SCALAR delta, ratio, error;
131 delta = ratio = error = (GUM_SCALAR)-1;
132 GUM_SCALAR oldPQ = 0.0;
133 GUM_SCALAR pp, pq, pmid;
134
135 do {
136 this->disableMinEpsilonRate();
137 gum::Instantiation I = drawSample_(topoOrder);
139
140 Iq.setValsFrom(map, I);
141
142 pp = p_.jointProbability(I);
143 pq = q_.jointProbability(Iq);
144 pmid = (pp + pq) / 2.0;
145
146 if (pp != (GUM_SCALAR)0.0) {
147 hellinger_ += std::pow(std::sqrt(pp) - std::sqrt(pq), 2) / pp;
148
149 if (pq != (GUM_SCALAR)0.0) {
150 bhattacharya_ += std::sqrt(pq / pp);
151 this->enableMinEpsilonRate();
152 ratio = pq / pp;
153 delta = (GUM_SCALAR)std::log2(ratio);
154 klPQ_ += delta;
155
156 // pmid!=0
157 jsd_ -= std::log2(pp / pmid) + ratio * std::log2(pq / pmid);
158 } else {
159 errorPQ_++;
160 }
161 }
162
163 if (pq != (GUM_SCALAR)0.0) {
164 if (pp != (GUM_SCALAR)0.0) {
165 // if we are here, it is certain that delta and ratio have been
166 // computed further lines above.
167 klQP_ += (GUM_SCALAR)(-delta * ratio);
168 } else {
169 errorQP_++;
170 }
171 }
172
173 if (this->isEnabledMinEpsilonRate()) {
174 // delta is used as a temporary variable
175 delta = klPQ_ / nbrIterations();
176 error = (GUM_SCALAR)std::abs(delta - oldPQ);
177 oldPQ = delta;
178 }
179 } while (continueApproximationScheme(error));
180
181 klPQ_ = -klPQ_ / (nbrIterations());
182 klQP_ = -klQP_ / (nbrIterations());
183 jsd_ = -0.5 * jsd_ / (nbrIterations());
184 hellinger_ = std::sqrt(hellinger_ / nbrIterations());
185 bhattacharya_ = -std::log(bhattacharya_ / (nbrIterations()));
186 }
187} // namespace gum
Class representing the minimal interface for Bayesian network with no numerical data.
algorithm for approximated computation KL divergence between BNs using independent Monte Carlo sampli...
#define MCBNDISTANCE_DEFAULT_MAXITER
#define MCBNDISTANCE_DEFAULT_TIMEOUT
#define MCBNDISTANCE_DEFAULT_VERBOSITY
#define MCBNDISTANCE_DEFAULT_PERIOD_SIZE
#define MCBNDISTANCE_DEFAULT_MIN_EPSILON_RATE
#define MCBNDISTANCE_DEFAULT_EPSILON
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)
bool continueApproximationScheme(double error)
Update the scheme w.r.t the new error.
void initApproximationScheme()
Initialise the scheme.
Size nbrIterations() const override
Returns the number of iterations.
void enableMinEpsilonRate() override
Enable stopping criterion on epsilon rate.
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_
Definition BNdistance.h:156
The class for generic Hash Tables.
Definition hashTable.h:640
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.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
void erase(const DiscreteVariable &v) final
Removes a variable from the Instantiation.
void computeKL_() final
Instantiation drawSample_(const Sequence< NodeId > &topoOrder) const
draws an instantiation of p_'s variables, independently, following topoOrder (no evidence to handle i...
MCBNDistance(const IBayesNet< GUM_SCALAR > &P, const IBayesNet< GUM_SCALAR > &Q)
constructor must give 2 BNs
~MCBNDistance() override
destructor
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