VectorValues.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 
20 
21 #include <functional>
22 #include <utility>
23 
24 // assert_throw needs a semicolon in Release mode.
25 #if defined(__clang__)
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Wextra-semi-stmt"
28 #endif
29 
30 namespace gtsam {
31 
32  /* ************************************************************************ */
34  {
35  // Merge using predicate for comparing first of pair
36  merge(first.begin(), first.end(), second.begin(), second.end(), inserter(values_, values_.end()),
37  std::bind(&std::less<Key>::operator(), std::less<Key>(), std::bind(&KeyValuePair::first, std::placeholders::_1),
38  std::bind(&KeyValuePair::first, std::placeholders::_2)));
39  if(size() != first.size() + second.size())
40  throw std::invalid_argument("Requested to merge two VectorValues that have one or more variables in common.");
41  }
42 
43  /* ************************************************************************ */
44  VectorValues::VectorValues(const Vector& x, const Dims& dims) {
45  size_t j = 0;
46  for (const auto& [key, n] : dims) {
47 #ifdef TBB_GREATER_EQUAL_2020
48  values_.emplace(key, x.segment(j, n));
49 #else
50  values_.insert({key, x.segment(j, n)});
51 #endif
52  j += n;
53  }
54  }
55 
56  /* ************************************************************************ */
57  VectorValues::VectorValues(const Vector& x, const Scatter& scatter) {
58  size_t j = 0;
59  for (const SlotEntry& v : scatter) {
60 #ifdef TBB_GREATER_EQUAL_2020
61  values_.emplace(v.key, x.segment(j, v.dimension));
62 #else
63  values_.insert({v.key, x.segment(j, v.dimension)});
64 #endif
65  j += v.dimension;
66  }
67  }
68 
69  /* ************************************************************************ */
70  std::map<Key, Vector> VectorValues::sorted() const {
71  std::map<Key, Vector> ordered;
72  for (const auto& kv : *this) ordered.emplace(kv);
73  return ordered;
74  }
75 
76  /* ************************************************************************ */
78  {
80  for (const auto& [key, value] : other)
81 #ifdef TBB_GREATER_EQUAL_2020
82  result.values_.emplace(key, Vector::Zero(value.size()));
83 #else
84  result.values_.insert({key, Vector::Zero(value.size())});
85 #endif
86  return result;
87  }
88 
89  /* ************************************************************************ */
90  VectorValues::iterator VectorValues::insert(const std::pair<Key, Vector>& key_value) {
91  const std::pair<iterator, bool> result = values_.insert(key_value);
92  if(!result.second)
93  throw std::invalid_argument(
94  "Requested to insert variable '" + DefaultKeyFormatter(key_value.first)
95  + "' already in this VectorValues.");
96  return result.first;
97  }
98 
99  /* ************************************************************************ */
101  iterator hint = begin();
102  for (const auto& [key, value] : values) {
103  // Use this trick to find the value using a hint, since we are inserting
104  // from another sorted map
105  size_t oldSize = values_.size();
106  hint = values_.insert(hint, {key, value});
107  if (values_.size() > oldSize) {
108  values_.unsafe_erase(hint);
109  throw std::out_of_range(
110  "Requested to update a VectorValues with another VectorValues that "
111  "contains keys not present in the first.");
112  } else {
113  hint->second = value;
114  }
115  }
116  return *this;
117  }
118 
119  /* ************************************************************************ */
121  size_t originalSize = size();
122  values_.insert(values.begin(), values.end());
123  if (size() != originalSize + values.size())
124  throw std::invalid_argument(
125  "Requested to insert a VectorValues into another VectorValues that "
126  "already contains one or more of its keys.");
127  return *this;
128  }
129 
130  /* ************************************************************************ */
132  {
133  for(auto& [key, value] : *this) {
134  value.setZero();
135  }
136  }
137 
138  /* ************************************************************************ */
139  GTSAM_EXPORT std::ostream& operator<<(std::ostream& os, const VectorValues& v) {
140  // Change print depending on whether we are using TBB
141 #ifdef GTSAM_USE_TBB
142  for (const auto& [key, value] : v.sorted())
143 #else
144  for (const auto& [key,value] : v)
145 #endif
146  {
147  os << " " << StreamedKey(key) << ": " << value.transpose() << "\n";
148  }
149  return os;
150  }
151 
152  /* ************************************************************************ */
153  void VectorValues::print(const std::string& str,
154  const KeyFormatter& formatter) const {
155  std::cout << str << ": " << size() << " elements\n";
156  std::cout << key_formatter(formatter) << *this;
157  std::cout.flush();
158 }
159 
160  /* ************************************************************************ */
161  bool VectorValues::equals(const VectorValues& x, double tol) const {
162  if(this->size() != x.size())
163  return false;
164  auto this_it = this->begin();
165  auto x_it = x.begin();
166  for(; this_it != this->end(); ++this_it, ++x_it) {
167  if(this_it->first != x_it->first ||
168  !equal_with_abs_tol(this_it->second, x_it->second, tol))
169  return false;
170  }
171  return true;
172  }
173 
174  /* ************************************************************************ */
176  // Count dimensions
177  DenseIndex totalDim = 0;
178  for (const auto& [key, value] : *this)
179  totalDim += value.size();
180 
181  // Copy vectors
182  Vector result(totalDim);
183  DenseIndex pos = 0;
184 #ifdef GTSAM_USE_TBB
185  // TBB uses un-ordered map, so inefficiently order them:
186  for (const auto& [key, value] : sorted()) {
187 #else
188  for (const auto& [key, value] : *this) {
189 #endif
190  result.segment(pos, value.size()) = value;
191  pos += value.size();
192  }
193 
194  return result;
195  }
196 
197  /* ************************************************************************ */
199  {
200  // Count dimensions
201  DenseIndex totalDim = 0;
202  for (const auto& [key, dim] : keys)
203  totalDim += dim;
204  Vector result(totalDim);
205  size_t j = 0;
206  for(const Dims::value_type& it: keys) {
207  result.segment(j,it.second) = at(it.first);
208  j += it.second;
209  }
210  return result;
211  }
212 
213  /* ************************************************************************ */
215  this->values_.swap(other.values_);
216  }
217 
218  /* ************************************************************************ */
219  namespace internal
220  {
222  {
223  return a.first == b.first && a.second.size() == b.second.size();
224  }
225  }
226 
227  /* ************************************************************************ */
229  {
230  // compare the "other" container with this one, using the structureCompareOp
231  // and then return true if all elements are compared as equal
232  return std::equal(this->begin(), this->end(), other.begin(), other.end(),
234  }
235 
236  /* ************************************************************************ */
237  double VectorValues::dot(const VectorValues& v) const
238  {
239  if(this->size() != v.size())
240  throw std::invalid_argument("VectorValues::dot called with a VectorValues of different structure");
241  double result = 0.0;
242  auto this_it = this->begin();
243  auto v_it = v.begin();
244  for(; this_it != this->end(); ++this_it, ++v_it) {
245  assert_throw(this_it->first == v_it->first,
246  std::invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
247  assert_throw(this_it->second.size() == v_it->second.size(),
248  std::invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
249  result += this_it->second.dot(v_it->second);
250  }
251  return result;
252  }
253 
254  /* ************************************************************************ */
255  double VectorValues::norm() const {
256  return std::sqrt(this->squaredNorm());
257  }
258 
259  /* ************************************************************************ */
260  double VectorValues::squaredNorm() const {
261  double sumSquares = 0.0;
262  for(const auto& [key, value]: *this) {
263  sumSquares += value.squaredNorm();
264  }
265  return sumSquares;
266  }
267 
268  /* ************************************************************************ */
270  {
271  if(this->size() != c.size())
272  throw std::invalid_argument("VectorValues::operator+ called with different vector sizes");
274  std::invalid_argument("VectorValues::operator+ called with different vector sizes"));
275 
277  // The result.end() hint here should result in constant-time inserts
278  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
279 #ifdef TBB_GREATER_EQUAL_2020
280  result.values_.emplace(j1->first, j1->second + j2->second);
281 #else
282  result.values_.insert({j1->first, j1->second + j2->second});
283 #endif
284 
285  return result;
286  }
287 
288  /* ************************************************************************ */
290  {
291  return *this + c;
292  }
293 
294  /* ************************************************************************ */
296  {
297  if(this->size() != c.size())
298  throw std::invalid_argument("VectorValues::operator+= called with different vector sizes");
300  std::invalid_argument("VectorValues::operator+= called with different vector sizes"));
301 
302  iterator j1 = begin();
303  const_iterator j2 = c.begin();
304  // The result.end() hint here should result in constant-time inserts
305  for(; j1 != end(); ++j1, ++j2)
306  j1->second += j2->second;
307 
308  return *this;
309  }
310 
311  /* ************************************************************************ */
313  {
314  return *this += c;
315  }
316 
317  /* ************************************************************************ */
319  {
320  for(const_iterator j2 = c.begin(); j2 != c.end(); ++j2) {
321  const auto& [it, success] = tryInsert(j2->first, Vector());
322  if(success)
323  it->second = j2->second;
324  else
325  it->second += j2->second;
326  }
327  return *this;
328  }
329 
330  /* ************************************************************************ */
332  {
333  if(this->size() != c.size())
334  throw std::invalid_argument("VectorValues::operator- called with different vector sizes");
336  std::invalid_argument("VectorValues::operator- called with different vector sizes"));
337 
339  // The result.end() hint here should result in constant-time inserts
340  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
341 #ifdef TBB_GREATER_EQUAL_2020
342  result.values_.emplace(j1->first, j1->second - j2->second);
343 #else
344  result.values_.insert({j1->first, j1->second - j2->second});
345 #endif
346 
347  return result;
348  }
349 
350  /* ************************************************************************ */
352  {
353  return *this - c;
354  }
355 
356  /* ************************************************************************ */
357  VectorValues operator*(const double a, const VectorValues& c) {
359  for (const auto& [key, value] : c)
360 #ifdef TBB_GREATER_EQUAL_2020
361  result.values_.emplace(key, a * value);
362 #else
363  result.values_.insert({key, a * value});
364 #endif
365  return result;
366  }
367 
368  /* ************************************************************************ */
369  VectorValues VectorValues::scale(const double a) const
370  {
371  return a * *this;
372  }
373 
374  /* ************************************************************************ */
376  {
377  for (auto& [key, value]: *this) {
378  value *= alpha;
379  }
380  return *this;
381  }
382 
383  /* ************************************************************************ */
385  {
386  return *this *= alpha;
387  }
388 
389  /* ************************************************************************ */
390  std::string VectorValues::html(const KeyFormatter& keyFormatter) const {
391  std::stringstream ss;
392 
393  // Print out preamble.
394  ss << "<div>\n<table class='VectorValues'>\n <thead>\n";
395 
396  // Print out header row.
397  ss << " <tr><th>Variable</th><th>value</th></tr>\n";
398 
399  // Finish header and start body.
400  ss << " </thead>\n <tbody>\n";
401 
402  // Print out all rows.
403 #ifdef GTSAM_USE_TBB
404  // TBB uses un-ordered map, so inefficiently order them:
405  for (const auto& kv : sorted()) {
406 #else
407  for (const auto& kv : *this) {
408 #endif
409  ss << " <tr>";
410  ss << "<th>" << keyFormatter(kv.first) << "</th><td>"
411  << kv.second.transpose() << "</td>";
412  ss << "</tr>\n";
413  }
414  ss << " </tbody>\n</table>\n</div>";
415  return ss.str();
416  }
417 
418  /* ************************************************************************ */
419 
420 } // \namespace gtsam
421 
422 #if defined(__clang__)
423 #pragma clang diagnostic pop
424 #endif
gtsam::VectorValues::print
void print(const std::string &str="VectorValues", const KeyFormatter &formatter=DefaultKeyFormatter) const
Definition: VectorValues.cpp:153
gtsam::VectorValues::scaleInPlace
VectorValues & scaleInPlace(double alpha)
Definition: VectorValues.cpp:384
gtsam::VectorValues::Dims
std::map< Key, size_t > Dims
Keyed vector dimensions.
Definition: VectorValues.h:89
assert_throw
#define assert_throw(CONDITION, EXCEPTION)
Definition: types.h:196
alpha
RealScalar alpha
Definition: level1_cplx_impl.h:147
gtsam::operator<<
std::ostream & operator<<(std::ostream &os, const Dih6 &m)
Definition: testGroup.cpp:109
keys
const KeyVector keys
Definition: testRegularImplicitSchurFactor.cpp:40
gtsam::VectorValues::insert
iterator insert(const std::pair< Key, Vector > &key_value)
Definition: VectorValues.cpp:90
gtsam::VectorValues::html
std::string html(const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Output as a html table.
Definition: VectorValues.cpp:390
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
gtsam::VectorValues::at
Vector & at(Key j)
Definition: VectorValues.h:142
gtsam::VectorValues::iterator
Values::iterator iterator
Iterator over vector values.
Definition: VectorValues.h:84
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
gtsam::VectorValues::values_
Values values_
Vectors making up this VectorValues.
Definition: VectorValues.h:78
gtsam::VectorValues::hasSameStructure
bool hasSameStructure(const VectorValues other) const
Definition: VectorValues.cpp:228
gtsam::VectorValues::operator+=
VectorValues & operator+=(const VectorValues &c)
Definition: VectorValues.cpp:295
formatter
const KeyFormatter & formatter
Definition: treeTraversal-inst.h:204
gtsam::equal_with_abs_tol
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
Definition: base/Matrix.h:80
gtsam::VectorValues::dot
double dot(const VectorValues &v) const
Definition: VectorValues.cpp:237
different_sigmas::values
HybridValues values
Definition: testHybridBayesNet.cpp:245
iterator
Definition: pytypes.h:1460
os
ofstream os("timeSchurFactors.csv")
gtsam::VectorValues::operator*
friend GTSAM_EXPORT VectorValues operator*(const double a, const VectorValues &v)
Definition: VectorValues.cpp:357
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:38
result
Values result
Definition: OdometryOptimize.cpp:8
gtsam::VectorValues::VectorValues
VectorValues()
Default constructor creates an empty VectorValues.
Definition: VectorValues.h:95
gtsam::DefaultKeyFormatter
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition: Key.cpp:30
gtsam::VectorValues::addInPlace
VectorValues & addInPlace(const VectorValues &c)
Definition: VectorValues.cpp:312
ss
static std::stringstream ss
Definition: testBTree.cpp:31
gtsam::VectorValues::sorted
std::map< Key, Vector > sorted() const
Definition: VectorValues.cpp:70
n
int n
Definition: BiCGSTAB_simple.cpp:1
gtsam::VectorValues::const_iterator
Values::const_iterator const_iterator
Const iterator over vector values.
Definition: VectorValues.h:85
gtsam::VectorValues::addInPlace_
VectorValues & addInPlace_(const VectorValues &c)
Definition: VectorValues.cpp:318
gtsam::VectorValues::subtract
VectorValues subtract(const VectorValues &c) const
Definition: VectorValues.cpp:351
gtsam::VectorValues
Definition: VectorValues.h:74
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
gtsam::KeyFormatter
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
gtsam::VectorValues::update
VectorValues & update(const VectorValues &values)
Definition: VectorValues.cpp:100
gtsam::VectorValues::scale
VectorValues scale(const double a) const
Definition: VectorValues.cpp:369
gtsam::VectorValues::squaredNorm
double squaredNorm() const
Definition: VectorValues.cpp:260
Eigen::internal::first
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
gtsam::VectorValues::Zero
static VectorValues Zero(const VectorValues &other)
Definition: VectorValues.cpp:77
gtsam::Scatter
Definition: Scatter.h:49
gtsam::VectorValues::tryInsert
std::pair< iterator, bool > tryInsert(Key j, const Vector &value)
Definition: VectorValues.h:212
gtsam::ConcurrentMap::unsafe_erase
void unsafe_erase(typename Base::iterator position)
Definition: ConcurrentMap.h:94
VectorValues.h
Factor Graph Values.
gtsam::VectorValues::operator+
VectorValues operator+(const VectorValues &c) const
Definition: VectorValues.cpp:269
gtsam::internal::structureCompareOp
bool structureCompareOp(const VectorValues::value_type &a, const VectorValues::value_type &b)
Definition: VectorValues.cpp:221
gtsam::VectorValues::operator-
VectorValues operator-(const VectorValues &c) const
Definition: VectorValues.cpp:331
gtsam::VectorValues::dim
size_t dim(Key j) const
Definition: VectorValues.h:133
gtsam::VectorValues::norm
double norm() const
Definition: VectorValues.cpp:255
str
Definition: pytypes.h:1558
key
const gtsam::Symbol key('X', 0)
gtsam::b
const G & b
Definition: Group.h:79
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
gtsam::StreamedKey
To use the key_formatter on Keys, they must be wrapped in a StreamedKey.
Definition: Key.h:64
gtsam::VectorValues::equals
bool equals(const VectorValues &x, double tol=1e-9) const
Definition: VectorValues.cpp:161
gtsam
traits
Definition: SFMdata.h:40
gtsam::DenseIndex
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:103
gtsam::key_formatter
Definition: Key.h:78
gtsam::VectorValues::size
size_t size() const
Definition: VectorValues.h:130
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
gtsam::tol
const G double tol
Definition: Group.h:79
gtsam::VectorValues::operator*=
VectorValues & operator*=(double alpha)
Definition: VectorValues.cpp:375
internal
Definition: BandTriangularSolver.h:13
Eigen::placeholders::end
static const EIGEN_DEPRECATED end_t end
Definition: IndexedViewHelper.h:181
pos
Definition: example-NearestNeighbor.cpp:32
gtsam::VectorValues::setZero
void setZero()
Definition: VectorValues.cpp:131
gtsam::SlotEntry
One SlotEntry stores the slot index for a variable, as well its dim.
Definition: Scatter.h:32
gtsam::VectorValues::add
VectorValues add(const VectorValues &c) const
Definition: VectorValues.cpp:289
gtsam::VectorValues::swap
void swap(VectorValues &other)
Definition: VectorValues.cpp:214
j1
double j1(double x)
Definition: j1.c:174
gtsam::equal
bool equal(const T &obj1, const T &obj2, double tol)
Definition: Testable.h:85
test_callbacks.value
value
Definition: test_callbacks.py:160
ceres::sqrt
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
gtsam::VectorValues::value_type
Values::value_type value_type
Typedef to pair<Key, Vector>
Definition: VectorValues.h:87
gtsam::VectorValues::vector
Vector vector() const
Definition: VectorValues.cpp:175


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:09:41