Skip to content

Commit 0f13303

Browse files
committed
One less template
1 parent fc74b85 commit 0f13303

File tree

3 files changed

+45
-50
lines changed

3 files changed

+45
-50
lines changed

gtsam/base/LeveledSpanningTree.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ namespace gtsam {
4242
}
4343
}
4444

45+
LeveledSpanningTree LeveledSpanningTree::FromEdges(const std::vector<Edge>& edges, size_t root) {
46+
// Calculate the number of vertices.
47+
size_t maxVertex = 0;
48+
for (const auto& edge : edges) {
49+
maxVertex = std::max({ maxVertex, edge.first, edge.second });
50+
}
51+
const size_t n = maxVertex + 1;
52+
53+
// Assert that we have at least n-1 vertices
54+
if (edges.size() < n - 1) {
55+
throw std::invalid_argument("Invalid edge list: need at least n-1 edges to form a tree");
56+
}
57+
58+
// Now create the adjacency list representation
59+
Graph graph(n);
60+
for (const auto& edge : edges) {
61+
// Assuming an undirected graph.
62+
graph[edge.first].push_back(edge.second);
63+
graph[edge.second].push_back(edge.first);
64+
}
65+
return LeveledSpanningTree(graph, root);
66+
}
67+
4568
size_t LeveledSpanningTree::parent(size_t vertex) const {
4669
return nodes[vertex]->parent;
4770
}
@@ -101,4 +124,17 @@ namespace gtsam {
101124
return result;
102125
}
103126

127+
LeveledSpanningTree::Cycles LeveledSpanningTree::allFundamentalCycles(const std::vector<LeveledSpanningTree::Edge>& edges) const {
128+
Cycles result;
129+
130+
// Compute fundamental cycles for each non-tree edge in O(E) iterations (each worst-case O(V))
131+
for (const auto& [i, j] : edges) {
132+
if (!contains(i, j)) {
133+
result.push_back(fundamentalCycle(i, j));
134+
}
135+
}
136+
137+
return result;
138+
}
139+
104140
} // namespace gtsam

gtsam/base/LeveledSpanningTree.h

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ namespace gtsam {
4141
*/
4242
class LeveledSpanningTree {
4343
public:
44-
// Type aliases for graph structures
45-
using Graph = std::vector<std::vector<size_t>>;
46-
using Cycle = std::vector<size_t>; // Sequence of vertex indices forming a cycle
44+
using Graph = std::vector<std::vector<size_t>>; // Type aliases for graph structures
45+
using Cycle = std::vector<size_t>; // Sequence of vertex indices forming a cycle
46+
using Cycles = std::vector<Cycle>; // Cycles: Holds all computed fundamental cycles
47+
using Edge = std::pair<size_t, size_t>; // Simple edge representation
4748

4849
private:
4950
struct Node {
@@ -64,34 +65,12 @@ namespace gtsam {
6465
LeveledSpanningTree(const Graph& graph, size_t root);
6566

6667
/**
67-
* Constructs a leveled spanning tree using breadth-first search, templated version.
68-
* @param graph The edge list representation of the graph
68+
* Constructs a leveled spanning tree from a list of edges.
69+
* @param edges The edge list representation of the graph
6970
* @param root The root vertex for the spanning tree
7071
* Time complexity: O(V+E) where V is the number of vertices and E is the number of edges
7172
*/
72-
template <typename EdgeType>
73-
static LeveledSpanningTree FromEdges(const std::vector<EdgeType>& edges, size_t root) {
74-
// Calculate the number of vertices.
75-
size_t maxVertex = 0;
76-
for (const auto& edge : edges) {
77-
maxVertex = std::max({ maxVertex, edge.i, edge.j });
78-
}
79-
const size_t n = maxVertex + 1;
80-
81-
// Assert that we have at least n-1 vertices
82-
if (edges.size() < n - 1) {
83-
throw std::invalid_argument("Invalid edge list: need at least n-1 edges to form a tree");
84-
}
85-
86-
// Now create the adjacency list representation
87-
Graph graph(n);
88-
for (const auto& edge : edges) {
89-
// Assuming an undirected graph.
90-
graph[edge.i].push_back(edge.j);
91-
graph[edge.j].push_back(edge.i);
92-
}
93-
return LeveledSpanningTree(graph, root);
94-
}
73+
static LeveledSpanningTree FromEdges(const std::vector<Edge>& edges, size_t root);
9574

9675
/**
9776
* Constructs a leveled spanning tree using breadth-first search, factor graph version.
@@ -156,9 +135,6 @@ namespace gtsam {
156135
*/
157136
Cycle fundamentalCycle(size_t u, size_t v) const;
158137

159-
// Cycles: Holds all computed fundamental cycles
160-
using Cycles = std::vector<Cycle>;
161-
162138
/**
163139
* Compute all fundamental cycles given an adjacency list.
164140
* @return A list of fundamental cycles, each represented as a sequence of vertices
@@ -171,19 +147,7 @@ namespace gtsam {
171147
* @return A list of fundamental cycles, each represented as a sequence of vertices
172148
* Overall running time: O(E·V) in the worst case.
173149
*/
174-
template <typename EdgeType>
175-
Cycles allFundamentalCycles(const std::vector<EdgeType>& edges) const {
176-
Cycles result;
177-
178-
// Compute fundamental cycles for each non-tree edge in O(E) iterations (each worst-case O(V))
179-
for (const auto& edge : edges) {
180-
if (!contains(edge.i, edge.j)) {
181-
result.push_back(fundamentalCycle(edge.i, edge.j));
182-
}
183-
}
184-
185-
return result;
186-
}
150+
Cycles allFundamentalCycles(const std::vector<Edge>& edges) const;
187151

188152
/**
189153
* Computes fundamental cycles in a factor graph using binary factors.

gtsam/base/tests/testLeveledSpanningTree.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ TEST(FundamentalCycles, AdjacencyList) {
5353
/* ************************************************************************* */
5454
TEST(FundamentalCycles, EdgeList) {
5555
// Test using edge list
56-
struct Edge {
57-
size_t i;
58-
size_t j;
59-
};
60-
61-
std::vector<Edge> edges = {
56+
std::vector<LeveledSpanningTree::Edge> edges = {
6257
{0, 1},
6358
{0, 2},
6459
{1, 2},

0 commit comments

Comments
 (0)