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

How to compare two Eigen::Vectors for std::sort?

Tags: None
(comma "," separated)
mholzapfel
Registered Member
Posts
2
Karma
0
OS
Hi everyone,

this is my first post here and first I need to say what a great library Eigen is!

Today, however, I stumbled upoon a problem I could not solve. I am currently trying to sort an std::vector<Eigen::Vector3d> via std::sort. In order for that to happen I need a binary comparison function I can pass to std::sort.

I want to sort by comparing the first coefficient. If one is greater than the other -> return; if they are the same (within epsilon), check the second coefficient and so on.

So I tried template recursion like this:
Code: Select all
template<typename T, unsigned int i>
  bool
  smallerThan (const Eigen::Matrix<T, i, 1 > & comp1,
               const Eigen::Matrix<T, i, 1 > & comp2)
  {
    if (comp1[0] < comp2[0])
      {
        return true;
      }
    else
      {
        if (fabs (comp1[0] - comp2[0]) < std::numeric_limits<double>::min ())
          {
            return smallerThan<T, i - 1 > (comp1.tail<i - 1> (), comp2.tail<i - 1> ());
            return true;
          }
        else
          {
            return false;
          }
      }
  }

with a specialization for i == 1 of course.

However, this does not compile (gcc 4.6). It seems like the compiler cannot instantiate the compX.tail<i - 1> () template. My guess is, that that is because it can't deduce Matrix<T, i, 1> to be a vector-only type, but of course I might be wrong.

Can anyone help me on this issue or are there any other ways of comparing Vectors?

Best regards, Matze
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
classic mistake, you have to add the template keywords:

comp1.template tail<i - 1> ()
mholzapfel
Registered Member
Posts
2
Karma
0
OS
Thank you very much, I did not know, that was actually possible. But using .tail <>() was a stupid idea anyway sicne it creates a new Vector for every step of the recursion ...

In case anybody needs this, here iy my working code:


Code: Select all
template <unsigned int COEFF, unsigned int DIM, typename T>
  struct smallerThan
  {

    static bool result (const Eigen::Matrix<T, DIM, 1 > & comp1,
                        const Eigen::Matrix<T, DIM, 1 > & comp2)
    {
      enum { coeff = DIM - COEFF };
      if (comp1[coeff] < comp2[coeff])
        {
          return true;
        }
      else
        {
          if (fabs (comp1[coeff] - comp2[coeff]) < std::numeric_limits<double>::min ())
            {
              return smallerThan < COEFF - 1, DIM, T>::result (comp1, comp2);
            }
          else
            {
              return false;
            }
        }
    }
  };

  template <unsigned int DIM, typename T>
  struct smallerThan < 1, DIM, T>
  {

    static bool result (const Eigen::Matrix<T, DIM, 1 > & comp1,
                        const Eigen::Matrix<T, DIM, 1 > & comp2)
    {
      enum { coeff = DIM - 1 };
      return comp1[coeff] < comp2[coeff];
    }
  };

  template <unsigned int DIM, typename T>
  bool
  aSmallerB (const Eigen::Matrix<T, DIM, 1 > & comp1,
             const Eigen::Matrix<T, DIM, 1 > & comp2)
  {
    return smallerThan <DIM, DIM, T>::result (comp1, comp2);
  }


One can pass i.e. aSmallerB<3, double> directly to std::sort or std::lower_bound.

Best regards

Matze


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell, Yahoo [Bot]