Direct Graphical Models  v.1.7.0
GraphWeiss.cpp
1 #include "GraphWeiss.h"
2 #include "macroses.h"
3 
4 namespace DirectGraphicalModels
5 {
6  // Constructor
7  CGraphWeiss::CGraphWeiss(byte nStates)
8  : IGraphPairwise(nStates)
9  , m_IDx(0)
10  {}
11 
12  // Destructor: clean up the Node objects
14  {
15  size_t nNodes = m_vpNodes.size();
16  for (size_t n = 0; n < nNodes; n++)
17  delete m_vpNodes.at(n);
18  m_vpNodes.clear();
19  }
20 
21  void CGraphWeiss::reset(void)
22  {
23  size_t nNodes = m_vpNodes.size();
24  for (size_t n = 0; n < nNodes; n++)
25  delete m_vpNodes.at(n);
26  m_vpNodes.clear();
27  m_IDx = 0;
28  }
29 
30  // Add a new node to the graph with specified potentional
31  size_t CGraphWeiss::addNode(const Mat &pot)
32  {
33  Node *n = new Node(m_IDx, pot);
34  m_vpNodes.push_back(n);
35  return m_IDx++;
36  }
37 
38  // Set or change the potential of node idx
39  void CGraphWeiss::setNode(size_t node, const Mat &pot)
40  {
41  // Assertions
42  DGM_ASSERT_MSG(node < m_vpNodes.size(), "Node %zu is out of range %zu", node, m_vpNodes.size());
43 
44  if (!m_vpNodes.at(node)->Pot.empty()) m_vpNodes.at(node)->Pot.release();
45  pot.copyTo(m_vpNodes.at(node)->Pot);
46  }
47 
48  // Return node potential vector
49  void CGraphWeiss::getNode(size_t node, Mat &pot) const
50  {
51  // Assertions
52  DGM_ASSERT_MSG(node < m_vpNodes.size(), "Node %zu is out of range %zu", node, m_vpNodes.size());
53  DGM_ASSERT_MSG(!m_vpNodes.at(node)->Pot.empty(), "Specified node %zu is not set", node);
54 
55  m_vpNodes.at(node)->Pot.copyTo(pot);
56  }
57 
58  // Return child nodes ID's
59  void CGraphWeiss::getChildNodes(size_t node, vec_size_t &vNodes) const
60  {
61  // Assertion
62  DGM_ASSERT_MSG(node < m_vpNodes.size(), "Node %zu is out of range %zu", node, m_vpNodes.size());
63 
64  for (size_t e_t = 0; e_t < m_vpNodes.at(node)->to.size(); e_t++)
65  vNodes.push_back(m_vpNodes.at(node)->to.at(e_t)->node2->id);
66  }
67 
68  // Return parent nodes ID's
69  void CGraphWeiss::getParentNodes(size_t node, vec_size_t &vNodes) const
70  {
71  // Assertion
72  DGM_ASSERT_MSG(node < m_vpNodes.size(), "Node %zu is out of range %zu", node, m_vpNodes.size());
73 
74  for (size_t e_f = 0; e_f < m_vpNodes.at(node)->from.size(); e_f++)
75  vNodes.push_back(m_vpNodes.at(node)->from.at(e_f)->node1->id);
76  }
77 
78  size_t CGraphWeiss::getNumEdges(void) const
79  {
80  size_t res = 0;
81  for (const Node* n : m_vpNodes)
82  res += n->to.size();
83  return res;
84  }
85 
86  // Add a new (directed) edge to the graph with specified potentional
87  void CGraphWeiss::addEdge(size_t srcNode, size_t dstNode, byte group, const Mat &pot)
88  {
89  // Assertions
90  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
91  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
92 
93  // Check if the edge exists
94  for (size_t e_t = 0; e_t < m_vpNodes.at(srcNode)->to.size(); e_t++) {
95  Edge *edge_to = m_vpNodes.at(srcNode)->to.at(e_t);
96  DGM_ASSERT(edge_to->node2->id != m_vpNodes.at(dstNode)->id);
97  } // e_t
98 
99  // Else: create a new one
100  Edge *e = new Edge(m_vpNodes.at(srcNode), m_vpNodes.at(dstNode), group, pot);
101  m_vpNodes.at(srcNode)->to.push_back(e);
102  m_vpNodes.at(dstNode)->from.push_back(e);
103  }
104 
105  // Set or change the potentional of an directed edge
106  void CGraphWeiss::setEdge(size_t srcNode, size_t dstNode, const Mat &pot)
107  {
108  // Assertions
109  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
110  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
111 
112  Edge* e = findEdge(srcNode, dstNode);
113  DGM_ASSERT_MSG(e, "The edge (%zu)->(%zu) is not found", srcNode, dstNode);
114 
115  pot.copyTo(e->Pot);
116  }
117 
118  void CGraphWeiss::setEdges(std::optional<byte> group, const Mat& pot)
119  {
120  for (Node* n : m_vpNodes)
121  for (Edge* e : n->to)
122  if (!group || e->group_id == group.value())
123  pot.copyTo(e->Pot);
124  }
125 
126  // Return edge potential matrix
127  void CGraphWeiss::getEdge(size_t srcNode, size_t dstNode, Mat &pot) const
128  {
129  // Assertions
130  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
131  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
132 
133  Edge* e = findEdge(srcNode, dstNode);
134  DGM_ASSERT_MSG(e, "The edge (%zu)->(%zu) is not found", srcNode, dstNode);
135 
136  e->Pot.copyTo(pot);
137  }
138 
139  void CGraphWeiss::setEdgeGroup(size_t srcNode, size_t dstNode, byte group)
140  {
141  // Assertions
142  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
143  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
144 
145  Edge* e = findEdge(srcNode, dstNode);
146  DGM_ASSERT_MSG(e, "The edge (%zu)->(%zu) is not found", srcNode, dstNode);
147 
148  e->group_id = group;
149  }
150 
151  byte CGraphWeiss::getEdgeGroup(size_t srcNode, size_t dstNode) const
152  {
153  // Assertions
154  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
155  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
156 
157  Edge* e = findEdge(srcNode, dstNode);
158  DGM_ASSERT_MSG(e, "The edge (%zu)->(%zu) is not found", srcNode, dstNode);
159 
160  return e->group_id;
161  }
162 
163  void CGraphWeiss::removeEdge(size_t srcNode, size_t dstNode)
164  {
165  // Assertions
166  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
167  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
168 
169  Edge* e = findEdge(srcNode, dstNode);
170  if (!e) {
171  DGM_WARNING("The edge (%zu)->(%zu) is not found", srcNode, dstNode);
172  return;
173  }
174 
175  auto it = std::find(m_vpNodes[srcNode]->to.begin(), m_vpNodes[srcNode]->to.end(), e);
176  m_vpNodes[srcNode]->to.erase(it);
177 
178  it = std::find(m_vpNodes[dstNode]->from.begin(), m_vpNodes[dstNode]->from.end(), e);
179  m_vpNodes[dstNode]->from.erase(it);
180 
181  delete e;
182  }
183 
184  bool CGraphWeiss::isEdgeExists(size_t srcNode, size_t dstNode) const
185  {
186  // Assertions
187  DGM_ASSERT_MSG(srcNode < m_vpNodes.size(), "The source node index %zu is out of range %zu", srcNode, m_vpNodes.size());
188  DGM_ASSERT_MSG(dstNode < m_vpNodes.size(), "The destination node index %zu is out of range %zu", dstNode, m_vpNodes.size());
189 
190  return findEdge(srcNode, dstNode) ? true : false;
191  }
192 
193  CGraphWeiss::Edge* CGraphWeiss::findEdge(size_t srcNode, size_t dstNode) const
194  {
195  for (Edge *edge_to : m_vpNodes[srcNode]->to)
196  if (edge_to->node2->id == dstNode)
197  return edge_to;
198  return NULL;
199  }
200 }
size_t getNumEdges(void) const override
Returns the number of edges in the graph.
Definition: GraphWeiss.cpp:78
size_t addNode(const Mat &pot=EmptyMat) override
Adds an additional node (with specified potentional)
Definition: GraphWeiss.cpp:31
void getEdge(size_t srcNode, size_t dstNode, Mat &pot) const override
Returns the edge potential.
Definition: GraphWeiss.cpp:127
void getNode(size_t node, Mat &pot) const override
Returns the node potential.
Definition: GraphWeiss.cpp:49
void getChildNodes(size_t node, vec_size_t &vNodes) const override
Returns the set of IDs of the child nodes of the argument node.
Definition: GraphWeiss.cpp:59
void setNode(size_t node, const Mat &pot) override
Sets or changes the potential of node.
Definition: GraphWeiss.cpp:39
Mat Pot
The edge potentials: Mat(size: nStates x nStates; type: CV_32FC1)
Definition: GraphWeiss.h:31
Edge * findEdge(size_t srcNode, size_t dstNode) const
Finds and returns the Edge defined by two nodes.
Definition: GraphWeiss.cpp:193
byte group_id
ID of the group, to which the edge belongs.
Definition: GraphWeiss.h:34
void setEdgeGroup(size_t srcNode, size_t dstNode, byte group) override
Assigns a directed edge (srcNode) –> (dstNode) to the group group.
Definition: GraphWeiss.cpp:139
void addEdge(size_t srcNode, size_t dstNode, byte group, const Mat &pot) override
Adds an additional directed edge with specified potentional.
Definition: GraphWeiss.cpp:87
void reset(void) override
Resets the graph.
Definition: GraphWeiss.cpp:21
void removeEdge(size_t srcNode, size_t dstNode) override
Removes the specified edge.
Definition: GraphWeiss.cpp:163
void setEdge(size_t srcNode, size_t dstNode, const Mat &pot) override
Sets or changes the potentional of directed edge.
Definition: GraphWeiss.cpp:106
bool isEdgeExists(size_t srcNode, size_t dstNode) const override
Checks whether the edge exists.
Definition: GraphWeiss.cpp:184
void setEdges(std::optional< byte > group, const Mat &pot) override
Sets the potential pot to all edges belonging to group group.
Definition: GraphWeiss.cpp:118
void getParentNodes(size_t node, vec_size_t &vNodes) const override
Returns the set of IDs of the parent nodes of the argument node.
Definition: GraphWeiss.cpp:69
Interface class for graphical models.
byte getEdgeGroup(size_t srcNode, size_t dstNode) const override
Returns the group of the edge.
Definition: GraphWeiss.cpp:151
Node * node2
Second node in edge.
Definition: GraphWeiss.h:30
CGraphWeiss(byte nStates)
Constructor.
Definition: GraphWeiss.cpp:7