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