← Documentation
ADS-IDAC Engine 5.0.0
graph.cpp
Go to the documentation of this file.
2
3namespace bncore {
4
5NodeId Graph::add_variable(const std::string &name,
6 const std::vector<std::string> &states) {
7 if (name_to_id_.find(name) != name_to_id_.end()) {
8 throw std::invalid_argument("Variable with name '" + name +
9 "' already exists.");
10 }
11
12 NodeId id = static_cast<NodeId>(variables_.size());
13 variables_.push_back({id, name, states});
14 name_to_id_[name] = id;
15
16 parents_.emplace_back();
17 children_.emplace_back();
18
19 return id;
20}
21
22void Graph::split_state(NodeId id, std::size_t state_idx,
23 const std::string &new_state1,
24 const std::string &new_state2) {
25 if (id >= variables_.size())
26 throw std::out_of_range("Invalid NodeId.");
27 auto &var = variables_[id];
28 if (state_idx >= var.states.size())
29 throw std::out_of_range("Invalid state index.");
30
31 var.states.erase(var.states.begin() + state_idx);
32 var.states.insert(var.states.begin() + state_idx, new_state2);
33 var.states.insert(var.states.begin() + state_idx, new_state1);
34}
35
36void Graph::add_edge(NodeId parent, NodeId child) {
37 if (parent >= variables_.size() || child >= variables_.size()) {
38 throw std::out_of_range("Invalid NodeId provided for edge.");
39 }
40 parents_[child].push_back(parent);
41 children_[parent].push_back(child);
42}
43
44void Graph::add_edge(const std::string &parent_name,
45 const std::string &child_name) {
46 add_edge(get_variable(parent_name).id, get_variable(child_name).id);
47}
48
49void Graph::set_cpt(NodeId id, const std::vector<double> &cpt) {
50 if (id >= variables_.size())
51 throw std::out_of_range("Invalid NodeId");
52
53 std::size_t family_states = variables_[id].states.size();
54 for (NodeId p : parents_[id]) {
55 family_states *= variables_[p].states.size();
56 }
57
58 if (cpt.empty()) {
59 throw std::invalid_argument("CPT for variable '" + variables_[id].name +
60 "' cannot be empty. Expected scalar size " +
61 std::to_string(family_states) +
62 " or batched size " +
63 std::to_string(family_states) + " * B.");
64 }
65
66 if (cpt.size() == family_states) {
67 variables_[id].cpt = cpt;
68 return;
69 }
70
71 if (cpt.size() % family_states != 0) {
72 throw std::invalid_argument(
73 "CPT size mismatch for variable '" + variables_[id].name +
74 "'. Expected scalar size " + std::to_string(family_states) +
75 " or batched size " + std::to_string(family_states) +
76 " * B (B > 0), but got " + std::to_string(cpt.size()) + ".");
77 }
78
79 std::size_t batch_size = cpt.size() / family_states;
80 if (batch_size == 0) {
81 throw std::invalid_argument("CPT for variable '" + variables_[id].name +
82 "' has invalid batch size 0.");
83 }
84
85 variables_[id].cpt = cpt;
86}
87
88void Graph::set_cpt(const std::string &name, const std::vector<double> &cpt) {
89 set_cpt(name_to_id_.at(name), cpt);
90}
91
93 if (id >= variables_.size())
94 throw std::out_of_range("Invalid NodeId.");
95 return variables_[id];
96}
97
98const VariableMetadata &Graph::get_variable(const std::string &name) const {
99 auto it = name_to_id_.find(name);
100 if (it == name_to_id_.end())
101 throw std::invalid_argument("Variable not found.");
102 return variables_[it->second];
103}
104
105const std::vector<NodeId> &Graph::get_parents(NodeId id) const {
106 if (id >= parents_.size())
107 throw std::out_of_range("Invalid NodeId.");
108 return parents_[id];
109}
110
111const std::vector<NodeId> &Graph::get_children(NodeId id) const {
112 if (id >= children_.size())
113 throw std::out_of_range("Invalid NodeId.");
114 return children_[id];
115}
116
117std::size_t Graph::num_variables() const { return variables_.size(); }
118
119} // namespace bncore
void add_edge(NodeId parent, NodeId child)
Adds a directed edge from parent to child.
Definition: graph.cpp:36
const std::vector< NodeId > & get_parents(NodeId id) const
Parents of a variable, in the order their edges were added.
Definition: graph.cpp:105
std::unordered_map< std::string, NodeId > name_to_id_
Definition: graph.hpp:135
std::vector< VariableMetadata > variables_
indexed by NodeId
Definition: graph.hpp:134
std::vector< std::vector< NodeId > > parents_
parents_[child], in edge insertion order
Definition: graph.hpp:138
void set_cpt(NodeId id, const std::vector< double > &cpt)
Stores the conditional probability table of a variable.
Definition: graph.cpp:49
std::vector< std::vector< NodeId > > children_
children_[parent], in edge insertion order
Definition: graph.hpp:139
std::size_t num_variables() const
Number of variables added so far.
Definition: graph.cpp:117
const std::vector< NodeId > & get_children(NodeId id) const
Children of a variable, in the order their edges were added.
Definition: graph.cpp:111
const VariableMetadata & get_variable(NodeId id) const
Metadata of a variable.
Definition: graph.cpp:92
NodeId add_variable(const std::string &name, const std::vector< std::string > &states)
Adds a variable.
Definition: graph.cpp:5
void split_state(NodeId id, std::size_t state_idx, const std::string &new_state1, const std::string &new_state2)
Replaces one state of a variable by two states.
Definition: graph.cpp:22
bncore::Graph, the discrete Bayesian network model: variables, their states, directed edges and condi...
std::uint32_t NodeId
Handle of a variable within one Graph.
Definition: node.hpp:20
Everything a Graph stores about one discrete variable.
Definition: node.hpp:23