[eigen] Re: Rework of numtraits / math functions (note: all integer types are now supported!)

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


2010/4/28 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
> 2010/4/28 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
>> Hi List,
>>
>> *** The big news ***
>>
>> All integer types, from "unsigned char" to "long long", are now
>> correctly supported. There's a new unit test for that: integer_types.
>>
>> This is a consequence of a big rework of NumTraits (does no longer
>> inherit numeric_limits) and of our global math functions (ei_sin...)
>> which are now templated.
>>
>> *** Interface changes ***
>>
>> All that also means some interface changes if you are adding support
>> for custom types.
>>
>> The NumTraits changes are small, see the "Customizing Eigen" dox page
>> once it'll be updated.
>>
>> For the math functions, the changes are a bit bigger as you can see in
>> MathFunctions.h. Let's take ei_sin as an example. It's a matter of
>> adding a specialization of a struct ei_sin_impl<Scalar> for your type.
>> Suppose that you want to add ei_sin() support for your custom
>> FixedPoint type. You'd do something like that:
>>
>> namespace Eigen
>> {
>
> template<>
>>  struct ei_sin_impl<FixedPoint>
>>  {
>>    // here you tell Eigen what's the return type of ei_sin(FixedPoint)
>>    typedef FixedPoint retval;
>
> Ooh, thinking more about it, you really shouldn't have to specify it
> since Eigen knows it already. I'll change that so it's not needed.

OK, this is done.

So now, no need for the retval typedef anymore, Eigen guesses it
automatically in 99.9% of cases. What's the remaining 0.01% ? It's
when the Scalar type that you're adding support to, has expression
templates itself. Then the return type is some abstract expression
that Eigen can't know about. So in that case, you can specialize
ei_sin_retval<Scalar> to provide that information, see in
MathFunctions.h. But almost nobody will ever need to do that. So the
documentation example should now look like:

namespace Eigen
{
 template<>
 struct ei_sin_impl<FixedPoint>
 {
   static inline FixedPoint run(const FixedPoint& x)
   {
     return my_fixedpoint_sin_function(x);
   }
 };
}

Notice that certain functions return a Scalar (like exp, cos, sin,
log...) while others return a NumTraits<Scalar>::Real  (like abs,
abs2, real, imag...) and some others return a bool (like
ei_isApprox...).

Benoit

>
> Benoit
>
>>
>>    // and here you implement the function
>>    static inline FixedPoint run(const FixedPoint& x)
>>    {
>>      return my_fixedpoint_sin_function(x);
>>    }
>>  };
>> }
>>
>> So yes, that's more verbose than before. But isn't it worth it, to get
>> that generic system that supports e.g. all integer types for free?
>> Another remark is that part of our global math functions were already
>> like that (e.g. ei_random) so we used to have a discrepancy between
>> templated and non-templated functions. Finally, if a user has to
>> support a lot of math functions for his custom type, he'll be able to
>> write a macro to factor the code.
>>
>> *** Call for good wills ***
>>
>> If you're looking for a useful task to accomplish, here's one: update
>> the dox page (doc/I00_CustomizingEigen.dox) to explain how to do these
>> specializations of math functions (like above). Instead of Adolc's
>> adouble which is quite special, and already handled in an unsupported
>> module, how about carrying on the FixedPoint example?
>>
>> *** Testing needed ***
>>
>> Especially in the Array support (so 'array' unit test), I'm using
>> SFINAE, that is highly susceptible of breaking MSC support.
>>
>> Benoit
>>
>



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