Eigen Array indexing
Asked Answered
S

1

0

I would like to create new Eigen::Array using an index.

I know it is possible for Eigen::Matrix, a code is given here.

A similar question has also been posted on stackoverflow

The question is how to update the following code to work with Eigen::Array

#include <iostream>
#include <stdio.h>
#include <Eigen/Core>

using namespace Eigen;

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]);
  }
};

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));
}
Sirloin answered 12/9, 2018 at 7:6 Comment(2)
If you can use the Default branch, then go ahead and directly write ArrayXXf a; a(row_indices,col_indices) where *_indices can be lot of things including sequences, all, symbolic, etc. See the online doc. Otherwise, you need to replace Matrix by Array and MatrixBase by ArrayBase.Aires
Thanks @ggael. Using Default branch, that actually matches master branch works like a charm. Do you know when a new tag will be released with these killing features? (Version : I have used github.com/eigenteam/eigen-git-mirror/commit/…)Sirloin
S
0

With @ggael's help, I made this little test program that uses Eigen master branch.

First I fetch eigen repo, that points on master branch, and includes new indexing features, that are not present in tagged version 3.3.5.

git clone https://github.com/eigenteam/eigen-git-mirror

Here is the program that I compile with g++ -O3 -isystem eigen-git-mirror -o eigen_indexing eigen_indexing.cpp

#include <iostream>
#include <Eigen/Dense>
int main()
{
    Eigen::ArrayX3d array = Eigen::ArrayX3d::Random(8, 3);
    Eigen::ArrayXi indices(5);
    indices << 4, 7, 0, 2, 1;
    Eigen::Array3i cols(0,1,2);
    std::cout << "array = " << std::endl << array << std::endl << std::endl;
    std::cout << "indices = " << std::endl << indices << std::endl << std::endl;
    std::cout << "cols = " << std::endl << cols << std::endl << std::endl;
    std::cout << "array(indices,cols) = " << std::endl << array(indices,cols) << std::endl << std::endl;
    std::cout << "Equivalent but Eigen::placeholders::all syntax may evolve " << std::endl << std::endl;
    std::cout << "array(indices, Eigen::placeholders::all)  = " << std::endl << array(indices,Eigen::placeholders::all) << std::endl << std::endl;
    std::cout << "Assignment also works array(indices,cols) = 0.0;" << std::endl<< std::endl;
    array(indices,cols) = 0.0;
    std::cout << "array = " << std::endl << array << std::endl << std::endl;

    std::cout << "Assignment also works array(indices,cols) = 10 * Eigen::ArrayX3d::Random(5, 3);" << std::endl<< std::endl;
    array(indices,cols) = 10 * Eigen::ArrayX3d::Random(5, 3);
    std::cout << "array = " << std::endl << array << std::endl << std::endl;
    return 0;
}

If the program can not compile, here is the version I have used

 cd eigen-git-mirror
 # git checkout master
 git checkout a31719c75f244673c962ee65f279606bee6fc7ef
 cd ..

Here is the output of the program

array =
-0.999984   0.358593   0.342299
-0.736924   0.869386  -0.984604
0.511211  -0.232996  -0.233169
-0.0826997  0.0388327  -0.866316
0.0655345   0.661931  -0.165028
-0.562082  -0.930856   0.373545
-0.905911  -0.893077   0.177953
0.357729  0.0594004   0.860873

indices =
4
7
0
2
1

cols =
0
1
2

array(indices,cols) =
0.0655345  0.661931 -0.165028
0.357729 0.0594004  0.860873
-0.999984  0.358593  0.342299
0.511211 -0.232996 -0.233169
-0.736924  0.869386 -0.984604

Equivalent but Eigen::placeholders::all syntax may evolve

array(indices, Eigen::placeholders::all)  =
0.0655345  0.661931 -0.165028
0.357729 0.0594004  0.860873
-0.999984  0.358593  0.342299
0.511211 -0.232996 -0.233169
-0.736924  0.869386 -0.984604

Assignment also works array(indices,cols) = 0.0;

array =
        0          0          0
        0          0          0
        0          0          0
-0.0826997  0.0388327  -0.866316
        0          0          0
-0.562082  -0.930856   0.373545
-0.905911  -0.893077   0.177953
        0          0          0

Assignment also works array(indices,cols) = 10 * Eigen::ArrayX3d::Random(5, 3);

array =
-8.1607    5.24396    2.65277
-1.68001   -9.05071    9.82075
3.07838   -4.75094    5.12821
-0.0826997  0.0388327  -0.866316
6.92334    4.02381    4.72164
-0.562082  -0.930856   0.373545
-0.905911  -0.893077   0.177953
0.538576    8.20642   -3.43532
Sirloin answered 15/9, 2018 at 7:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.