MSCEqF 1.0
Multi State Constraint Equivariant Filter for visual inertial navigation
Loading...
Searching...
No Matches
tools.hpp
1// Copyright (C) 2023 Alessandro Fornasier.
2// Control of Networked Systems, University of Klagenfurt, Austria.
3//
4// All rights reserved.
5//
6// This software is licensed under the terms of the BSD-2-Clause-License with
7// no commercial use allowed, the full terms of which are made available
8// in the LICENSE file. No license in patents is granted.
9//
10// You can contact the authors at <alessandro.fornasier@ieee.org>
11
12#ifndef TOOLS_HPP
13#define TOOLS_HPP
14
15#include <algorithm>
16#include <array>
17#include <cmath>
18#include <iterator>
19#include <queue>
20#include <random>
21#include <type_traits>
22#include <Eigen/Dense>
23
24namespace utils
25{
32template <typename Key, typename Value>
34{
35 public:
42 void insert(const Key& key, const Value& value)
43 {
44 if (map_.find(key) == map_.end())
45 {
46 map_[key] = vector_.size();
47 vector_.emplace_back(std::make_pair(key, value));
48 }
49 }
50
57 const Value& at(const Key& key) const
58 {
59 auto index = map_.at(key);
60 return vector_.at(index).second;
61 }
62
69 Value& at(const Key& key)
70 {
71 auto index = map_.at(key);
72 return vector_.at(index).second;
73 }
74
80 const std::vector<Key> keys() const
81 {
82 std::vector<Key> result;
83 for (const auto& pair : vector_)
84 {
85 result.push_back(pair.first);
86 }
87 return result;
88 }
89
95 const std::vector<Value> values() const
96 {
97 std::vector<Value> result;
98 for (const auto& pair : vector_)
99 {
100 result.push_back(pair.second);
101 }
102 return result;
103 }
104
109 void clear()
110 {
111 map_.clear();
112 vector_.clear();
113 }
114
115 private:
116 std::unordered_map<Key, size_t> map_;
117 std::vector<std::pair<Key, Value>> vector_;
118};
119
129template <typename FPType>
130static Eigen::Matrix<FPType, Eigen::Dynamic, 1> diff(
131 const Eigen::Matrix<FPType, Eigen::Dynamic, 1>& x,
132 const std::function<double(const Eigen::Matrix<FPType, Eigen::Dynamic, 1>&)>& f,
133 double h = 1e-6)
134{
135 int n = x.size();
136 Eigen::Matrix<FPType, Eigen::Dynamic, 1> grad(n);
137 for (int i = 0; i < n; i++)
138 {
139 Eigen::Matrix<FPType, Eigen::Dynamic, 1> x_plus = x, x_minus = x;
140 x_plus(i) += h;
141 x_minus(i) -= h;
142 grad(i) = (f(x_plus) - f(x_minus)) / (2 * h);
143 }
144 return grad;
145}
146
159template <typename Numeric, typename Generator = std::mt19937>
160static Numeric random(Numeric from, Numeric to)
161{
162 thread_local static Generator gen(std::random_device{}());
163 using dist_type = typename std::conditional<std::is_integral<Numeric>::value, std::uniform_int_distribution<Numeric>,
164 std::uniform_real_distribution<Numeric>>::type;
165 thread_local static dist_type dist;
166 return dist(gen, typename dist_type::param_type{from, to});
167}
168
174static inline void trimString(std::string& s)
175{
176 s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), [](unsigned char ch) { return std::isspace(ch); }));
177 s.erase(std::find_if_not(s.rbegin(), s.rend(), [](unsigned char ch) { return std::isspace(ch); }).base(), s.end());
178}
179
187template <typename T>
188static std::vector<T> flatten(const std::vector<std::vector<T>>& vector_of_vectors)
189{
190 std::vector<T> flat;
191 size_t total_size = std::accumulate(vector_of_vectors.begin(), vector_of_vectors.end(), 0,
192 [](size_t size, const std::vector<T>& vec) { return size + vec.size(); });
193 flat.reserve(total_size);
194 for (const auto& vec : vector_of_vectors)
195 {
196 flat.insert(flat.end(), vec.begin(), vec.end());
197 }
198 return flat;
199}
200
201// /**
202// * @brief Flatten a vector of vectors and insert in given vector (append if the given vector in non empty)
203// *
204// * @tparam Type of data in vector
205// * @param vector_of_vectors Vector of vectors
206// * @return Flatten vector
207// *
208// * @note The vector of vectors is moved into flat so it becames unusable
209// */
210// template <typename T>
211// static void flattenInto(const std::vector<std::vector<T>>& vector_of_vectors, std::vector<T>& flat)
212// {
213// size_t total_size =
214// flat.size() + std::accumulate(vector_of_vectors.begin(), vector_of_vectors.end(), 0,
215// [](size_t size, const std::vector<T>& vec) { return size + vec.size(); });
216// flat.reserve(total_size);
217// for (const auto& vec : vector_of_vectors)
218// {
219// flat.insert(flat.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()));
220// }
221// }
222
229static inline int pow2(const int& n) { return static_cast<int>(std::ldexp(1.0f, n)); }
230
231} // namespace utils
232
240template <typename T>
241std::ostream& operator<<(std::ostream& stream, const std::vector<T>& v)
242{
243 // Check container is not empty
244 if (!v.empty())
245 {
246 // Beginning bracket
247 stream << "[";
248
249 // Copy element of container into output stream
250 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
251
252 // Last element and end bracket
253 stream << v.back() << "]";
254 }
255 return stream;
256}
257
265template <typename T, std::size_t N>
266std::ostream& operator<<(std::ostream& stream, const std::array<T, N>& v)
267{
268 // Check container is not empty
269 if (!v.empty())
270 {
271 // Beginning bracket
272 stream << "[";
273
274 // Copy element of container into output stream
275 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
276
277 // Last element and end bracket
278 stream << v.back() << "]";
279 }
280 return stream;
281}
282
290template <typename T>
291std::ostream& operator<<(std::ostream& stream, const std::deque<T>& v)
292{
293 // Check container is not empty
294 if (!v.empty())
295 {
296 // Beginning bracket
297 stream << "[";
298
299 // Copy element of container into output stream
300 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
301
302 // Last element and end bracket
303 stream << v.back() << "]";
304 }
305 return stream;
306}
307
315template <typename T, typename std::enable_if<std::is_enum<T>::value, T>::type* = nullptr>
316std::ostream& operator<<(std::ostream& stream, const T& e)
317{
318 return stream << static_cast<typename std::underlying_type<T>::type>(e);
319}
320
321#endif // TOOLS_HPP
This calss define a map that keeps the insertion order.
Definition tools.hpp:34
const std::vector< Key > keys() const
Return a vector containing the keys.
Definition tools.hpp:80
const Value & at(const Key &key) const
Return the value associated with the key.
Definition tools.hpp:57
void clear()
Clear the map and the vector.
Definition tools.hpp:109
void insert(const Key &key, const Value &value)
Insert a key-value pair into the map if the key does not exists.
Definition tools.hpp:42
Value & at(const Key &key)
Return the value associated with the key.
Definition tools.hpp:69
const std::vector< Value > values() const
Return a vector containing the values.
Definition tools.hpp:95