Values.cpp
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 
25 #include <gtsam/nonlinear/Values.h>
27 
28 #ifdef __GNUC__
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-Wunused-variable"
31 #endif
32 #include <boost/bind.hpp>
33 #ifdef __GNUC__
34 #pragma GCC diagnostic pop
35 #endif
36 #include <boost/iterator/transform_iterator.hpp>
37 
38 #include <list>
39 #include <memory>
40 #include <sstream>
41 
42 using namespace std;
43 
44 namespace gtsam {
45 
46  /* ************************************************************************* */
47  Values::Values(const Values& other) {
48  this->insert(other);
49  }
50 
51  /* ************************************************************************* */
52  Values::Values(Values&& other) : values_(std::move(other.values_)) {
53  }
54 
55  /* ************************************************************************* */
56  Values::Values(std::initializer_list<ConstKeyValuePair> init) {
57  for (const auto &kv : init)
58  insert(kv.key, kv.value);
59  }
60 
61  /* ************************************************************************* */
62  Values::Values(const Values& other, const VectorValues& delta) {
63  for (const_iterator key_value = other.begin(); key_value != other.end(); ++key_value) {
64  VectorValues::const_iterator it = delta.find(key_value->key);
65  Key key = key_value->key; // Non-const duplicate to deal with non-const insert argument
66  if (it != delta.end()) {
67  const Vector& v = it->second;
68  Value* retractedValue(key_value->value.retract_(v)); // Retract
69  values_.insert(key, retractedValue); // Add retracted result directly to result values
70  } else {
71  values_.insert(key, key_value->value.clone_()); // Add original version to result values
72  }
73  }
74  }
75 
76  /* ************************************************************************* */
77  void Values::print(const string& str, const KeyFormatter& keyFormatter) const {
78  cout << str << (str.empty() ? "" : "\n");
79  cout << "Values with " << size() << " values:\n";
80  for(const_iterator key_value = begin(); key_value != end(); ++key_value) {
81  cout << "Value " << keyFormatter(key_value->key) << ": ";
82  key_value->value.print("");
83  cout << "\n";
84  }
85  }
86 
87  /* ************************************************************************* */
88  bool Values::equals(const Values& other, double tol) const {
89  if (this->size() != other.size())
90  return false;
91  for (const_iterator it1 = this->begin(), it2 = other.begin();
92  it1 != this->end(); ++it1, ++it2) {
93  const Value& value1 = it1->value;
94  const Value& value2 = it2->value;
95  if (typeid(value1) != typeid(value2) || it1->key != it2->key
96  || !value1.equals_(value2, tol)) {
97  return false;
98  }
99  }
100  return true; // We return false earlier if we find anything that does not match
101 }
102 
103  /* ************************************************************************* */
104  bool Values::exists(Key j) const {
105  return values_.find(j) != values_.end();
106  }
107 
108  /* ************************************************************************* */
110  return Values(*this, delta);
111  }
112 
113  /* ************************************************************************* */
115  if(this->size() != cp.size())
116  throw DynamicValuesMismatched();
118  for(const_iterator it1=this->begin(), it2=cp.begin(); it1!=this->end(); ++it1, ++it2) {
119  if(it1->key != it2->key)
120  throw DynamicValuesMismatched(); // If keys do not match
121  // Will throw a dynamic_cast exception if types do not match
122  // NOTE: this is separate from localCoordinates(cp, ordering, result) due to at() vs. insert
123  result.insert(it1->key, it1->value.localCoordinates_(it2->value));
124  }
125  return result;
126  }
127 
128  /* ************************************************************************* */
129  const Value& Values::at(Key j) const {
130  // Find the item
131  KeyValueMap::const_iterator item = values_.find(j);
132 
133  // Throw exception if it does not exist
134  if(item == values_.end())
135  throw ValuesKeyDoesNotExist("retrieve", j);
136  return *item->second;
137  }
138 
139  /* ************************************************************************* */
140  void Values::insert(Key j, const Value& val) {
141  std::pair<iterator,bool> insertResult = tryInsert(j, val);
142  if(!insertResult.second)
143  throw ValuesKeyAlreadyExists(j);
144  }
145 
146  /* ************************************************************************* */
147  void Values::insert(const Values& values) {
148  for(const_iterator key_value = values.begin(); key_value != values.end(); ++key_value) {
149  Key key = key_value->key; // Non-const duplicate to deal with non-const insert argument
150  insert(key, key_value->value);
151  }
152  }
153 
154  /* ************************************************************************* */
155  std::pair<Values::iterator, bool> Values::tryInsert(Key j, const Value& value) {
156  std::pair<KeyValueMap::iterator, bool> result = values_.insert(j, value.clone_());
157  return std::make_pair(boost::make_transform_iterator(result.first, &make_deref_pair), result.second);
158  }
159 
160  /* ************************************************************************* */
161  void Values::update(Key j, const Value& val) {
162  // Find the value to update
163  KeyValueMap::iterator item = values_.find(j);
164  if (item == values_.end())
165  throw ValuesKeyDoesNotExist("update", j);
166 
167  // Cast to the derived type
168  const Value& old_value = *item->second;
169  if (typeid(old_value) != typeid(val))
170  throw ValuesIncorrectType(j, typeid(old_value), typeid(val));
171 
172  values_.replace(item, val.clone_());
173  }
174 
175  /* ************************************************************************* */
176  void Values::update(const Values& values) {
177  for(const_iterator key_value = values.begin(); key_value != values.end(); ++key_value) {
178  this->update(key_value->key, key_value->value);
179  }
180  }
181 
182  /* ************************************************************************* */
184  KeyValueMap::iterator item = values_.find(j);
185  if(item == values_.end())
186  throw ValuesKeyDoesNotExist("erase", j);
187  values_.erase(item);
188  }
189 
190  /* ************************************************************************* */
193  result.reserve(size());
194  for(const_iterator key_value = begin(); key_value != end(); ++key_value)
195  result.push_back(key_value->key);
196  return result;
197  }
198 
199  /* ************************************************************************* */
201  this->clear();
202  this->insert(rhs);
203  return *this;
204  }
205 
206  /* ************************************************************************* */
207  size_t Values::dim() const {
208  size_t result = 0;
209  for(const auto key_value: *this) {
210  result += key_value.value.dim();
211  }
212  return result;
213  }
214 
215  /* ************************************************************************* */
218  for(const auto key_value: *this)
219  result.insert(key_value.key, Vector::Zero(key_value.value.dim()));
220  return result;
221  }
222 
223  /* ************************************************************************* */
224  const char* ValuesKeyAlreadyExists::what() const noexcept {
225  if(message_.empty())
226  message_ =
227  "Attempting to add a key-value pair with key \"" + DefaultKeyFormatter(key_) + "\", key already exists.";
228  return message_.c_str();
229  }
230 
231  /* ************************************************************************* */
232  const char* ValuesKeyDoesNotExist::what() const noexcept {
233  if(message_.empty())
234  message_ =
235  "Attempting to " + std::string(operation_) + " the key \"" +
236  DefaultKeyFormatter(key_) + "\", which does not exist in the Values.";
237  return message_.c_str();
238  }
239 
240  /* ************************************************************************* */
241  const char* ValuesIncorrectType::what() const noexcept {
242  if(message_.empty()) {
243  std::string storedTypeName = demangle(storedTypeId_.name());
244  std::string requestedTypeName = demangle(requestedTypeId_.name());
245 
246  if (storedTypeName == requestedTypeName) {
247  message_ = "WARNING: Detected types with same name but different `typeid`. \
248  This is usually caused by incorrect linking/inlining settings when compiling libraries using GTSAM. \
249  If you are a user, please report to the author of the library using GTSAM. \
250  If you are a package maintainer, please consult `cmake/GtsamPybindWrap.cmake`, line 74 for details.";
251  } else {
252  message_ =
253  "Attempting to retrieve value with key \"" + DefaultKeyFormatter(key_) + "\", type stored in Values is " +
254  storedTypeName + " but requested type was " + requestedTypeName;
255  }
256  }
257  return message_.c_str();
258  }
259 
260  /* ************************************************************************* */
261  const char* NoMatchFoundForFixed::what() const noexcept {
262  if(message_.empty()) {
263  ostringstream oss;
264  oss
265  << "Attempting to retrieve fixed-size matrix with dimensions " //
266  << M1_ << "x" << N1_
267  << ", but found dynamic Matrix with mismatched dimensions " //
268  << M2_ << "x" << N2_;
269  message_ = oss.str();
270  }
271  return message_.c_str();
272  }
273 
274 }
virtual bool equals_(const Value &other, double tol=1e-9) const =0
iterator find(Key j)
Definition: VectorValues.h:235
size_t dim() const
Definition: Values.cpp:207
void clear()
Definition: Values.h:311
A insert(1, 2)=0
bool exists(Key j) const
Definition: Values.cpp:104
A non-templated config holding any types of Manifold-group elements.
VectorValues zeroVectors() const
Definition: Values.cpp:216
void insert(Key j, const Value &val)
Definition: Values.cpp:140
GTSAM_EXPORT const char * what() const noexceptoverride
The message to be displayed to the user.
Definition: Values.cpp:224
ArrayXcf v
Definition: Cwise_arg.cpp:1
virtual Value * clone_() const =0
leaf::MyValues values
Definition: Half.h:150
iterator end()
Iterator over variables.
Definition: VectorValues.h:228
Values retract(const VectorValues &delta) const
Definition: Values.cpp:109
KeyVector keys() const
Definition: Values.cpp:191
static const KeyFormatter DefaultKeyFormatter
Definition: Key.h:43
bool equals(const Values &other, double tol=1e-9) const
Definition: Values.cpp:88
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
Definition: cast.h:1756
Factor Graph Values.
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
GTSAM_EXPORT const char * what() const noexceptoverride
Definition: Values.cpp:261
Eigen::VectorXd Vector
Definition: Vector.h:38
size_t size() const
Definition: Values.h:236
Values result
const ValueType at(Key j) const
Definition: Values-inl.h:342
KeyValueMap values_
Definition: Values.h:87
Definition: pytypes.h:928
std::string demangle(const char *name)
Pretty print Value type name.
Definition: types.cpp:37
const_iterator end() const
Definition: Values.h:242
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
boost::transform_iterator< boost::function1< ConstKeyValuePair, const ConstKeyValuePtrPair & >, KeyValueMap::const_iterator > const_iterator
Const forward iterator, with value type ConstKeyValuePair.
Definition: Values.h:124
void erase(Key j)
Definition: Values.cpp:183
Values::const_iterator const_iterator
Const iterator over vector values.
Definition: VectorValues.h:82
const_iterator begin() const
Definition: Values.h:241
traits
Definition: chartTesting.h:28
GTSAM_EXPORT const char * what() const noexceptoverride
The message to be displayed to the user.
Definition: Values.cpp:232
void print(const std::string &str="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Definition: Values.cpp:77
std::vector< float > Values
GTSAM_EXPORT const char * what() const noexceptoverride
The message to be displayed to the user.
Definition: Values.cpp:241
Values & operator=(const Values &rhs)
Definition: Values.cpp:200
VectorValues localCoordinates(const Values &cp) const
Definition: Values.cpp:114
void update(Key j, const Value &val)
Definition: Values.cpp:161
const G double tol
Definition: Group.h:83
std::pair< iterator, bool > tryInsert(Key j, const Value &value)
Definition: Values.cpp:155
static KeyValuePair make_deref_pair(const KeyValueMap::iterator::value_type &key_value)
Definition: Values.h:427
iterator insert(const std::pair< Key, Vector > &key_value)
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
std::ptrdiff_t j


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:51:23