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

Colwise/Rowwise transformations with user defined Functors

Tags: None
(comma "," separated)
infinitei
Registered Member
Posts
4
Karma
0
Is there something like unaryExpr,which allows for applying a custom functor on each colum/row vector of a matrix. Maybe something like:
Code: Select all
mat = mat.colwise(functor)


I will illustrate my use case with the following example. Let me know if there is a better existing solution.
Say, I have a functor which works on single Vector point.
Code: Select all
template <typename Scalar, int Dimension>
struct RayAABBIntersection {
  typedef Eigen::Matrix<Scalar, Dimension, 1> VectorType;

template<class BoundingBoxType, class PointType>
  RayAABBIntersection(const BoundingBoxType& bbx, const PointType& ray_origin)
    :min_start(bbx.min() - ray_origin),
     max_start(bbx.max() - ray_origin),
     ray_origin(ray_origin) { }

  template<class PointType>
  VectorType operator()(const PointType& ray) const {
    const VectorType ray_inv = ray.cwiseInverse();
    const VectorType tmin = bbx_min_to_ray_origin_.cwiseProduct(ray_inv);
    const VectorType tmax = bbx_max_to_ray_origin_.cwiseProduct(ray_inv);
    return ray_origin + ray * tmin.cwiseMax(tmax).minCoeff();
  }

  VectorType ray_origin_;
  VectorType bbx_min_to_ray_origin_;
  VectorType bbx_max_to_ray_origin_;
};


Now I would like to reuse this functor and apply it on every columns of a matrix by writing something simple as :
Code: Select all
// Matrix<double, 3, Dynamic> rays; rays.setRandom(); rays.colwise().normalize();
MatrixXd intersections = rays.colwise(RayAABBIntersection<double, 3>(bbx, Vector3d::Zero()));


In this special case, another option might be to make RayAABBIntersection operator() more generic by allowing to work on matrix types like:
Code: Select all
template <typename Scalar, int Dimension>
struct RayAABBIntersection2 {
  typedef Eigen::Matrix<Scalar, Dimension, 1> VectorType;

template<class BoundingBoxType, class PointType>
  RayAABBIntersection2(const BoundingBoxType& bbx, const PointType& ray_origin)
    :min_start(bbx.min() - ray_origin),
     max_start(bbx.max() - ray_origin),
     ray_origin(ray_origin) { }

  template<class Derived>
  typename  Derived::PlainObject operator()(const Eigen::MatrixBase<Derived>& ray) const {
    PointCloudType ray_inv = rays.cwiseInverse();
    return (rays * (bbx_min_to_ray_origin_.asDiagonal() * ray_inv).cwiseMax(bbx_max_to_ray_origin_.asDiagonal() * ray_inv)
            .colwise().minCoeff().asDiagonal()
           ).colwise() + ray_origin;
  }

  VectorType ray_origin_;
  VectorType bbx_min_to_ray_origin_;
  VectorType bbx_max_to_ray_origin_;
};

However RayAABBIntersection2 is slower. For a matrix of size 3 X 10000000 applying RayAABBIntersection1 to each column takes 0.15s compared to 0.23s for RayAABBIntersection2 on my machine.

Is this a useful feature request, or is there a better way to write RayAABBIntersection2?


Bookmarks



Who is online

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