This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Possible bug in custom matrix scalar operation ?

Tags: None
(comma "," separated)
vkubicki
Registered Member
Posts
14
Karma
0
Hi,

this is a follow-up from my previous post. I want to implement (scalar - matrix operation), like 1. - myMatrix. I use the Matrix API in my code, and I would like to add this operation properly in EigenMatrixBaseAddon by using a CwiseUnaryOp. Here is the code I added in EigenMatrixBaseAddon:

Code: Select all
/** Element-wise - between a scalar and a matrix */
friend inline const CwiseUnaryOp<internal::scalar_add_op<Scalar>,
                                 Derived>
operator-(const Scalar& scalar,
          const MatrixBase<Derived>& mat)
{
  return CwiseUnaryOp<internal::scalar_add_op<Scalar>,
                      const Derived>(- mat.derived(),
                                     internal::scalar_add_op<Scalar>(scalar));
}


Now, here is one of my unit test:

Code: Select all
/** Coefficient-wise substract a vector to a scalar */
TEST(Vector, SubScalar)
{
  int nbTest = 1000;
  int nbInd = 10;
  Vector<bool> testCorrect(nbTest, false);

  Real bound = 1.e8;

  UniformStatistic uni;

  for (int t = 0; t < nbTest; ++t)
  {
    Real scalar = uni.sample(- bound,
                               bound);
    Vector<Real> vector(nbInd);
    Vector<Real> expectedSub(nbInd);
    for (int i = 0; i < nbInd; ++i)
    {
      vector(i) = uni.sample(- bound,
                               bound);
      expectedSub(i) = scalar - vector(i);
    }

    std::cout << t << std::endl;
    std::cout << expectedSub.transpose() << std::endl;
    std::cout << (scalar - vector).transpose() << std::endl;

    testCorrect(t) = expectedSub.isApprox(scalar - vector);
  }

ASSERT_EQ(testCorrect.isConstant(true), true);
}


Where UniformStatistic::sample() simply samples a decimal number between the bounds using an uniform distribution. For a given t, the output looks like:

Code: Select all
0
 8.82895e+07  9.90147e+07  9.40475e+07 -7.56236e+07 -6.97492e+07 -2.87381e+07 -2.42102e+07 -1.90435e+06  1.98254e+07  6.92643e+07
  1.4564e+07  9.90147e+07  9.40475e+07 -7.56236e+07 -6.97492e+07 -2.87381e+07 -2.42102e+07 -1.90435e+06  1.98254e+07  6.92643e+07


One can see that there is a discrepancy only on the first item. I have upgraded Eigen to version 3.2.5. If I increase nbInd, I get more errors. For example, with nbInd = 100 instead of 10, I get the first four coefficients wrong. I mentionned a possible bug because this implementation is very similar to other I have done, and I do not understand why only the first coefficients would be wrong. Note that when the discrepancy occur, the value of the corresponding coefficient in scalar - vector is equal to scalar, so it looks like the first coefficients of vector are considered equal to 0.

Regards
vkubicki
Registered Member
Posts
14
Karma
0
My mistake, here is the working implementation:

Code: Select all
/** Element-wise - between a scalar and a matrix */
friend inline const CwiseUnaryOp<internal::scalar_add_op<Scalar>,
                                 CwiseUnaryOp<internal::scalar_opposite_op<Scalar>,
                                              const Derived> >
operator-(const Scalar& scalar,
          const MatrixBase<Derived>& mat)
{
  return (-mat) + scalar;
}


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Yahoo [Bot]