aligator  0.15.0
A versatile and efficient C++ library for real-time constrained trajectory optimization.
Loading...
Searching...
No Matches
arena-matrix.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include "aligator/math.hpp"
6
7namespace aligator {
8
21template <typename MatrixType, int Alignment = Eigen::AlignedMax>
22class ArenaMatrix;
23
24template <typename MatrixType, int Alignment>
25class ArenaMatrix : public Eigen::Map<std::decay_t<MatrixType>, Alignment> {
26public:
27 using Scalar = typename std::decay_t<MatrixType>::Scalar;
28 using PlainObject = std::decay_t<MatrixType>;
29 using Base = Eigen::Map<PlainObject, Alignment>;
30 using Index = Eigen::Index;
31 using ConstMapType = Eigen::Map<const PlainObject, Alignment>;
32 static constexpr int RowsAtCompileTime = MatrixType::RowsAtCompileTime;
33 static constexpr int ColsAtCompileTime = MatrixType::ColsAtCompileTime;
35 using Base::data;
36
38 : Base::Map(nullptr,
41 , m_allocator()
42 , m_alloc_size(0l) {}
43
44 explicit ArenaMatrix(const allocator_type &allocator)
45 : Base::Map(nullptr,
48 , m_allocator(allocator)
49 , m_alloc_size(0l) {}
50
51 [[nodiscard]] allocator_type get_allocator() const noexcept {
52 return m_allocator;
53 }
54
55 ArenaMatrix(Index cols, Index rows, const allocator_type &allocator = {})
56 : Base::Map(_allocate(cols * rows, allocator), cols, rows)
57 , m_allocator(allocator)
58 , m_alloc_size(cols * rows) {}
59
60 explicit ArenaMatrix(Index size, const allocator_type &allocator = {})
61 : Base::Map(_allocate(size, allocator), size)
62 , m_allocator(allocator)
63 , m_alloc_size(size) {}
64
65 template <typename D, enable_if_eigen_t<D> * = nullptr>
66 ArenaMatrix(const D &other, const allocator_type &alloc = {})
67 : Base::Map(_allocate(other.size(), alloc), get_rows(other),
68 get_cols(other))
69 , m_allocator(alloc)
70 , m_alloc_size(other.size()) {
71 Base::operator=(other);
72 }
73
74 explicit ArenaMatrix(const ArenaMatrix &other,
75 const allocator_type &alloc = {})
76 : ArenaMatrix(other.rows(), other.cols(), alloc) {
77 // copy values from other, delegate to base type's operator=
78 Base::operator=(other);
79 }
80
81 ArenaMatrix(ArenaMatrix &&other) noexcept
82 : Base::Map(other.data(), get_rows(other), get_cols(other))
83 , m_allocator(other.m_allocator)
84 , m_alloc_size(other.m_alloc_size) {
85 other.m_data = nullptr;
86 other.m_alloc_size = 0;
87 }
88
90 ArenaMatrix(ArenaMatrix &&other, const allocator_type &alloc)
91 : ArenaMatrix(alloc) {
92 if (m_allocator == other.m_allocator) {
93 // do not reallocate
94 new (this) Base(other.data(), get_rows(other), get_cols(other));
95 m_alloc_size = other.m_alloc_size;
96 } else {
97 // allocate
98 this->resize(get_rows(other), get_cols(other));
99 Base::operator=(other);
100 }
101 other.m_data = nullptr;
102 other.m_alloc_size = 0;
103 }
104
105 template <typename D, enable_if_eigen_t<D> * = nullptr>
106 ArenaMatrix &operator=(const D &other) {
107 this->resize(get_rows(other), get_cols(other));
108 Base::operator=(other);
109 return *this;
110 }
111
116 this->resize(get_rows(other), get_cols(other));
117 Base::operator=(other);
118 return *this;
119 }
120
121 using Base::operator=;
122
124 if (this == &other)
125 return *this;
126
127 if (m_allocator == other.m_allocator) {
128 this->deallocate();
129 m_alloc_size = other.m_alloc_size;
130 new (this) Base(other.data(), get_rows(other), get_cols(other));
131 } else {
132 this->resize(get_rows(other), get_cols(other));
133 Base::operator=(other);
134 }
135 other.m_data = nullptr;
136 return *this;
137 }
138
139 operator ConstMapType() const {
140 return ConstMapType(this->m_data, this->rows(), this->cols());
141 }
142
143 ~ArenaMatrix() { this->deallocate(); }
144
146 void resize(Index size) {
147 if (m_alloc_size != size) {
148 this->deallocate();
149 Scalar *p = _allocate(size, m_allocator);
150 m_alloc_size = size;
151 new (this) Base(p, size);
152 } else {
153 // simply replace the Map object
154 new (this) Base(this->m_data, size);
155 }
156 }
157
159 void resize(Index rows, Index cols) {
160 const Index size = rows * cols;
161 if (m_alloc_size != size) {
162 this->deallocate();
163 Scalar *p = _allocate(size, m_allocator);
164 m_alloc_size = size;
165 new (this) Base(p, rows, cols);
166 } else {
167 // simply replace the Map object
168 new (this) Base(this->m_data, rows, cols);
169 }
170 }
171
174 if (m_alloc_size < size) {
175 Scalar *p = _allocate(size, m_allocator);
176 std::copy_n(this->m_data, m_alloc_size, p);
177 this->deallocate();
178 m_alloc_size = size;
179 new (this) Base(p, size);
180 } else {
181 new (this) Base(this->m_data, size);
182 }
183 }
184
185 void conservativeResize(Index rows, Index cols) {
186 const Index size = rows * cols;
187 if (m_alloc_size < size) {
188 Scalar *p = _allocate(size, m_allocator);
189 std::copy_n(this->m_data, m_alloc_size, p);
190 this->deallocate();
191 m_alloc_size = size;
192 new (this) Base(p, rows, cols);
193 } else {
194 new (this) Base(this->m_data, rows, cols);
195 }
196 }
197
200 Index allocatedSize() const noexcept { return m_alloc_size; }
201
202 using Base::setZero;
203
205 *this = MatrixType::Zero(newSize);
206 return *this;
207 }
208
210 *this = MatrixType::Zero(rows, cols);
211 return *this;
212 }
213
214 using Base::setIdentity;
215
217 *this = MatrixType::Identity(rows, cols);
218 }
219
220private:
221 template <typename T> constexpr auto get_rows(const T &x) {
222 return (RowsAtCompileTime == 1 && T::ColsAtCompileTime == 1) ||
223 (ColsAtCompileTime == 1 && T::RowsAtCompileTime == 1)
224 ? x.cols()
225 : x.rows();
226 }
227 template <typename T> constexpr auto get_cols(const T &x) {
228 return (RowsAtCompileTime == 1 && T::ColsAtCompileTime == 1) ||
229 (ColsAtCompileTime == 1 && T::RowsAtCompileTime == 1)
230 ? x.rows()
231 : x.cols();
232 }
233
234 [[nodiscard]] static auto *_allocate(Index size, allocator_type alloc) {
235 return alloc.allocate<Scalar>(size_t(size), Alignment);
236 }
237
238 void deallocate() {
239 if (this->m_data)
240 m_allocator.deallocate(this->m_data, size_t(this->size()), Alignment);
241 }
242
243private:
244 allocator_type m_allocator;
245 Index m_alloc_size;
246};
247
248} // namespace aligator
249
250namespace Eigen {
251namespace internal {
252
253// lifted from the stan-dev/math library
254template <typename T>
255struct traits<aligator::ArenaMatrix<T>> : traits<Eigen::Map<T>> {
256 using TraitsBase = traits<Eigen::Map<T>>;
257 using Scalar = typename TraitsBase::Scalar;
258 using XprKind = typename Eigen::internal::traits<std::decay_t<T>>::XprKind;
259 using StorageKind =
260 typename Eigen::internal::traits<std::decay_t<T>>::StorageKind;
261 static constexpr int RowsAtCompileTime =
262 Eigen::internal::traits<std::decay_t<T>>::RowsAtCompileTime;
263 static constexpr int ColsAtCompileTime =
264 Eigen::internal::traits<std::decay_t<T>>::ColsAtCompileTime;
265};
266
267} // namespace internal
268} // namespace Eigen
allocator_type get_allocator() const noexcept
ArenaMatrix(const allocator_type &allocator)
ArenaMatrix & operator=(ArenaMatrix &&other)
ArenaMatrix & operator=(const D &other)
void resize(Index size)
Resize this matrix. This will reallocate.
void resize(Index rows, Index cols)
Resize this matrix. This will reallocate.
ArenaMatrix(ArenaMatrix &&other) noexcept
ArenaMatrix & setZero(Index rows, Index cols)
std::decay_t< MatrixXs > PlainObject
ArenaMatrix & setZero(Index newSize)
ArenaMatrix(Index cols, Index rows, const allocator_type &allocator={})
polymorphic_allocator allocator_type
ArenaMatrix(const D &other, const allocator_type &alloc={})
ArenaMatrix & setIdentity(Index rows, Index cols)
static constexpr int ColsAtCompileTime
ArenaMatrix & operator=(const ArenaMatrix &other)
static constexpr int RowsAtCompileTime
Eigen::Map< PlainObject, Alignment > Base
void conservativeResize(Index size)
Index allocatedSize() const noexcept
Current allocated size for this matrix. This is what allows resizing without reallocation.
ArenaMatrix(ArenaMatrix &&other, const allocator_type &alloc)
Extended move constructor.
ArenaMatrix(const ArenaMatrix &other, const allocator_type &alloc={})
Eigen::Map< const PlainObject, Alignment > ConstMapType
typename std::decay_t< MatrixXs >::Scalar Scalar
ArenaMatrix(Index size, const allocator_type &allocator={})
void conservativeResize(Index rows, Index cols)
A convenience subclass of std::pmr::polymorphic_allocator for bytes.
Definition allocator.hpp:16
Math utilities.
::aligator::context::Scalar Scalar
Definition context.hpp:14
Main package namespace.