Reputation: 31
I came across the problem that I want to convert from a std::vector<Eigen::Vector3d>
to a std::vector<Eigen::Vector3f>
. I was wondering if there is a solution where I dont have to iterate over the points.
// mapping using iteration
std::vector< Eigen::Vector3d> tf{ {1,1,1},{1,1,1},{1,1,1} };
std::vector< Eigen::Vector3f> tf2;
tf2.reserve(tf.size());
std::transform(tf.begin(), tf.end(), std::back_inserter(tf2), [](const Eigen::Vector3d& p) {
return p.cast<float>();
});
I tried some things like tf.data()
and tried to cast that, but I didnt found a solution. I also looked into Eigen::Map<>
class, but didnt really find a solution.
Upvotes: 3
Views: 2078
Reputation: 18807
Assuming Vector3d
and Vector3f
don't introduce any padding (which is true for all compilers which Eigen supports), you could use an Eigen::Map<const Matrix3Xd>
and .cast<float>()
that into an Eigen::Map<Matrix3Xf>
over the destination vector:
std::vector< Eigen::Vector3d> tf{ {1,1,1},{1,1,1},{1,1,1} };
std::vector< Eigen::Vector3f> tf2(tf.size()); // target needs to be actually allocated
Eigen::Matrix3Xf::Map(tf2[0].data(), 3, tf2.size())
= Eigen::Matrix3Xd::Map(tf[0].data(), 3, tf.size()).cast<float>();
With the upcoming 3.4 branch of Eigen you can also use iterators over the casted-map, like so:
Eigen::Map<Eigen::Matrix3Xd> input(tf[0].data(), 3, tf.size());
std::vector<Eigen::Vector3f> tf2(input.cast<float>().colwise().begin(),
input.cast<float>().colwise().end());
Upvotes: 0
Reputation: 2438
I don't think what you are asking is possible. Eigen::Map
allows you to construct an Eigen data structure without needing to copy or move, it merely takes a view on existing contiguous data (typically from a std::array
or std::vector
). The operation you are looking to do, casting from doubles to float, two distinct types with different memory layouts, is an explicit operation. You would be shrinking the size of the vector in half. It is not possible to achieve this by taking a different view on the same data.
Upvotes: 3