Ocean
CorrespondenceSet.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_TRACKING_CORRESPONDENCE_SET_H
9 #define META_OCEAN_TRACKING_CORRESPONDENCE_SET_H
10 
12 
13 #include "ocean/base/Subset.h"
14 
15 #include <set>
16 
17 namespace Ocean
18 {
19 
20 namespace Tracking
21 {
22 
23 /**
24  * This class manages a set of element correspondences.
25  * @tparam T Data type of the individual elements for that the set of correspondences will be stored
26  * @ingroup tracking
27  */
28 template <typename T>
30 {
31  public:
32 
33  /**
34  * Defines the data type of the individual elements.
35  */
36  typedef T Type;
37 
38  /**
39  * This class defines a vector storing individual elements.
40  */
41  typedef std::vector<T> Elements;
42 
43  /**
44  * This class defines a vector storing vectors of elements.
45  */
46  typedef std::vector<Elements> ElementsVector;
47 
48  public:
49 
50  /**
51  * Creates an empty object.
52  */
54 
55  /**
56  * Creates new object by adding the first elements.
57  * @param elements First elements that will be stored as first reference elements
58  */
59  inline explicit CorrespondenceSet(const Elements& elements);
60 
61  /**
62  * Creates new object by adding the first elements.
63  * @param elements First elements that will be stored as first reference elements
64  */
65  inline explicit CorrespondenceSet(Elements&& elements);
66 
67  /**
68  * Move constructor.
69  * @param correspondenceSet Correspondence object to be moved
70  */
71  inline CorrespondenceSet(CorrespondenceSet<T>&& correspondenceSet) noexcept;
72 
73  /**
74  * Returns the number of correspondences.
75  * @return Correspondence number
76  */
77  inline size_t size() const;
78 
79  /**
80  * Returns the number of corresponding elements.
81  * @return Number of elements
82  */
83  inline size_t elements() const;
84 
85  /**
86  * Returns the set of stored correspondences.
87  * @return Set of correspondences
88  */
89  inline const ElementsVector& correspondences() const;
90 
91  /**
92  * Changes (or sets) the first set of elements.
93  * Beware: The number of provided elements must match to the number of stored elements in each set of this object, if elements have been set already.<br>
94  * @param elements Elements that replace the existing ones
95  * @return True, if succeeded
96  */
97  inline bool setFirstElements(const Elements& elements);
98 
99  /**
100  * Changes (or sets) the first set of elements.
101  * Beware: The number of provided elements must match to the number of stored elements in each set of this object, if elements have been set already.<br>
102  * @param elements Elements that replace the existing ones
103  * @return True, if succeeded
104  */
106 
107  /**
108  * Changes (or sets) the first set of elements.
109  * This function takes a set of indices which define the valid subset of the given elements.<br>
110  * Only valid elements will be added while also the already stored sets of elements will be reduced so that only valid elements are stored finally.<br>
111  * @param elements Elements that replace the existing ones
112  * @param validIndices Indices that define a valid subset of the given elements, each index must exist at most once and must lie inside the range [0, elements.size())
113  * @return True, if succeeded
114  */
115  bool setFirstElements(const Elements& elements, const Indices32& validIndices);
116 
117  /**
118  * Changes (or sets) the last set of elements.
119  * Beware: The number of provided elements must match to the number of stored elements in each set of this object, if elements have been set already.<br>
120  * @param elements Elements that replace the existing ones
121  * @return True, if succeeded
122  */
123  inline bool setLastElements(const Elements& elements);
124 
125  /**
126  * Changes (or sets) the last set of elements.
127  * Beware: The number of provided elements must match to the number of stored elements in each set of this object, if elements have been set already.<br>
128  * @param elements Elements that replace the existing ones
129  * @return True, if succeeded
130  */
132 
133  /**
134  * Changes (or sets) the last set of elements.
135  * This function takes a set of indices which define the valid subset of the given elements.<br>
136  * Only valid elements will be added while also the already stored sets of elements will be reduced so that only valid elements are stored finally.<br>
137  * @param elements Elements that replace the existing ones
138  * @param validIndices Indices that define a valid subset of the given elements, each index must exist at most once and must lie inside the range [0, elements.size())
139  * @return True, if succeeded
140  */
141  bool setLastElements(const Elements& elements, const Indices32& validIndices);
142 
143  /**
144  * Adds a new set of elements that corresponds to the stored sets of elements.
145  * Element correspondence is defined by the index of the given elements.<br>
146  * Beware: The number of provided elements must match to the number of stored elements in each set of this object.<br>
147  * @param elements Elements to be added
148  * @return True, if succeeded
149  */
150  inline bool addElements(const Elements& elements);
151 
152  /**
153  * Adds a new set of elements that corresponds to the stored sets of elements.
154  * Element correspondence is defined by the index of the given elements.<br>
155  * Beware: The number of provided elements must match to the number of stored elements in each set of this object.<br>
156  * @param elements Elements to be added
157  * @return True, if succeeded
158  */
159  inline bool addElements(Elements&& elements);
160 
161  /**
162  * Adds a new subset of elements that corresponds to a subset of the stored sets of elements.
163  * Element correspondence is defined by the index of the given elements.<br>
164  * This function takes a set of indices which define the valid subset of the given elements.<br>
165  * Only valid elements will be added while also the already stored sets of elements will be reduced so that only valid elements are stored finally.<br>
166  * @param elements Elements to be added
167  * @param validIndices Indices that define a valid subset of the given elements, each index must exist at most once and must lie inside the range [0, elements.size())
168  * @return True, if succeeded
169  */
170  bool addElements(const Elements& elements, const Indices32& validIndices);
171 
172  /**
173  * Reduces the elements within each set of corresponding elements.
174  * The remaining elements are defined by a set of indices.<br>
175  * @param validIndices Indices that define a valid subset of the already stored elements, each index must exist at most once and must lie inside the range [0, elements())
176  * @return True, if succeeded
177  */
178  bool reduce(const Indices32& validIndices);
179 
180  /**
181  * Returns whether this object does not hold any set of elements.
182  * Beware: This state does not say anything about the number of elements that are stored in the individual sets.<br>
183  * To ensure that this object holds a valid number of sets and a valid number of elements check also elements().<br>
184  * @return True, if so
185  * @see elements().
186  */
187  inline bool isEmpty() const;
188 
189  /**
190  * Returns whether this object holds at least one set of elements.
191  * @return True, if so
192  */
193  explicit inline operator bool() const;
194 
195  /**
196  * Move operator.
197  * @param right Second object to be moved
198  * @return Reference to this object
199  */
201 
202  protected:
203 
204  /**
205  * Returns whether this object stores sets of elements with same number of elements.
206  * @return True, if so
207  */
208  inline bool isValid() const;
209 
210  protected:
211 
212  /// The set of corresponding elements.
214 };
215 
216 template <typename T>
218 {
219  // nothing to do here
220 }
221 
222 template <typename T>
224  correspondenceElementsSet(1, elements)
225 {
226  // nothing to do here
227 }
228 
229 template <typename T>
231  correspondenceElementsSet(1, elements)
232 {
233  // nothing to do here
234 }
235 
236 template <typename T>
237 inline CorrespondenceSet<T>::CorrespondenceSet(CorrespondenceSet<T>&& correspondenceSet) noexcept :
238  correspondenceElementsSet(std::move(correspondenceSet.correspondenceElementsSet))
239 {
240  // nothing to do here
241 }
242 
243 template <typename T>
244 inline size_t CorrespondenceSet<T>::size() const
245 {
246  ocean_assert(isValid());
247  return correspondenceElementsSet.size();
248 }
249 
250 template <typename T>
251 inline size_t CorrespondenceSet<T>::elements() const
252 {
253  ocean_assert(isValid());
254  return correspondenceElementsSet.empty() ? 0 : correspondenceElementsSet.front().size();
255 }
256 
257 template <typename T>
259 {
260  ocean_assert(isValid());
261  return correspondenceElementsSet;
262 }
263 
264 template <typename T>
266 {
267  ocean_assert(isValid());
268  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
269 
270  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
271  return false;
272 
273  if (correspondenceElementsSet.empty())
274  correspondenceElementsSet.push_back(elements);
275  else
276  correspondenceElementsSet.front() = elements;
277 
278  return true;
279 }
280 
281 template <typename T>
283 {
284  ocean_assert(isValid());
285  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
286 
287  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
288  return false;
289 
290  if (correspondenceElementsSet.empty())
291  correspondenceElementsSet.push_back(elements);
292  else
293  correspondenceElementsSet.front() = elements;
294 
295  return true;
296 }
297 
298 template <typename T>
299 bool CorrespondenceSet<T>::setFirstElements(const Elements& elements, const Indices32& validIndices)
300 {
301  ocean_assert(isValid() && !elements.empty());
302 
303  ocean_assert(elements.size() >= validIndices.size());
304  ocean_assert(CorrespondenceSet<T>::elements() == 0 || elements.size() == CorrespondenceSet<T>::elements());
305 
306  if (elements.size() < validIndices.size() || (CorrespondenceSet<T>::elements() != 0 && elements.size() != CorrespondenceSet<T>::elements()))
307  return false;
308 
309 #ifdef OCEAN_DEBUG
310 
311  const IndexSet32 indexSet(validIndices.begin(), validIndices.end());
312 
313  // ensure that each index exists only once
314  ocean_assert(indexSet.size() == validIndices.size());
315 
316  if (elements.size() == validIndices.size())
317  ocean_assert(*indexSet.rbegin() == validIndices.size() - 1);
318  else
319  {
320  for (Indices32::const_iterator i = validIndices.begin(); i != validIndices.end(); ++i)
321  ocean_assert(*i < elements.size());
322  }
323 
324 #endif // OCEAN_DEBUG
325 
326  if (elements.size() == validIndices.size())
327  {
328  if (correspondenceElementsSet.empty())
329  correspondenceElementsSet.push_back(elements);
330  else
331  correspondenceElementsSet.front() = elements;
332  }
333  else
334  {
335  for (typename ElementsVector::iterator i = correspondenceElementsSet.begin(); i != correspondenceElementsSet.end(); ++i)
336  *i = std::move(Subset::subset(*i, validIndices));
337 
338  if (correspondenceElementsSet.empty())
339  correspondenceElementsSet.push_back(std::move(Subset::subset(elements, validIndices)));
340  else
341  correspondenceElementsSet.front() = std::move(Subset::subset(elements, validIndices));
342  }
343 
344  return true;
345 }
346 
347 template <typename T>
349 {
350  ocean_assert(isValid());
351  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
352 
353  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
354  return false;
355 
356  if (correspondenceElementsSet.empty())
357  correspondenceElementsSet.push_back(elements);
358  else
359  correspondenceElementsSet.back() = elements;
360 
361  return true;
362 }
363 
364 template <typename T>
366 {
367  ocean_assert(isValid());
368  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
369 
370  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
371  return false;
372 
373  if (correspondenceElementsSet.empty())
374  correspondenceElementsSet.push_back(elements);
375  else
376  correspondenceElementsSet.back() = elements;
377 
378  return true;
379 }
380 
381 template <typename T>
382 bool CorrespondenceSet<T>::setLastElements(const Elements& elements, const Indices32& validIndices)
383 {
384  ocean_assert(isValid() && !elements.empty());
385 
386  ocean_assert(elements.size() >= validIndices.size());
387  ocean_assert(CorrespondenceSet<T>::elements() == 0 || elements.size() == CorrespondenceSet<T>::elements());
388 
389  if (elements.size() < validIndices.size() || (CorrespondenceSet<T>::elements() != 0 && elements.size() != CorrespondenceSet<T>::elements()))
390  return false;
391 
392 #ifdef OCEAN_DEBUG
393 
394  const IndexSet32 indexSet(validIndices.begin(), validIndices.end());
395 
396  // ensure that each index exists only once
397  ocean_assert(indexSet.size() == validIndices.size());
398 
399  if (elements.size() == validIndices.size())
400  ocean_assert(*indexSet.rbegin() == validIndices.size() - 1);
401  else
402  {
403  for (Indices32::const_iterator i = validIndices.begin(); i != validIndices.end(); ++i)
404  ocean_assert(*i < elements.size());
405  }
406 
407 #endif // OCEAN_DEBUG
408 
409  if (elements.size() == validIndices.size())
410  {
411  if (correspondenceElementsSet.empty())
412  correspondenceElementsSet.push_back(elements);
413  else
414  correspondenceElementsSet.back() = elements;
415  }
416  else
417  {
418  for (typename ElementsVector::iterator i = correspondenceElementsSet.begin(); i != correspondenceElementsSet.end(); ++i)
419  *i = std::move(Subset::subset(*i, validIndices));
420 
421  if (correspondenceElementsSet.empty())
422  correspondenceElementsSet.push_back(std::move(Subset::subset(elements, validIndices)));
423  else
424  correspondenceElementsSet.back() = std::move(Subset::subset(elements, validIndices));
425  }
426 
427  return true;
428 }
429 
430 template <typename T>
431 inline bool CorrespondenceSet<T>::addElements(const Elements& elements)
432 {
433  ocean_assert(isValid());
434  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
435 
436  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
437  return false;
438 
439  correspondenceElementsSet.push_back(elements);
440 
441  return true;
442 }
443 
444 template <typename T>
446 {
447  ocean_assert(isValid());
448  ocean_assert(correspondenceElementsSet.empty() || correspondenceElementsSet.front().size() == elements.size());
449 
450  if (!correspondenceElementsSet.empty() && correspondenceElementsSet.front().size() != elements.size())
451  return false;
452 
453  correspondenceElementsSet.push_back(elements);
454 
455  return true;
456 }
457 
458 template <typename T>
459 inline bool CorrespondenceSet<T>::addElements(const Elements& elements, const Indices32& validIndices)
460 {
461  ocean_assert(isValid() && !elements.empty());
462 
463  ocean_assert(elements.size() >= validIndices.size());
464  ocean_assert(CorrespondenceSet<T>::elements() == 0 || elements.size() == CorrespondenceSet<T>::elements());
465 
466  if (elements.size() < validIndices.size() || (CorrespondenceSet<T>::elements() != 0 && elements.size() != CorrespondenceSet<T>::elements()))
467  return false;
468 
469 #ifdef OCEAN_DEBUG
470 
471  const IndexSet32 indexSet(validIndices.begin(), validIndices.end());
472 
473  // ensure that each index exists only once
474  ocean_assert(indexSet.size() == validIndices.size());
475 
476  if (elements.size() == validIndices.size())
477  ocean_assert(*indexSet.rbegin() == validIndices.size() - 1);
478  else
479  {
480  for (Indices32::const_iterator i = validIndices.begin(); i != validIndices.end(); ++i)
481  ocean_assert(*i < elements.size());
482  }
483 
484 #endif // OCEAN_DEBUG
485 
486  if (elements.size() == validIndices.size())
487  correspondenceElementsSet.push_back(elements);
488  else
489  {
490  for (typename ElementsVector::iterator i = correspondenceElementsSet.begin(); i != correspondenceElementsSet.end(); ++i)
491  *i = std::move(Subset::subset(*i, validIndices));
492 
493  correspondenceElementsSet.push_back(std::move(Subset::subset(elements, validIndices)));
494  }
495 
496  return true;
497 }
498 
499 template <typename T>
500 inline bool CorrespondenceSet<T>::reduce(const Indices32& validIndices)
501 {
502  ocean_assert(isValid());
503 
504  ocean_assert(elements() >= validIndices.size());
505 
506  if (elements() < validIndices.size())
507  return false;
508 
509 #ifdef OCEAN_DEBUG
510 
511  const IndexSet32 indexSet(validIndices.begin(), validIndices.end());
512 
513  // ensure that each index exists only once
514  ocean_assert(indexSet.size() == validIndices.size());
515 
516  if (elements() == validIndices.size())
517  ocean_assert(*indexSet.rbegin() == validIndices.size() - 1);
518  else
519  {
520  for (Indices32::const_iterator i = validIndices.begin(); i != validIndices.end(); ++i)
521  ocean_assert(*i < elements());
522  }
523 
524 #endif // OCEAN_DEBUG
525 
526  if (elements() != validIndices.size())
527  {
528  for (typename ElementsVector::iterator i = correspondenceElementsSet.begin(); i != correspondenceElementsSet.end(); ++i)
529  *i = std::move(Subset::subset(*i, validIndices));
530  }
531 
532  return true;
533 }
534 
535 template <typename T>
536 inline bool CorrespondenceSet<T>::isEmpty() const
537 {
538  ocean_assert(isValid());
539  return correspondenceElementsSet.empty();
540 }
541 
542 template <typename T>
544 {
545  ocean_assert(isValid());
546  return !correspondenceElementsSet.empty();
547 }
548 
549 template <typename T>
550 inline bool CorrespondenceSet<T>::isValid() const
551 {
552  for (size_t n = 1; n < correspondenceElementsSet.size(); ++n)
553  if (correspondenceElementsSet[0].size() != correspondenceElementsSet[n].size())
554  return false;
555 
556  return true;
557 }
558 
559 template <typename T>
561 {
562  ocean_assert(isValid() && right.isValid());
563 
564  if (this != &right)
565  correspondenceElementsSet = std::move(right.correspondenceElementsSet);
566 
567  return *this;
568 }
569 
570 }
571 
572 }
573 
574 #endif // META_OCEAN_TRACKING_CORRESPONDENCE_SET_H
static std::vector< T > subset(const std::vector< T > &objects, const std::vector< TIndex > &indices)
Extracts a subset of a given set of objects by usage of an index vector holding the indices of all ob...
Definition: Subset.h:751
This class manages a set of element correspondences.
Definition: CorrespondenceSet.h:30
bool addElements(const Elements &elements, const Indices32 &validIndices)
Adds a new subset of elements that corresponds to a subset of the stored sets of elements.
Definition: CorrespondenceSet.h:459
CorrespondenceSet(Elements &&elements)
Creates new object by adding the first elements.
Definition: CorrespondenceSet.h:230
bool isEmpty() const
Returns whether this object does not hold any set of elements.
Definition: CorrespondenceSet.h:536
T Type
Defines the data type of the individual elements.
Definition: CorrespondenceSet.h:36
bool setFirstElements(Elements &&elements)
Changes (or sets) the first set of elements.
Definition: CorrespondenceSet.h:282
size_t elements() const
Returns the number of corresponding elements.
Definition: CorrespondenceSet.h:251
CorrespondenceSet(CorrespondenceSet< T > &&correspondenceSet) noexcept
Move constructor.
Definition: CorrespondenceSet.h:237
bool isValid() const
Returns whether this object stores sets of elements with same number of elements.
Definition: CorrespondenceSet.h:550
CorrespondenceSet< T > & operator=(CorrespondenceSet< T > &&right) noexcept
Move operator.
Definition: CorrespondenceSet.h:560
bool setLastElements(Elements &&elements)
Changes (or sets) the last set of elements.
Definition: CorrespondenceSet.h:365
bool reduce(const Indices32 &validIndices)
Reduces the elements within each set of corresponding elements.
Definition: CorrespondenceSet.h:500
CorrespondenceSet(const Elements &elements)
Creates new object by adding the first elements.
Definition: CorrespondenceSet.h:223
bool setFirstElements(const Elements &elements)
Changes (or sets) the first set of elements.
Definition: CorrespondenceSet.h:265
std::vector< T > Elements
This class defines a vector storing individual elements.
Definition: CorrespondenceSet.h:41
std::vector< Elements > ElementsVector
This class defines a vector storing vectors of elements.
Definition: CorrespondenceSet.h:46
bool setLastElements(const Elements &elements)
Changes (or sets) the last set of elements.
Definition: CorrespondenceSet.h:348
CorrespondenceSet()
Creates an empty object.
Definition: CorrespondenceSet.h:217
bool setFirstElements(const Elements &elements, const Indices32 &validIndices)
Changes (or sets) the first set of elements.
Definition: CorrespondenceSet.h:299
bool addElements(Elements &&elements)
Adds a new set of elements that corresponds to the stored sets of elements.
Definition: CorrespondenceSet.h:445
ElementsVector correspondenceElementsSet
The set of corresponding elements.
Definition: CorrespondenceSet.h:213
size_t size() const
Returns the number of correspondences.
Definition: CorrespondenceSet.h:244
bool setLastElements(const Elements &elements, const Indices32 &validIndices)
Changes (or sets) the last set of elements.
Definition: CorrespondenceSet.h:382
bool addElements(const Elements &elements)
Adds a new set of elements that corresponds to the stored sets of elements.
Definition: CorrespondenceSet.h:431
const ElementsVector & correspondences() const
Returns the set of stored correspondences.
Definition: CorrespondenceSet.h:258
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition: Base.h:114
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition: Base.h:96
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15