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 Apache License, Version 2.0
7// (the "License"); you may not use this file except in compliance with the
8// License. You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15// License for the specific language governing permissions and limitations
16// under the License.
17//
18// You can contact the authors at <alessandro.fornasier@ieee.org>
19
20#ifndef TOOLS_HPP
21#define TOOLS_HPP
22
23#include <algorithm>
24#include <array>
25#include <cmath>
26#include <iterator>
27#include <queue>
28#include <random>
29#include <type_traits>
30#include <Eigen/Dense>
31
32namespace utils
33{
40template <typename Key, typename Value>
42{
43 public:
50 void insert(const Key& key, const Value& value)
51 {
52 if (map_.find(key) == map_.end())
53 {
54 map_[key] = vector_.size();
55 vector_.emplace_back(std::make_pair(key, value));
56 }
57 }
58
65 const Value& at(const Key& key) const
66 {
67 auto index = map_.at(key);
68 return vector_.at(index).second;
69 }
70
77 Value& at(const Key& key)
78 {
79 auto index = map_.at(key);
80 return vector_.at(index).second;
81 }
82
88 const std::vector<Key> keys() const
89 {
90 std::vector<Key> result;
91 for (const auto& pair : vector_)
92 {
93 result.push_back(pair.first);
94 }
95 return result;
96 }
97
103 const std::vector<Value> values() const
104 {
105 std::vector<Value> result;
106 for (const auto& pair : vector_)
107 {
108 result.push_back(pair.second);
109 }
110 return result;
111 }
112
117 void clear()
118 {
119 map_.clear();
120 vector_.clear();
121 }
122
123 private:
124 std::unordered_map<Key, size_t> map_;
125 std::vector<std::pair<Key, Value>> vector_;
126};
127
137template <typename FPType>
138static Eigen::Matrix<FPType, Eigen::Dynamic, 1> diff(
139 const Eigen::Matrix<FPType, Eigen::Dynamic, 1>& x,
140 const std::function<double(const Eigen::Matrix<FPType, Eigen::Dynamic, 1>&)>& f,
141 double h = 1e-6)
142{
143 int n = x.size();
144 Eigen::Matrix<FPType, Eigen::Dynamic, 1> grad(n);
145 for (int i = 0; i < n; i++)
146 {
147 Eigen::Matrix<FPType, Eigen::Dynamic, 1> x_plus = x, x_minus = x;
148 x_plus(i) += h;
149 x_minus(i) -= h;
150 grad(i) = (f(x_plus) - f(x_minus)) / (2 * h);
151 }
152 return grad;
153}
154
167template <typename Numeric, typename Generator = std::mt19937>
168static Numeric random(Numeric from, Numeric to)
169{
170 thread_local static Generator gen(std::random_device{}());
171 using dist_type = typename std::conditional<std::is_integral<Numeric>::value, std::uniform_int_distribution<Numeric>,
172 std::uniform_real_distribution<Numeric>>::type;
173 thread_local static dist_type dist;
174 return dist(gen, typename dist_type::param_type{from, to});
175}
176
182static inline void trimString(std::string& s)
183{
184 s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), [](unsigned char ch) { return std::isspace(ch); }));
185 s.erase(std::find_if_not(s.rbegin(), s.rend(), [](unsigned char ch) { return std::isspace(ch); }).base(), s.end());
186}
187
195template <typename T>
196static std::vector<T> flatten(const std::vector<std::vector<T>>& vector_of_vectors)
197{
198 std::vector<T> flat;
199 size_t total_size = std::accumulate(vector_of_vectors.begin(), vector_of_vectors.end(), 0,
200 [](size_t size, const std::vector<T>& vec) { return size + vec.size(); });
201 flat.reserve(total_size);
202 for (const auto& vec : vector_of_vectors)
203 {
204 flat.insert(flat.end(), vec.begin(), vec.end());
205 }
206 return flat;
207}
208
209// /**
210// * @brief Flatten a vector of vectors and insert in given vector (append if the given vector in non empty)
211// *
212// * @tparam Type of data in vector
213// * @param vector_of_vectors Vector of vectors
214// * @return Flatten vector
215// *
216// * @note The vector of vectors is moved into flat so it becames unusable
217// */
218// template <typename T>
219// static void flattenInto(const std::vector<std::vector<T>>& vector_of_vectors, std::vector<T>& flat)
220// {
221// size_t total_size =
222// flat.size() + std::accumulate(vector_of_vectors.begin(), vector_of_vectors.end(), 0,
223// [](size_t size, const std::vector<T>& vec) { return size + vec.size(); });
224// flat.reserve(total_size);
225// for (const auto& vec : vector_of_vectors)
226// {
227// flat.insert(flat.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()));
228// }
229// }
230
237static inline int pow2(const int& n) { return static_cast<int>(std::ldexp(1.0f, n)); }
238
239} // namespace utils
240
248template <typename T>
249std::ostream& operator<<(std::ostream& stream, const std::vector<T>& v)
250{
251 // Check container is not empty
252 if (!v.empty())
253 {
254 // Beginning bracket
255 stream << "[";
256
257 // Copy element of container into output stream
258 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
259
260 // Last element and end bracket
261 stream << v.back() << "]";
262 }
263 return stream;
264}
265
273template <typename T, std::size_t N>
274std::ostream& operator<<(std::ostream& stream, const std::array<T, N>& v)
275{
276 // Check container is not empty
277 if (!v.empty())
278 {
279 // Beginning bracket
280 stream << "[";
281
282 // Copy element of container into output stream
283 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
284
285 // Last element and end bracket
286 stream << v.back() << "]";
287 }
288 return stream;
289}
290
298template <typename T>
299std::ostream& operator<<(std::ostream& stream, const std::deque<T>& v)
300{
301 // Check container is not empty
302 if (!v.empty())
303 {
304 // Beginning bracket
305 stream << "[";
306
307 // Copy element of container into output stream
308 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(stream, ", "));
309
310 // Last element and end bracket
311 stream << v.back() << "]";
312 }
313 return stream;
314}
315
323template <typename T, typename std::enable_if<std::is_enum<T>::value, T>::type* = nullptr>
324std::ostream& operator<<(std::ostream& stream, const T& e)
325{
326 return stream << static_cast<typename std::underlying_type<T>::type>(e);
327}
328
329#endif // TOOLS_HPP
This calss define a map that keeps the insertion order.
Definition tools.hpp:42
const std::vector< Key > keys() const
Return a vector containing the keys.
Definition tools.hpp:88
const Value & at(const Key &key) const
Return the value associated with the key.
Definition tools.hpp:65
void clear()
Clear the map and the vector.
Definition tools.hpp:117
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:50
Value & at(const Key &key)
Return the value associated with the key.
Definition tools.hpp:77
const std::vector< Value > values() const
Return a vector containing the values.
Definition tools.hpp:103