xref: /aosp_15_r20/external/eigen/doc/CustomizingEigen_Plugins.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \page TopicCustomizing_Plugins Extending MatrixBase (and other classes)
4*bf2c3715SXin Li
5*bf2c3715SXin LiIn 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*bf2c3715SXin Li
7*bf2c3715SXin LiYou 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*bf2c3715SXin Li\code
9*bf2c3715SXin Liclass MatrixBase {
10*bf2c3715SXin Li  // ...
11*bf2c3715SXin Li  #ifdef EIGEN_MATRIXBASE_PLUGIN
12*bf2c3715SXin Li  #include EIGEN_MATRIXBASE_PLUGIN
13*bf2c3715SXin Li  #endif
14*bf2c3715SXin Li};
15*bf2c3715SXin Li\endcode
16*bf2c3715SXin LiTherefore 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*bf2c3715SXin Li
18*bf2c3715SXin LiYou 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*bf2c3715SXin Li
20*bf2c3715SXin LiHere is an example of an extension file for adding methods to MatrixBase: \n
21*bf2c3715SXin Li\b MatrixBaseAddons.h
22*bf2c3715SXin Li\code
23*bf2c3715SXin Liinline Scalar at(uint i, uint j) const { return this->operator()(i,j); }
24*bf2c3715SXin Liinline Scalar& at(uint i, uint j) { return this->operator()(i,j); }
25*bf2c3715SXin Liinline Scalar at(uint i) const { return this->operator[](i); }
26*bf2c3715SXin Liinline Scalar& at(uint i) { return this->operator[](i); }
27*bf2c3715SXin Li
28*bf2c3715SXin Liinline RealScalar squaredLength() const { return squaredNorm(); }
29*bf2c3715SXin Liinline RealScalar length() const { return norm(); }
30*bf2c3715SXin Liinline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); }
31*bf2c3715SXin Li
32*bf2c3715SXin Litemplate<typename OtherDerived>
33*bf2c3715SXin Liinline Scalar squaredDistanceTo(const MatrixBase<OtherDerived>& other) const
34*bf2c3715SXin Li{ return (derived() - other.derived()).squaredNorm(); }
35*bf2c3715SXin Li
36*bf2c3715SXin Litemplate<typename OtherDerived>
37*bf2c3715SXin Liinline RealScalar distanceTo(const MatrixBase<OtherDerived>& other) const
38*bf2c3715SXin Li{ return internal::sqrt(derived().squaredDistanceTo(other)); }
39*bf2c3715SXin Li
40*bf2c3715SXin Liinline void scaleTo(RealScalar l) { RealScalar vl = norm(); if (vl>1e-9) derived() *= (l/vl); }
41*bf2c3715SXin Li
42*bf2c3715SXin Liinline Transpose<Derived> transposed() {return this->transpose();}
43*bf2c3715SXin Liinline const Transpose<Derived> transposed() const {return this->transpose();}
44*bf2c3715SXin Li
45*bf2c3715SXin Liinline uint minComponentId(void) const  { int i; this->minCoeff(&i); return i; }
46*bf2c3715SXin Liinline uint maxComponentId(void) const  { int i; this->maxCoeff(&i); return i; }
47*bf2c3715SXin Li
48*bf2c3715SXin Litemplate<typename OtherDerived>
49*bf2c3715SXin Livoid makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMin(other.derived()); }
50*bf2c3715SXin Litemplate<typename OtherDerived>
51*bf2c3715SXin Livoid makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMax(other.derived()); }
52*bf2c3715SXin Li
53*bf2c3715SXin Liconst CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>
54*bf2c3715SXin Lioperator+(const Scalar& scalar) const
55*bf2c3715SXin Li{ return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const ConstantReturnType>(derived(), Constant(rows(),cols(),scalar)); }
56*bf2c3715SXin Li
57*bf2c3715SXin Lifriend const CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>
58*bf2c3715SXin Lioperator+(const Scalar& scalar, const MatrixBase<Derived>& mat)
59*bf2c3715SXin Li{ return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const ConstantReturnType, Derived>(Constant(rows(),cols(),scalar), mat.derived()); }
60*bf2c3715SXin Li\endcode
61*bf2c3715SXin Li
62*bf2c3715SXin LiThen one can the following declaration in the config.h or whatever prerequisites header file of his project:
63*bf2c3715SXin Li\code
64*bf2c3715SXin Li#define EIGEN_MATRIXBASE_PLUGIN "MatrixBaseAddons.h"
65*bf2c3715SXin Li\endcode
66*bf2c3715SXin Li
67*bf2c3715SXin Li*/
68*bf2c3715SXin Li
69*bf2c3715SXin Li}
70