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 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wextra-semi-stmt"
27 
28 namespace gtsam {
29 
30  /* ************************************************************************ */
32  {
33  // Merge using predicate for comparing first of pair
34  merge(first.begin(), first.end(), second.begin(), second.end(), inserter(values_, values_.end()),
35  std::bind(&std::less<Key>::operator(), std::less<Key>(), std::bind(&KeyValuePair::first, std::placeholders::_1),
36  std::bind(&KeyValuePair::first, std::placeholders::_2)));
37  if(size() != first.size() + second.size())
38  throw std::invalid_argument("Requested to merge two VectorValues that have one or more variables in common.");
39  }
40 
41  /* ************************************************************************ */
42  VectorValues::VectorValues(const Vector& x, const Dims& dims) {
43  size_t j = 0;
44  for (const auto& [key, n] : dims) {
45 #ifdef TBB_GREATER_EQUAL_2020
46  values_.emplace(key, x.segment(j, n));
47 #else
48  values_.insert({key, x.segment(j, n)});
49 #endif
50  j += n;
51  }
52  }
53 
54  /* ************************************************************************ */
55  VectorValues::VectorValues(const Vector& x, const Scatter& scatter) {
56  size_t j = 0;
57  for (const SlotEntry& v : scatter) {
58 #ifdef TBB_GREATER_EQUAL_2020
59  values_.emplace(v.key, x.segment(j, v.dimension));
60 #else
61  values_.insert({v.key, x.segment(j, v.dimension)});
62 #endif
63  j += v.dimension;
64  }
65  }
66 
67  /* ************************************************************************ */
68  std::map<Key, Vector> VectorValues::sorted() const {
69  std::map<Key, Vector> ordered;
70  for (const auto& kv : *this) ordered.emplace(kv);
71  return ordered;
72  }
73 
74  /* ************************************************************************ */
76  {
78  for (const auto& [key, value] : other)
79 #ifdef TBB_GREATER_EQUAL_2020
80  result.values_.emplace(key, Vector::Zero(value.size()));
81 #else
82  result.values_.insert({key, Vector::Zero(value.size())});
83 #endif
84  return result;
85  }
86 
87  /* ************************************************************************ */
88  VectorValues::iterator VectorValues::insert(const std::pair<Key, Vector>& key_value) {
89  const std::pair<iterator, bool> result = values_.insert(key_value);
90  if(!result.second)
91  throw std::invalid_argument(
92  "Requested to insert variable '" + DefaultKeyFormatter(key_value.first)
93  + "' already in this VectorValues.");
94  return result.first;
95  }
96 
97  /* ************************************************************************ */
99  iterator hint = begin();
100  for (const auto& [key, value] : values) {
101  // Use this trick to find the value using a hint, since we are inserting
102  // from another sorted map
103  size_t oldSize = values_.size();
104  hint = values_.insert(hint, {key, value});
105  if (values_.size() > oldSize) {
106  values_.unsafe_erase(hint);
107  throw std::out_of_range(
108  "Requested to update a VectorValues with another VectorValues that "
109  "contains keys not present in the first.");
110  } else {
111  hint->second = value;
112  }
113  }
114  return *this;
115  }
116 
117  /* ************************************************************************ */
119  size_t originalSize = size();
120  values_.insert(values.begin(), values.end());
121  if (size() != originalSize + values.size())
122  throw std::invalid_argument(
123  "Requested to insert a VectorValues into another VectorValues that "
124  "already contains one or more of its keys.");
125  return *this;
126  }
127 
128  /* ************************************************************************ */
130  {
131  for(auto& [key, value] : *this) {
132  value.setZero();
133  }
134  }
135 
136  /* ************************************************************************ */
137  GTSAM_EXPORT std::ostream& operator<<(std::ostream& os, const VectorValues& v) {
138  // Change print depending on whether we are using TBB
139 #ifdef GTSAM_USE_TBB
140  for (const auto& [key, value] : v.sorted())
141 #else
142  for (const auto& [key,value] : v)
143 #endif
144  {
145  os << " " << StreamedKey(key) << ": " << value.transpose() << "\n";
146  }
147  return os;
148  }
149 
150  /* ************************************************************************ */
151  void VectorValues::print(const std::string& str,
152  const KeyFormatter& formatter) const {
153  std::cout << str << ": " << size() << " elements\n";
154  std::cout << key_formatter(formatter) << *this;
155  std::cout.flush();
156 }
157 
158  /* ************************************************************************ */
159  bool VectorValues::equals(const VectorValues& x, double tol) const {
160  if(this->size() != x.size())
161  return false;
162  auto this_it = this->begin();
163  auto x_it = x.begin();
164  for(; this_it != this->end(); ++this_it, ++x_it) {
165  if(this_it->first != x_it->first ||
166  !equal_with_abs_tol(this_it->second, x_it->second, tol))
167  return false;
168  }
169  return true;
170  }
171 
172  /* ************************************************************************ */
174  // Count dimensions
175  DenseIndex totalDim = 0;
176  for (const auto& [key, value] : *this)
177  totalDim += value.size();
178 
179  // Copy vectors
180  Vector result(totalDim);
181  DenseIndex pos = 0;
182 #ifdef GTSAM_USE_TBB
183  // TBB uses un-ordered map, so inefficiently order them:
184  for (const auto& [key, value] : sorted()) {
185 #else
186  for (const auto& [key, value] : *this) {
187 #endif
188  result.segment(pos, value.size()) = value;
189  pos += value.size();
190  }
191 
192  return result;
193  }
194 
195  /* ************************************************************************ */
197  {
198  // Count dimensions
199  DenseIndex totalDim = 0;
200  for (const auto& [key, dim] : keys)
201  totalDim += dim;
202  Vector result(totalDim);
203  size_t j = 0;
204  for(const Dims::value_type& it: keys) {
205  result.segment(j,it.second) = at(it.first);
206  j += it.second;
207  }
208  return result;
209  }
210 
211  /* ************************************************************************ */
213  this->values_.swap(other.values_);
214  }
215 
216  /* ************************************************************************ */
217  namespace internal
218  {
220  {
221  return a.first == b.first && a.second.size() == b.second.size();
222  }
223  }
224 
225  /* ************************************************************************ */
227  {
228  // compare the "other" container with this one, using the structureCompareOp
229  // and then return true if all elements are compared as equal
230  return std::equal(this->begin(), this->end(), other.begin(), other.end(),
232  }
233 
234  /* ************************************************************************ */
235  double VectorValues::dot(const VectorValues& v) const
236  {
237  if(this->size() != v.size())
238  throw std::invalid_argument("VectorValues::dot called with a VectorValues of different structure");
239  double result = 0.0;
240  auto this_it = this->begin();
241  auto v_it = v.begin();
242  for(; this_it != this->end(); ++this_it, ++v_it) {
243  assert_throw(this_it->first == v_it->first,
244  std::invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
245  assert_throw(this_it->second.size() == v_it->second.size(),
246  std::invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
247  result += this_it->second.dot(v_it->second);
248  }
249  return result;
250  }
251 
252  /* ************************************************************************ */
253  double VectorValues::norm() const {
254  return std::sqrt(this->squaredNorm());
255  }
256 
257  /* ************************************************************************ */
258  double VectorValues::squaredNorm() const {
259  double sumSquares = 0.0;
260  for(const auto& [key, value]: *this) {
261  sumSquares += value.squaredNorm();
262  }
263  return sumSquares;
264  }
265 
266  /* ************************************************************************ */
268  {
269  if(this->size() != c.size())
270  throw std::invalid_argument("VectorValues::operator+ called with different vector sizes");
272  std::invalid_argument("VectorValues::operator+ called with different vector sizes"));
273 
275  // The result.end() hint here should result in constant-time inserts
276  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
277 #ifdef TBB_GREATER_EQUAL_2020
278  result.values_.emplace(j1->first, j1->second + j2->second);
279 #else
280  result.values_.insert({j1->first, j1->second + j2->second});
281 #endif
282 
283  return result;
284  }
285 
286  /* ************************************************************************ */
288  {
289  return *this + c;
290  }
291 
292  /* ************************************************************************ */
294  {
295  if(this->size() != c.size())
296  throw std::invalid_argument("VectorValues::operator+= called with different vector sizes");
298  std::invalid_argument("VectorValues::operator+= called with different vector sizes"));
299 
300  iterator j1 = begin();
301  const_iterator j2 = c.begin();
302  // The result.end() hint here should result in constant-time inserts
303  for(; j1 != end(); ++j1, ++j2)
304  j1->second += j2->second;
305 
306  return *this;
307  }
308 
309  /* ************************************************************************ */
311  {
312  return *this += c;
313  }
314 
315  /* ************************************************************************ */
317  {
318  for(const_iterator j2 = c.begin(); j2 != c.end(); ++j2) {
319  const auto& [it, success] = tryInsert(j2->first, Vector());
320  if(success)
321  it->second = j2->second;
322  else
323  it->second += j2->second;
324  }
325  return *this;
326  }
327 
328  /* ************************************************************************ */
330  {
331  if(this->size() != c.size())
332  throw std::invalid_argument("VectorValues::operator- called with different vector sizes");
334  std::invalid_argument("VectorValues::operator- called with different vector sizes"));
335 
337  // The result.end() hint here should result in constant-time inserts
338  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
339 #ifdef TBB_GREATER_EQUAL_2020
340  result.values_.emplace(j1->first, j1->second - j2->second);
341 #else
342  result.values_.insert({j1->first, j1->second - j2->second});
343 #endif
344 
345  return result;
346  }
347 
348  /* ************************************************************************ */
350  {
351  return *this - c;
352  }
353 
354  /* ************************************************************************ */
355  VectorValues operator*(const double a, const VectorValues& c) {
357  for (const auto& [key, value] : c)
358 #ifdef TBB_GREATER_EQUAL_2020
359  result.values_.emplace(key, a * value);
360 #else
361  result.values_.insert({key, a * value});
362 #endif
363  return result;
364  }
365 
366  /* ************************************************************************ */
367  VectorValues VectorValues::scale(const double a) const
368  {
369  return a * *this;
370  }
371 
372  /* ************************************************************************ */
374  {
375  for (auto& [key, value]: *this) {
376  value *= alpha;
377  }
378  return *this;
379  }
380 
381  /* ************************************************************************ */
383  {
384  return *this *= alpha;
385  }
386 
387  /* ************************************************************************ */
388  std::string VectorValues::html(const KeyFormatter& keyFormatter) const {
389  std::stringstream ss;
390 
391  // Print out preamble.
392  ss << "<div>\n<table class='VectorValues'>\n <thead>\n";
393 
394  // Print out header row.
395  ss << " <tr><th>Variable</th><th>value</th></tr>\n";
396 
397  // Finish header and start body.
398  ss << " </thead>\n <tbody>\n";
399 
400  // Print out all rows.
401 #ifdef GTSAM_USE_TBB
402  // TBB uses un-ordered map, so inefficiently order them:
403  for (const auto& kv : sorted()) {
404 #else
405  for (const auto& kv : *this) {
406 #endif
407  ss << " <tr>";
408  ss << "<th>" << keyFormatter(kv.first) << "</th><td>"
409  << kv.second.transpose() << "</td>";
410  ss << "</tr>\n";
411  }
412  ss << " </tbody>\n</table>\n</div>";
413  return ss.str();
414  }
415 
416  /* ************************************************************************ */
417 
418 } // \namespace gtsam
419 
420 #pragma clang diagnostic pop
421 
gtsam::VectorValues::print
void print(const std::string &str="VectorValues", const KeyFormatter &formatter=DefaultKeyFormatter) const
Definition: VectorValues.cpp:151
gtsam::VectorValues::scaleInPlace
VectorValues & scaleInPlace(double alpha)
Definition: VectorValues.cpp:382
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
gtsam::Values::size
size_t size() const
Definition: Values.h:178
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:88
gtsam::VectorValues::html
std::string html(const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Output as a html table.
Definition: VectorValues.cpp:388
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:226
gtsam::VectorValues::operator+=
VectorValues & operator+=(const VectorValues &c)
Definition: VectorValues.cpp:293
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:235
iterator
Definition: pytypes.h:1426
os
ofstream os("timeSchurFactors.csv")
gtsam::VectorValues::operator*
friend GTSAM_EXPORT VectorValues operator*(const double a, const VectorValues &v)
Definition: VectorValues.cpp:355
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:310
ss
static std::stringstream ss
Definition: testBTree.cpp:31
gtsam::VectorValues::sorted
std::map< Key, Vector > sorted() const
Definition: VectorValues.cpp:68
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:316
gtsam::VectorValues::subtract
VectorValues subtract(const VectorValues &c) const
Definition: VectorValues.cpp:349
gtsam::Values::end
deref_iterator end() const
Definition: Values.h:206
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:98
gtsam::VectorValues::scale
VectorValues scale(const double a) const
Definition: VectorValues.cpp:367
gtsam::VectorValues::squaredNorm
double squaredNorm() const
Definition: VectorValues.cpp:258
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:75
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:267
gtsam::internal::structureCompareOp
bool structureCompareOp(const VectorValues::value_type &a, const VectorValues::value_type &b)
Definition: VectorValues.cpp:219
gtsam::VectorValues::operator-
VectorValues operator-(const VectorValues &c) const
Definition: VectorValues.cpp:329
gtsam::VectorValues::dim
size_t dim(Key j) const
Definition: VectorValues.h:133
gtsam::VectorValues::norm
double norm() const
Definition: VectorValues.cpp:253
str
Definition: pytypes.h:1524
key
const gtsam::Symbol key('X', 0)
gtsam::Values::begin
deref_iterator begin() const
Definition: Values.h:205
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:159
gtsam
traits
Definition: chartTesting.h:28
leaf::values
leaf::MyValues values
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:373
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:129
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:287
gtsam::VectorValues::swap
void swap(VectorValues &other)
Definition: VectorValues.cpp:212
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:158
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:173


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:11:31