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…
	
		Reference in New Issue
	
	Block a user
	 Gael Guennebaud
						Gael Guennebaud