#include #include using namespace Eigen; // [circulant_func] template class circulant_functor { const ArgType &m_vec; public: circulant_functor(const ArgType& arg) : m_vec(arg) {} const typename ArgType::Scalar& operator() (Index row, Index col) const { Index index = row - col; if (index < 0) index += m_vec.size(); return m_vec(index); } }; // [circulant_func] // [square] template struct circulant_helper { typedef Matrix MatrixType; }; // [square] // [makeCirculant] template CwiseNullaryOp, typename circulant_helper::MatrixType> makeCirculant(const Eigen::MatrixBase& arg) { typedef typename circulant_helper::MatrixType MatrixType; return MatrixType::NullaryExpr(arg.size(), arg.size(), circulant_functor(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]