1背景

注意:这个文件是指版本2的beachmatAPI,它仍然支持但不再正在积极开发之中。bob电竞体育官网鼓励开发人员编写新的代码使用版本3,这是更加精简。

通常,直接支持矩阵表示需要适当的方法定义beachmat在编译时间。这是使用最广泛的矩阵类但有点限制其他提供了数以千计的矩阵表示。幸运的是,R跨共享库提供了一种机制将从不同的包。这意味着包开发人员定义一个R矩阵表示还可以定义本bob电竞体育官网地c++方法读/写的支持beachmat端依赖代码。通过这样做,我们可以提高效率获得这些新类通过R通过避免块处理的必要性。

一个功能演示这种方法是可用的扩展测试包。这个描述中的代码将提供一个解释扩展,我们建议在同一时间检查源代码:

系统。文件(“扩展”,包=“beachmat”)
# # [1]“/ tmp / RtmphAMjmS / Rinst7c87b6092a494 / beachmat /扩展”

2外部链接输入

2.1在R中设置

假设我们已经定义了一个新的矩阵像S4类(在这里,AaronMatrix)。通知beachmat直接输入支持的API是可用的,我们需要:

  • 定义一个方法supportCppAccess ()通用(从beachmat这个类)。这应该返回真正的如果直接支持可用(很明显)。
  • 定义一个方法类型()通用的DelayedArray包中。这应该返回的类型矩阵,即。、整数、逻辑、数字或字符。

有可能只有直接支持特定数据类型的给定的矩阵表示。中的例子扩展只有直接支持整数和性格AaronMatrix对象1因为我太懒添加他们所有人。并将只返回真正的这样的类型。

2.2设置在c++中

我们将使用整数矩阵为示范,尽管它很简单概括所有类型代替_integer,例如,_character2一些c++模板的理解将会大大简化的定义不同类型的相同的方法。。首先,我们定义了一个create ()函数接受一个饱和度指数对象,并返回一个无效指针。这应该可能指向一些c++类可以包含中间数据结构有效的访问。

void * ptr = AaronMatrix_integer_input_create(在/ *饱和度指数* /);

我们定义了一个克隆()函数执行上述深拷贝指针。

void * ptr_copy = AaronMatrix_integer_input_clone (ptr / * void * * /);

我们定义了一个destroy ()函数释放指向的内存ptr

AaronMatrix_integer_input_destroy (ptr / * void * * /);

我们定义了一个get_dim ()函数,记录的行数和列所指向的对象ptr。注意指针nrowncol

AaronMatrix_integer_input_dim (ptr, void * / * * / nrow, / * size_t * * / ncol / * size_t * * /);

系统命名方案用于所有功能,包括:

  • 矩阵表示的名称,即AaronMatrix
  • 数据类型,即整数
  • 是否它是一个输入输出类。
  • 函数的目的,例如,摧毁

2.3定义getter方法

2.3.1对所有类型

一般来说,getter函数遵循相同的结构的描述输入API。我们预计得到矩阵的函数来获取指定的条目:

AaronMatrix_integer_intput_get (ptr, void * / * * / r, / * size_t * / c / * size_t * / val / * int * * /);

请注意,瓦尔是一个指针矩阵类型。例如,瓦尔应该是一个Rcpp:字符串*对于字符矩阵,双*数字矩阵,和一个int *对逻辑矩阵。

bob电竞体育官网开发人员可以假设rc是有效的,也就是说。内,[0,nrow)[0,ncol)分别。这些检查是执行的beachmat和不需要重复在通过功能3显然,指出矩阵的维度ptr不应该改变!

2.3.2非数字类型

在这里,我们将使用字符矩阵4字符矩阵往往需要特别注意,因为字符数组需要强迫Rcpp:字符串对象中返回作为一个例子。我们预计getCol函数来获得一个列的矩阵:

AaronMatrix_character_input_getCol (ptr, void * / * * / c / * size_t * /, / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

…,另一个getRow函数来获得一个矩阵的行:

AaronMatrix_character_input_getRow (ptr, void * / * * / r, / * size_t * / * / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

这些都是在camelcase简化解析函数的名称。我们进一步期待getCols函数获取多个列:

AaronMatrix_character_input_getCols (ptr, void * / * * / c / * size_t * /指标,/ * Rcpp:: IntegerVector:: iterator * * / n, / * size_t * /, / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

…和一个getRows函数获取多行:

AaronMatrix_character_input_getRows (ptr, void * / * * / r, / * size_t * /指标,/ * Rcpp:: IntegerVector:: iterator * * / n, / * size_t * /, / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

在所有情况下,第一个去年可以认为是有效的,即姓< =和两个[0,nrow)[0,ncol)(分别为列和行访问)。指数在指数也可以认为是有效的,即内,matrix dimensions and strictly increasing.

我们强调不同的迭代器参数迭代器的指针而不是自己的迭代器。这是为了避免潜在问题与c++类使用时通过R C风格的链接R_GetCCallable ()框架。

2.3.3数值类型

为整数,逻辑或数字矩阵,我们需要考虑类型转换。这是通过定义以下功能(使用整数矩阵为例):

  • 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 * /, / * Rcpp:: IntegerVector:: iterator * * /, / * size_t去年/ * size_t * / * /);AaronMatrix_integer_input_getCol_numeric (ptr, void * / * * / c / * size_t * /, / * Rcpp:: NumericVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

函数名现在有一个额外的后缀表示目的地类型。这里我们明确定义转换cross-library链接框架不支持模板或重载

3外部链接输出

3.1在R中设置

通知beachmatAPI直接输出支持是可用的,我们需要定义旗帜在我们包的名称空间。

beachmat_AaronMatrix_integer_output < -真的beachmat_AaronMatrix_character_output < -真的

这表明支持AaronMatrix整型和字符输出。缺失或国旗表明不支持是可用的,在这种情况下beachmat默认情况下将写一个普通的矩阵。

3.2设置在c++中

再一次,我们将使用整数矩阵用于演示。所需的功能主要是类似于输入情况。为创造,我们预计的行数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_表明我们正在处理一个输出矩阵类。

3.3定义setter方法

3.3.1对所有类型

一般来说,setter函数遵循相同的结构的描述从API。我们预计矩阵的函数来获取指定的条目:

AaronMatrix_integer_intput_set (ptr, void * / * * / r, / * size_t * / c / * size_t * / val / * int * * /);

再一次,请注意,瓦尔是一个指针矩阵类型。

3.3.2非数字类型

在这里,我们将使用字符矩阵5字符矩阵往往需要特别注意,因为字符数组需要强迫Rcpp:字符串对象中返回作为一个例子。我们预计setCol函数来获得一个列的矩阵:

AaronMatrix_character_output_setCol (ptr, void * / * * / c / * size_t * /, / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

…,另一个setRow函数来获得一个矩阵的行:

AaronMatrix_character_output_setRow (ptr, void * / * * / r, / * size_t * / * / * Rcpp:: StringVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

这些都是在camelcase简化解析函数的名称。我们进一步期待setColIndexed函数设置特定元素的列:

AaronMatrix_character_output_setColIndexed (ptr、/ * void * / c、n / * size_t * /, / * size_t * / idx, / * Rcpp:: IntegerVector:: iterator * / / * Rcpp:: StringVector:: iterator * /)

在…idx指向数组n0行指数和瓦尔指向一个数组的值。这个函数应该将每个值分配给相应的行,列c的输出矩阵。

同样,我们预计setRowIndexed函数设置特定元素的行:

AaronMatrix_character_output_setRowIndexed (ptr, void * / * / r / * size_t * / n, / * size_t * / idx, / * Rcpp:: IntegerVector:: iterator * / / * Rcpp:: StringVector:: iterator * /)

在…idx现在包含列索引。

3.3.3数值类型

为整数,逻辑或数字矩阵,我们需要考虑类型转换。这是通过定义以下功能(使用整数矩阵为例):

  • 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 * /, / * Rcpp:: IntegerVector:: iterator * * /, / * size_t去年/ * size_t * / * /);AaronMatrix_integer_output_setCol_numeric (ptr, void * / * * / c / * size_t * /, / * Rcpp:: NumericVector:: iterator * * /, / * size_t去年/ * size_t * / * /);

3.4定义getter方法

所有的单个元素和单行/列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

4确保可发现性

我们使用R_RegisterCCallable ()R的函数API注册(见上面的函数在这里一个解释)。这可以确保他们可以找到beachmat当一个AaronMatrix实例。注意,必须定义函数与c风格的链接为了这个过程正常工作,因此使用外来的“C”扩展测试包。

不用说,名称空间应该包含一个适当的useDynLib命令。这意味着将加载共享库的方案,允许beachmat进入注册程序。然而,supportCppAccess方法和输出标记不需要出口,因为这些将直接从包的名称空间中恢复过来。

5测试

我们建议使用beachtest包测试正确输入和输出通过外部链接自定义矩阵表示。当使用testthat框架,这可以添加setup.R:

testpkg < -系统。文件(“testpkg”,包=“beachmat”) devtools::安装(testpkg,快= TRUE)库(beachtest)

是简单的使用功能编写测试脚本check_read_allcheck_write_all快速验证链接工作正常。bob电竞体育官网开发人员再次提到了扩展为一个工作示例测试包。