14#include <lagrange/Logger.h>
15#include <lagrange/common.h>
16#include <lagrange/experimental/Scalar.h>
17#include <lagrange/utils/assert.h>
18#include <lagrange/utils/range.h>
19#include <lagrange/utils/strings.h>
27namespace experimental {
29template <
typename Data>
37 using Index = Eigen::Index;
47 template <
typename TargetType>
48 Eigen::Map<TargetType> view()
51 is_compatible<TargetType>(),
52 "Target view type is not compatible with the data.");
53 return Eigen::Map<TargetType>(data<typename TargetType::Scalar>(), rows(), cols());
56 template <
typename TargetType>
57 Eigen::Map<const TargetType> view()
const
60 is_compatible<TargetType>(),
61 "Target view type is not compatible with the data.");
62 return Eigen::Map<const TargetType>(data<typename TargetType::Scalar>(), rows(), cols());
65 virtual std::any get_type_info()
const = 0;
67 template <
typename Derived>
68 bool is_base_of()
const
70 std::any info = get_type_info();
71 return std::any_cast<ArrayTypeInfo<Derived>>(&info) !=
nullptr;
74 template <
typename DerivedPtr>
75 auto down_cast() -> std::add_pointer_t<std::decay_t<std::remove_pointer_t<DerivedPtr>>>
77 using Derived = std::decay_t<std::remove_pointer_t<DerivedPtr>>;
78 if (is_base_of<Derived>()) {
79 return static_cast<Derived*
>(
this);
84 template <
typename DerivedPtr>
85 auto down_cast()
const
86 -> std::add_pointer_t<std::add_const_t<std::decay_t<std::remove_pointer_t<DerivedPtr>>>>
88 using Derived = std::decay_t<std::remove_pointer_t<DerivedPtr>>;
89 if (is_base_of<Derived>()) {
90 return static_cast<const Derived*
>(
this);
95 template <
typename Derived>
96 void set(
const Eigen::MatrixBase<Derived>& data);
98 template <
typename Derived>
99 void set(Eigen::MatrixBase<Derived>&& data);
101 ScalarEnum get_scalar_type()
const {
return m_scalar_type; }
103 template <
typename TargetType>
104 const auto& get()
const;
106 template <
typename TargetType>
109 template <
typename Scalar>
113 return static_cast<Scalar*
>(data());
116 template <
typename Scalar>
117 const Scalar* data()
const
120 return static_cast<const Scalar*
>(data());
123 virtual Index rows()
const = 0;
124 virtual Index cols()
const = 0;
125 virtual bool is_row_major()
const = 0;
126 virtual void* data() = 0;
127 virtual const void* data()
const = 0;
128 virtual void resize(Index, Index) = 0;
129 virtual std::unique_ptr<ArrayBase> clone()
const = 0;
131 using IndexFunction = std::function<Index(Index)>;
132 using WeightedIndexFunction =
133 std::function<void(Index, std::vector<std::pair<Index, double>>&)>;
135 template <
typename T>
136 std::unique_ptr<ArrayBase> row_slice(
const std::vector<T>& row_indices)
const
138 return row_slice(safe_cast<Index>(row_indices.size()), [&](Index i) {
139 return safe_cast<Index>(row_indices[i]);
149 virtual std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
160 const WeightedIndexFunction& mapping_fn)
const = 0;
162 virtual std::string type_name()
const = 0;
165 template <
typename TargetType>
166 bool is_compatible(
bool ignore_storage_order =
false)
const;
168 template <
typename Derived>
169 static std::unique_ptr<ArrayBase> row_slice_impl(
170 const Eigen::MatrixBase<Derived>& matrix,
172 const IndexFunction& mapping);
174 template <
typename Derived>
176 enable_if_t<std::is_integral<typename Derived::Scalar>::value, std::unique_ptr<ArrayBase>>
178 const Eigen::MatrixBase<Derived>& matrix,
180 const WeightedIndexFunction& mapping);
182 template <
typename Derived>
184 enable_if_t<!std::is_integral<typename Derived::Scalar>::value, std::unique_ptr<ArrayBase>>
186 const Eigen::MatrixBase<Derived>& matrix,
188 const WeightedIndexFunction& mapping);
191 const ScalarEnum m_scalar_type;
198template <
typename _EigenType>
202 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
203 using EigenType = _EigenType;
205 using Index = ArrayBase::Index;
206 using ArrayBase::WeightedIndexFunction;
208 std::is_base_of<typename Eigen::EigenBase<EigenType>, EigenType>::value,
209 "Template parameter `_EigenType` is not an Eigen type!");
210 static_assert(!std::is_const<EigenType>::value,
"EigenType should not be const type.");
211 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
215 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
218 template <
typename T>
219 explicit EigenArray(
const Eigen::MatrixBase<T>& data)
220 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
224 template <
typename T>
225 explicit EigenArray(Eigen::MatrixBase<T>&& data)
226 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
227 , m_data(std::move(data.derived()))
230 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
233 EigenType& get_ref() {
return m_data; }
234 const EigenType& get_ref()
const {
return m_data; }
236 template <
typename Derived>
237 void set(Derived&& data)
239 m_data = std::forward<Derived>(data);
242 Index rows()
const override {
return m_data.rows(); }
243 Index cols()
const override {
return m_data.cols(); }
244 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
245 void* data()
override {
return static_cast<void*
>(m_data.derived().data()); }
246 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
247 void resize(Index r, Index c)
override { m_data.resize(r, c); }
249 std::unique_ptr<ArrayBase> clone()
const override
251 return std::make_unique<EigenArray<EigenType>>(m_data);
254 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
257 return row_slice_impl(m_data, num_rows, mapping_fn);
259 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
262 return row_slice_impl(m_data, num_rows, mapping_fn);
265 std::string type_name()
const override
269 "EigenArray<Eigen::Matrix<{}, {}, {}, {}>>",
271 static_cast<int>(EigenType::RowsAtCompileTime),
272 static_cast<int>(EigenType::ColsAtCompileTime),
273 static_cast<int>(EigenType::Options));
285template <typename _EigenType, bool IsConst = std::is_const<_EigenType>::value>
288template <
typename _EigenType>
292 using EigenType = _EigenType;
294 using DecayedEigenType = std::decay_t<_EigenType>;
295 using Index = ArrayBase::Index;
296 using ArrayBase::WeightedIndexFunction;
298 std::is_base_of<typename Eigen::EigenBase<DecayedEigenType>, DecayedEigenType>::value,
299 "Template parameter `_EigenType` is not an Eigen type!");
300 static_assert(!std::is_const<EigenType>::value,
"EigenType should not be const type.");
301 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
304 template <
typename T>
306 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
307 , m_data(data.derived())
310 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
313 EigenType& get_ref() {
return m_data; }
314 const EigenType& get_ref()
const {
return m_data; }
316 template <
typename Derived>
317 void set(Derived&& data)
319 m_data = std::forward<Derived>(data);
322 Index rows()
const override {
return m_data.rows(); }
323 Index cols()
const override {
return m_data.cols(); }
324 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
325 void* data()
override {
return static_cast<void*
>(m_data.derived().data()); }
326 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
327 void resize(Index r, Index c)
override { m_data.resize(r, c); }
329 std::unique_ptr<ArrayBase> clone()
const override
331 return std::make_unique<EigenArray<DecayedEigenType>>(m_data);
334 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
337 return row_slice_impl(m_data, num_rows, mapping_fn);
339 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
342 return row_slice_impl(m_data, num_rows, mapping_fn);
345 std::string type_name()
const override
349 "EigenArrayRef<Eigen::Matrix<{}, {}, {}, {}>>",
351 static_cast<int>(EigenType::RowsAtCompileTime),
352 static_cast<int>(EigenType::ColsAtCompileTime),
353 static_cast<int>(EigenType::Options));
360template <
typename _EigenType>
364 using EigenType = _EigenType;
366 using DecayedEigenType = std::decay_t<_EigenType>;
367 using Index = ArrayBase::Index;
368 using ArrayBase::WeightedIndexFunction;
370 std::is_base_of<typename Eigen::EigenBase<DecayedEigenType>, DecayedEigenType>::value,
371 "Template parameter `_EigenType` is not an Eigen type!");
372 static_assert(std::is_const<EigenType>::value,
"EigenType must const type.");
373 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
376 template <
typename T>
378 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
379 , m_data(data.derived())
382 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
385 const EigenType& get_ref()
const {
return m_data; }
387 Index rows()
const override {
return m_data.rows(); }
388 Index cols()
const override {
return m_data.cols(); }
389 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
390 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
391 void* data()
override {
throw std::runtime_error(
"This method is not supported"); }
393 void resize(Index r, Index c)
override
395 if (r != m_data.rows() || c != m_data.cols()) {
396 throw std::runtime_error(
"Resizing const EigenArrayRef is not allowed.");
400 std::unique_ptr<ArrayBase> clone()
const override
402 return std::make_unique<EigenArray<DecayedEigenType>>(m_data);
405 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
408 return row_slice_impl(m_data, num_rows, mapping_fn);
410 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
413 return row_slice_impl(m_data, num_rows, mapping_fn);
416 std::string type_name()
const override
420 "EigenArrayRef<const Eigen::Matrix<{}, {}, {}, {}>>",
422 static_cast<int>(EigenType::RowsAtCompileTime),
423 static_cast<int>(EigenType::ColsAtCompileTime),
424 static_cast<int>(EigenType::Options));
438 int _Rows = Eigen::Dynamic,
439 int _Cols = Eigen::Dynamic,
440 int _Options = Eigen::RowMajor,
441 bool IsConst = std::is_const<_Scalar>::value>
444template <
typename _Scalar,
int _Rows,
int _Cols,
int _Options>
449 using Scalar = _Scalar;
450 using Index = ArrayBase::Index;
451 using EigenType = Eigen::Matrix<Scalar, _Rows, _Cols, _Options>;
452 using EigenMap = Eigen::Map<EigenType>;
453 using ConstEigenMap = Eigen::Map<const EigenType>;
454 using ArrayBase::WeightedIndexFunction;
457 RawArray(Scalar* data, Index rows, Index cols)
458 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
459 , m_data(data, rows, cols)
462 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
465 EigenMap& get_ref() {
return m_data; }
466 ConstEigenMap get_ref()
const {
return m_data; }
468 template <
typename Derived>
469 void set(
const Eigen::MatrixBase<Derived>& data)
474 void set(Scalar* data, Index rows, Index cols) { m_data = EigenMap(data, rows, cols); }
476 Index rows()
const override {
return m_data.rows(); }
477 Index cols()
const override {
return m_data.cols(); }
478 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
479 void* data()
override {
return static_cast<void*
>(m_data.data()); }
480 const void* data()
const override {
return static_cast<const void*
>(m_data.data()); }
481 void resize(Index r, Index c)
override
483 if (r != m_data.rows() || c != m_data.cols()) {
484 throw std::runtime_error(
"Resizing RawArray is not allowed.");
488 std::unique_ptr<ArrayBase> clone()
const override
490 return std::make_unique<EigenArray<EigenType>>(m_data);
493 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
496 return row_slice_impl(m_data, num_rows, mapping_fn);
498 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
501 return row_slice_impl(m_data, num_rows, mapping_fn);
504 std::string type_name()
const override
507 return string_format(
"RawArray<{}, {}, {}, {}>", scalar_name, _Rows, _Cols, _Options);
514template <
typename _Scalar,
int _Rows,
int _Cols,
int _Options>
519 using Scalar = std::decay_t<_Scalar>;
520 using Index = ArrayBase::Index;
521 using EigenType = Eigen::Matrix<Scalar, _Rows, _Cols, _Options>;
522 using EigenMap = Eigen::Map<const EigenType>;
523 using ArrayBase::WeightedIndexFunction;
526 RawArray(
const Scalar* data, Index rows, Index cols)
527 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
528 , m_data(data, rows, cols)
531 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
534 const EigenMap& get_ref()
const {
return m_data; }
536 Index rows()
const override {
return m_data.rows(); }
537 Index cols()
const override {
return m_data.cols(); }
538 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
539 const void* data()
const override {
return static_cast<const void*
>(m_data.data()); }
540 void* data()
override {
throw std::runtime_error(
"This method is not supported"); }
542 void resize(Index r, Index c)
override
544 if (r != m_data.rows() || c != m_data.cols()) {
545 throw std::runtime_error(
"Resizing RawArray is not allowed.");
549 std::unique_ptr<ArrayBase> clone()
const override
551 return std::make_unique<EigenArray<EigenType>>(m_data);
554 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
557 return row_slice_impl(m_data, num_rows, mapping_fn);
559 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
562 return row_slice_impl(m_data, num_rows, mapping_fn);
565 std::string type_name()
const override
568 return string_format(
"RawArray<const {}, {}, {}, {}>", scalar_name, _Rows, _Cols, _Options);
572 const EigenMap m_data;
578#include "Array.impl.h"
579#include "Array.serialization.h"
virtual std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const =0
Using index function for row mapping.
virtual std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const =0
This is the most generic version of row_slice method.
This class is a thin wrapper around an Eigen matrix.
Definition: Array.h:200
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:254
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const override
This is the most generic version of row_slice method.
Definition: Array.h:259
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:334
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const override
This is the most generic version of row_slice method.
Definition: Array.h:339
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:405
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const override
This is the most generic version of row_slice method.
Definition: Array.h:410
This class is a thin wrapper around an Eigen matrix.
Definition: Array.h:286
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:493
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const override
This is the most generic version of row_slice method.
Definition: Array.h:498
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:554
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const WeightedIndexFunction &mapping_fn) const override
This is the most generic version of row_slice method.
Definition: Array.h:559
This class provide a thin wrapper around a raw array.
Definition: Array.h:442
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
std::string string_format(fmt::format_string< Args... > format, Args &&... args)
Format args according to the format string fmt, and return the result as a string.
Definition: strings.h:103
Main namespace for Lagrange.
Definition: AABBIGL.h:30