Austin Schuh | 189376f | 2018-12-20 22:11:15 +1100 | [diff] [blame] | 1 | namespace Eigen { |
| 2 | |
| 3 | /** \page TopicCustomizing_Plugins Extending MatrixBase (and other classes) |
| 4 | |
| 5 | In this section we will see how to add custom methods to MatrixBase. Since all expressions and matrix types inherit MatrixBase, adding a method to MatrixBase make it immediately available to all expressions ! A typical use case is, for instance, to make Eigen compatible with another API. |
| 6 | |
| 7 | You certainly know that in C++ it is not possible to add methods to an existing class. So how that's possible ? Here the trick is to include in the declaration of MatrixBase a file defined by the preprocessor token \c EIGEN_MATRIXBASE_PLUGIN: |
| 8 | \code |
| 9 | class MatrixBase { |
| 10 | // ... |
| 11 | #ifdef EIGEN_MATRIXBASE_PLUGIN |
| 12 | #include EIGEN_MATRIXBASE_PLUGIN |
| 13 | #endif |
| 14 | }; |
| 15 | \endcode |
| 16 | Therefore to extend MatrixBase with your own methods you just have to create a file with your method declaration and define EIGEN_MATRIXBASE_PLUGIN before you include any Eigen's header file. |
| 17 | |
| 18 | You can extend many of the other classes used in Eigen by defining similarly named preprocessor symbols. For instance, define \c EIGEN_ARRAYBASE_PLUGIN if you want to extend the ArrayBase class. A full list of classes that can be extended in this way and the corresponding preprocessor symbols can be found on our page \ref TopicPreprocessorDirectives. |
| 19 | |
| 20 | Here is an example of an extension file for adding methods to MatrixBase: \n |
| 21 | \b MatrixBaseAddons.h |
| 22 | \code |
| 23 | inline Scalar at(uint i, uint j) const { return this->operator()(i,j); } |
| 24 | inline Scalar& at(uint i, uint j) { return this->operator()(i,j); } |
| 25 | inline Scalar at(uint i) const { return this->operator[](i); } |
| 26 | inline Scalar& at(uint i) { return this->operator[](i); } |
| 27 | |
| 28 | inline RealScalar squaredLength() const { return squaredNorm(); } |
| 29 | inline RealScalar length() const { return norm(); } |
| 30 | inline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); } |
| 31 | |
| 32 | template<typename OtherDerived> |
| 33 | inline Scalar squaredDistanceTo(const MatrixBase<OtherDerived>& other) const |
| 34 | { return (derived() - other.derived()).squaredNorm(); } |
| 35 | |
| 36 | template<typename OtherDerived> |
| 37 | inline RealScalar distanceTo(const MatrixBase<OtherDerived>& other) const |
| 38 | { return internal::sqrt(derived().squaredDistanceTo(other)); } |
| 39 | |
| 40 | inline void scaleTo(RealScalar l) { RealScalar vl = norm(); if (vl>1e-9) derived() *= (l/vl); } |
| 41 | |
| 42 | inline Transpose<Derived> transposed() {return this->transpose();} |
| 43 | inline const Transpose<Derived> transposed() const {return this->transpose();} |
| 44 | |
| 45 | inline uint minComponentId(void) const { int i; this->minCoeff(&i); return i; } |
| 46 | inline uint maxComponentId(void) const { int i; this->maxCoeff(&i); return i; } |
| 47 | |
| 48 | template<typename OtherDerived> |
| 49 | void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMin(other.derived()); } |
| 50 | template<typename OtherDerived> |
| 51 | void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMax(other.derived()); } |
| 52 | |
| 53 | const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType> |
| 54 | operator+(const Scalar& scalar) const |
| 55 | { return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>(derived(), Constant(rows(),cols(),scalar)); } |
| 56 | |
| 57 | friend const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived> |
| 58 | operator+(const Scalar& scalar, const MatrixBase<Derived>& mat) |
| 59 | { return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>(Constant(rows(),cols(),scalar), mat.derived()); } |
| 60 | \endcode |
| 61 | |
| 62 | Then one can the following declaration in the config.h or whatever prerequisites header file of his project: |
| 63 | \code |
| 64 | #define EIGEN_MATRIXBASE_PLUGIN "MatrixBaseAddons.h" |
| 65 | \endcode |
| 66 | |
| 67 | */ |
| 68 | |
| 69 | } |