Re: [eigen] Bugs in Mat::Random, reductions

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


On Tue, Oct 21, 2008 at 8:51 PM, Benoît Jacob <jacob@xxxxxxxxxxxxxxx> wrote:
First of all, your compiler errors are likely caused by forgetting to include
#include<Eigen/Array>
which is where the random matrices stuff is defined.

Oh... yes, that would be the problem, thanks. Now I see that this is noted at various places in the Doxygen docs. But, as you noticed, <Eigen/Array> is not mentioned at all in the tutorial - that could have saved me some confusion. Probably that #include should appear in the initialization and reduction sections, and a more general note (or even table) explaining that certain member functions of MatrixBase require modules other than Core would be nice. I had another moment of confusion when determinant() didn't compile without LU.

Btw, I think there is a typo in the "Basis vectors" code box: UnixX() instead of UnitX(), etc.

Otherwise I am impressed with the documentation so far, which is already much better than some projects I've seen. More is always better, of course!

I know that the compilation errors are very ugly, the root of the problem is
that the Random() method has to be declared in Core because it is a member of
MatrixBase, so you don't get the simple "undefined Random() method" error
message that you expect. Any suggestion towards getting friendlier error
messages are welcome.

Well, this design makes me uncomfortable - it seems like it's asking for this sort of trouble. Normally a module named Core would have no dependencies on other modules, which isn't strictly true here. I'm not sure why Array can't just be merged into Core, and things like MatrixBase::svd() left as free functions or distinct classes.

Still, I thought of a cute trick you could use to get friendlier error messages. According to the standard, "The default arguments in a member function definition that appears outside of the class definition are added to the set of default arguments provided by the member function declaration in the class definition." We can abuse this to make nicer error messages, like so:

// Changes to MatrixBase
template<typename Derived> class MatrixBase
{
  private:
    struct you_must_include_Eigen_Array {};

  public:
    const PartialRedux<Derived,Horizontal> rowwise(you_must_include_Eigen_Array) const;
};

// Changes to implementation in Array module
template<typename Derived>
const PartialRedux<Derived,Horizontal> MatrixBase<Derived>::rowwise(you_must_include_Eigen_Array = you_must_include_Eigen_Array()) const
{
  /* implementation */
}

Then when the user includes <Eigen/Array>, he effectively gets the expected zero-arg version of rowwise. If he forgets to include it, no zero-arg version exists, so mat.rowwise() should produce a compiler error along the lines of:

error: no matching function for call to 'MatrixBase<Derived>::rowwise()'
note: candidates are: const PartialRedux<Derived, 0> MatrixBase<Derived>::rowwise(MatrixBase<Derived>::you_must_include_Eigen_Array) const

You would probably want to coerce Doxygen into hiding this bit of trickery, though.


> I could imagine it being
> useful to specify the dimensions of a large, dynamically-allocated matrix
> at compile time; e.g. if you know the inner dimension is a multiple of the
> level of loop unrolling, you can avoid some unnecessary code.

Eigen can already handle that very well. You can do Matrix<double, 8,
Dynamic>. Eigen will then allocate dynamically, which is what you want since
you said the matrix is large, and at the same time Eigen will make use of the
information that one dimension is fixed to unroll inner loop. In this respect
it can greatly help if you manually specify the storage orders (using the
optional template parameter Flags of Matrix) so that the fixed size is the
inner size. Eigen will not by itself take the decision to switch to row-major
order, as that could easily break the user's assumptions.

Very nice.

I did a straightforward reimplementation of some of the pose estimation code using Eigen2 - it's about half the lines of code, far more readable, and almost twice as fast. Very impressive work you've done; I will be playing with this library more.

Cheers,
Patrick


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