aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
estimator_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
50
51#include <agrum/BN/inference/tools/estimator.h> // to ease IDE parser
52
53namespace gum {
54
55 template < GUM_Numeric GUM_SCALAR >
57 GUM_CONSTRUCTOR(Estimator);
58 wtotal_ = (GUM_SCALAR)0.;
59 ntotal_ = (Size)0;
60 bn_ = nullptr;
61 }
62
63 template < GUM_Numeric GUM_SCALAR >
65 bn_ = bn;
66
67 for (gum::NodeGraphPartIterator iter = bn->nodes().begin(); iter != bn->nodes().end(); ++iter)
68 estimator_.insert(bn->variable(*iter).name(),
69 std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), 0.0));
70
71 GUM_CONSTRUCTOR(Estimator);
72 }
73
74 template < GUM_Numeric GUM_SCALAR >
76 GUM_DESTRUCTOR(Estimator);
77 // remove all the posteriors computed
78 clear();
79 }
80
81 /* adds all tensor target variables from a given BN to the Estimator */
82
83 template < GUM_Numeric GUM_SCALAR >
85 const NodeSet& hardEvidence) {
86 for (gum::NodeGraphPartIterator iter = bn->nodes().begin(); iter != bn->nodes().end(); ++iter) {
87 auto v = bn->variable(*iter).name();
88
89 if (!hardEvidence.contains(*iter)) {
90 if (estimator_.exists(v))
91 estimator_[v]
92 = std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), (GUM_SCALAR)0.0);
93 else
94 estimator_.insert(
95 v,
96 std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), (GUM_SCALAR)0.0));
97 }
98 }
99 }
100
101 // we multiply the posteriors obtained by LoopyBeliefPropagation by the it's
102 // number of iterations
103 template < GUM_Numeric GUM_SCALAR >
105 const NodeSet& hardEvidence,
106 GUM_SCALAR virtualLBPSize) {
107 for (const auto& node: lbp->BN().nodes()) {
108 if (!hardEvidence.contains(node)) {
109 std::vector< GUM_SCALAR > v;
110 auto p = lbp->posterior(node);
111 gum::Instantiation inst(p);
112
113 for (inst.setFirst(); !inst.end(); ++inst) {
114 v.push_back(p[inst] * virtualLBPSize);
115 }
116
117 estimator_.insert(lbp->BN().variable(node).name(), v);
118 }
119 }
120 ntotal_ = (Size)virtualLBPSize;
121 wtotal_ = virtualLBPSize;
122 }
123
124 /*update the Estimator given an instantiation I with weight bias w*/
125
126 template < GUM_Numeric GUM_SCALAR >
128 wtotal_ += w;
129 ntotal_ += (Size)1;
130
131 for (Idx i = 0; i < I.nbrDim(); i++) {
132 if (estimator_.exists(I.variable(i).name())) estimator_[I.variable(i).name()][I.val(i)] += w;
133 }
134 }
135
136 /* returns the approximation CPT of a variable */
137
138 template < GUM_Numeric GUM_SCALAR >
139 const Tensor< GUM_SCALAR >& Estimator< GUM_SCALAR >::posterior(const DiscreteVariable& var) {
140 Tensor< GUM_SCALAR >* p = nullptr;
141
142 if (!estimator_.exists(var.name())) GUM_ERROR(NotFound, "Target variable not found")
143
144 // check if we have already computed the posterior
145 if (_target_posteriors_.exists(var.name())) {
146 p = _target_posteriors_[var.name()];
147 } else {
148 p = new Tensor< GUM_SCALAR >();
149 *p << var;
150 _target_posteriors_.insert(var.name(), p);
151 }
152
153 p->fillWith(estimator_[var.name()]);
154 p->normalize();
155 return *p;
156 }
157
158 /* expected value considering a Bernouilli variable with parameter val */
159
160 template < GUM_Numeric GUM_SCALAR >
161 GUM_SCALAR Estimator< GUM_SCALAR >::EV(std::string_view name, Idx val) {
162 return estimator_[name][val] / wtotal_;
163 }
164
165 /* variance considering a Bernouilli variable with parameter val */
166
167 template < GUM_Numeric GUM_SCALAR >
168 GUM_SCALAR Estimator< GUM_SCALAR >::variance(std::string_view name, Idx val) {
169 GUM_SCALAR p = EV(name, val);
170 return p * (1 - p);
171 }
172
173 /* returns maximum length of confidence intervals for each variable, each
174 * parameter */
175
176 template < GUM_Numeric GUM_SCALAR >
178 GUM_SCALAR ic_max = 0;
179
180 for (auto iter = estimator_.begin(); iter != estimator_.end(); ++iter) {
181 for (Idx i = 0; i < iter.val().size(); i++) {
182 GUM_SCALAR ic = GUM_SCALAR(2 * 1.96 * std::sqrt(variance(iter.key(), i) / (ntotal_ - 1)));
183 if (ic > ic_max) ic_max = ic;
184 }
185 }
186
187 return ic_max;
188 }
189
190 template < GUM_Numeric GUM_SCALAR >
192 estimator_.clear();
193 wtotal_ = (GUM_SCALAR)0;
194 ntotal_ = Size(0);
195 for (const auto& pot: _target_posteriors_)
196 delete pot.second;
197 _target_posteriors_.clear();
198 }
199} // namespace gum
virtual const IBayesNet< GUM_SCALAR > & BN() const final
Returns a constant reference over the IBayesNet referenced by this class.
const NodeGraphPart & nodes() const final
Returns a named copy of the internal DAG: each node id is assigned the name of the corresponding vari...
const DiscreteVariable & variable(NodeId id) const override
Returns a constant reference over a variable given its node id.
Base class for discrete random variable.
virtual Size domainSize() const =0
GUM_SCALAR wtotal_
cumulated weights of all samples
Definition estimator.h:142
HashTable< std::string, std::vector< GUM_SCALAR > > estimator_
estimator represented by hashtable between each variable name and a vector of cumulative sample weigh...
Definition estimator.h:139
void setFromLBP(LoopyBeliefPropagation< GUM_SCALAR > *lbp, const NodeSet &hardEvidence, GUM_SCALAR virtualLBPSize)
sets the estimatoor object with posteriors obtained by LoopyBeliefPropagation
void setFromBN(const IBayesNet< GUM_SCALAR > *bn, const NodeSet &hardEvidence)
estimator initializing
const IBayesNet< GUM_SCALAR > * bn_
Bayesian network on which approximation is done.
Definition estimator.h:148
const Tensor< GUM_SCALAR > & posterior(const DiscreteVariable &var)
returns the posterior of a node
Estimator()
Default constructor.
void clear()
refresh the estimator state as empty
Size ntotal_
number of generated samples
Definition estimator.h:145
GUM_SCALAR variance(std::string_view name, Idx val)
returns variance of Bernouilli variable (called by it's name) of given parameter
GUM_SCALAR EV(std::string_view name, Idx val)
returns expected value of Bernouilli variable (called by it's name) of given parameter
void update(Instantiation I, GUM_SCALAR w)
updates the estimator with a given sample
HashTable< std::string, Tensor< GUM_SCALAR > * > _target_posteriors_
the set of single posteriors computed during the last inference
Definition estimator.h:178
GUM_SCALAR confidence()
computes the maximum length of confidence interval for each possible value of each variable
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.
bool end() const
Returns true if the Instantiation reached the end.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setFirst()
Assign the first values to the tuple of the Instantiation.
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.
<agrum/BN/inference/loopyBeliefPropagation.h>
virtual const Tensor< GUM_SCALAR > & posterior(NodeId node)
Computes and returns the posterior of a node.
Unsafe iterator on the node set of a graph.
node_iterator begin() const noexcept
a begin iterator to parse the set of nodes contained in the NodeGraphPart
const node_iterator & end() const noexcept
the end iterator to parse the set of nodes contained in the NodeGraphPart
Exception : the element we looked for cannot be found.
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition set_tpl.h:468
const std::string & name() const
returns the name of the variable
This file contains estimating tools for approximate inference.
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
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
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
gum is the global namespace for all aGrUM entities
Definition agrum.h:46