aligator  0.14.0
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
 
Loading...
Searching...
No Matches
managed-matrix.hpp
Go to the documentation of this file.
1
2#pragma once
3
5#include <Eigen/Core>
6
7namespace aligator {
8
20template <typename _Scalar, int _Rows, int _Cols,
21 int _Options = Eigen::ColMajor, int Alignment = Eigen::AlignedMax>
23 using alloc_traits = std::allocator_traits<polymorphic_allocator>;
24 static_assert((_Rows == Eigen::Dynamic) || (_Cols == Eigen::Dynamic));
25
26 void allocate() {
27 m_data = m_allocator.allocate<_Scalar>(size_t(size()), Alignment);
28 m_allocated_size = size();
29 }
30
31 void deallocate() {
32 if (m_data)
33 m_allocator.deallocate<_Scalar>(m_data, size_t(m_allocated_size),
34 Alignment);
35 }
36
37public:
38 using Scalar = _Scalar;
39 static constexpr int Rows = _Rows;
40 static constexpr int Cols = _Cols;
41 static constexpr int Options = _Options;
42 using MatrixType = Eigen::Matrix<Scalar, Rows, Cols, Options>;
43 using MapType = Eigen::Map<MatrixType, Alignment>;
44 using ConstMapType = Eigen::Map<const MatrixType, Alignment>;
45 using Index = Eigen::Index;
47
48 static constexpr bool IsVectorAtCompileTime =
49 MatrixType::IsVectorAtCompileTime;
50
52 explicit ManagedMatrix(const allocator_type &allocator = {})
53 : m_allocated_size(0)
54 , m_rows()
55 , m_cols()
56 , m_allocator(allocator) {}
57
58 explicit ManagedMatrix(Index size, const allocator_type &allocator)
59 : m_rows()
60 , m_cols()
61 , m_allocator(allocator) {
62 static_assert(IsVectorAtCompileTime);
63 if constexpr (Rows == 1) {
64 m_rows = 1;
65 m_cols = size;
66 } else if constexpr (Cols == 1) {
67 m_rows = size;
68 m_cols = 1;
69 }
70 this->allocate();
71 assert(m_data);
72 }
73
75 const allocator_type &allocator)
76 : m_rows(rows)
77 , m_cols(cols)
78 , m_allocator(allocator) {
79 this->allocate();
80 assert(m_data);
81 }
82
83 ManagedMatrix(const ManagedMatrix &other, const allocator_type &alloc = {})
84 : ManagedMatrix(other.rows(), other.cols(), alloc) {
85 this->to_map() = other.to_const_map();
86 }
87
90 : ManagedMatrix(alloc) {
91 m_rows = std::move(other.m_rows);
92 m_cols = std::move(other.m_cols);
93
94 if (!other.m_data)
95 return;
96
97 if (m_allocator == other.get_allocator()) {
98 // same allocator: just steal the pointer
99 m_data = other.m_data;
100 other.m_data = nullptr;
101 } else if (size() > 0) {
102 // different allocator: allocate, copy values
103 this->allocate();
104 this->to_map() = other.to_const_map();
105 }
106 // dtor of 'other' cleans up if necessary
107 }
108
110 ManagedMatrix(ManagedMatrix &&other) noexcept
111 : m_allocator(other.get_allocator()) {
112 m_allocated_size = other.m_allocated_size;
113 m_rows = other.m_rows;
114 m_cols = other.m_cols;
115 m_data = other.m_data;
116
117 other.m_data = nullptr;
118 other.m_allocated_size = 0;
119 }
120
122 template <typename Derived>
123 ManagedMatrix(const Eigen::MatrixBase<Derived> &mat,
124 const allocator_type &alloc = {})
125 : ManagedMatrix(mat.rows(), mat.cols(), alloc) {
126 this->to_map() = mat;
127 }
128
130 // set new dimensions
131 m_rows = other.m_rows;
132 m_cols = other.m_cols;
133 if (m_allocated_size < other.size()) {
134 // reallocate
135 this->deallocate();
136 this->allocate();
137 assert(m_allocated_size == size());
138 }
139 this->to_map() = other.to_const_map();
140 return *this;
141 }
142
144 m_rows = other.m_rows;
145 m_cols = other.m_cols;
146
147 if (!other.m_data)
148 return *this;
149
150 if (m_allocator == other.get_allocator()) {
151 // just steal the pointer, return early
152 m_data = other.m_data;
153 other.m_data = nullptr;
154 return *this;
155 } else {
156 this->resize(other.rows(), other.cols());
157 }
158 this->to_map() = other.to_const_map();
159 return *this;
160 }
161
162 template <typename Derived>
163 ManagedMatrix &operator=(const Eigen::MatrixBase<Derived> &mat) {
164 this->resize(mat.rows(), mat.cols());
165 this->to_map() = mat;
166 return *this;
167 }
168
170 static_assert(IsVectorAtCompileTime);
171 if constexpr (Rows == 1) {
172 m_rows = 1;
173 m_cols = size;
174 } else if constexpr (Cols == 1) {
175 m_rows = size;
176 m_cols = 1;
177 }
178 if (m_allocated_size < size) {
179 this->deallocate();
180 this->allocate();
181 }
182 }
183
185 const Index new_size = rows * cols;
186 m_rows = rows;
187 m_cols = cols;
188 if (m_allocated_size < new_size) {
189 this->deallocate();
190 this->allocate();
191 }
192 }
193
194 Index rows() const noexcept { return m_rows; }
195
196 Index cols() const noexcept { return m_cols; }
197
198 Index size() const noexcept { return m_rows * m_cols; }
199
201 Index allocated_size() const noexcept { return m_allocated_size; }
202
204 [[nodiscard]] allocator_type get_allocator() const noexcept {
205 return m_allocator;
206 }
207
208 [[nodiscard]] explicit operator MapType() {
209 if constexpr (IsVectorAtCompileTime) {
210 return MapType{m_data, size()};
211 } else {
212 return MapType{m_data, m_rows, m_cols};
213 }
214 }
215
216 [[nodiscard]] explicit operator ConstMapType() const {
217 if constexpr (IsVectorAtCompileTime) {
218 return ConstMapType{m_data, size()};
219 } else {
220 return ConstMapType{m_data, m_rows, m_cols};
221 }
222 }
223
224 ~ManagedMatrix() { this->deallocate(); }
225
227 MapType to_map() { return MapType{*this}; }
228
230 ConstMapType to_map() const { return to_const_map(); }
231
233 ConstMapType to_const_map() const { return ConstMapType{*this}; }
234
235 void setZero() { this->to_map().setZero(); }
236
238 this->resize(rows, cols);
239 this->setZero();
240 }
241
243 this->resize(size);
244 this->setZero();
245 }
246
247 void setRandom() { this->to_map().setRandom(); }
248
249 void setIdentity() { this->to_map().setIdentity(); }
250
251 void setConstant(Scalar s) { this->to_map().setConstant(s); }
252
253 auto noalias() { return to_map().noalias(); }
254
255 auto diagonal() { return to_map().diagonal(); }
256 auto diagonal() const { return to_const_map().diagonal(); }
257
258 auto topRows(Index n) { return to_map().topRows(n); }
259 auto topRows(Index n) const { return to_const_map().topRows(n); }
260
261 auto head(Index n) { return to_map().head(n); }
262 auto head(Index n) const { return to_const_map().head(n); }
263
264 auto tail(Index n) { return to_map().tail(n); }
265 auto tail(Index n) const { return to_const_map().tail(n); }
266
267 bool isApprox(const ManagedMatrix &other,
268 Scalar prec = std::numeric_limits<Scalar>::epsilon()) const {
269 return to_const_map().isApprox(other.to_const_map(), prec);
270 }
271
272 template <typename Derived>
273 bool isApprox(const Eigen::DenseBase<Derived> &mat,
274 Scalar prec = std::numeric_limits<Scalar>::epsilon()) const {
275 return to_const_map().isApprox(mat, prec);
276 }
277
279 [[nodiscard]] Scalar *data() { return m_data; }
280
282 [[nodiscard]] const Scalar *data() const { return m_data; }
283
284private:
285 Index m_allocated_size; // might be different than size()
286 Index m_rows;
287 Index m_cols;
288 Scalar *m_data{nullptr};
289 allocator_type m_allocator;
290};
291
292} // namespace aligator
Thin wrapper around Eigen::Map representing a matrix object with memory managed by a C++17 polymorphi...
ManagedMatrix & operator=(const ManagedMatrix &other)
ManagedMatrix(ManagedMatrix &&other, const allocator_type &alloc)
Extended move constructor, will use the provided allocator.
Eigen::Matrix< Scalar, Rows, Cols, Options > MatrixType
ManagedMatrix(Index rows, Index cols, const allocator_type &allocator)
ManagedMatrix(const Eigen::MatrixBase< Derived > &mat, const allocator_type &alloc={})
Copy constructor from another Eigen matrix.
ConstMapType to_map() const
Obtain const map since this is const.
ManagedMatrix(const ManagedMatrix &other, const allocator_type &alloc={})
ManagedMatrix(ManagedMatrix &&other) noexcept
Nonextended move constructor, will use moved-from object's allocator.
Scalar * data()
Pointer to stored data.
auto head(Index n) const
bool isApprox(const ManagedMatrix &other, Scalar prec=std::numeric_limits< Scalar >::epsilon()) const
ManagedMatrix(const allocator_type &allocator={})
Extended default constructor.
void resize(Index rows, Index cols)
ManagedMatrix(Index size, const allocator_type &allocator)
auto tail(Index n) const
bool isApprox(const Eigen::DenseBase< Derived > &mat, Scalar prec=std::numeric_limits< Scalar >::epsilon()) const
const Scalar * data() const
Pointer to stored data.
MapType to_map()
Obtain mutable map.
ManagedMatrix & operator=(const Eigen::MatrixBase< Derived > &mat)
Eigen::Map< MatrixType, Eigen::AlignedMax > MapType
ManagedMatrix & operator=(ManagedMatrix &&other)
Index allocated_size() const noexcept
Get current allocated size.
Eigen::Map< const MatrixType, Eigen::AlignedMax > ConstMapType
void setZero(Index rows, Index cols)
ConstMapType to_const_map() const
Obtain a const map.
auto topRows(Index n) const
allocator_type get_allocator() const noexcept
Accessor to retrieve the allocator used for this matrix.
Index size() const noexcept
A convenience subclass of std::pmr::polymorphic_allocator for bytes.
Definition allocator.hpp:17
Main package namespace.