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/build.h>
19#include <lagrange/utils/range.h>
20#include <lagrange/utils/strings.h>
28namespace experimental {
30template <
typename Data>
38 using Index = Eigen::Index;
48 template <
typename TargetType>
49 Eigen::Map<TargetType> view()
52 is_compatible<TargetType>(),
53 "Target view type is not compatible with the data.");
54 return Eigen::Map<TargetType>(data<typename TargetType::Scalar>(), rows(), cols());
57 template <
typename TargetType>
58 Eigen::Map<const TargetType> view()
const
61 is_compatible<TargetType>(),
62 "Target view type is not compatible with the data.");
63 return Eigen::Map<const TargetType>(data<typename TargetType::Scalar>(), rows(), cols());
66 virtual std::any get_type_info()
const = 0;
68 template <
typename Derived>
69 bool is_base_of()
const
71 std::any info = get_type_info();
72 return std::any_cast<ArrayTypeInfo<Derived>>(&info) !=
nullptr;
75 template <
typename DerivedPtr>
76 auto down_cast() -> std::add_pointer_t<std::decay_t<std::remove_pointer_t<DerivedPtr>>>
78 using Derived = std::decay_t<std::remove_pointer_t<DerivedPtr>>;
79#if LAGRANGE_ENABLE_RTTI
80 return dynamic_cast<Derived*
>(
this);
82 if (is_base_of<Derived>()) {
83 return static_cast<Derived*
>(
this);
89 template <
typename DerivedPtr>
90 auto down_cast()
const
91 -> std::add_pointer_t<std::add_const_t<std::decay_t<std::remove_pointer_t<DerivedPtr>>>>
93 using Derived = std::decay_t<std::remove_pointer_t<DerivedPtr>>;
94#if LAGRANGE_ENABLE_RTTI
95 return dynamic_cast<const Derived*
>(
this);
97 if (is_base_of<Derived>()) {
98 return static_cast<const Derived*
>(
this);
104 template <
typename Derived>
105 void set(
const Eigen::MatrixBase<Derived>& data);
107 template <
typename Derived>
108 void set(Eigen::MatrixBase<Derived>&& data);
110 ScalarEnum get_scalar_type()
const {
return m_scalar_type; }
112 template <
typename TargetType>
113 const auto& get()
const;
115 template <
typename TargetType>
118 template <
typename Scalar>
122 return static_cast<Scalar*
>(data());
125 template <
typename Scalar>
126 const Scalar* data()
const
129 return static_cast<const Scalar*
>(data());
132 virtual Index rows()
const = 0;
133 virtual Index cols()
const = 0;
134 virtual bool is_row_major()
const = 0;
135 virtual void* data() = 0;
136 virtual const void* data()
const = 0;
137 virtual void resize(Index, Index) = 0;
138 virtual std::unique_ptr<ArrayBase> clone()
const = 0;
140 using IndexFunction = std::function<Index(Index)>;
141 using WeightedIndexFunction =
142 std::function<void(Index, std::vector<std::pair<Index, double>>&)>;
144 template <
typename T>
145 std::unique_ptr<ArrayBase> row_slice(
const std::vector<T>& row_indices)
const
147 return row_slice(safe_cast<Index>(row_indices.size()), [&](Index i) {
148 return safe_cast<Index>(row_indices[i]);
158 virtual std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
169 const WeightedIndexFunction& mapping_fn)
const = 0;
171 virtual std::string type_name()
const = 0;
174 template <
typename TargetType>
175 bool is_compatible(
bool ignore_storage_order =
false)
const;
177 template <
typename Derived>
178 static std::unique_ptr<ArrayBase> row_slice_impl(
179 const Eigen::MatrixBase<Derived>& matrix,
181 const IndexFunction& mapping);
183 template <
typename Derived>
185 enable_if_t<std::is_integral<typename Derived::Scalar>::value, std::unique_ptr<ArrayBase>>
187 const Eigen::MatrixBase<Derived>& matrix,
189 const WeightedIndexFunction& mapping);
191 template <
typename Derived>
193 enable_if_t<!std::is_integral<typename Derived::Scalar>::value, std::unique_ptr<ArrayBase>>
195 const Eigen::MatrixBase<Derived>& matrix,
197 const WeightedIndexFunction& mapping);
200 const ScalarEnum m_scalar_type;
207template <
typename _EigenType>
211 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
212 using EigenType = _EigenType;
214 using Index = ArrayBase::Index;
215 using ArrayBase::WeightedIndexFunction;
217 std::is_base_of<typename Eigen::EigenBase<EigenType>, EigenType>::value,
218 "Template parameter `_EigenType` is not an Eigen type!");
219 static_assert(!std::is_const<EigenType>::value,
"EigenType should not be const type.");
220 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
224 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
227 template <
typename T>
228 explicit EigenArray(
const Eigen::MatrixBase<T>& data)
229 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
233 template <
typename T>
234 explicit EigenArray(Eigen::MatrixBase<T>&& data)
235 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
236 , m_data(std::move(data.derived()))
239 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
242 EigenType& get_ref() {
return m_data; }
243 const EigenType& get_ref()
const {
return m_data; }
245 template <
typename Derived>
246 void set(Derived&& data)
248 m_data = std::forward<Derived>(data);
251 Index rows()
const override {
return m_data.rows(); }
252 Index cols()
const override {
return m_data.cols(); }
253 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
254 void* data()
override {
return static_cast<void*
>(m_data.derived().data()); }
255 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
256 void resize(Index r, Index c)
override { m_data.resize(r, c); }
258 std::unique_ptr<ArrayBase> clone()
const override
260 return std::make_unique<EigenArray<EigenType>>(m_data);
263 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
266 return row_slice_impl(m_data, num_rows, mapping_fn);
268 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
271 return row_slice_impl(m_data, num_rows, mapping_fn);
274 std::string type_name()
const override
278 "EigenArray<Eigen::Matrix<{}, {}, {}, {}>>",
280 static_cast<int>(EigenType::RowsAtCompileTime),
281 static_cast<int>(EigenType::ColsAtCompileTime),
282 static_cast<int>(EigenType::Options));
294template <typename _EigenType, bool IsConst = std::is_const<_EigenType>::value>
297template <
typename _EigenType>
301 using EigenType = _EigenType;
303 using DecayedEigenType = std::decay_t<_EigenType>;
304 using Index = ArrayBase::Index;
305 using ArrayBase::WeightedIndexFunction;
307 std::is_base_of<typename Eigen::EigenBase<DecayedEigenType>, DecayedEigenType>::value,
308 "Template parameter `_EigenType` is not an Eigen type!");
309 static_assert(!std::is_const<EigenType>::value,
"EigenType should not be const type.");
310 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
313 template <
typename T>
315 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
316 , m_data(data.derived())
319 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
322 EigenType& get_ref() {
return m_data; }
323 const EigenType& get_ref()
const {
return m_data; }
325 template <
typename Derived>
326 void set(Derived&& data)
328 m_data = std::forward<Derived>(data);
331 Index rows()
const override {
return m_data.rows(); }
332 Index cols()
const override {
return m_data.cols(); }
333 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
334 void* data()
override {
return static_cast<void*
>(m_data.derived().data()); }
335 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
336 void resize(Index r, Index c)
override { m_data.resize(r, c); }
338 std::unique_ptr<ArrayBase> clone()
const override
340 return std::make_unique<EigenArray<DecayedEigenType>>(m_data);
343 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
346 return row_slice_impl(m_data, num_rows, mapping_fn);
348 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
351 return row_slice_impl(m_data, num_rows, mapping_fn);
354 std::string type_name()
const override
358 "EigenArrayRef<Eigen::Matrix<{}, {}, {}, {}>>",
360 static_cast<int>(EigenType::RowsAtCompileTime),
361 static_cast<int>(EigenType::ColsAtCompileTime),
362 static_cast<int>(EigenType::Options));
369template <
typename _EigenType>
373 using EigenType = _EigenType;
375 using DecayedEigenType = std::decay_t<_EigenType>;
376 using Index = ArrayBase::Index;
377 using ArrayBase::WeightedIndexFunction;
379 std::is_base_of<typename Eigen::EigenBase<DecayedEigenType>, DecayedEigenType>::value,
380 "Template parameter `_EigenType` is not an Eigen type!");
381 static_assert(std::is_const<EigenType>::value,
"EigenType must const type.");
382 static_assert(!std::is_reference<EigenType>::value,
"EigenType should not be reference type.");
385 template <
typename T>
387 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
388 , m_data(data.derived())
391 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
394 const EigenType& get_ref()
const {
return m_data; }
396 Index rows()
const override {
return m_data.rows(); }
397 Index cols()
const override {
return m_data.cols(); }
398 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
399 const void* data()
const override {
return static_cast<const void*
>(m_data.derived().data()); }
400 void* data()
override {
throw std::runtime_error(
"This method is not supported"); }
402 void resize(Index r, Index c)
override
404 if (r != m_data.rows() || c != m_data.cols()) {
405 throw std::runtime_error(
"Resizing const EigenArrayRef is not allowed.");
409 std::unique_ptr<ArrayBase> clone()
const override
411 return std::make_unique<EigenArray<DecayedEigenType>>(m_data);
414 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
417 return row_slice_impl(m_data, num_rows, mapping_fn);
419 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
422 return row_slice_impl(m_data, num_rows, mapping_fn);
425 std::string type_name()
const override
429 "EigenArrayRef<const Eigen::Matrix<{}, {}, {}, {}>>",
431 static_cast<int>(EigenType::RowsAtCompileTime),
432 static_cast<int>(EigenType::ColsAtCompileTime),
433 static_cast<int>(EigenType::Options));
447 int _Rows = Eigen::Dynamic,
448 int _Cols = Eigen::Dynamic,
449 int _Options = Eigen::RowMajor,
450 bool IsConst = std::is_const<_Scalar>::value>
453template <
typename _Scalar,
int _Rows,
int _Cols,
int _Options>
458 using Scalar = _Scalar;
459 using Index = ArrayBase::Index;
460 using EigenType = Eigen::Matrix<Scalar, _Rows, _Cols, _Options>;
461 using EigenMap = Eigen::Map<EigenType>;
462 using ConstEigenMap = Eigen::Map<const EigenType>;
463 using ArrayBase::WeightedIndexFunction;
466 RawArray(Scalar* data, Index rows, Index cols)
467 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
468 , m_data(data, rows, cols)
471 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
474 EigenMap& get_ref() {
return m_data; }
475 ConstEigenMap get_ref()
const {
return m_data; }
477 template <
typename Derived>
478 void set(
const Eigen::MatrixBase<Derived>& data)
483 void set(Scalar* data, Index rows, Index cols) { m_data = EigenMap(data, rows, cols); }
485 Index rows()
const override {
return m_data.rows(); }
486 Index cols()
const override {
return m_data.cols(); }
487 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
488 void* data()
override {
return static_cast<void*
>(m_data.data()); }
489 const void* data()
const override {
return static_cast<const void*
>(m_data.data()); }
490 void resize(Index r, Index c)
override
492 if (r != m_data.rows() || c != m_data.cols()) {
493 throw std::runtime_error(
"Resizing RawArray is not allowed.");
497 std::unique_ptr<ArrayBase> clone()
const override
499 return std::make_unique<EigenArray<EigenType>>(m_data);
502 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
505 return row_slice_impl(m_data, num_rows, mapping_fn);
507 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
510 return row_slice_impl(m_data, num_rows, mapping_fn);
513 std::string type_name()
const override
516 return string_format(
"RawArray<{}, {}, {}, {}>", scalar_name, _Rows, _Cols, _Options);
523template <
typename _Scalar,
int _Rows,
int _Cols,
int _Options>
528 using Scalar = std::decay_t<_Scalar>;
529 using Index = ArrayBase::Index;
530 using EigenType = Eigen::Matrix<Scalar, _Rows, _Cols, _Options>;
531 using EigenMap = Eigen::Map<const EigenType>;
532 using ArrayBase::WeightedIndexFunction;
535 RawArray(
const Scalar* data, Index rows, Index cols)
536 :
ArrayBase(ScalarToEnum_v<typename EigenType::Scalar>)
537 , m_data(data, rows, cols)
540 std::any get_type_info()
const override {
return std::make_any<ArrayTypeInfo<Self>>(); }
543 const EigenMap& get_ref()
const {
return m_data; }
545 Index rows()
const override {
return m_data.rows(); }
546 Index cols()
const override {
return m_data.cols(); }
547 bool is_row_major()
const override {
return EigenType::IsRowMajor != 0; }
548 const void* data()
const override {
return static_cast<const void*
>(m_data.data()); }
549 void* data()
override {
throw std::runtime_error(
"This method is not supported"); }
551 void resize(Index r, Index c)
override
553 if (r != m_data.rows() || c != m_data.cols()) {
554 throw std::runtime_error(
"Resizing RawArray is not allowed.");
558 std::unique_ptr<ArrayBase> clone()
const override
560 return std::make_unique<EigenArray<EigenType>>(m_data);
563 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const IndexFunction& mapping_fn)
566 return row_slice_impl(m_data, num_rows, mapping_fn);
568 std::unique_ptr<ArrayBase>
row_slice(Index num_rows,
const WeightedIndexFunction& mapping_fn)
571 return row_slice_impl(m_data, num_rows, mapping_fn);
574 std::string type_name()
const override
577 return string_format(
"RawArray<const {}, {}, {}, {}>", scalar_name, _Rows, _Cols, _Options);
581 const EigenMap m_data;
587#include "Array.impl.h"
588#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:209
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:263
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:268
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:343
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:348
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:414
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:419
This class is a thin wrapper around an Eigen matrix.
Definition: Array.h:295
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:502
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:507
std::unique_ptr< ArrayBase > row_slice(Index num_rows, const IndexFunction &mapping_fn) const override
Using index function for row mapping.
Definition: Array.h:563
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:568
This class provide a thin wrapper around a raw array.
Definition: Array.h:451
#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