【问题标题】:Converting Rcpp NumericMatrix for use with Boost Geometry转换 Rcpp NumericMatrix 以与 Boost Geometry 一起使用
【发布时间】:2013-03-04 05:48:37
【问题描述】:

我发现如果没有 Rcpp 及其相关软件包为不同对象类型之间的转换提供的漂亮的 <as><wrap> 命令,我会迷失方向。

我有一个点矩阵,其中的行代表二维笛卡尔空间中的点:

 pointsMatrix <- matrix(runif(100,-1,1),50,50)

然后我想使用convex_hull algorithm from boost geometry 找到点的凸包。

但是,我不确定如何将NumericMatrix 转换为convex_hull 可以理解的数据类型之一。此外,我不确定如何将 Boost Geometry 的输出转换回 Rcpp 可以交回给 R 的东西。

 #include <Rcpp.h>
 #include <boost/geometry.hpp>
 #include <boost/geometry/geometries/polygon.hpp>
 using namespace Rcpp;

 BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)

 // [[Rcpp::export]]
 NumericMatrix convexHullRcpp(NumericMatrix pointsMatrix){

     typedef boost::tuple<double, double> point;
     typedef boost::geometry::model::polygon<point> polygon;

 // Some sort of conversion of pointsMatrix here to pointsMatrixBG//

     polygon hull;
     boost::geometry::convex_hull(pointsMatrixBG, hull);

     //Now to convert hull into something that Rcpp can hand back to R.//

  return hullToR;
 }

看来 boost.tuple 可能是最好的选择

【问题讨论】:

  • Rcpp-extending的指导下,也许你可以自己写一篇
  • 我对 Rcpp 了解不多,但我相信使用 Boost.Geometry 无需任何转换即可完成。 AFAIU 一些任意数据可以表示为 NumericMatrix。您可以实现一些视图/代理包装,例如对 NumericMatrix 的引用(仅用于以各种方式表示矩阵)。这些视图可以适应来自 Boost.Geometry - 多边形、线串等的各种几何概念。然后你可以将它传递给任意的 Boost.Geometry 算法,或多或少像这样:bg::convex_hull(view_as_polygon(pointsMatrix), view_as_polygon (hullToR))

标签: c++ r boost rcpp boost-geometry


【解决方案1】:

这是一个小小的 test.cpp 文件

#include <Rcpp.h>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

using namespace Rcpp;

typedef boost::geometry::model::d2::point_xy<double, boost::geometry::cs::cartesian> Point;
typedef boost::geometry::model::polygon<Point, true, true> Polygon; 

namespace Rcpp {
  template <> Polygon as(SEXP pointsMatrixSEXP) {
    NumericMatrix pointsMatrix(pointsMatrixSEXP);
    Polygon pointsMatrixBG;
    for (int i = 0; i < pointsMatrix.nrow(); ++i) {
      double x = pointsMatrix(i,0);
      double y = pointsMatrix(i,1);
      Point p(x,y);
      pointsMatrixBG.outer().push_back(p); 
    }
    return (pointsMatrixBG);
  } 

  template <> SEXP wrap(const Polygon& poly) {
    const std::vector<Point>& points = poly.outer();
    NumericMatrix rmat(points.size(), 2);
    for(int i = 0; i < points.size(); ++i) {
      const Point& p = points[i];
      rmat(i,0) = p.x();
      rmat(i,1) = p.y();
    }
    return Rcpp::wrap(rmat);
  }
}

// [[Rcpp::export]]
NumericMatrix convexHullRcpp(SEXP pointsMatrixSEXP){

  // Conversion of pointsMatrix here to pointsMatrixBG
  Polygon pointsMatrixBG = as<Polygon>(pointsMatrixSEXP);

  Polygon hull;
  boost::geometry::convex_hull(pointsMatrixBG, hull);

  //Now to convert hull into something that Rcpp can hand back to R.//
  return wrap(hull);
}

然后你可以在 R 中测试一下。

library(Rcpp)
sourceCpp("test.cpp")
points <- c(2.0, 1.3, 2.4, 1.7, 2.8, 1.8, 3.4, 1.2, 3.7, 1.6,3.4, 2.0, 4.1, 3.0, 5.3, 2.6, 5.4, 1.2, 4.9, 0.8, 2.9, 0.7,2.0, 1.3)
points.matrix <- matrix(points, ncol=2, byrow=TRUE)
> convexHullRcpp(points.matrix)
     [,1] [,2]
[1,]  2.0  1.3
[2,]  2.4  1.7
[3,]  4.1  3.0
[4,]  5.3  2.6
[5,]  5.4  1.2
[6,]  4.9  0.8
[7,]  2.9  0.7
[8,]  2.0  1.3

【讨论】:

  • 谢谢——做得很好。你想为 Rcpp Gallery 扩展它吗?
  • 我会尝试考虑如何将其推广到n维点,然后提交给Rcpp Gallery。
【解决方案2】:

一般来说,一旦你转到 R 不知道的类型,你需要构建自己的自定义转换器函数 as&lt;&gt;()wrap()

正如评论中所指出的,有一个完整的小插曲专门用于它。包中也有示例,例如this article in the Rcpp Gallery 关于自定义as&lt;&gt;()wrap()。我将从 C++ 中的 Boost Geometry 示例开始了解它们的数据结构是如何填充的,然后从我的 C++ 中填充它们。没有捷径可走。 没有免费的午餐定理仍然成立。

【讨论】:

  • 我已经通过Rcp Gallery exampleExtensions vignette。我想我就在整理东西的门口。我有一个快速的问题,可能会加快我的进度。 BH 包中的 aswrap 扩展在哪里?我在 RcppBDT 中看到了你是如何做到的,但在 BH 中看不到它。
  • 我假设这些必须在BH 的某个地方提供,因为当您运行replicate the RcppBDT functionality 的示例时。它似乎不需要来回转换就可以工作。事实证明,我需要的许多数据类型都在 BH 中,如果我理解了该包中的过程,那么为我需要与 boost::geometry 一起使用的其他几个类滚动我自己的 aswrap 应该直截了当。
  • 顺便说一句,您有计划将boost::geometry 包含在BH 中吗?需要做什么才能将其添加到BH
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多