Re: [eigen] DenseBase<Derived>::Zero initialization problem

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


It is normally defined for custom numeric values - your specific issue is because you're using a combination of types, one of which (Jet) requires an explicit constructor.  complex<Jet> only allows

complex(Jet real)

but because Jet requires an explicit constructor, it will refuse to implicitly convert an int, float, double, etc.. to Jet, preventing you from calling complex(0) directly.  complex(Jet(0)) will work:

Mat A = Mat::Constant(10, Jet<double,3>(0.0));




On Wed, Jun 22, 2022 at 10:58 AM Oleg Shirokobrod <oleg.shirokobrod@xxxxxxxxx> wrote:
Antonio, You are right 
auto z2 = std::complex < ceres::Jet<double, 3>>(0.0);
does not work, but
auto z2 = std::complex < ceres::Jet<double, 3>>();
does work.

From this discussion it seems that the general idea of Zero for custom numerical values is not well defined. Maybe this function must be marked as deprecated and only used for primitive types like int, float and double.

ср, 22 июн. 2022 г. в 20:22, Oleg Shirokobrod <oleg.shirokobrod@xxxxxxxxx>:
Hi Rasmus,

You are right. This abbreviated declaration of Jet

template <typename T, int N>
struct Jet {
  enum { DIMENSION = N };
  using Scalar = T;

  // Default-construct "a" because otherwise this can lead to false errors about
  // uninitialized uses when other classes relying on default constructed T
  // (where T is a Jet<T, N>). This usually only happens in opt mode. Note that
  // the C++ standard mandates that e.g. default constructed doubles are
  // initialized to 0.0; see sections 8..5 of the C++03 standard.
  Jet() : a() { v.setConstant(Scalar()); }

  // Constructor from scalar: a + 0.
  explicit Jet(const T& value) {
    a = value;
    v.setConstant(Scalar());
  }
  // The scalar part.
  T a;

  // The infinitesimal part.
  Eigen::Matrix<T, N, 1> v;
};
It has default zero initialized CTOR and CTOR initializing Jet from floating value. Of course instead of using Mat::Zero() -> return Mat::Constant(0) I can use Mat::Constant(0.0).

ср, 22 июн. 2022 г. в 19:00, Rasmus Munk Larsen <rmlarsen@xxxxxxxxxx>:
BTW: What happens if you do Mat x = Mat::Zero(10.0); ? Perhaps conversion from double or float work, because those types are "differentiable", as opposed to int.

On Wed, Jun 22, 2022 at 5:13 AM Oleg Shirokobrod <oleg.shirokobrod@xxxxxxxxx> wrote:
Hi,

In the file CwiseNullaryOp.h the functions DenseBase<Derived>::Zero call function DenseBase<Derived>::Constant which uses Scalar(0) for zero-initialization. It gives compilation error for this line 
using Mat = Eigen::Matrix<std::complex<ceres::Jet<double, 3>>, -1, 1, 0, -1, 1>; 
Mat x = Mat::Zero(10);
Here ceres::Jet<double, 3> is autodif type in ceres-solver. The problem is that it is not always possible to make conversion from int. From the other side for non-class-type scalar values, Scalar() provides a temporary which is zero-initialized. It is likely that for custom numerical class types Scalar() provides zero-initialized temporary. This is the case for Jet. When I replaced 

return Constant(size, Scalar(0)); 

with 

return Constant(size, Scalar()); 

in all Zero and setZero functions, code was compiled without errors.

Best,

Oleg



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