1#include <Eigen/Core> 2#include <iostream> 3 4using namespace Eigen; 5 6// [circulant_func] 7template<class ArgType> 8class circulant_functor { 9 const ArgType &m_vec; 10public: 11 circulant_functor(const ArgType& arg) : m_vec(arg) {} 12 13 const typename ArgType::Scalar& operator() (Index row, Index col) const { 14 Index index = row - col; 15 if (index < 0) index += m_vec.size(); 16 return m_vec(index); 17 } 18}; 19// [circulant_func] 20 21// [square] 22template<class ArgType> 23struct circulant_helper { 24 typedef Matrix<typename ArgType::Scalar, 25 ArgType::SizeAtCompileTime, 26 ArgType::SizeAtCompileTime, 27 ColMajor, 28 ArgType::MaxSizeAtCompileTime, 29 ArgType::MaxSizeAtCompileTime> MatrixType; 30}; 31// [square] 32 33// [makeCirculant] 34template <class ArgType> 35CwiseNullaryOp<circulant_functor<ArgType>, typename circulant_helper<ArgType>::MatrixType> 36makeCirculant(const Eigen::MatrixBase<ArgType>& arg) 37{ 38 typedef typename circulant_helper<ArgType>::MatrixType MatrixType; 39 return MatrixType::NullaryExpr(arg.size(), arg.size(), circulant_functor<ArgType>(arg.derived())); 40} 41// [makeCirculant] 42 43// [main] 44int main() 45{ 46 Eigen::VectorXd vec(4); 47 vec << 1, 2, 4, 8; 48 Eigen::MatrixXd mat; 49 mat = makeCirculant(vec); 50 std::cout << mat << std::endl; 51} 52// [main] 53