#include <Eigen/Core> #include <iostream> // [circulant_func] template <class ArgType> class circulant_functor { const ArgType& m_vec; public: circulant_functor(const ArgType& arg) : m_vec(arg) {} const typename ArgType::Scalar& operator()(Eigen::Index row, Eigen::Index col) const { Eigen::Index index = row - col; if (index < 0) index += m_vec.size(); return m_vec(index); } }; // [circulant_func] // [square] template <class ArgType> struct circulant_helper { typedef Eigen::Matrix<typename ArgType::Scalar, ArgType::SizeAtCompileTime, ArgType::SizeAtCompileTime, Eigen::ColMajor, ArgType::MaxSizeAtCompileTime, ArgType::MaxSizeAtCompileTime> MatrixType; }; // [square] // [makeCirculant] template <class ArgType> Eigen::CwiseNullaryOp<circulant_functor<ArgType>, typename circulant_helper<ArgType>::MatrixType> makeCirculant( const Eigen::MatrixBase<ArgType>& arg) { typedef typename circulant_helper<ArgType>::MatrixType MatrixType; return MatrixType::NullaryExpr(arg.size(), arg.size(), circulant_functor<ArgType>(arg.derived())); } // [makeCirculant] // [main] int main() { Eigen::VectorXd vec(4); vec << 1, 2, 4, 8; Eigen::MatrixXd mat; mat = makeCirculant(vec); std::cout << mat << std::endl; } // [main]