2014-09-28 06:25:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								namespace Eigen {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/** \page TopicNewExpressionType Adding a new expression type
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-30 21:57:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<!--<span style="font-size:130%; color:red; font-weight: 900;"></span>-->
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\warning
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Disclaimer: this page is tailored to very advanced users who are not afraid of dealing with some %Eigen's internal aspects.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In most cases, a custom expression can be avoided by either using custom \ref MatrixBase::unaryExpr "unary" or \ref MatrixBase::binaryExpr "binary" functors,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								while extremely complex matrix manipulations can be achieved by a nullary functors as described in the \ref TopicCustomizing_NullaryExpr "previous page".
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-09-28 06:25:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								This page describes with the help of an example how to implement a new
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								light-weight expression type in %Eigen. This consists of three parts:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								the expression type itself, a traits class containing compile-time
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								information about the expression, and the evaluator class which is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								used to evaluate the expression to a matrix.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\b TO \b DO: Write a page explaining the design, with details on
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								vectorization etc., and refer to that page here.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\eigenAutoToc
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicSetting The setting
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								A circulant matrix is a matrix where each column is the same as the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								column to the left, except that it is cyclically shifted downwards.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								For example, here is a 4-by-4 circulant matrix:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\f[ \begin{bmatrix} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    1 & 8 & 4 & 2 \\ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    2 & 1 & 8 & 4 \\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    4 & 2 & 1 & 8 \\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    8 & 4 & 2 & 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\end{bmatrix} \f]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								A circulant matrix is uniquely determined by its first column. We wish
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								to write a function \c makeCirculant which, given the first column,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								returns an expression representing the circulant matrix.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								For simplicity, we restrict the \c makeCirculant function to dense
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								matrices. It may make sense to also allow arrays, or sparse matrices,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								but we will not do so here. We also do not want to support
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								vectorization.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicPreamble Getting started
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								We will present the file implementing the \c makeCirculant function
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								part by part. We start by including the appropriate header files and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								forward declaring the expression class, which we will call
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\c Circulant. The \c makeCirculant function will return an object of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								this type. The class \c Circulant is in fact a class template; the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template argument \c ArgType refers to the type of the vector passed
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								to the \c makeCirculant function.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.preamble
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicTraits The traits class
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								For every expression class \c X, there should be a traits class 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\c Traits<X> in the \c Eigen::internal namespace containing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								information about \c X known as compile time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								As explained in \ref TopicSetting, we designed the \c Circulant
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								expression class to refer to dense matrices. The entries of the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								circulant matrix have the same type as the entries of the vector
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								passed to the \c makeCirculant function. The type used to index the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								entries is also the same. Again for simplicity, we will only return
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								column-major matrices. Finally, the circulant matrix is a square
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								matrix (number of rows equals number of columns), and the number of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rows equals the number of rows of the column vector passed to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\c makeCirculant function. If this is a dynamic-size vector, then the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size of the circulant matrix is not known at compile-time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								This leads to the following code:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.traits
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicExpression The expression class
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The next step is to define the expression class itself. In our case,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								we want to inherit from \c MatrixBase in order to expose the interface
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								for dense matrices. In the constructor, we check that we are passed a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								column vector (see \ref TopicAssertions) and we store the vector from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								which we are going to build the circulant matrix in the member
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								variable \c m_arg. Finally, the expression class should compute the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size of the corresponding circulant matrix. As explained above, this
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								is a square matrix with as many columns as the vector used to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								construct the matrix.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\b TO \b DO: What about the \c Nested typedef? It seems to be
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								necessary; is this only temporary?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.expression
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicEvaluator The evaluator
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The last big fragment implements the evaluator for the \c Circulant
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								expression. The evaluator computes the entries of the circulant
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								matrix; this is done in the \c .coeff() member function. The entries
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								are computed by finding the corresponding entry of the vector from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								which the circulant matrix is constructed. Getting this entry may
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								actually be non-trivial when the circulant matrix is constructed from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a vector which is given by a complicated expression, so we use the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								evaluator which corresponds to the vector.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The \c CoeffReadCost constant records the cost of computing an entry
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								of the circulant matrix; we ignore the index computation and say that
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								this is the same as the cost of computing an entry of the vector from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								which the circulant matrix is constructed.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In the constructor, we save the evaluator for the column vector which
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								defined the circulant matrix. We also save the size of that vector;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								remember that we can query an expression object to find the size but
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								not the evaluator. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.evaluator
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicEntry The entry point
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								After all this, the \c makeCirculant function is very simple. It
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								simply creates an expression object and returns it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.entry
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\section TopicMain A simple main function for testing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Finally, a short \c main function that shows how the \c makeCirculant
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function can be called.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								\include make_circulant.cpp.main
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If all the fragments are combined, the following output is produced,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								showing that the program works as expected:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-30 21:40:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								\include make_circulant.out
							 
						 
					
						
							
								
									
										
										
										
											2014-09-28 06:25:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}