转换Rcpp NumericMatrix与Boost几何使用
Converting Rcpp NumericMatrix for use with Boost Geometry
我发现如果没有Rcpp及其相关包提供的用于不同对象类型之间转换的漂亮的<as>
和<wrap>
命令,我就迷失了。
我有一个点矩阵,其行表示二维笛卡尔空间中的点:
pointsMatrix <- matrix(runif(100,-1,1),50,50)
然后我想使用boost geometry中的convex_hull算法来查找点的凸壳。
然而,我不确定如何将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。元组可能是最好的选择
这是一个小小的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
一般来说,一旦您转到R不知道的类型,您需要构建自己的自定义转换函数as<>()
和wrap()
。
正如评论中所指出的,有一个完整的小插图专门讨论它。在包中以及Rcpp库中的这篇文章中也有关于自定义as<>()
和wrap()
的示例。我会从c++中的Boost Geometry示例开始了解它们的数据结构是如何填充的,然后从我的c++中填充它们。没有捷径可走。天下没有免费的午餐定理仍然成立。
相关文章:
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 使用 boost 进行标记化会给出相同的输出
- 如何使用 Boost Asio 在 Android 上获取我的本地 udp IP 地址?
- 在成员dynamic_bitset上使用 boost::from_block_range 时出错,但在本地dynamic
- 执行时使用 boost::asio::d eadline_timer 时出错
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?
- 避免使用 boost::进程间::消息队列创建文件
- 使用Boost文件系统C++将具有特定扩展名的文件的名称保存在特定文件夹中
- 程序崩溃使用boost::asio
- 如何使用 boost beast websocket 客户端收听 websocket feed?
- 在 Julia 中使用 boost 库和 Windows 上的 Cxx.jl
- 如何使用 boost 将流放入缓冲区
- 使用boost::multiprecision cpp_int左移时出现超时错误
- 使用 boost::p rogram_options 指定多个标志
- TCP 服务器的异步读取使用 boost::asio 打印客户端套接字发送的数据
- yum :在 CentOS 上使用 Boost 1.69 而不是默认 (1.53) 版本
- 使用 boost::p roperty_tree::p tree 如何获取特定键的值
- 如何在使用 Boost MSM 编写的状态机中直接访问任何状态