1 #include <Eigen/Core> 2 #include <iostream> 3 4 using namespace Eigen; 5 6 // [circulant_func] 7 template<class ArgType> 8 class circulant_functor { 9 const ArgType &m_vec; 10 public: 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] 22 template<class ArgType> 23 struct 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] 34 template <class ArgType> 35 CwiseNullaryOp<circulant_functor<ArgType>, typename circulant_helper<ArgType>::MatrixType> 36 makeCirculant(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] 44 int 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