New doc page on implementing a new expression class.

This commit is contained in:
Jitse Niesen
2014-09-27 23:25:58 +01:00
parent 6d0f0b8cec
commit ce2035af86
9 changed files with 238 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
/*
This program is presented in several fragments in the doc page.
Every fragment is in its own file; this file simply combines them.
*/
#include "make_circulant.cpp.preamble"
#include "make_circulant.cpp.traits"
#include "make_circulant.cpp.expression"
#include "make_circulant.cpp.evaluator"
#include "make_circulant.cpp.entry"
#include "make_circulant.cpp.main"

View File

@@ -0,0 +1,5 @@
template <class ArgType>
Circulant<ArgType> makeCirculant(const Eigen::MatrixBase<ArgType>& arg)
{
return Circulant<ArgType>(arg.derived());
}

View File

@@ -0,0 +1,33 @@
namespace Eigen {
namespace internal {
template<typename ArgType>
struct evaluator<Circulant<ArgType> >
: evaluator_base<Circulant<ArgType> >
{
typedef Circulant<ArgType> XprType;
typedef typename nested_eval<ArgType, XprType::ColsAtCompileTime>::type ArgTypeNested;
typedef typename remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
typedef typename XprType::CoeffReturnType CoeffReturnType;
typedef typename XprType::Index Index;
enum {
CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
Flags = Eigen::ColMajor
};
evaluator(const XprType& xpr)
: m_argImpl(xpr.m_arg), m_rows(xpr.rows())
{ }
CoeffReturnType coeff(Index row, Index col) const
{
Index index = row - col;
if (index < 0) index += m_rows;
return m_argImpl.coeff(index);
}
typename evaluator<ArgTypeNestedCleaned>::nestedType m_argImpl;
const Index m_rows;
};
}
}

View File

@@ -0,0 +1,20 @@
template <class ArgType>
class Circulant : public Eigen::MatrixBase<Circulant<ArgType> >
{
public:
Circulant(const ArgType& arg)
: m_arg(arg)
{
EIGEN_STATIC_ASSERT(ArgType::ColsAtCompileTime == 1,
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX);
}
typedef typename Eigen::internal::ref_selector<Circulant>::type Nested;
typedef typename Eigen::internal::traits<Circulant>::Index Index;
Index rows() const { return m_arg.rows(); }
Index cols() const { return m_arg.rows(); }
typedef typename Eigen::internal::ref_selector<ArgType>::type ArgTypeNested;
ArgTypeNested m_arg;
};

View File

@@ -0,0 +1,8 @@
int main()
{
Eigen::VectorXd vec(4);
vec << 1, 2, 4, 8;
Eigen::MatrixXd mat;
mat = makeCirculant(vec);
std::cout << mat << std::endl;
}

View File

@@ -0,0 +1,4 @@
#include <Eigen/Core>
#include <iostream>
template <class ArgType> class Circulant;

View File

@@ -0,0 +1,19 @@
namespace Eigen {
namespace internal {
template <class ArgType>
struct traits<Circulant<ArgType> >
{
typedef Eigen::Dense StorageKind;
typedef Eigen::MatrixXpr XprKind;
typedef typename ArgType::Index Index;
typedef typename ArgType::Scalar Scalar;
enum {
Flags = Eigen::ColMajor,
RowsAtCompileTime = ArgType::RowsAtCompileTime,
ColsAtCompileTime = ArgType::RowsAtCompileTime,
MaxRowsAtCompileTime = ArgType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ArgType::MaxRowsAtCompileTime
};
};
}
}