1namespace Eigen {
2
3/** \page TopicCustomizing_Plugins Extending MatrixBase (and other classes)
4
5In 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
7You 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
9class MatrixBase {
10  // ...
11  #ifdef EIGEN_MATRIXBASE_PLUGIN
12  #include EIGEN_MATRIXBASE_PLUGIN
13  #endif
14};
15\endcode
16Therefore 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
18You 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
20Here is an example of an extension file for adding methods to MatrixBase: \n
21\b MatrixBaseAddons.h
22\code
23inline Scalar at(uint i, uint j) const { return this->operator()(i,j); }
24inline Scalar& at(uint i, uint j) { return this->operator()(i,j); }
25inline Scalar at(uint i) const { return this->operator[](i); }
26inline Scalar& at(uint i) { return this->operator[](i); }
27
28inline RealScalar squaredLength() const { return squaredNorm(); }
29inline RealScalar length() const { return norm(); }
30inline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); }
31
32template<typename OtherDerived>
33inline Scalar squaredDistanceTo(const MatrixBase<OtherDerived>& other) const
34{ return (derived() - other.derived()).squaredNorm(); }
35
36template<typename OtherDerived>
37inline RealScalar distanceTo(const MatrixBase<OtherDerived>& other) const
38{ return internal::sqrt(derived().squaredDistanceTo(other)); }
39
40inline void scaleTo(RealScalar l) { RealScalar vl = norm(); if (vl>1e-9) derived() *= (l/vl); }
41
42inline Transpose<Derived> transposed() {return this->transpose();}
43inline const Transpose<Derived> transposed() const {return this->transpose();}
44
45inline uint minComponentId(void) const  { int i; this->minCoeff(&i); return i; }
46inline uint maxComponentId(void) const  { int i; this->maxCoeff(&i); return i; }
47
48template<typename OtherDerived>
49void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMin(other.derived()); }
50template<typename OtherDerived>
51void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMax(other.derived()); }
52
53const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>
54operator+(const Scalar& scalar) const
55{ return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>(derived(), Constant(rows(),cols(),scalar)); }
56
57friend const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>
58operator+(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
62Then 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}
70