Re: [eigen] docs updates

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


On Sunday 12 October 2008 11:46:39 Scott Wheeler wrote:
> The reason that I did that, and cleared up the docs similarly, was at
> the first glance at the docs I didn't get that you didn't have to
> specify the sizes -- I just noticed that there were sizes as template
> parameters and they were required.  So when I first tried Eigen, I
> specified the template parameters ... and then when it always crashed I
> initially just wrote off the library.

Indeed, there is no default value. I'll update the docs to mention that you 
can use the special value Eigen::Dynamic.

>
> That said, if you're using alloca() anyway for your matrix allocation
> (under the size limit), I don't see why it wouldn't make sense to go
> ahead and do that in the fixed size arrays -- or similarly, if you even
> really need fixed sized ones.  If you can get the same results with a
> simpler API, that would seem to be ideal.

alloca() has a nonzero cost. By contrast allocating memory by doing Scalar 
data[SIZE] has zero runtime cost. With fixed-size matrices, it is crucial to 
avoid any runtime overhead, even small, or else most people will prefer using 
their own custom vector classes.

Moreover, alloca() is nonstandard and is broken on many platforms and absent 
from others, so we only can use it on Linux.

> > Moreover we set Eigen::Dynamic to 10000 assuming nobody would ever use a
> > fixed size of that order of magnitude. If anybody does, he'll get serious
> > problems. /me makes a mental note to add a static assert for that.
>
> Well, as I mentioned on IRC, our projection matrix is a dense matrix of
> 3000000 x 24.

Yes but I said a _fixed_ size of that order of magnitude. With a size of 
3000000 x 24 one needs to use a dynamic-size matrix i.e. something like

MatrixXd m(3000000,24)

where MatrixXd is a typedef for Matrix<double,Dynamic,Dynamic>.

I'll update the docs to make clear that fixed-size matrices are allocated as 
fixed-size arrays hence are only for small sizes.

>
> > Sorry about that. I thought that norm() meant the usual norm a.k.a.
> > the "length" and norm2() meant squared-norm. I am opposed to using such a
> > good function name as norm() to designate the l1 norm which is not a very
> > natural thing in math; however if you want the l1 norm of a vector v just
> > do:
>
> I think it depends on what classes of algorithms you're using.  I've run
> across several things that use l1 recently.  I however was looking for
> the l2 norm and ended up using the squared l2 norm.  :-)
>
> Maybe something like this?
>
>   enum
>   {
>     L1Norm = 1,    //!< \em Taxi-Cab Norm
>     L2Norm = 2,    //!< Euclidean Norm
>     LInfNorm = -1 //!< Infinite Norm
>   };
>
>   Scalar norm(int p = L2Norm);

We can always add that as a convenience function, but it can't replace the 
others. Indeed, such a function could be implemented with the formula that I 
gave in the previous e-mail, but for the most important special cases 
p=1,2,infinity, it would be much slower than a specialized function.

I still believe that norm() should return the l2 norm, but I agree with the 
need to clarify things much more in the documentation, I could agree with 
adding convenience functions l1Norm() l2Norm() lInfNorm() and why not 
lpNorm(RealScalar p) and I agree with the API change you propose below:

> And for norm2() -- just to avoid confusion, I'd prefer squaredNorm() or
> normSquared()

I've been thinking about this since your last e-mail. I was about to ask this 
list for everybody's opinions, now I have yours.

Other people, you opinions? Ok with adding l???Norm() and renaming norm2
() ---> squaredNorm()?

> > Moreover the notation v1 * v2 would be very ambiguous: it would seem to
> > mean the coefficient-wise product (v1.cwise()*v2).
>
> I agree that the notation could be ambiguous.  This is, however, another
> point where Eigen differs from other libs.

Other libs may allow the notation v1 * v2, but then they will differ greatly 
with one another: certain will interpret this as v1.transpose() * v2, certain 
others as v1.cwise()*v2. In any case it is not clear at all, reading such 
source code as "v1*v2", what it does, so I prefer to not allow that.

> How about this -- make a 
> smarter assert that first checks if the vector needs to be transposed
> and if so gives that as the error message instead of that the sizes
> aren't the same?

Now we're talking :) I'll have a look at that.

> In general I like that Eigen uses readable asserts (a 
> big difference to uBLAS), but I think that could be taken even further.

Here the standard library is not helping us: the assert() macro (which 
ei_assert() calls) does not allow passing a string. So being human-readable 
would require to get rid of assert() and implementing our own, but that's not 
easy as a good assert() needs to pretty-print the current C++ function name 
which relies on nonstandard compiler extensions. We could do it for GCC but 
non-GCC users would then see a regression of the niceness of assert messages. 

For static asserts, we have our own system, allowing to pass a "string", or 
rather a_symbol_name_with_underscores.

>
> On the things that I've mentioned I wouldn't mind implementing them
> myself for the most part.  But while I felt pretty confident that I
> wouldn't annoy anyone with docs updates without asking first, I thought
> API changes would be a little touchier.  :-)

Exactly, so thanks for using this list :)

Cheers,
Benoit

---


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