mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 16:40:38 +08:00
Add ExpressionGraph::Erase(ExpressionId)
Add the function ExpressionGraph::Erase and a test-case for it. Erase removes the given expression from the graph by shifting all later expressions to the front. Indices and references are updated accordingly. Change-Id: Ic0449ccf28b369600fd2959a7e2a919d47f4cbe3
This commit is contained in:
@@ -64,6 +64,12 @@ class ExpressionGraph {
|
||||
|
||||
int Size() const { return expressions_.size(); }
|
||||
|
||||
// Erases the expression at "location". All expression after "location" are
|
||||
// moved by one element to the front. References to moved expressions are
|
||||
// updated. Removing an expression that is still referenced somewhere is
|
||||
// undefined behaviour.
|
||||
void Erase(ExpressionId location);
|
||||
|
||||
// Insert a new expression at "location" into the graph. All expression
|
||||
// after "location" are moved by one element to the back. References to
|
||||
// moved expressions are updated.
|
||||
|
||||
@@ -250,5 +250,37 @@ TEST(ExpressionGraph, InsertExpression_UpdateReferences) {
|
||||
EXPECT_EQ(graph, ref);
|
||||
}
|
||||
|
||||
TEST(ExpressionGraph, Erase) {
|
||||
// This test checks if references to shifted expressions are updated
|
||||
// accordingly.
|
||||
ExpressionGraph graph;
|
||||
graph.InsertBack(Expression::CreateCompileTimeConstant(42));
|
||||
graph.InsertBack(Expression::CreateCompileTimeConstant(10));
|
||||
graph.InsertBack(Expression::CreateCompileTimeConstant(3));
|
||||
graph.InsertBack(Expression::CreateBinaryArithmetic(
|
||||
"+", ExpressionId(0), ExpressionId(2)));
|
||||
// Code:
|
||||
// v_0 = 42
|
||||
// v_1 = 10
|
||||
// v_2 = 3
|
||||
// v_3 = v_0 + v_2
|
||||
|
||||
// Erase the unused expression v_1 = 10
|
||||
graph.Erase(1);
|
||||
// This should shift all indices like this:
|
||||
// v_0 = 42
|
||||
// v_1 = 3
|
||||
// v_2 = v_0 + v_1
|
||||
|
||||
// Test by inserting it in the correct order
|
||||
ExpressionGraph ref;
|
||||
ref.InsertBack(Expression::CreateCompileTimeConstant(42));
|
||||
ref.InsertBack(Expression::CreateCompileTimeConstant(3));
|
||||
ref.InsertBack(Expression::CreateBinaryArithmetic(
|
||||
"+", ExpressionId(0), ExpressionId(1)));
|
||||
EXPECT_EQ(graph.Size(), ref.Size());
|
||||
EXPECT_EQ(graph, ref);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
@@ -87,8 +87,30 @@ bool ExpressionGraph::operator==(const ExpressionGraph& other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExpressionGraph::Erase(ExpressionId location) {
|
||||
CHECK_GE(location, 0);
|
||||
CHECK_LT(location, Size());
|
||||
// Move everything after id to the front and update references
|
||||
for (ExpressionId id = location + 1; id < Size(); ++id) {
|
||||
expressions_[id - 1] = expressions_[id];
|
||||
auto& expression = expressions_[id - 1];
|
||||
// Decrement reference if it points to a shifted variable.
|
||||
if (expression.lhs_id() >= location) {
|
||||
expression.set_lhs_id(expression.lhs_id() - 1);
|
||||
}
|
||||
for (auto& arg : *expression.mutable_arguments()) {
|
||||
if (arg >= location) {
|
||||
arg--;
|
||||
}
|
||||
}
|
||||
}
|
||||
expressions_.resize(Size() - 1);
|
||||
}
|
||||
|
||||
void ExpressionGraph::Insert(ExpressionId location,
|
||||
const Expression& expression) {
|
||||
CHECK_GE(location, 0);
|
||||
CHECK_LE(location, Size());
|
||||
ExpressionId last_expression_id = Size() - 1;
|
||||
// Increase size by adding a dummy expression.
|
||||
expressions_.push_back(Expression());
|
||||
|
||||
Reference in New Issue
Block a user