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 <boost/bind.hpp>
22 #include <boost/range/combine.hpp>
23 #include <boost/range/numeric.hpp>
24 #include <boost/range/adaptor/transformed.hpp>
25 #include <boost/range/adaptor/map.hpp>
26 
27 using namespace std;
28 
29 namespace gtsam {
30 
31  using boost::combine;
32  using boost::adaptors::transformed;
33  using boost::adaptors::map_values;
34  using boost::accumulate;
35 
36  /* ************************************************************************* */
37  VectorValues::VectorValues(const VectorValues& first, const VectorValues& second)
38  {
39  // Merge using predicate for comparing first of pair
40  merge(first.begin(), first.end(), second.begin(), second.end(), inserter(values_, values_.end()),
41  boost::bind(&less<Key>::operator(), less<Key>(), boost::bind(&KeyValuePair::first, _1), boost::bind(&KeyValuePair::first, _2)));
42  if(size() != first.size() + second.size())
43  throw invalid_argument("Requested to merge two VectorValues that have one or more variables in common.");
44  }
45 
46  /* ************************************************************************* */
47  VectorValues::VectorValues(const Vector& x, const Dims& dims) {
48  using Pair = pair<const Key, size_t>;
49  size_t j = 0;
50  for (const Pair& v : dims) {
51  Key key;
52  size_t n;
53  boost::tie(key, n) = v;
54 #ifdef TBB_GREATER_EQUAL_2020
55  values_.emplace(key, x.segment(j, n));
56 #else
57  values_.insert(std::make_pair(key, x.segment(j, n)));
58 #endif
59  j += n;
60  }
61  }
62 
63  /* ************************************************************************* */
64  VectorValues::VectorValues(const Vector& x, const Scatter& scatter) {
65  size_t j = 0;
66  for (const SlotEntry& v : scatter) {
67 #ifdef TBB_GREATER_EQUAL_2020
68  values_.emplace(v.key, x.segment(j, v.dimension));
69 #else
70  values_.insert(std::make_pair(v.key, x.segment(j, v.dimension)));
71 #endif
72  j += v.dimension;
73  }
74  }
75 
76  /* ************************************************************************* */
77  VectorValues VectorValues::Zero(const VectorValues& other)
78  {
80  for(const KeyValuePair& v: other)
81 #ifdef TBB_GREATER_EQUAL_2020
82  result.values_.emplace(v.first, Vector::Zero(v.second.size()));
83 #else
84  result.values_.insert(std::make_pair(v.first, Vector::Zero(v.second.size())));
85 #endif
86  return result;
87  }
88 
89  /* ************************************************************************* */
90  VectorValues::iterator VectorValues::insert(const std::pair<Key, Vector>& key_value) {
91  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  {
102  iterator hint = begin();
103  for(const KeyValuePair& key_value: values)
104  {
105  // Use this trick to find the value using a hint, since we are inserting from another sorted map
106  size_t oldSize = values_.size();
107  hint = values_.insert(hint, key_value);
108  if(values_.size() > oldSize) {
109  values_.unsafe_erase(hint);
110  throw out_of_range("Requested to update a VectorValues with another VectorValues that contains keys not present in the first.");
111  } else {
112  hint->second = key_value.second;
113  }
114  }
115  }
116 
117  /* ************************************************************************* */
119  {
120  size_t originalSize = size();
121  values_.insert(values.begin(), values.end());
122  if(size() != originalSize + values.size())
123  throw invalid_argument("Requested to insert a VectorValues into another VectorValues that already contains one or more of its keys.");
124  }
125 
126  /* ************************************************************************* */
128  {
129  for(Vector& v: values_ | map_values)
130  v.setZero();
131  }
132 
133  /* ************************************************************************* */
134  GTSAM_EXPORT ostream& operator<<(ostream& os, const VectorValues& v) {
135  // Change print depending on whether we are using TBB
136 #ifdef GTSAM_USE_TBB
137  map<Key, Vector> sorted;
138  for (const auto& key_value : v) {
139  sorted.emplace(key_value.first, key_value.second);
140  }
141  for (const auto& key_value : sorted)
142 #else
143  for (const auto& key_value : v)
144 #endif
145  {
146  os << " " << StreamedKey(key_value.first) << ": " << key_value.second.transpose()
147  << "\n";
148  }
149  return os;
150  }
151 
152  /* ************************************************************************* */
153  void VectorValues::print(const string& str,
154  const KeyFormatter& formatter) const {
155  cout << str << ": " << size() << " elements\n";
156  cout << key_formatter(formatter) << *this;
157  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  for(const auto values: boost::combine(*this, x)) {
165  if(values.get<0>().first != values.get<1>().first ||
166  !equal_with_abs_tol(values.get<0>().second, values.get<1>().second, tol))
167  return false;
168  }
169  return true;
170  }
171 
172  /* ************************************************************************* */
173  Vector VectorValues::vector() const {
174  // Count dimensions
175  DenseIndex totalDim = 0;
176  for (const Vector& v : *this | map_values) totalDim += v.size();
177 
178  // Copy vectors
179  Vector result(totalDim);
180  DenseIndex pos = 0;
181  for (const Vector& v : *this | map_values) {
182  result.segment(pos, v.size()) = v;
183  pos += v.size();
184  }
185 
186  return result;
187  }
188 
189  /* ************************************************************************* */
190  Vector VectorValues::vector(const Dims& keys) const
191  {
192  // Count dimensions
193  DenseIndex totalDim = 0;
194  for(size_t dim: keys | map_values)
195  totalDim += dim;
196  Vector result(totalDim);
197  size_t j = 0;
198  for(const Dims::value_type& it: keys) {
199  result.segment(j,it.second) = at(it.first);
200  j += it.second;
201  }
202  return result;
203  }
204 
205  /* ************************************************************************* */
207  this->values_.swap(other.values_);
208  }
209 
210  /* ************************************************************************* */
211  namespace internal
212  {
215  {
216  return vv.get<0>().first == vv.get<1>().first
217  && vv.get<0>().second.size() == vv.get<1>().second.size();
218  }
219  }
220 
221  /* ************************************************************************* */
222  bool VectorValues::hasSameStructure(const VectorValues other) const
223  {
224  return accumulate(combine(*this, other)
225  | transformed(internal::structureCompareOp), true, logical_and<bool>());
226  }
227 
228  /* ************************************************************************* */
229  double VectorValues::dot(const VectorValues& v) const
230  {
231  if(this->size() != v.size())
232  throw invalid_argument("VectorValues::dot called with a VectorValues of different structure");
233  double result = 0.0;
234  typedef boost::tuple<value_type, value_type> ValuePair;
235  using boost::adaptors::map_values;
236  for(const ValuePair values: boost::combine(*this, v)) {
237  assert_throw(values.get<0>().first == values.get<1>().first,
238  invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
239  assert_throw(values.get<0>().second.size() == values.get<1>().second.size(),
240  invalid_argument("VectorValues::dot called with a VectorValues of different structure"));
241  result += values.get<0>().second.dot(values.get<1>().second);
242  }
243  return result;
244  }
245 
246  /* ************************************************************************* */
247  double VectorValues::norm() const {
248  return std::sqrt(this->squaredNorm());
249  }
250 
251  /* ************************************************************************* */
252  double VectorValues::squaredNorm() const {
253  double sumSquares = 0.0;
254  using boost::adaptors::map_values;
255  for(const Vector& v: *this | map_values)
256  sumSquares += v.squaredNorm();
257  return sumSquares;
258  }
259 
260  /* ************************************************************************* */
262  {
263  if(this->size() != c.size())
264  throw invalid_argument("VectorValues::operator+ called with different vector sizes");
265  assert_throw(hasSameStructure(c),
266  invalid_argument("VectorValues::operator+ called with different vector sizes"));
267 
269  // The result.end() hint here should result in constant-time inserts
270  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
271 #ifdef TBB_GREATER_EQUAL_2020
272  result.values_.emplace(j1->first, j1->second + j2->second);
273 #else
274  result.values_.insert(std::make_pair(j1->first, j1->second + j2->second));
275 #endif
276 
277  return result;
278  }
279 
280  /* ************************************************************************* */
282  {
283  return *this + c;
284  }
285 
286  /* ************************************************************************* */
288  {
289  if(this->size() != c.size())
290  throw invalid_argument("VectorValues::operator+= called with different vector sizes");
291  assert_throw(hasSameStructure(c),
292  invalid_argument("VectorValues::operator+= called with different vector sizes"));
293 
294  iterator j1 = begin();
295  const_iterator j2 = c.begin();
296  // The result.end() hint here should result in constant-time inserts
297  for(; j1 != end(); ++j1, ++j2)
298  j1->second += j2->second;
299 
300  return *this;
301  }
302 
303  /* ************************************************************************* */
304  VectorValues& VectorValues::addInPlace(const VectorValues& c)
305  {
306  return *this += c;
307  }
308 
309  /* ************************************************************************* */
310  VectorValues& VectorValues::addInPlace_(const VectorValues& c)
311  {
312  for(const_iterator j2 = c.begin(); j2 != c.end(); ++j2) {
313  pair<VectorValues::iterator, bool> xi = tryInsert(j2->first, Vector());
314  if(xi.second)
315  xi.first->second = j2->second;
316  else
317  xi.first->second += j2->second;
318  }
319  return *this;
320  }
321 
322  /* ************************************************************************* */
324  {
325  if(this->size() != c.size())
326  throw invalid_argument("VectorValues::operator- called with different vector sizes");
327  assert_throw(hasSameStructure(c),
328  invalid_argument("VectorValues::operator- called with different vector sizes"));
329 
331  // The result.end() hint here should result in constant-time inserts
332  for(const_iterator j1 = begin(), j2 = c.begin(); j1 != end(); ++j1, ++j2)
333 #ifdef TBB_GREATER_EQUAL_2020
334  result.values_.emplace(j1->first, j1->second - j2->second);
335 #else
336  result.values_.insert(std::make_pair(j1->first, j1->second - j2->second));
337 #endif
338 
339  return result;
340  }
341 
342  /* ************************************************************************* */
343  VectorValues VectorValues::subtract(const VectorValues& c) const
344  {
345  return *this - c;
346  }
347 
348  /* ************************************************************************* */
349  VectorValues operator*(const double a, const VectorValues &v)
350  {
352  for(const VectorValues::KeyValuePair& key_v: v)
353 #ifdef TBB_GREATER_EQUAL_2020
354  result.values_.emplace(key_v.first, a * key_v.second);
355 #else
356  result.values_.insert(std::make_pair(key_v.first, a * key_v.second));
357 #endif
358  return result;
359  }
360 
361  /* ************************************************************************* */
362  VectorValues VectorValues::scale(const double a) const
363  {
364  return a * *this;
365  }
366 
367  /* ************************************************************************* */
369  {
370  for(Vector& v: *this | map_values)
371  v *= alpha;
372  return *this;
373  }
374 
375  /* ************************************************************************* */
376  VectorValues& VectorValues::scaleInPlace(double alpha)
377  {
378  return *this *= alpha;
379  }
380 
381  /* ************************************************************************* */
382 
383 } // \namespace gtsam
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
Vector3_ operator*(const Double_ &s, const Vector3_ &v)
One SlotEntry stores the slot index for a variable, as well its dim.
Definition: Scatter.h:32
A insert(1, 2)=0
Values::iterator iterator
Iterator over vector values.
Definition: VectorValues.h:81
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half & operator*=(half &a, const half &b)
Definition: Half.h:289
def update(text)
Definition: relicense.py:46
ArrayXcf v
Definition: Cwise_arg.cpp:1
int n
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
leaf::MyValues values
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
size_t size() const
Definition: VectorValues.h:125
Definition: Half.h:150
Values::value_type value_type
Typedef to pair<Key, Vector>
Definition: VectorValues.h:84
iterator end()
Iterator over variables.
Definition: VectorValues.h:228
std::map< Key, size_t > Dims
Keyed vector dimensions.
Definition: VectorValues.h:86
GTSAM_EXPORT ostream & operator<<(ostream &os, const VectorValues &v)
static const KeyFormatter DefaultKeyFormatter
Definition: Key.h:43
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:67
const KeyFormatter & formatter
graph add(boost::make_shared< UnaryFactor >(1, 0.0, 0.0, unaryNoise))
Array33i a
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Factor Graph Values.
int EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:152
Scalar EIGEN_BLAS_FUNC() dot(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
constexpr int first(int i)
Implementation details for constexpr functions.
Eigen::VectorXd Vector
Definition: Vector.h:38
size_t size() const
Definition: Values.h:236
Values result
Definition: pytypes.h:928
Values values_
Vectors making up this VectorValues.
Definition: VectorValues.h:78
To use the key_formatter on Keys, they must be wrapped in a StreamedKey.
Definition: Key.h:58
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
RealScalar alpha
value_type KeyValuePair
Typedef to pair<Key, Vector>
Definition: VectorValues.h:85
Values::const_iterator const_iterator
Const iterator over vector values.
Definition: VectorValues.h:82
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half & operator+=(half &a, const half &b)
Definition: Half.h:285
bool structureCompareOp(const boost::tuple< VectorValues::value_type, VectorValues::value_type > &vv)
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
Definition: base/Matrix.h:84
Vector xi
Definition: testPose2.cpp:150
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2201
traits
Definition: chartTesting.h:28
ofstream os("timeSchurFactors.csv")
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 y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
Jet< T, N > operator-(const Jet< T, N > &f)
Definition: jet.h:258
const G double tol
Definition: Group.h:83
const KeyVector keys
#define assert_throw(CONDITION, EXCEPTION)
Definition: types.h:186
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
iterator begin()
Iterator over variables.
Definition: VectorValues.h:226
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
std::ptrdiff_t j
Jet< T, N > const & operator+(const Jet< T, N > &f)
Definition: jet.h:249
v setZero(3)


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