Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize a Vector in Eigen3

Tags:

c++

eigen

eigen3

I'm wrapping two Eigen3 vectors in a templated LineSegment<T,dim> class. You might use it like this:

typedef LineSegment<double,2> LineSegment2d;
typedef LineSegment<double,3> LineSegment3d;
typedef LineSegment<int,3> LineSegment3i;

It contains a templated method to change the dimensions of the components. Here is the trimmed definition:

template<typename T,int dim>
struct LineSegment
{
public:
  template<int newDim>
  LineSegment<T,newDim> to() const
  {
    Eigen::Matrix<T,newDim,1> newp1;
    Eigen::Matrix<T,newDim,1> newp2;

    // TODO initialise newp1 and newp2 from d_p1 and d_p2

    return LineSegment<T,newDim>(newp1, newp2);
  }

  // ... other members ...

protected:
  Eigen::Matrix<T,dim,1> d_p1;
  Eigen::Matrix<T,dim,1> d_p2;
}

So my question is, how can I compose the return value, as shown above? This should support both increasing and decreasing the dimension.

I tried using the Eigen3 resize(int) method, but couldn't get it to work without seeing warnings about mixing matrix sizes.

Ultimately, this should work:

LineSegment2d ls2d;
LineSegment3d ls3d = ls2d.to<3>(); // increase dim
ls2d = ls3d.to<2>();               // decrease dim

I'm relatively new to C++ templates, and would appreciate a bit of explanation if this isn't just an API question and is related to templates.

like image 597
Drew Noakes Avatar asked Mar 18 '13 16:03

Drew Noakes


People also ask

How do you change the size of a vector?

We can set the size of a Vector using setSize() method of Vector class. If new size is greater than the current size then all the elements after current size index have null values. If new size is less than current size then the elements after current size index have been deleted from the Vector.

Can a vector be resized?

Vectors are known as dynamic arrays which can change its size automatically when an element is inserted or deleted.

How do I resize an eigen matrix?

Resizing. The current size of a matrix can be retrieved by rows(), cols() and size(). These methods return the number of rows, the number of columns and the number of coefficients, respectively. Resizing a dynamic-size matrix is done by the resize() method.


1 Answers

Firstly, Eigen's resize method reallocates memory if the new number of elements is not the same as the old, both when growing and when shrinking, so you would lose data in this case

The following method uses .head<int>(), which is Eigen3's version of .start<int>(), plus some template programming so you don't have to check whether you're shrinking or growing:

#include <Eigen/Core>

template <bool COND, int A, int B>
struct IF
{
  enum { val = A };
};

template <int A, int B>
struct IF<false, A, B>
{
  enum { val = B };
};

template <int A, int B>
struct MIN : IF<A < B, A, B>
{
};

template <typename T,int dim,int newDim>
Eigen::Matrix<T,newDim,1> to(Eigen::Matrix<T,dim,1> p)
{
  Eigen::Matrix<int,newDim,1> newp =
    Eigen::Matrix<T,newDim,1>::Zero();

  newp.template head< MIN<dim,newDim>::val >() =
    p.template head< MIN<dim,newDim>::val >();

  return newp;
}

Using this, the following program:

#include <iostream>

int main()
{
  Eigen::Vector2i p_2i(1,2);
  Eigen::Vector3i p_3i(3,4,5);

  std::cout << to<int, 2, 3>(p_2i) << std::endl << std::endl;
  std::cout << to<int, 3, 2>(p_3i) << std::endl << std::endl;

}

Gives as output:

1
2
0

3
4
like image 104
sgvd Avatar answered Sep 24 '22 01:09

sgvd