aGrUM 2.3.2
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-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
49
50namespace gum {
51
52 template < typename GUM_SCALAR >
54 GUM_CONSTRUCTOR(Estimator);
55 wtotal_ = (GUM_SCALAR)0.;
56 ntotal_ = (Size)0;
57 bn_ = nullptr;
58 }
59
60 template < typename GUM_SCALAR >
62 bn_ = bn;
63
64 for (gum::NodeGraphPartIterator iter = bn->nodes().begin(); iter != bn->nodes().end(); ++iter)
65 estimator_.insert(bn->variable(*iter).name(),
66 std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), 0.0));
67
68 GUM_CONSTRUCTOR(Estimator);
69 }
70
71 template < typename GUM_SCALAR >
73 GUM_DESTRUCTOR(Estimator);
74 // remove all the posteriors computed
75 clear();
76 }
77
78 /* adds all tensor target variables from a given BN to the Estimator */
79
80 template < typename GUM_SCALAR >
82 const NodeSet& hardEvidence) {
83 for (gum::NodeGraphPartIterator iter = bn->nodes().begin(); iter != bn->nodes().end(); ++iter) {
84 auto v = bn->variable(*iter).name();
85
86 if (!hardEvidence.contains(*iter)) {
87 if (estimator_.exists(v))
88 estimator_[v]
89 = std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), (GUM_SCALAR)0.0);
90 else
91 estimator_.insert(
92 v,
93 std::vector< GUM_SCALAR >(bn->variable(*iter).domainSize(), (GUM_SCALAR)0.0));
94 }
95 }
96 }
97
98 // we multiply the posteriors obtained by LoopyBeliefPropagation by the it's
99 // number of iterations
100 template < typename GUM_SCALAR >
102 const NodeSet& hardEvidence,
103 GUM_SCALAR virtualLBPSize) {
104 for (const auto& node: lbp->BN().nodes()) {
105 if (!hardEvidence.contains(node)) {
106 std::vector< GUM_SCALAR > v;
107 auto p = lbp->posterior(node);
108 gum::Instantiation inst(p);
109
110 for (inst.setFirst(); !inst.end(); ++inst) {
111 v.push_back(p[inst] * virtualLBPSize);
112 }
113
114 estimator_.insert(lbp->BN().variable(node).name(), v);
115 }
116 }
117 ntotal_ = (Size)virtualLBPSize;
118 wtotal_ = virtualLBPSize;
119 }
120
121 /*update the Estimator given an instantiation I with weight bias w*/
122
123 template < typename GUM_SCALAR >
125 wtotal_ += w;
126 ntotal_ += (Size)1;
127
128 for (Idx i = 0; i < I.nbrDim(); i++) {
129 if (estimator_.exists(I.variable(i).name())) estimator_[I.variable(i).name()][I.val(i)] += w;
130 }
131 }
132
133 /* returns the approximation CPT of a variable */
134
135 template < typename GUM_SCALAR >
136 const Tensor< GUM_SCALAR >& Estimator< GUM_SCALAR >::posterior(const DiscreteVariable& var) {
137 Tensor< GUM_SCALAR >* p = nullptr;
138
139 if (!estimator_.exists(var.name())) GUM_ERROR(NotFound, "Target variable not found")
140
141 // check if we have already computed the posterior
142 if (_target_posteriors_.exists(var.name())) {
143 p = _target_posteriors_[var.name()];
144 } else {
145 p = new Tensor< GUM_SCALAR >();
146 *p << var;
147 _target_posteriors_.insert(var.name(), p);
148 }
149
150 p->fillWith(estimator_[var.name()]);
151 p->normalize();
152 return *p;
153 }
154
155 /* expected value considering a Bernouilli variable with parameter val */
156
157 template < typename GUM_SCALAR >
158 GUM_SCALAR Estimator< GUM_SCALAR >::EV(std::string name, Idx val) {
159 return estimator_[name][val] / wtotal_;
160 }
161
162 /* variance considering a Bernouilli variable with parameter val */
163
164 template < typename GUM_SCALAR >
165 GUM_SCALAR Estimator< GUM_SCALAR >::variance(std::string name, Idx val) {
166 GUM_SCALAR p = EV(name, val);
167 return p * (1 - p);
168 }
169
170 /* returns maximum length of confidence intervals for each variable, each
171 * parameter */
172
173 template < typename GUM_SCALAR >
175 GUM_SCALAR ic_max = 0;
176
177 for (auto iter = estimator_.begin(); iter != estimator_.end(); ++iter) {
178 for (Idx i = 0; i < iter.val().size(); i++) {
179 GUM_SCALAR ic = GUM_SCALAR(2 * 1.96 * std::sqrt(variance(iter.key(), i) / (ntotal_ - 1)));
180 if (ic > ic_max) ic_max = ic;
181 }
182 }
183
184 return ic_max;
185 }
186
187 template < typename GUM_SCALAR >
189 estimator_.clear();
190 wtotal_ = (GUM_SCALAR)0;
191 ntotal_ = Size(0);
192 for (const auto& pot: _target_posteriors_)
193 delete pot.second;
194 _target_posteriors_.clear();
195 }
196} // 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 constant reference to the dag of this Bayes Net.
Base class for discrete random variable.
virtual Size domainSize() const =0
GUM_SCALAR wtotal_
cumulated weights of all samples
Definition estimator.h:140
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:137
void setFromLBP(LoopyBeliefPropagation< GUM_SCALAR > *lbp, const NodeSet &hardEvidence, GUM_SCALAR virtualLBPSize)
sets the estimatoor object with posteriors obtained by LoopyBeliefPropagation
GUM_SCALAR EV(std::string name, Idx val)
returns expected value of Bernouilli variable (called by it's name) of given parameter
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:146
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:143
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:176
GUM_SCALAR confidence()
computes the maximum length of confidence interval for each possible value of each variable
GUM_SCALAR variance(std::string name, Idx val)
returns variance of Bernouilli variable (called by it's name) of given parameter
Class representing the minimal interface for Bayesian network with no numerical data.
Definition IBayesNet.h:75
virtual const DiscreteVariable & variable(NodeId id) const =0
Returns a constant reference over a variable given it's node id.
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:497
const std::string & name() const
returns the name of the variable
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
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