52 template < GUM_Numeric GUM_ELEMENT >
63 template < GUM_Numeric GUM_ELEMENT >
77 template < GUM_Numeric GUM_ELEMENT >
87 for (
const auto& w:
whatif) {
91 for (
auto nid: origBN.nodes()) {
92 if (origBN.parents(nid).size() == 0) { idiosyncratic.
insert(nid); }
94 for (
auto id: whatifIds) {
95 idiosyncratic.
erase(
id);
98 idiosyncratic.
erase(
id);
104 for (
const auto& kv:
profile) {
105 const auto& varName = kv.first;
106 const auto& valName = kv.second;
108 const auto& var = origBN.variable(nid);
109 const Idx valId = var.index(valName);
116 for (
auto f: idiosyncratic) {
117 const auto& name = origBN.variable(f).name();
118 auto twinId = twinBN.idFromName(name);
120 twinBN.cpt(twinId).fillWith(post);
125 template < GUM_Numeric GUM_ELEMENT >
133 for (
auto nid: origBN.nodes()) {
134 if (origBN.parents(nid).size() == 0) { idiosyncratic.
insert(nid); }
136 for (
auto id: whatifIds) {
137 idiosyncratic.
erase(
id);
140 idiosyncratic.
erase(
id);
147 if (!profileIds.
empty()) {
148 for (
const auto& kv: profileIds) {
149 const NodeId nid = kv.first;
150 const Idx valId = kv.second;
156 for (
auto f: idiosyncratic) {
157 const auto& name = origBN.variable(f).name();
158 const NodeId twinId = twinBN.idFromName(name);
160 twinBN.cpt(twinId).fillWith(post);
168 template < GUM_Numeric GUM_ELEMENT >
177 if (!
_values.empty() && adj.nbrDim() > 0) {
179 if (I.nbrDim() > 0) adj = adj.extract(I);
188 template < GUM_Numeric GUM_ELEMENT >
197 res.
add(bn.variableFromName(v->name()));
205 template < GUM_Numeric GUM_ELEMENT >
207 return _ci->getResult();
212 template < GUM_Numeric GUM_ELEMENT >
214 std::stringstream os;
215 os <<
"[Counterfactual]\n";
220 for (
const auto& s:
_on) {
221 if (!first) os <<
", ";
226 os <<
"}\n whatif = {";
230 if (!first) os <<
", ";
240 for (
const auto& [k, v]:
_profile) {
241 if (!first) os <<
", ";
251 for (
const auto& [k, v]:
_values) {
252 if (!first) os <<
", ";
259 os <<
" result (symbolic): ";
261 else os <<
"<unidentified>\n";
264 os <<
" value (adapted to original variables):\n";
273 template < GUM_Numeric GUM_ELEMENT >
279 for (
auto nid: ids) {
280 const auto& var = bn.variable(nid);
286 template < GUM_Numeric GUM_ELEMENT >
294 for (
const auto& kv: idAssign) {
295 const NodeId nid = kv.first;
296 const Idx valId = kv.second;
297 const auto& var = bn.variable(nid);
298 out.
insert(var.name(), var.label(valId));
307 template < GUM_Numeric GUM_ELEMENT >
318 template < GUM_Numeric GUM_ELEMENT >
319 CausalModel< GUM_ELEMENT >
330 for (
const auto& w: whatif)
335 for (
auto nid: origBN.nodes())
336 if (origBN.parents(nid).size() == 0) idiosyncratic.
insert(nid);
337 for (
auto id: whatifIds)
338 idiosyncratic.
erase(
id);
340 idiosyncratic.
erase(
id);
344 if (!profile.
empty()) {
345 for (
const auto& kv: profile) {
347 const auto& var = origBN.variable(nid);
348 const Idx valId = var.index(kv.second);
356 for (
auto f: idiosyncratic) {
357 const auto& name = origBN.variable(f).name();
358 const NodeId twinId = twinBN.idFromName(name);
360 twinBN.cpt(twinId).fillWith(post);
368 template < GUM_Numeric GUM_ELEMENT >
373 template < GUM_Numeric GUM_ELEMENT >
378 template < GUM_Numeric GUM_ELEMENT >
383 template < GUM_Numeric GUM_ELEMENT >
388 template < GUM_Numeric GUM_ELEMENT >
393 template < GUM_Numeric GUM_ELEMENT >
398 template < GUM_Numeric GUM_ELEMENT >
405 template < GUM_Numeric GUM_ELEMENT >
NodeSet latentVariablesIds() const
Node ids of all latent variables.
NodeId idFromName(std::string_view name) const
Node id from variable name (observed or latent).
const BayesNet< GUM_SCALAR > & observationalBN() const
Observational BN (observed variables only).
Computes a counterfactual distribution by building a twin model, then evaluating a causal effect on t...
CausalModel< GUM_ELEMENT > _twin
const Set< std::string > & on() const
std::unique_ptr< CausalImpact< GUM_ELEMENT > > _ci
HashTable< VarName, ValName > _profile
const CausalFormula< GUM_ELEMENT > & _ciResult() const
HashTable< VarName, ValName > _values
const CausalModel< GUM_ELEMENT > & twinModel() const
const CausalModel< GUM_ELEMENT > & originalModel() const
Tensor< GUM_ELEMENT > _adaptedValue
const Set< std::string > & whatif() const
static CausalModel< GUM_ELEMENT > counterFactualModel(const CausalModel< GUM_ELEMENT > &cm, const HashTable< VarName, ValName > &profile, const Set< std::string > &whatif)
static Tensor< GUM_ELEMENT > _adaptToOriginalVariables_(const Tensor< GUM_ELEMENT > &adj, const CausalModel< GUM_ELEMENT > &cm)
static HashTable< VarName, ValName > _idAssignToNameAssign_(const CausalModel< GUM_ELEMENT > &cm, const HashTable< NodeId, Idx > &idAssign)
const Tensor< GUM_ELEMENT > & value() const
Numeric result adapted to the original model’s variables.
static Set< std::string > _idsToNames_(const CausalModel< GUM_ELEMENT > &cm, const NodeSet &ids)
const HashTable< VarName, ValName > & values() const
const CausalImpact< GUM_ELEMENT > & impact() const
Symbolic result produced on the twin model.
std::string toString() const
const CausalModel< GUM_ELEMENT > & _cm
const HashTable< VarName, ValName > & profile() const
Set< std::string > _whatif
void run()
Rebuild the internal CausalImpact (ctor already calls this).
Counterfactual(const CausalModel< GUM_ELEMENT > &cm, const Set< std::string > &on, const Set< std::string > &whatif, const HashTable< VarName, ValName > &profile=HashTable< VarName, ValName >(), const HashTable< VarName, ValName > &values=HashTable< VarName, ValName >())
Construct a counterfactual query using variable names.
virtual void makeInference() final
perform the heavy computations needed to compute the targets' posteriors
virtual void addEvidence(NodeId id, const Idx val) final
adds a new hard evidence on node id
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
bool empty() const noexcept
Indicates whether the hash table is empty.
const Tensor< GUM_SCALAR > & posterior(NodeId node) final
Computes and returns the posterior of a node.
Implementation of a Shafer-Shenoy's-like version of lazy propagation for inference in Bayesian networ...
const Sequence< const DiscreteVariable * > & variablesSequence() const final
void add(const DiscreteVariable &v) final
void insert(const Key &k)
Inserts a new element into the set.
void erase(const Key &k)
Erases an element from the set.
const Tensor< GUM_SCALAR > & fillWith(const Tensor< GUM_SCALAR > &src) const
copy a Tensor data using name of variables and labels (not necessarily the same variables in the same...
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
gum is the global namespace for all aGrUM entities
CausalModel< GUM_ELEMENT > counterfactualModel(const CausalModel< GUM_ELEMENT > &cm, const HashTable< std::string, std::string > &profile, const Set< std::string > &whatif)
Build the twin causal model.
Tensor< GUM_ELEMENT > counterfactual(const CausalModel< GUM_ELEMENT > &cm, const Set< std::string > &on, const Set< std::string > &whatif, const HashTable< std::string, std::string > &profile=HashTable< std::string, std::string >(), const HashTable< std::string, std::string > &values=HashTable< std::string, std::string >())
Compute a counterfactual distribution using the high-level API.
Instantiation makeInstantiationFromValues(const Tensor< GUM_SCALAR > &tensor, const HashTable< std::string, std::string > &values)
Creates an instance for a tensor based on a HashTable.