beachmat 2.14.0
注:本文档参考第2版beachmatAPI,它仍然受到支持,但不再处于积极的开发中。bob电竞体育官网鼓励编写新代码的开发人员使用版本3,它更加简化。
通常,直接支持矩阵表示需要在中定义适当的方法beachmat在编译时。这是最广泛使用的矩阵类的情况,但对其他社区贡献的矩阵表示有一定的限制。幸运的是,R提供了一种机制来链接来自不同包的共享库。这意味着定义R矩阵表示的包开发人员也可以定义c+bob电竞体育官网+方法,以支持在beachmat端依赖代码。通过这样做,我们可以通过避免通过R进行块处理来提高访问这些新类的效率。
该方法的功能演示可在扩展
测试包。这篇短文将解释扩展
,我们建议同时检查源代码:
系统。文件(“扩展”,包=“beachmat”)
## [1] "/tmp/RtmpvcXcVI/Rinst3cc67a28eaa669/beachmat/extensions"
假设我们已经定义了一个新的类似矩阵的S4类(这里,AaronMatrix
).通知beachmatAPI,直接输入支持可用,我们需要:
supportCppAccess ()
通用(从beachmat)。这应该会返回真正的
如果直接支持是可用的(显然)。类型()
通用的DelayedArray包中。这应该返回矩阵的类型,即整数、逻辑、数字或字符。可能只对给定矩阵表示的特定数据类型提供直接支持。例子是扩展
仅直接支持整数和字符AaronMatrix
对象1因为我懒得把它们都加起来。只会回来真正的
对于这样的类型。
我们将使用整数矩阵进行演示,不过通过替换将其推广到所有类型很简单_integer
,例如,_character
2对c++模板的一些理解将极大地简化不同类型的相同方法的定义。.首先,我们定义acreate ()
函数,该函数接受饱和度指数
对象,并返回无效
指针。这应该指向一些c++类,该类可以包含用于有效访问的中间数据结构。
void * ptr = AaronMatrix_integer_input_create(in /* SEXP */);
我们定义一个克隆()
函数执行上述指针的深度复制。
void* ptr_copy = AaronMatrix_integer_input_clone(ptr /* void* */);
我们定义一个destroy ()
函数释放指向的内存ptr
.
AaronMatrix_integer_input_destroy(ptr /* void* */);
我们定义一个get_dim ()
函数记录由所指向的对象中的行数和列数ptr
.注意nrow
而且ncol
.
AaronMatrix_integer_input_dim(ptr, /* void* */ nrow, /* size_t* */ ncol /* size_t* */);
所有功能都采用系统的命名方案,包括:
AaronMatrix
.整数
.输入
或输出
类。摧毁
.类所描述的getter函数通常遵循相同的结构输入API.我们期待得到
函数获取矩阵的指定项:
AaronMatrix_integer_intput_get(ptr, /* void* */ r, /* size_t */ c, /* size_t */ val /* int* */);
请注意,瓦尔
是一个指针到矩阵类型。例如,瓦尔
应该是Rcpp:字符串*
对于字符矩阵,a双*
对于数值矩阵,和int *
对于逻辑矩阵。
bob电竞体育官网开发人员可以假设r
而且c
是有效的,即,在[0, nrow)
而且[0, ncol)
分别。这些检查由beachmat并且不必在开发人员定义的函数中重复3.显然,矩阵的维数指向ptr
不应该改变!.
在这里,我们将使用字符矩阵4字符矩阵往往需要特别注意,因为字符数组需要强制转换为Rcpp:字符串
中返回的对象在
.举个例子。我们期待getCol
函数获取矩阵的一列:
AaronMatrix_character_input_getCol(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
……另一个getRow
函数获取矩阵中的一行:
AaronMatrix_character_input_getRow(ptr, /* void* */ r, /* size_t */ in*, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
它们采用驼峰格式,以简化函数名的解析。我们进一步期望getCols
函数获取多个列:
AaronMatrix_character_input_getCols(ptr, /* void* */ c, /* size_t */ indexes, /* Rcpp::IntegerVector::iterator* */ n, /* size_t */ in, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
…和一个getRows
函数获取多行:
AaronMatrix_character_input_getRows(ptr, /* void* */ r, /* size_t */ indexes, /* Rcpp::IntegerVector::iterator* */ n, /* size_t */ in, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
在所有情况下,第一个
而且最后的
都是有效的,也就是说,第一<=最后
两者都在[0, nrow)
或[0, ncol)
(分别用于列和行访问)。指数在指数
也可以假设是有效的,即在矩阵维内且严格递增。
我们强调不同的迭代器参数是指向迭代器的指针而不是迭代器本身。这是为了避免c++类在通过R使用C风格的链接时出现潜在的问题R_GetCCallable ()
框架。
对于整数、逻辑或数字矩阵,我们需要考虑类型转换。这可以通过定义以下函数来实现(以整数矩阵为例):
AaronMatrix_integer_input_getCol_integer
,用于以整数形式获取单个列的值。AaronMatrix_integer_input_getCol_numeric
,用于将单列的值作为双精度值获取。AaronMatrix_integer_input_getRow_integer
,用于获取作为整数的单行值。AaronMatrix_integer_input_getRow_numeric
,用于将单行的值作为双精度值获取。AaronMatrix_integer_input_getCols_integer
,用于以整数形式获取多列的值。AaronMatrix_integer_input_getCols_numeric
,用于将多列的值作为双精度值获取。AaronMatrix_integer_input_getRows_integer
,用于以整数形式获取多行值。AaronMatrix_integer_input_getRows_numeric
,用于将多行值作为双精度值获取。以单列getter为例:
AaronMatrix_integer_input_getCol_integer(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::IntegerVector::iterator* */ first, /* size_t */ last /* size_t */);AaronMatrix_integer_input_getCol_numeric(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::NumericVector::iterator* */ first, /* size_t */ last /* size_t */);
函数名现在有一个额外的后缀来表示目标类型。我们在这里显式地定义转换,因为跨库链接框架不支持的模板或重载在
.
通知beachmat如果API支持直接输出,我们需要在包的命名空间中定义标志。
beachmat_AaronMatrix_integer_output <- TRUE beachmat_AaronMatrix_character_output <- TRUE
这表明支持可用于AaronMatrix
整数和字符输出。缺失或假
在这种情况下,标志表示没有可用的支持beachmat默认情况下将写入普通矩阵。
同样,我们将使用整数矩阵进行演示。所需的函数大多类似于输入情况。对于创建,我们期望有行数nr
和列数控
:
void * ptr = AaronMatrix_integer_output_create(nr /* size_t */, nc /* size_t */);
我们定义一个克隆()
函数执行深度拷贝:
void* ptr_copy = AaronMatrix_integer_output_clone(ptr /* void* */);
我们还定义了destroy ()
释放内存的函数:
AaronMatrix_integer_output_destroy(ptr /* void* */);
在所有情况下,我们使用_output_
表示我们处理的是一个输出矩阵类。
类中所描述的setter函数遵循相同的结构从API.我们期待集
函数获取矩阵的指定项:
AaronMatrix_integer_intput_set(ptr, /* void* */ r, /* size_t */ c, /* size_t */ val /* int* */);
请再次注意瓦尔
是一个指针到矩阵类型。
在这里,我们将使用字符矩阵5字符矩阵往往需要特别注意,因为字符数组需要强制转换为Rcpp:字符串
中返回的对象在
.举个例子。我们期待setCol
函数获取矩阵的一列:
AaronMatrix_character_output_setCol(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
……另一个setRow
函数获取矩阵中的一行:
AaronMatrix_character_output_setRow(ptr, /* void* */ r, /* size_t */ in*, /* Rcpp::StringVector::iterator* */ first, /* size_t */ last /* size_t */);
它们采用驼峰格式,以简化函数名的解析。我们进一步期望setColIndexed
函数设置列的特定元素:
AaronMatrix_character_output_setColIndexed(ptr, /* void */ c, /* size_t */ n, /* size_t */ idx, /* Rcpp::IntegerVector::iterator */ in /* Rcpp::StringVector::iterator */)
…idx
的数组n
零索引的行索引和瓦尔
指向一个值数组。该函数应将每个值赋给列对应的行c
输出矩阵的。
同样,我们期望asetRowIndexed
函数设置一行中的特定元素:
AaronMatrix_character_output_setRowIndexed(ptr, /* void */ r, /* size_t */ n, /* size_t */ idx, /* Rcpp::IntegerVector::iterator */ in /* Rcpp::StringVector::iterator */)
…idx
现在包含列索引。
对于整数、逻辑或数字矩阵,我们需要考虑类型转换。这可以通过定义以下函数来实现(以整数矩阵为例):
AaronMatrix_integer_output_setCol_integer
,用于从整数中设置单个列的值。AaronMatrix_integer_output_setCol_numeric
,用于从双精度值设置单列的值。AaronMatrix_integer_output_setRow_integer
,用于从整数中设置单行的值。AaronMatrix_integer_output_setRow_numeric
,用于从双精度值设置单行值。AaronMatrix_integer_output_setColIndexed_integer
,用于从整数中索引单个列的值。AaronMatrix_integer_output_setColIndexed_numeric
,用于从双精度值到单列值的索引设置。AaronMatrix_integer_output_setRowIndexed_integer
,用于从整数中索引单行值的设置。AaronMatrix_integer_output_setRowIndexed_numeric
,用于从双精度值到单行值的索引设置以单列setter为例:
AaronMatrix_integer_output_setCol_integer(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::IntegerVector::iterator* */ first, /* size_t */ last /* size_t */);AaronMatrix_integer_output_setCol_numeric(ptr, /* void* */ c, /* size_t */ in, /* Rcpp::NumericVector::iterator* */ first, /* size_t */ last /* size_t */);
应该支持所有单元素和单行/列getter:
AaronMatrix_character_output_get
AaronMatrix_character_output_getRow
AaronMatrix_character_output_getCol
对于数字类型,也应该支持可转换getter:
AaronMatrix_character_output_get
AaronMatrix_character_output_getRow_integer
AaronMatrix_character_output_getRow_numeric
AaronMatrix_character_output_getCol_integer
AaronMatrix_character_output_getCol_numeric
我们使用R_RegisterCCallable ()
函数来注册上面的函数(参见在这里为了一个解释)。这样可以确保通过beachmat当一个AaronMatrix
实例。注意,函数必须用c风格的链接定义,以便此过程能够正常工作,因此使用外来的“C”
在扩展
测试包。
不用说,名称空间
应该包含适当的useDynLib
命令。这意味着共享库将与包一起加载,允许beachmat以访问内部的已注册例程。然而,supportCppAccess
方法和输出标志不需要导出,因为它们将直接从包的命名空间中恢复。
我们建议使用beachtest包来测试通过外部链接到自定义矩阵表示的正确输入和输出。当使用testthat框架,这可以添加到设置。R
:
Testpkg <- system。devtools::install(testpkg, quick=TRUE) library(beachtest)
使用类似的函数来编写测试脚本是很简单的check_read_all
而且check_write_all
快速验证链接是否正确工作。bob电竞体育官网开发人员再次被提及扩展
测试包的工作示例。