mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-19 16:19:37 +08:00
Add a nullary-functor example performing index-based sub-matrices.
This commit is contained in:
parent
ca3746c6f8
commit
9bcdc8b756
@ -53,6 +53,33 @@ showing that the program works as expected:
|
||||
|
||||
This implementation of \c makeCirculant is much simpler than \ref TopicNewExpressionType "defining a new expression" from scratch.
|
||||
|
||||
|
||||
\section NullaryExpr_Indexing Example 2: indexing rows and columns
|
||||
|
||||
The goal here is to mimic MatLab's ability to index a matrix through two vectors of indices referencing the rows and columns to be picked respectively, like this:
|
||||
|
||||
\snippet nullary_indexing.out main1
|
||||
|
||||
To this end, let us first write a nullary-functor storing references to the input matrix and to the two arrays of indices, and implementing the required \c operator()(i,j):
|
||||
|
||||
\snippet nullary_indexing.cpp functor
|
||||
|
||||
Then, let's create an \c indexing(A,rows,cols) function creating the nullary expression:
|
||||
|
||||
\snippet nullary_indexing.cpp function
|
||||
|
||||
Finally, here is an example of how this function can be used:
|
||||
|
||||
\snippet nullary_indexing.cpp main1
|
||||
|
||||
This straightforward implementation is already quite powerful as the row or column index arrays can also be expressions to perform offsetting, modulo, striding, reverse, etc.
|
||||
|
||||
\snippet nullary_indexing.cpp main2
|
||||
|
||||
and the output is:
|
||||
|
||||
\snippet nullary_indexing.out main2
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -14,3 +14,8 @@ foreach(example_src ${examples_SRCS})
|
||||
)
|
||||
add_dependencies(all_examples ${example})
|
||||
endforeach(example_src)
|
||||
|
||||
check_cxx_compiler_flag("-std=c++11" EIGEN_COMPILER_SUPPORT_CPP11)
|
||||
if(EIGEN_COMPILER_SUPPORT_CPP11)
|
||||
ei_add_target_property(nullary_indexing COMPILE_FLAGS "-std=c++11")
|
||||
endif()
|
66
doc/examples/nullary_indexing.cpp
Normal file
66
doc/examples/nullary_indexing.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <Eigen/Core>
|
||||
#include <iostream>
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
// [functor]
|
||||
template<class ArgType, class RowIndexType, class ColIndexType>
|
||||
class indexing_functor {
|
||||
const ArgType &m_arg;
|
||||
const RowIndexType &m_rowIndices;
|
||||
const ColIndexType &m_colIndices;
|
||||
public:
|
||||
typedef Matrix<typename ArgType::Scalar,
|
||||
RowIndexType::SizeAtCompileTime,
|
||||
ColIndexType::SizeAtCompileTime,
|
||||
ArgType::Flags&RowMajorBit?RowMajor:ColMajor,
|
||||
RowIndexType::MaxSizeAtCompileTime,
|
||||
ColIndexType::MaxSizeAtCompileTime> MatrixType;
|
||||
|
||||
indexing_functor(const ArgType& arg, const RowIndexType& row_indices, const ColIndexType& col_indices)
|
||||
: m_arg(arg), m_rowIndices(row_indices), m_colIndices(col_indices)
|
||||
{}
|
||||
|
||||
const typename ArgType::Scalar& operator() (Index row, Index col) const {
|
||||
return m_arg(m_rowIndices[row], m_colIndices[col]);
|
||||
}
|
||||
};
|
||||
// [functor]
|
||||
|
||||
// [function]
|
||||
template <class ArgType, class RowIndexType, class ColIndexType>
|
||||
CwiseNullaryOp<indexing_functor<ArgType,RowIndexType,ColIndexType>, typename indexing_functor<ArgType,RowIndexType,ColIndexType>::MatrixType>
|
||||
indexing(const Eigen::MatrixBase<ArgType>& arg, const RowIndexType& row_indices, const ColIndexType& col_indices)
|
||||
{
|
||||
typedef indexing_functor<ArgType,RowIndexType,ColIndexType> Func;
|
||||
typedef typename Func::MatrixType MatrixType;
|
||||
return MatrixType::NullaryExpr(row_indices.size(), col_indices.size(), Func(arg.derived(), row_indices, col_indices));
|
||||
}
|
||||
// [function]
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "[main1]\n";
|
||||
Eigen::MatrixXi A = Eigen::MatrixXi::Random(4,4);
|
||||
Array3i ri(1,2,1);
|
||||
ArrayXi ci(6); ci << 3,2,1,0,0,2;
|
||||
Eigen::MatrixXi B = indexing(A, ri, ci);
|
||||
std::cout << "A =" << std::endl;
|
||||
std::cout << A << std::endl << std::endl;
|
||||
std::cout << "A([" << ri.transpose() << "], [" << ci.transpose() << "]) =" << std::endl;
|
||||
std::cout << B << std::endl;
|
||||
std::cout << "[main1]\n";
|
||||
|
||||
std::cout << "[main2]\n";
|
||||
B = indexing(A, ri+1, ci);
|
||||
std::cout << "A(ri+1,ci) =" << std::endl;
|
||||
std::cout << B << std::endl << std::endl;
|
||||
#if __cplusplus >= 201103L
|
||||
B = indexing(A, ArrayXi::LinSpaced(13,0,12).unaryExpr([](int x){return x%4;}), ArrayXi::LinSpaced(4,0,3));
|
||||
std::cout << "A(ArrayXi::LinSpaced(13,0,12).unaryExpr([](int x){return x%4;}), ArrayXi::LinSpaced(4,0,3)) =" << std::endl;
|
||||
std::cout << B << std::endl << std::endl;
|
||||
#endif
|
||||
std::cout << "[main2]\n";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user