Home | History | Annotate | Download | only in doc
      1 namespace Eigen {
      2 
      3 /** \page TopicNewExpressionType Adding a new expression type
      4 
      5 <!--<span style="font-size:130%; color:red; font-weight: 900;"></span>-->
      6 \warning
      7 Disclaimer: this page is tailored to very advanced users who are not afraid of dealing with some %Eigen's internal aspects.
      8 In most cases, a custom expression can be avoided by either using custom \ref MatrixBase::unaryExpr "unary" or \ref MatrixBase::binaryExpr "binary" functors,
      9 while extremely complex matrix manipulations can be achieved by a nullary functors as described in the \ref TopicCustomizing_NullaryExpr "previous page".
     10 
     11 This page describes with the help of an example how to implement a new
     12 light-weight expression type in %Eigen. This consists of three parts:
     13 the expression type itself, a traits class containing compile-time
     14 information about the expression, and the evaluator class which is
     15 used to evaluate the expression to a matrix.
     16 
     17 \b TO \b DO: Write a page explaining the design, with details on
     18 vectorization etc., and refer to that page here.
     19 
     20 
     21 \eigenAutoToc
     22 
     23 \section TopicSetting The setting
     24 
     25 A circulant matrix is a matrix where each column is the same as the
     26 column to the left, except that it is cyclically shifted downwards.
     27 For example, here is a 4-by-4 circulant matrix:
     28 \f[ \begin{bmatrix} 
     29     1 & 8 & 4 & 2 \\ 
     30     2 & 1 & 8 & 4 \\
     31     4 & 2 & 1 & 8 \\
     32     8 & 4 & 2 & 1
     33 \end{bmatrix} \f]
     34 A circulant matrix is uniquely determined by its first column. We wish
     35 to write a function \c makeCirculant which, given the first column,
     36 returns an expression representing the circulant matrix.
     37 
     38 For simplicity, we restrict the \c makeCirculant function to dense
     39 matrices. It may make sense to also allow arrays, or sparse matrices,
     40 but we will not do so here. We also do not want to support
     41 vectorization.
     42 
     43 
     44 \section TopicPreamble Getting started
     45 
     46 We will present the file implementing the \c makeCirculant function
     47 part by part. We start by including the appropriate header files and
     48 forward declaring the expression class, which we will call
     49 \c Circulant. The \c makeCirculant function will return an object of
     50 this type. The class \c Circulant is in fact a class template; the
     51 template argument \c ArgType refers to the type of the vector passed
     52 to the \c makeCirculant function.
     53 
     54 \include make_circulant.cpp.preamble
     55 
     56 
     57 \section TopicTraits The traits class
     58 
     59 For every expression class \c X, there should be a traits class 
     60 \c Traits<X> in the \c Eigen::internal namespace containing
     61 information about \c X known as compile time.
     62 
     63 As explained in \ref TopicSetting, we designed the \c Circulant
     64 expression class to refer to dense matrices. The entries of the
     65 circulant matrix have the same type as the entries of the vector
     66 passed to the \c makeCirculant function. The type used to index the
     67 entries is also the same. Again for simplicity, we will only return
     68 column-major matrices. Finally, the circulant matrix is a square
     69 matrix (number of rows equals number of columns), and the number of
     70 rows equals the number of rows of the column vector passed to the
     71 \c makeCirculant function. If this is a dynamic-size vector, then the
     72 size of the circulant matrix is not known at compile-time.
     73 
     74 This leads to the following code:
     75 
     76 \include make_circulant.cpp.traits
     77 
     78 
     79 \section TopicExpression The expression class
     80 
     81 The next step is to define the expression class itself. In our case,
     82 we want to inherit from \c MatrixBase in order to expose the interface
     83 for dense matrices. In the constructor, we check that we are passed a
     84 column vector (see \ref TopicAssertions) and we store the vector from
     85 which we are going to build the circulant matrix in the member
     86 variable \c m_arg. Finally, the expression class should compute the
     87 size of the corresponding circulant matrix. As explained above, this
     88 is a square matrix with as many columns as the vector used to
     89 construct the matrix.
     90 
     91 \b TO \b DO: What about the \c Nested typedef? It seems to be
     92 necessary; is this only temporary?
     93 
     94 \include make_circulant.cpp.expression
     95 
     96 
     97 \section TopicEvaluator The evaluator
     98 
     99 The last big fragment implements the evaluator for the \c Circulant
    100 expression. The evaluator computes the entries of the circulant
    101 matrix; this is done in the \c .coeff() member function. The entries
    102 are computed by finding the corresponding entry of the vector from
    103 which the circulant matrix is constructed. Getting this entry may
    104 actually be non-trivial when the circulant matrix is constructed from
    105 a vector which is given by a complicated expression, so we use the
    106 evaluator which corresponds to the vector.
    107 
    108 The \c CoeffReadCost constant records the cost of computing an entry
    109 of the circulant matrix; we ignore the index computation and say that
    110 this is the same as the cost of computing an entry of the vector from
    111 which the circulant matrix is constructed.
    112 
    113 In the constructor, we save the evaluator for the column vector which
    114 defined the circulant matrix. We also save the size of that vector;
    115 remember that we can query an expression object to find the size but
    116 not the evaluator. 
    117 
    118 \include make_circulant.cpp.evaluator
    119 
    120 
    121 \section TopicEntry The entry point
    122 
    123 After all this, the \c makeCirculant function is very simple. It
    124 simply creates an expression object and returns it.
    125 
    126 \include make_circulant.cpp.entry
    127 
    128 
    129 \section TopicMain A simple main function for testing
    130 
    131 Finally, a short \c main function that shows how the \c makeCirculant
    132 function can be called.
    133 
    134 \include make_circulant.cpp.main
    135 
    136 If all the fragments are combined, the following output is produced,
    137 showing that the program works as expected:
    138 
    139 \include make_circulant.out
    140 
    141 */
    142 }
    143 
    144