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

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


Hi list,

I have implementations (as a plugin) that allows the following syntax:

mat<int> m{{1, 2, 3}, // simple 2x3 matrix from lists
{4, 5, 6}};
// Single entry lookup is not changed. Notice zero indexing.
EXPECT_EQ(m(1, 1), 5);
// Entire matrix
EXPECT_THAT(m(all, all), MatEq({{1, 2, 3}, {4, 5, 6}}));
// Second column
EXPECT_THAT(m(all, 1), MatEq({{2}, {5}}));
// First 1 row, first 2 columns.. The returned block has static row count and
// dynamic column count.
EXPECT_THAT(m(first<1>, first(2)), MatEq({{1, 2}}));
// First row, last two columns
EXPECT_THAT(m(0, last(2)), MatEq({{2, 3}}));
// Row 1..2 inclusive, second column.
EXPECT_THAT(m(range(0, 1), 1), MatEq({{2}, {5}}));
// Row 1..2 inclusive, column 2..3, second column. The returned block
// has dynamic row count and static column count
EXPECT_THAT(m(range(0, 1), range<1, 2>), MatEq({{2, 3}, {5, 6}}));
// Row 1..2 inclusive, second column. The row count of the returned block is
// constant at compile time.
EXPECT_THAT(m(static_sized_range<2>(0), 1), MatEq({{2}, {5}}));

The MatEq is my GoogleTest matcher for eigen matrices. I used range instead of span since I was also using gsl::spans in my application.

Just want to throw this out to see if people are interested. The main trick worth mentioning is that first(2) produces a struct, whereas first<2> produces a (templated) function pointer. By dispatching based on types, I can support both, as I hate to write first<2>(). I learned this trick from the recent C++ proposal on using in_place_t  for optionals and variants.

Regarding API naming and convention, I also much prefer a matlab/STL like syntax of normalized(v) instead of v.normalized(), as well as writing cwise_max instead of cwiseMax, so I also have those aliases in my plugin. But I guess those are for another thread.



On Thu, Dec 22, 2016 at 5: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/