gtsam
Loading...
Searching...
No Matches
Values.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
24
25#pragma once
26
27#include <gtsam/inference/Key.h>
29#include <gtsam/base/GenericValue.h>
30#include <gtsam/base/VectorSpace.h>
31
32#if GTSAM_ENABLE_BOOST_SERIALIZATION
33#include <boost/serialization/unique_ptr.hpp>
34#endif
35
36
37#include <memory>
38#include <string>
39#include <utility>
40
41namespace gtsam {
42
43 // Forward declarations / utilities
44 class VectorValues;
45 class ValueAutomaticCasting;
46 template<typename T> static bool _truePredicate(const T&) { return true; }
47
48 /* ************************************************************************* */
49 class GTSAM_EXPORT ValueCloneAllocator {
50 public:
51 static Value* allocate_clone(const Value& a) { return a.clone_(); }
52 static void deallocate_clone(const Value* a) { a->deallocate_(); }
53 ValueCloneAllocator() {}
54 };
55
65 class GTSAM_EXPORT Values {
66
67 private:
68 // Internally we store a boost ptr_map, with a ValueCloneAllocator (defined
69 // below) to clone and deallocate the Value objects, and our compile-flag-
70 // dependent FastDefaultAllocator to allocate map nodes. In this way, the
71 // user defines the allocation details (i.e. optimize for memory pool/arenas
72 // concurrency).
73 typedef internal::FastDefaultAllocator<typename std::pair<const Key, void*>>::type KeyValuePtrPairAllocator;
74 using KeyValueMap =
75 std::map<Key, std::unique_ptr<Value>, std::less<Key>,
76 std::allocator<std::pair<const Key, std::unique_ptr<Value>>>>;
77
78 // The member to store the values, see just above
79 KeyValueMap values_;
80
81 // Friend access for efficient in-place updates.
82 friend class NonlinearMultifrontalSolver;
83
84 public:
85
87 typedef std::shared_ptr<Values> shared_ptr;
88
90 typedef std::shared_ptr<const Values> const_shared_ptr;
91
93 struct GTSAM_EXPORT KeyValuePair {
94 const Key key;
96
97 KeyValuePair(Key _key, Value& _value) : key(_key), value(_value) {}
98 };
99
101 struct GTSAM_EXPORT ConstKeyValuePair {
102 const Key key;
103 const Value& value;
104
105 ConstKeyValuePair(Key _key, const Value& _value) : key(_key), value(_value) {}
106 ConstKeyValuePair(const KeyValuePair& kv) : key(kv.key), value(kv.value) {}
107 };
108
109 typedef KeyValuePair value_type;
110
113
115 Values() = default;
116
118 Values(const Values& other);
119
121 Values(Values&& other);
122
128 Values(std::initializer_list<ConstKeyValuePair> init);
129
131 Values(const Values& other, const VectorValues& delta);
132
136
138 void print(const std::string& str = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const;
139
141 bool equals(const Values& other, double tol=1e-9) const;
142
146
155 template <typename ValueType>
156 const ValueType at(Key j) const;
157
162 template <typename ValueType>
163 const ValueType& atRef(Key j) const;
164
166 double atDouble(size_t key) const { return at<double>(key);}
167
173 const Value& at(Key j) const;
174
178 bool exists(Key j) const;
179
184 template<typename ValueType>
185 const ValueType * exists(Key j) const;
186
188 size_t size() const { return values_.size(); }
189
191 bool empty() const { return values_.empty(); }
192
196
197 struct deref_iterator {
198 using const_iterator_type = typename KeyValueMap::const_iterator;
199 const_iterator_type it_;
200 deref_iterator(const_iterator_type it) : it_(it) {}
201 ConstKeyValuePair operator*() const { return {it_->first, *(it_->second)}; }
202 std::unique_ptr<ConstKeyValuePair> operator->() const {
203 return std::make_unique<ConstKeyValuePair>(it_->first, *(it_->second));
204 }
205 bool operator==(const deref_iterator& other) const {
206 return it_ == other.it_;
207 }
208 bool operator!=(const deref_iterator& other) const { return it_ != other.it_; }
209 deref_iterator& operator++() {
210 ++it_;
211 return *this;
212 }
213 };
214
215 deref_iterator begin() const { return deref_iterator(values_.begin()); }
216 deref_iterator end() const { return deref_iterator(values_.end()); }
217
220 deref_iterator find(Key j) const { return deref_iterator(values_.find(j)); }
221
223 deref_iterator lower_bound(Key j) const { return deref_iterator(values_.lower_bound(j)); }
224
226 deref_iterator upper_bound(Key j) const { return deref_iterator(values_.upper_bound(j)); }
227
231
233 Values retract(const VectorValues& delta) const;
234
245 Values retract(const VectorValues& delta, const KeyVector& keys) const;
246
251 void retractMasked(const VectorValues& delta, const KeySet& mask);
252
254 VectorValues localCoordinates(const Values& cp) const;
255
257
259 void insert(Key j, const Value& val);
260
262 void insert(const Values& values);
263
267 template <typename ValueType>
268 void insert(Key j, const ValueType& val);
269
279 template <typename UnaryOp, typename ValueType>
280 void insert(Key j, const Eigen::CwiseUnaryOp<UnaryOp, const ValueType>& val);
281
292 template <typename BinaryOp, typename ValueType1, typename ValueType2>
293 void insert(Key j, const Eigen::CwiseBinaryOp<BinaryOp, const ValueType1, const ValueType2>& val);
294
296 void insertDouble(Key j, double c) { insert<double>(j,c); }
297
299 void insertPoint3(Key j, const Vector3& point3) {
300 insert<Vector3>(j, point3);
301 }
302
304 void update(Key j, const Value& val);
305
310 template <typename T>
311 void update(Key j, const T& val);
312
316 template <typename UnaryOp, typename ValueType>
317 void update(Key j, const Eigen::CwiseUnaryOp<UnaryOp, const ValueType>& val);
318
322 template <typename BinaryOp, typename ValueType1, typename ValueType2>
323 void update(Key j, const Eigen::CwiseBinaryOp<BinaryOp, const ValueType1, const ValueType2>& val);
324
326 void update(const Values& values);
327
329 void insert_or_assign(Key j, const Value& val);
330
335 void insert_or_assign(const Values& values);
336
338 template <typename ValueType>
339 void insert_or_assign(Key j, const ValueType& val);
340
344 template <typename UnaryOp, typename ValueType>
345 void insert_or_assign(Key j, const Eigen::CwiseUnaryOp<UnaryOp, const ValueType>& val);
346
350 template <typename BinaryOp, typename ValueType1, typename ValueType2>
351 void insert_or_assign(Key j, const Eigen::CwiseBinaryOp<BinaryOp, const ValueType1, const ValueType2>& val);
352
354 void erase(Key j);
355
360 KeyVector keys() const;
361
365 KeySet keySet() const;
366
375 Values extract(const KeyVector& keys) const;
376
378 Values& operator=(const Values& rhs);
379
381 void swap(Values& other) { values_.swap(other.values_); }
382
384 void clear() { values_.clear(); }
385
387 size_t dim() const;
388
390 std::map<Key,size_t> dims() const;
391
393 VectorValues zeroVectors() const;
394
395 // Count values of given type \c ValueType
396 template <class ValueType>
397 size_t count() const;
398
418 template <class ValueType>
419 std::map<Key, ValueType> // , std::less<Key>, Eigen::aligned_allocator<ValueType>
420 extract(const std::function<bool(Key)>& filterFcn = &_truePredicate<Key>) const;
421
422 private:
423 // Filters based on ValueType (if not Value) and also based on the user-
424 // supplied \c filter function.
425 template<class ValueType>
426 static bool filterHelper(const std::function<bool(Key)> filter, const ConstKeyValuePair& key_value) {
427 // static_assert if ValueType is type: Value
428 static_assert(!std::is_same<Value, ValueType>::value, "ValueType must not be type: Value to use this filter");
429 // Filter and check the type
430 return filter(key_value.key) && (dynamic_cast<const GenericValue<ValueType>*>(&key_value.value));
431 }
432
433#if GTSAM_ENABLE_BOOST_SERIALIZATION
435 friend class boost::serialization::access;
436 template<class ARCHIVE>
437 void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
438 ar & BOOST_SERIALIZATION_NVP(values_);
439 }
440#endif
441
442 };
443
444 /* ************************************************************************* */
445 class ValuesKeyAlreadyExists : public std::exception {
446 protected:
447 const Key key_;
448
449 private:
450 mutable std::string message_;
451
452 public:
455 key_(key) {}
456
457 ~ValuesKeyAlreadyExists() noexcept override {}
458
460 Key key() const noexcept { return key_; }
461
463 GTSAM_EXPORT const char* what() const noexcept override;
464 };
465
466 /* ************************************************************************* */
467 class ValuesKeyDoesNotExist : public std::exception {
468 protected:
469 const char* operation_;
470 const Key key_;
471
472 private:
473 mutable std::string message_;
474
475 public:
477 ValuesKeyDoesNotExist(const char* operation, Key key) noexcept :
478 operation_(operation), key_(key) {}
479
480 ~ValuesKeyDoesNotExist() noexcept override {}
481
483 Key key() const noexcept { return key_; }
484
486 GTSAM_EXPORT const char* what() const noexcept override;
487 };
488
489 /* ************************************************************************* */
490 class ValuesIncorrectType : public std::exception {
491 protected:
492 const Key key_;
493 const std::type_info& storedTypeId_;
494 const std::type_info& requestedTypeId_;
495
496 private:
497 mutable std::string message_;
498
499 public:
502 const std::type_info& storedTypeId, const std::type_info& requestedTypeId) noexcept :
503 key_(key), storedTypeId_(storedTypeId), requestedTypeId_(requestedTypeId) {}
504
505 ~ValuesIncorrectType() noexcept override {}
506
508 Key key() const noexcept { return key_; }
509
511 const std::type_info& storedTypeId() const { return storedTypeId_; }
512
514 const std::type_info& requestedTypeId() const { return requestedTypeId_; }
515
517 GTSAM_EXPORT const char* what() const noexcept override;
518 };
519
520 /* ************************************************************************* */
521 class DynamicValuesMismatched : public std::exception {
522
523 public:
524 DynamicValuesMismatched() noexcept {}
525
526 ~DynamicValuesMismatched() noexcept override {}
527
528 const char* what() const noexcept override {
529 return "The Values 'this' and the argument passed to Values::localCoordinates have mismatched keys and values";
530 }
531 };
532
533 /* ************************************************************************* */
534 class NoMatchFoundForFixed: public std::exception {
535
536 protected:
537 const size_t M1_, N1_;
538 const size_t M2_, N2_;
539
540 private:
541 mutable std::string message_;
542
543 public:
544 NoMatchFoundForFixed(size_t M1, size_t N1, size_t M2, size_t N2) noexcept :
545 M1_(M1), N1_(N1), M2_(M2), N2_(N2) {
546 }
547
548 ~NoMatchFoundForFixed() noexcept override {
549 }
550
551 GTSAM_EXPORT const char* what() const noexcept override;
552 };
553
554 /* ************************************************************************* */
556 template<>
557 struct traits<Values> : public Testable<Values> {
558 };
559
560} //\ namespace gtsam
561
562
563#include <gtsam/nonlinear/Values-inl.h>
An easy way to control which allocator is used for Fast* collections.
STL namespace.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition Key.cpp:30
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition Key.h:35
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
Default allocator for list, map, and set types.
Definition FastDefaultAllocator.h:50
Wraps any type T so it can play as a Value.
Definition GenericValue.h:48
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152
This is the base class for any type to be stored in Values.
Definition Value.h:39
virtual void deallocate_() const =0
Deallocate a raw pointer of this value.
virtual Value * clone_() const =0
Clone this value in a special memory pool, must be deleted with Value::deallocate_,...
VectorValues represents a collection of vector-valued variables associated each with a unique integer...
Definition VectorValues.h:73
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
void update(Key j, const T &val)
Templated version to update a variable with the given j, throws KeyDoesNotExist<J> if j is not presen...
bool empty() const
whether the config is empty
Definition Values.h:191
void update(Key j, const Value &val)
single element change of existing element
Definition Values.cpp:186
std::shared_ptr< const Values > const_shared_ptr
A const shared_ptr to this class.
Definition Values.h:90
bool equals(const Values &other, double tol=1e-9) const
Test whether the sets of keys and values are identical.
Definition Values.cpp:79
deref_iterator upper_bound(Key j) const
Find the lowest-ordered element greater than the specified key.
Definition Values.h:226
void insertPoint3(Key j, const Vector3 &point3)
Insert a fixed-size 3-vector without Python overload ambiguity.
Definition Values.h:299
Values & operator=(const Values &rhs)
Replace all keys and variables.
Definition Values.cpp:259
const ValueType at(Key j) const
Retrieve a variable by key j.
Definition Values-inl.h:260
void clear()
Remove all variables from the config.
Definition Values.h:384
std::shared_ptr< Values > shared_ptr
A shared_ptr to this class.
Definition Values.h:87
void swap(Values &other)
Swap the contents of two Values without copying data.
Definition Values.h:381
void insertDouble(Key j, double c)
version for double
Definition Values.h:296
void insert(Key j, const Value &val)
Add a variable with the given j, throws KeyAlreadyExists<J> if j is already present.
Definition Values.cpp:170
size_t size() const
The number of variables in this config.
Definition Values.h:188
deref_iterator find(Key j) const
Find an element by key, returning an iterator, or end() if the key was not found.
Definition Values.h:220
KeyVector keys() const
Returns a vector of keys in the config.
Definition Values.cpp:235
const ValueType & atRef(Key j) const
Retrieve a variable by key j without copying.
Definition Values-inl.h:275
KeySet keySet() const
Returns a set of keys in the config.
Definition Values.cpp:244
void insert_or_assign(Key j, const Value &val)
If key j exists, update value, else perform an insert.
Definition Values.cpp:209
Values extract(const KeyVector &keys) const
Returns a new Values holding copies of the values at the given keys, whatever their types.
Definition Values.cpp:252
void print(const std::string &str="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print method for testing and debugging
Definition Values.cpp:68
Values()=default
Default constructor creates an empty Values class.
void erase(Key j)
Remove a variable from the config, throws KeyDoesNotExist<J> if j is not present.
Definition Values.cpp:227
deref_iterator lower_bound(Key j) const
Find the element greater than or equal to the specified key.
Definition Values.h:223
double atDouble(size_t key) const
version for double
Definition Values.h:166
A key-value pair, which you get by dereferencing iterators.
Definition Values.h:93
Value & value
The value.
Definition Values.h:95
const Key key
The key.
Definition Values.h:94
A key-value pair, which you get by dereferencing iterators.
Definition Values.h:101
const Key key
The key.
Definition Values.h:102
const Value & value
The value.
Definition Values.h:103
Definition Values.h:197
Definition Values.h:445
const Key key_
The key that already existed.
Definition Values.h:447
GTSAM_EXPORT const char * what() const noexcept override
The message to be displayed to the user.
Definition Values.cpp:292
ValuesKeyAlreadyExists(Key key) noexcept
Construct with the key-value pair attempted to be added.
Definition Values.h:454
Key key() const noexcept
The duplicate key that was attempted to be added.
Definition Values.h:460
Definition Values.h:467
ValuesKeyDoesNotExist(const char *operation, Key key) noexcept
Construct with the key that does not exist in the values.
Definition Values.h:477
const Key key_
The key that does not exist.
Definition Values.h:470
Key key() const noexcept
The key that was attempted to be accessed that does not exist.
Definition Values.h:483
const char * operation_
The operation that attempted to access the key.
Definition Values.h:469
Definition Values.h:490
const std::type_info & storedTypeId() const
The typeid of the value stores in the Values.
Definition Values.h:511
Key key() const noexcept
The key that was attempted to be accessed that does not exist.
Definition Values.h:508
const Key key_
The key requested.
Definition Values.h:492
ValuesIncorrectType(Key key, const std::type_info &storedTypeId, const std::type_info &requestedTypeId) noexcept
Construct with the key that does not exist in the values.
Definition Values.h:501
const std::type_info & requestedTypeId() const
The requested typeid.
Definition Values.h:514