Re: [eigen] Combining different types

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


Hi,

sorry for the late reply, just to say that we are aware of that
shortcoming, and some days I'd like to address it seriously. There are
some discussions there:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=279
http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2011/05/msg00038.html

gael

On Sat, Sep 29, 2012 at 6:47 PM, Norman Goldstein <normvcr@xxxxxxxxx> wrote:
> The MatrixBase::cast() is very helpful, but I would like to point out how
> using that does introduce non-trivial temporaries into my code.  For
> example,
>
>    double x;
>    adouble ax; // adouble is a non-trivial class from the package ADOL-C
>
> The sum   ax + x  is handled by operator+( adouble, double )  and results in
> one temporary.
> However, the sum   ax + adouble(x)  results in two temporaries:
> 1. The result of adouble(x), and
> 2. The result of operator+(adouble, adouble)
>
> Fortunately, I was able to avoid the MatrixBase::cast(), in this case, by
> introducing the following specialization
>
>    namespace Eigen{ namespace internal {
>    template<>
>    struct functor_allows_mixing_real_and_complex
>    < scalar_sum_op<adouble> > { enum { ret = 1 }; };
>    } }
>
> However, the story is not so straightforward for the sum in the opposite
> order:   x + ax
> I have analyzed this situation, but have not, yet, coded up a solution /
> work-around.
> I would appreciate any comments on this.
>
> Many thanks,
> Norm
>
>
>
>
> On 09/28/2012 02:37 PM, Norman Goldstein wrote:
>
> If the MatrixBase::cast() is, indeed, a lazy cast (I suspect you are right),
> and does not actually instantiate a vector
> of the new type, then that would be very helpful.  Thanks for your comments.
>
>
> On 09/28/2012 12:30 PM, Ryan Pavlik wrote:
>
>
>
> On Fri, Sep 28, 2012 at 3:05 AM, Norman Goldstein <normvcr@xxxxxxxxx> wrote:
>>
>> I understand that Eigen does not allow adding vectors of different types.
>> For example, the code
>>
>>    VectorXf    f(3);
>>    VectorXd   d(3);
>>
>>    cout << (f+d) << endl;
>>
>> yields the compilation error
>>
>>
>> YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
>>
>> I also understand the Eigen has this restriction because of the difficulty
>> (correctness?) of doing vectorization with such expressions.  However,
>> casting a float vector to a double vector is, of course, inefficient.  Does
>> it make sense to move the prohibition of mixing types to be a pre-condition
>> for vectorization, and allow the mixing of types in general in Eigen?
>>
>> A concrete situation where this is desirable is where a bunch of
>> parameters can be stored in a vector of floats (to save space), but the main
>> calculations are done in double, to maintain sufficient precision.
>>
>> The following template
>>
>>    template< typename A, typename B >
>>    struct promote
>>    {
>>      typedef decltype( A(0) + B(0) ) type;
>>    };
>>
>> makes the promotion type explicit.  [In my actual situation, this does not
>> work with a new scalar type, adouble (from ADOL-C) that I am using, but this
>> can be handled by writing down specializations for the above template].
>>
>> I have been able to, largely, work around the prohibition of mixing types
>> with adouble by adding small amounts of code to specialize the existing
>> Eigen infrastructure that does the checking.  However, I have not been able
>> to solve this definitively, for adouble, and may need to (mildly) constrain
>> my code, instead.  It would be more elegant if Eigen, from ground up,
>> allowed the user the option to mix types
>>
>> Any comments much appreciated ...
>>
>>
>>
>>
>>
>
> If I understand correctly, when you do double(5) * float(10) in C++, the
> float(10) is automatically converted/promoted to a double before the
> operation takes place. (For integer types, there's a whole list in order,
> from smallest to largest, unsigned following/"larger than" signed for a
> given size, and operands are converted to the later/"larger" of the two
> types.)  Sometimes this automatic promotion may lead to data loss
> (particularly if it's int to float, or signed int to unsigned larger int)
> and the compiler warns you. You can make the conversion explicit and
> acknowledge the limitations with static_cast<thetype>(arg).
>
> My impression was that, in Eigen, since operations may #1. be more
> complicated/operate on larger data (making conversion overhead more
> substantial, etc) and #2. be more accuracy-focused than "general computing"
> (turn perhaps accidental mixing into errors so the code is clear about
> intent), automatic type-promotion operators for matrix types were not
> defined, requiring every mixing of matrices with differing scalar types to
> involve a .cast<type>() expression, serving a similar purposes as the
> static_cast in the scalar case above.
>
> I'm not sure exactly what the .cast<type>() method actually does.  Based on
> a user's perspective for the library, I presume it just adds to the
> expression tree, so conversion is lazily evaluated just like in the rest of
> Eigen. (that is, it wouldn't be converting the entire vector from float to
> double en-masse immediately)  However, I don't have enough experience with
> the innards to actually know if this is true or not.
>
>
> --
> Ryan Pavlik
> HCI Graduate Student
> Virtual Reality Applications Center
> Iowa State University
>
> rpavlik@xxxxxxxxxxx
> http://academic.cleardefinition.com
>
>
>



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