| #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] |