Spec-Zone.ru › Eigen3

Расширение MatrixBase

В этом разделе мы увидим, как добавить пользовательские методы к MatrixBase. Поскольку все выражения и типы матриц наследуют MatrixBase, добавление метода к MatrixBase делает его немедленно доступным для всех выражений! Типичный случай использования, например, сделать Eigen совместимым с другим API.

Вы наверняка знаете, что в C++ невозможно добавить методы к существующему классу. Так как же это возможно? Здесь трюк заключается в том, чтобы включить в объявление MatrixBase файл, определенный препроцессорным токеном EIGEN_MATRIXBASE_PLUGIN:.

class MatrixBase {
  // ...
  #ifdef EIGEN_MATRIXBASE_PLUGIN
  #include EIGEN_MATRIXBASE_PLUGIN
  #endif
};

Таким образом, чтобы расширить MatrixBase своими методами, вам просто нужно создать файл с объявлением вашего метода и определить EIGEN_MATRIXBASE_PLUGIN перед включением любого заголовочного файла Eigen.

Вы можете расширить многие другие классы, используемые в Eigen, определив аналогичные препроцессорные символы. Например, определите EIGEN_ARRAYBASE_PLUGIN, если вы хотите расширить класс ArrayBase. Полный список классов, которые можно расширить таким образом, и соответствующие препроцессорные символы можно найти на нашей странице Директивы препроцессора.

Вот пример файла расширения для добавления методов к MatrixBase:
MatrixBaseAddons.h

inline Scalar at(uint i, uint j) const { return this->operator()(i,j); }
inline Scalar& at(uint i, uint j) { return this->operator()(i,j); }
inline Scalar at(uint i) const { return this->operator[](i); }
inline Scalar& at(uint i) { return this->operator[](i); }
 
inline RealScalar squaredLength() const { return squaredNorm(); }
inline RealScalar length() const { return norm(); }
inline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); }
 
template<typename OtherDerived>
inline Scalar squaredDistanceTo(const MatrixBase<OtherDerived>& other) const
{ return (derived() - other.derived()).squaredNorm(); }
 
template<typename OtherDerived>
inline RealScalar distanceTo(const MatrixBase<OtherDerived>& other) const
{ return internal::sqrt(derived().squaredDistanceTo(other)); }
 
inline void scaleTo(RealScalar l) { RealScalar vl = norm(); if (vl>1e-9) derived() *= (l/vl); }
 
inline Transpose<Derived> transposed() {return this->transpose();}
inline const Transpose<Derived> transposed() const {return this->transpose();}
 
inline uint minComponentId(void) const  { int i; this->minCoeff(&i); return i; }
inline uint maxComponentId(void) const  { int i; this->maxCoeff(&i); return i; }
 
template<typename OtherDerived>
void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMin(other.derived()); }
template<typename OtherDerived>
void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMax(other.derived()); }
 
const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>
operator+(const Scalar& scalar) const
{ return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>(derived(), Constant(rows(),cols(),scalar)); }
 
friend const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>
operator+(const Scalar& scalar, const MatrixBase<Derived>& mat)
{ return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>(Constant(rows(),cols(),scalar), mat.derived()); }

Затем можно ввести следующее объявление в файл config.h или любой другой предварительный заголовочный файл своего проекта:

#define EIGEN_MATRIXBASE_PLUGIN "MatrixBaseAddons.h"

© Eigen.
Licensed under the MPL2 License.
https://eigen.tuxfamily.org/dox/TopicCustomizing_Plugins.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API