aGrUM  0.17.1
a C++ library for (probabilistic) graphical models
structuralComparator.cpp
Go to the documentation of this file.
1 
24 
25 
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 
28 namespace gum {
30  GUM_CONSTRUCTOR(StructuralComparator);
31  }
32 
35  GUM_DESTRUCTOR(StructuralComparator);
36  }
37 
38  void StructuralComparator::compare(const DiGraph& ref, const DiGraph& test) {
39  if (ref.size() != test.size()) {
40  GUM_ERROR(OperationNotAllowed, "Graphs of different sizes");
41  }
42  for (const NodeId node: ref.asNodeSet()) {
43  if (!test.existsNode(node)) {
44  GUM_ERROR(InvalidNode, "Test doesn't contain all nodes from ref");
45  }
46  }
47  // compute the orientation matrix
48  // no edges so these stay null
49  __true_edge = 0;
50  __wrong_edge_arc = 0;
52  __wrong_arc_edge = 0;
54  // these will be filled
55  __true_arc = 0;
56  __true_none = 0;
58  __wrong_arc_none = 0;
59  __wrong_none_arc = 0;
60 
61  for (const Arc& arc: ref.arcs()) {
62  if (test.existsArc(arc)) {
63  ++__true_arc;
64  } else if (test.existsArc(arc.head(), arc.tail())) {
66  } else {
68  }
69  }
70  for (const Arc& arc: test.arcs()) {
71  if (!ref.existsArc(arc) && !ref.existsArc(arc.head(), arc.tail())) {
73  }
74  }
75  // TN = #possible arcs - #existing arcs
76  __true_none = ref.size() * (ref.size() - 1) - __true_arc - __misoriented_arc
78  }
79 
80  void StructuralComparator::compare(const UndiGraph& ref, const UndiGraph& test) {
81  if (ref.size() != test.size()) {
82  GUM_ERROR(OperationNotAllowed, "Graphs of different sizes");
83  }
84  for (const NodeId node: ref.asNodeSet()) {
85  if (!test.existsNode(node)) {
86  GUM_ERROR(InvalidNode, "Test doesn't contain all nodes from ref");
87  }
88  }
89  // compute the orientation matrix
90  // no arcs so these stay null
91  __true_arc = 0;
93  __wrong_arc_none = 0;
94  __wrong_none_arc = 0;
95  __wrong_edge_arc = 0;
96  __wrong_arc_edge = 0;
97  // these will be filled
98  __true_edge = 0;
99  __true_none = 0;
100  __wrong_edge_none = 0;
101  __wrong_none_edge = 0;
102 
103  for (const Edge& edge: ref.edges()) {
104  if (test.existsEdge(edge)) {
105  ++__true_edge;
106  } else {
108  }
109  }
110  for (const Edge& edge: test.edges()) {
111  if (!ref.existsEdge(edge)) { ++__wrong_edge_none; }
112  }
113  // TN = #possible edges - #existing edges
114  __true_none = ref.size() * (ref.size() - 1) / 2 - __true_edge
116  }
117 
118  void StructuralComparator::compare(const MixedGraph& ref,
119  const MixedGraph& test) {
120  if (ref.size() != test.size()) {
121  GUM_ERROR(OperationNotAllowed, "Graphs of different sizes");
122  }
123  for (const NodeId node: ref.asNodeSet()) {
124  if (!test.existsNode(node)) {
125  GUM_ERROR(InvalidNode, "Test doesn't contain all nodes from ref");
126  }
127  }
128 
129  // compute the orientation matrix
130  __true_arc = 0;
131  __true_edge = 0;
132  __true_none = 0;
133  __misoriented_arc = 0;
134  __wrong_arc_edge = 0;
135  __wrong_arc_none = 0;
136  __wrong_edge_arc = 0;
137  __wrong_edge_none = 0;
138  __wrong_none_arc = 0;
139  __wrong_none_edge = 0;
140 
141  for (const Arc& arc: ref.arcs()) {
142  if (test.existsArc(arc)) {
143  ++__true_arc;
144  } else if (test.existsArc(arc.head(), arc.tail())) {
146  } else if (test.existsEdge(arc.tail(), arc.head())) {
148  } else {
150  }
151  }
152  for (const Edge& edge: ref.edges()) {
153  if (test.existsEdge(edge)) {
154  ++__true_edge;
155  } else if (test.existsArc(edge.first(), edge.second())
156  || test.existsArc(edge.second(), edge.first())) {
158  } else {
160  }
161  }
162  for (const Arc& arc: test.arcs()) {
163  if (!ref.existsArc(arc) && !ref.existsArc(arc.head(), arc.tail())
164  && !ref.existsEdge(arc.tail(), arc.head())) {
166  }
167  }
168  for (const Edge& edge: test.edges()) {
169  if (!ref.existsEdge(edge) && !ref.existsArc(edge.first(), edge.second())
170  && !ref.existsArc(edge.second(), edge.first())) {
172  }
173  }
174  // TN = #possible edges - #existing edges
175  __true_none = ref.size() * (ref.size() - 1) / 2 - __true_edge
178  }
179 
181  double tp, fp, precision;
185  precision = tp / (tp + fp);
186  return precision;
187  }
188 
190  double tp, fn, recall;
194  recall = tp / (tp + fn);
195  return recall;
196  }
197 
199  double tp, fp, fn, precision, recall, f_score;
204 
205  precision = tp / (tp + fp);
206  recall = tp / (tp + fn);
207  f_score = 2 * precision * recall / (precision + recall);
208  return f_score;
209  }
210 
211  double StructuralComparator::precision() const {
212  double tp, fp, precision;
213  tp = __true_arc + __true_edge;
216  precision = tp / (tp + fp);
217  return precision;
218  }
219 
220  double StructuralComparator::recall() const {
221  double tp, fn, recall;
222  tp = __true_arc + __true_edge;
224  recall = tp / (tp + fn);
225  return recall;
226  }
227 
228  double StructuralComparator::f_score() const {
229  double tp, fp, fn, precision, recall, f_score;
230  tp = __true_arc + __true_edge;
234 
235  precision = tp / (tp + fp);
236  recall = tp / (tp + fn);
237 
238  f_score = 2 * precision * recall / (precision + recall);
239  return f_score;
240  }
241 
242 } /* namespace gum */
243 
244 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
double f_score_skeleton() const
compare two DiGraphs
double recall_skeleton() const
compare two DiGraphs
double f_score() const
compare two DiGraphs
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
double precision() const
Measures for the graphs.
double recall() const
compare two DiGraphs
StructuralComparator()
default constructor
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
void compare(const DiGraph &ref, const DiGraph &test)
compare two DiGraphs
double __true_edge
Confusion matrix.
double precision_skeleton() const
Measures for the skeleton, aka graph without orientations.
~StructuralComparator()
destructor
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55