Re: [eigen] Matrix2i mean

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


I agree with Peter here. Trying to workaround overflow behavior for sum/prod/mean would be way to complicated to implement generically.

We _could_ provide something like `stable_mean()` which with some sophisticated algorithm works around overflows. If larger types are available, this could just cast to that type before summing.

But you can do that manually already:

    int32_t mean = m.cast<int32_t>().mean();
    // convert back to int16_t, if you like ...




The reason that this line worked as you expected:

    double mean = (INT16_MAX / 2.0 + INT16_MAX + 2 + 2) / 4.0;

is that due to the `2.0` in `INT16_MAX / 2.0` the expression gets converted to `double` and stays to be `double` even after adding more integers or `uint16_t`. And `double` is perfectly capable of adding your values without overflowing.

If you insert `INT16_MAX / 2.0` into your matrix, it gets converted to a `int16_t` (already truncating away the `.5` part) and additions for `mean()` happen in the `int16_t` domain, which overflows (which is technically undefined behavior).


Christoph

On 05/11/2019 10.07, Peter wrote:
Dear Petr,


Am 05.11.19 um 00:35 schrieb Petr Kubánek:
Hi,

calculating mean on int matrix fails to produce expected results - see
below. I noticed
[...]
Obviously all similar reduxes (sum, prod) fails as well. Is there a way
how to change type used as the internal storage and result for sum.
mean calculations?

In my opinion Eigen behaves perfectly well.
The problem you face is related to the fact, that the compiler can calculate known expression with higher precision, see the example below, where I also introduced
the argc/argv only to avoid further compiler optimizations.

Output on my machine:

-4095 12288 -4095
12288.5 12288 -4095

Best regards,
Peter


#include <Eigen/Eigen>
#include <iostream>

int main( const int argc, const char *argv[] )
{
   int16_t  Two = (argc>1) ? atoi(argv[1]) : 2;
   int16_t  Max = (argc>99) ? atoi(argv[99]) : INT16_MAX;

   Eigen::Matrix<int16_t, 2, 2> m;
   m <<
     INT16_MAX / 2, INT16_MAX,
     2, 2;

   int16_t mean = ( Max/2 + Max + Two + Two ) / int16_t(4);
   int16_t mean2 = Max/2;
   mean2 += Max;
   mean2 += Two;
   mean2 += Two;
   mean2 /= int16_t(4);
   std::cout << m.mean() << " " << mean << " " << mean2 << std::endl;

   Eigen::Matrix<double, 2, 2> md = m.cast<double>();
   std::cout << md.mean() << " " << mean << " " << mean2 << std::endl;
}



--
 Dr.-Ing. Christoph Hertzberg

 Besuchsadresse der Nebengeschäftsstelle:
 DFKI GmbH
 Robotics Innovation Center
 Robert-Hooke-Straße 5
 28359 Bremen, Germany

 Postadresse der Hauptgeschäftsstelle Standort Bremen:
 DFKI GmbH
 Robotics Innovation Center
 Robert-Hooke-Straße 1
 28359 Bremen, Germany

 Tel.:     +49 421 178 45-4021
 Zentrale: +49 421 178 45-0
 E-Mail:   christoph.hertzberg@xxxxxxx

 Weitere Informationen: http://www.dfki.de/robotik
  -------------------------------------------------------------
  Deutsches Forschungszentrum für Künstliche Intelligenz GmbH
  Trippstadter Strasse 122, D-67663 Kaiserslautern, Germany

  Geschäftsführung:
  Prof. Dr. Jana Koehler (Vorsitzende)
  Dr. Walter Olthoff

  Vorsitzender des Aufsichtsrats:
  Prof. Dr. h.c. Hans A. Aukes
  Amtsgericht Kaiserslautern, HRB 2313
  -------------------------------------------------------------




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