Re: [eigen] On a flexible API for submatrices, slicing, indexing, masking, etc.

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]



A general update:

I've started to migrate the stand alone demo-code in Eigen's in the following fork:

https://bitbucket.org/ggael/eigen-flexidexing

don't pay attention to the current naming, I'll do search/replace once we have truly settled down them.

PLEASE share your opinion!

For the record, we have to agree on at least 4 names:

1 - one to denote a kind of alias to std::integral_constant<int,N>, the current best choice seems to be: fix<N>

2/3 - a pair of names to denote an arithmetic sequence starting at position i, with increment d, and either an inclusive upper bound j or a size n. The current best candidates are: 

   *  seq(i,j,d) / seqN(i,n,d)  or seqn(i,n,d)
   *  aseq(i,j,d) / aseqN(i,n,d) or aseqn(i,n,d)
   *  range(i,j,d) / span(i,n,d)

With the 'n' vs 'N' suffix variations this makes 5 options. My current personal preference go to seq/seqN.

4 - A pseudo "keyword" to denote all elements, aka ':' in MatLab. Two candidates so far: All and all

You can see more (mis-inspired?) suggestions there: http://eigen.tuxfamily.org/index.php?title=Working_notes_-_Indexing%2B%2B#Choice_of_identifier_names



FYI, the current fork already supports various ops, as shown in the testing code below.

There is still a lot of work to do for a more seamless and efficient integration, in particular I have to figure out a way to unify this API with Eigen::Block/Eigen::MapBase. There are many approaches, including:

1 - return a Block<> _expression_ if the arguments are compatibles (unit steps)
2 - make IndexedView inherits MapBase when possible, and cleanup redundancies by writing Block<> on top of IndexedView

I'll probably try option 1 first. Less risky regarding regressions in the current Block.

cheers,
gael


#include <iostream>
#include <Eigen/Dense>
#include <valarray>
#include <vector>
using namespace Eigen;
using namespace std;

#define PRINT(X) cout << #X << "\n" << X << "\n\n"

int main()
{
  MatrixXi A(10,10);
  for(int i=0; i<10; ++i)
    for(int j=0; j<10; ++j)
      A(i,j) = i*10+j;

  cout << A << "\n\n";

  ArrayXd eia(10); eia.setRandom();
  Array4i eii(4); eii << 3, 1, 6, 5;
  valarray<double> vala(10); Map<ArrayXd>(&vala[0],10) = eia;
  valarray<int> vali(4); Map<ArrayXi>(&vali[0],4) = eii;
  vector<int> veci(4); Map<ArrayXi>(veci.data(),4) = eii;

  PRINT( A(3, range(9,3,-1)) );
  PRINT( A(span(2,5), range(9,3,-1)) );
  PRINT( A(span(2,5), 5) );
  PRINT( A(span(last,5,-1), range(2,last)) );
  PRINT( A(eii, veci) );
  PRINT( A(eii, all) );
  // takes the row numer 3, and repeat it 5 times
  PRINT( A(span(3,5,0), all) );

On Thu, Dec 22, 2016 at 11:49 AM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:
Hi list,

this is probably one of the most awaited feature that is still shamefully missing in Eigen. So let's have it for 3.4!

To this end, we first have to converge an API that will be unanimously adopted by the community. The challenge is to maximize expressivity, extensibility, concision, optimization opportunities, while avoiding ambiguities.

To help discussion, I've prepare this wiki page that contains a compilable c++ example demonstrating some ideas:
http://eigen.tuxfamily.org/index.php?title=Working_notes_-_Indexing%2B%2B

Please share your though, here or on the bugzilla entry: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=329

Speaking about "ambiguous" API, I hate the current MatrixXd::Constant(...) and VectorXd::LinSpaced(...) function: I never managed to remember the parameter orders, do the sizes come first? or last? I guess this is because the two answers make sense: one is consistent when moving from Constant to Ones, and the other when moving from Matrix to Vector or fixed-size object. This is thus a high source of hard to track bugs. I'd really like to avoid this caveat.

cheers,
gael



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/