diff --git a/gtsam/nonlinear/Values-inl.h b/gtsam/nonlinear/Values-inl.h index 8ebdcab17..e3e534668 100644 --- a/gtsam/nonlinear/Values-inl.h +++ b/gtsam/nonlinear/Values-inl.h @@ -391,4 +391,10 @@ namespace gtsam { update(j, static_cast(GenericValue(val))); } + // upsert with templated value + template + void Values::upsert(Key j, const ValueType& val) { + upsert(j, static_cast(GenericValue(val))); + } + } diff --git a/gtsam/nonlinear/Values.cpp b/gtsam/nonlinear/Values.cpp index ebc9c51f6..c866cc3b5 100644 --- a/gtsam/nonlinear/Values.cpp +++ b/gtsam/nonlinear/Values.cpp @@ -171,6 +171,24 @@ namespace gtsam { } } + /* ************************************************************************* */ + void Values::upsert(Key j, const Value& val) { + if (this->exists(j)) { + // If key already exists, perform an update. + this->update(j, val); + } else { + // If key does not exist, perform an insert. + this->insert(j, val); + } + } + + /* ************************************************************************* */ + void Values::upsert(const Values& values) { + for(const_iterator key_value = values.begin(); key_value != values.end(); ++key_value) { + this->upsert(key_value->key, key_value->value); + } + } + /* ************************************************************************* */ void Values::erase(Key j) { KeyValueMap::iterator item = values_.find(j); diff --git a/gtsam/nonlinear/Values.h b/gtsam/nonlinear/Values.h index 207f35540..8c318ef93 100644 --- a/gtsam/nonlinear/Values.h +++ b/gtsam/nonlinear/Values.h @@ -285,6 +285,16 @@ namespace gtsam { /** update the current available values without adding new ones */ void update(const Values& values); + /** Update a variable with key j. If j does not exist, then perform an insert. */ + void upsert(Key j, const Value& val); + + /** Update a set of variables. If any variable key doe not exist, then perform an insert. */ + void upsert(const Values& values); + + /** Templated version to upsert (update/insert) a variable with the given j. */ + template + void upsert(Key j, const ValueType& val); + /** Remove a variable from the config, throws KeyDoesNotExist if j is not present */ void erase(Key j); diff --git a/gtsam/nonlinear/nonlinear.i b/gtsam/nonlinear/nonlinear.i index 152c4b8e7..695117847 100644 --- a/gtsam/nonlinear/nonlinear.i +++ b/gtsam/nonlinear/nonlinear.i @@ -275,6 +275,7 @@ class Values { void insert(const gtsam::Values& values); void update(const gtsam::Values& values); + void upsert(const gtsam::Values& values); void erase(size_t j); void swap(gtsam::Values& values); @@ -351,6 +352,32 @@ class Values { void update(size_t j, Matrix matrix); void update(size_t j, double c); + void upsert(size_t j, const gtsam::Point2& point2); + void upsert(size_t j, const gtsam::Point3& point3); + void upsert(size_t j, const gtsam::Rot2& rot2); + void upsert(size_t j, const gtsam::Pose2& pose2); + void upsert(size_t j, const gtsam::SO3& R); + void upsert(size_t j, const gtsam::SO4& Q); + void upsert(size_t j, const gtsam::SOn& P); + void upsert(size_t j, const gtsam::Rot3& rot3); + void upsert(size_t j, const gtsam::Pose3& pose3); + void upsert(size_t j, const gtsam::Unit3& unit3); + void upsert(size_t j, const gtsam::Cal3_S2& cal3_s2); + void upsert(size_t j, const gtsam::Cal3DS2& cal3ds2); + void upsert(size_t j, const gtsam::Cal3Bundler& cal3bundler); + void upsert(size_t j, const gtsam::Cal3Fisheye& cal3fisheye); + void upsert(size_t j, const gtsam::Cal3Unified& cal3unified); + void upsert(size_t j, const gtsam::EssentialMatrix& essential_matrix); + void upsert(size_t j, const gtsam::PinholeCamera& camera); + void upsert(size_t j, const gtsam::PinholeCamera& camera); + void upsert(size_t j, const gtsam::PinholeCamera& camera); + void upsert(size_t j, const gtsam::PinholeCamera& camera); + void upsert(size_t j, const gtsam::imuBias::ConstantBias& constant_bias); + void upsert(size_t j, const gtsam::NavState& nav_state); + void upsert(size_t j, Vector vector); + void upsert(size_t j, Matrix matrix); + void upsert(size_t j, double c); + template (key1))); } +TEST(Values, upsert) { + Values values; + Key X(0); + double x = 1; + + CHECK(values.size() == 0); + // This should perform an insert. + values.upsert(X, x); + EXPECT(assert_equal(values.at(X), x)); + + // This should perform an update. + double y = 2; + values.upsert(X, y); + EXPECT(assert_equal(values.at(X), y)); +} + /* ************************************************************************* */ TEST(Values, basic_functions) {