-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgraph.cc
129 lines (112 loc) · 3.87 KB
/
graph.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2013 Jacob Emmert-Aronson
// This file is part of Tensor Network.
//
// Tensor Network is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Tensor Network is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Tensor Network. If not, see
// <http://www.gnu.org/licenses/>.
#include <functional>
#include "graph.hh"
#include "tensor.hh"
using std::hash;
using std::iterator;
using std::unordered_set;
// ########################### GraphEdge ################################
// ########################### operator== ############################
bool GraphEdge::operator== (const GraphEdge &v) const
{
return input_tensor == v.input_tensor && input_num == v.input_num
&& output_tensor == v.output_tensor && output_num == v.output_num;
}
// ########################### operator!= ############################
bool GraphEdge::operator!= (const GraphEdge &v) const
{
return input_tensor != v.input_tensor || input_num != v.input_num
|| output_tensor != v.output_tensor || output_num != v.output_num;
}
// ########################### DFSGraph ##############################
// ########################### constructor ###########################
DFSGraph::DFSGraph(Tensor *t)
{
_dfs(t);
}
// ########################### vertices ##############################
size_t DFSGraph::vertices()
{
return _vertices.size();
}
// ########################### edges #################################
size_t DFSGraph::edges()
{
return _edges.size();
}
// ########################### vertex_begin ##########################
unordered_set<Tensor*>::const_iterator DFSGraph::vertex_begin()
{
return _vertices.cbegin();
}
// ########################### vertex_end ############################
unordered_set<Tensor*>::const_iterator DFSGraph::vertex_end()
{
return _vertices.cend();
}
// ########################### edge_begin ############################
unordered_set<GraphEdge>::const_iterator DFSGraph::edge_begin()
{
return _edges.cbegin();
}
// ########################### edge_end ##############################
unordered_set<GraphEdge>::const_iterator DFSGraph::edge_end()
{
return _edges.cend();
}
// ########################### endpt_begin ###########################
unordered_set<GraphEdge>::const_iterator DFSGraph::endpt_begin()
{
return _endpts.cbegin();
}
// ########################### endpt_end #############################
unordered_set<GraphEdge>::const_iterator DFSGraph::endpt_end()
{
return _endpts.cend();
}
// ########################### _dfs ##################################
void DFSGraph::_dfs(Tensor *t)
{
// add to "unprocessed" list
_vertices.insert(t);
for(size_t i = 0; i < t->inputs(); ++i)
{
// process all tensors linked via inputs and outputs
Tensor *adj = t->input_tensor(i);
if(nullptr != adj)
{
// Record the discovered edge, and recurse into the adjacent
// tensor if it has not been previously encountered.
if( !_vertices.count(adj) ) _dfs(adj);
_edges.insert(GraphEdge{t, i, adj, t->input_num(i)});
}
else _endpts.insert(GraphEdge{t, i, nullptr, 0});
}
for(size_t i = 0; i < t->outputs(); ++i)
{
// If the adjacent tensor has not yet been encountered, register
// the edge and recurse into it. The edge has been / will be
// recorded when processing in the opposite direction.
Tensor *adj = t->output_tensor(i);
if(nullptr != adj)
{
if(!_vertices.count(adj)) _dfs(adj);
}
else _endpts.insert(GraphEdge{nullptr, 0, t, i});
}
}