beachmat 2.2.1
本文档描述的使用beachmat在R矩阵API来存储数据。我们将演示API数字矩阵,虽然相同的语义用于矩阵的其他类型(如逻辑、整数、字符)。首先,我们包括相关的头文件:
# include“beachmat / numeric_matrix.h”
支持三种类型的输出矩阵——简单矩阵
,* gCMatrix
和HDF5Matrix
对象。例如,一个简单的数字输出矩阵nrow
行和ncol
列是由:
/ /返回一个std:: unique_ptr < numeric_output >对象汽车odptr = beachmat:: create_numeric_output (/ * size_t * / ncol nrow, / * size_t * / oparam / * beachmat:: output_param * /);
的beachmat: output_param
类指定了输出矩阵表示。它仅仅是通过构造类和包名称:
beachmat: output_param simple_param;beachmat: output_param simple_param2(“矩阵”、“基础”);/ *默认* / beachmat: output_param sparse_param (“dgCMatrix”、“矩阵”);
其他类/包组合可以由外部链接是否可用。否则,output_param
构造函数将默认为一个普通的矩阵。
另一个选择是允许函数来动态选择输出类型匹配现有的矩阵。这是用于自动选择一个输出格式,反映了输入格式的选择。例如,如果数据被提供给一个函数在一个简单的矩阵,将是合理的期望输出同样是小到可以存储为一个简单的矩阵。另一方面,如果输入文件备份,它表明,输出也可能非常大,因此需要文件备份存储。
动态的选择输出类型是通过使用来执行的Rcpp: Robject
包含输入矩阵初始化的对象output_param
对象。如果我们有一个矩阵对象质素
,输出类型可以匹配输入类型:
beachmat: output_param oparam(质素/ * Rcpp:: RObject * /);汽车odptr = beachmat:: create_numeric_output (nrow、ncol oparam);
类似的过程可用于一个指针焦度
到现有的* _matrix
实例:
beachmat: output_param oparam(焦度- > get_class(),焦度- > get_package ());
的set_col ()
填列方法c
与迭代器所指向的元素出
到一个Rcpp向量。c
应该是一个0的整数[0,ncol)
至少,应该有nrow
访问元素,即*出
和* (+ nrow-1)
应该有效的条目。
odptr - > set_col (c / * size_t * / / * Rcpp::向量::iterator * /);
出
可以迭代器吗Rcpp: NumericVector
,Rcpp: LogicalVector
或Rcpp: IntegerVector
;类型转换将发生预期输出矩阵的类型。没有通过此方法返回的值。
set_col ()
还可以使用吗第一个
和去年
参数。这将填补列c
从行第一个
来持续1
的条目*出
来* (+ last-first-1)
,分别。这两个第一个
和去年
应该在[0,nrow]
0,有额外的要求去年> =第一
。
odptr - > set_col (c / * size_t * / / * Rcpp::向量::iterator * /, / * size_t * / / * size_t * /);
的set_col_indexed ()
填列方法c
向量的元素从迭代器瓦尔
在一个向量行指数开始idx
。行指标可以无序和重复1但显然他们应该0。;以后将会覆盖之前的条目。注意,不执行检查理智的行索引。
odptr - > set_col_indexed (c、N / * size_t * / / * size_t * / idx, / * Rcpp:: IntegerVector:: iterator * / valm / * Rcpp::向量::iterator * /);
的set_row ()
方法填补了行r
与迭代器所指向的元素出
到一个Rcpp向量。r
应该是一个0的整数[0,nrow)
至少,应该有nrow
访问元素,即*出
和* (+ nrow-1)
应该有效的条目。没有返回值。
odptr - > set_row (r, / * size_t * / / * Rcpp::向量::iterator * /);
填写一系列的行可以与实现第一个
和去年
参数。这将填补行r
从列第一个
来持续1
的条目*出
来* (+ last-first-1)
,分别。这两个第一个
和去年
应该在[0,ncol]
0,有额外的要求去年> =第一
。
odptr - > set_row (r, / * size_t * /, / * Rcpp::向量::iterator * /, / * size_t * / / * size_t * /);
的set_row_indexed ()
方法填补了行r
向量的元素从迭代器瓦尔
在一个向量的列指数开始idx
。列指数可以无序和重复2再一次,0。;以后将会覆盖之前的条目。请注意,不执行检查的理智列索引。
odptr - > set_row_indexed (r / * size_t * / N / * size_t * / idx, / * Rcpp:: IntegerVector:: iterator * / val / * Rcpp::向量::iterator * /);
的设置()
方法行填充矩阵的条目r
和列c
双精度值Y
。这两个r
和c
应该是0的整数[0,nrow)
和[0,ncol)
分别。没有通过此方法返回的值。
odptr - >组(r / c * size_t * /, / * size_t * / Y / *双* /)
的产量()
方法返回一个Rcpp: RObject
对象包含一个矩阵通过R。
Rcpp:: RObject = odptr - >收益率();
这是常用的R的函数返回一个矩阵:
返回真倾角- >产量();
注意,此操作可能涉及一个R-level内存分配,可能随后触发垃圾回收。这通常不是一个问题Rcpp很好,防止意外的对象集合。然而,一个例外是随机数生成,破坏的地方Rcpp: RNGScope
可能触发的保护饱和度指数
年代。这将几乎总是在使用产量()
天真的,如矩阵的构造饱和度指数
完成的功能:
/ /可能的段错误:外来的“C”饱和度指数dummy1(){汽车odptr = beachmat:: create_numeric_output (nrow、ncol beachmat:: output_param ());Rcpp: RNGScope rng;/ /做某事odptr随机数和存储。返回odptr - >产量();}
一个解决方案是限制的范围Rcpp: RNGScope
。这将确保没有不受保护的饱和度指数
对象的破坏RNGScope
,因为产量()
还没有被调用。
外来的“C”饱和度指数dummy2(){汽车odptr = beachmat:: create_numeric_output (nrow、ncol beachmat:: output_param ());{Rcpp:: RNGScope rng;/ /做某事odptr随机数和存储。}返回odptr - >产量();}
访问方法也被用来实现的一个子集* _output
对象:
get_nrow ()
和get_ncol ()
get_row ()
,get_col ()
和get ()
get_class ()
,get_package ()
和克隆()
。这些方法所描述的行为以前为* _matrix
对象。的情况下他们可能有用数据都存储在一个中间矩阵和矩阵之前需要查询完全填满。
不过,在大多数应用程序中,可以完全填充输出矩阵,电话产量()
然后创建一个numeric_matrix
从产生的Rcpp: RObject
。这通常是更快,因为某些优化成为可能beachmat知道提供的矩阵是只读的(例如,get_const_col ()
和get_const_col_indexed ()
)。
支持逻辑、整数、字符输出矩阵通过改变类型的创造者函数(和它的变体):
/ /返回一个std:: unique_ptr < integer_output >汽车oimat = beachmat:: create_integer_output (nrow、ncol beachmat:: output_param ());/ /返回一个std:: unique_ptr < logical_output >汽车olmat = beachmat:: create_logical_output (nrow、ncol beachmat:: output_param ());/ /返回一个std:: unique_ptr < character_output >汽车ocmat = beachmat:: create_character_output (nrow、ncol beachmat:: output_param ());
为整数,逻辑和数字矩阵,出
可以迭代器吗Rcpp: NumericVector
,Rcpp: IntegerVector
或Rcpp: LogicalVector
对象。整数和逻辑矩阵,Y
应该是一个整数。对于字符矩阵,出
应的类型Rcpp: StringVector:: iterator
和Y
应该是一个Rcpp:字符串
对象。
额外的笔记
Rcpp: LogicalVector:: iterator
作为出
当存储数据logical_output
。这是因为在c++级别类型转换将不会提供相同的结果作为转换在R级。API不是线程安全的,因为(i)使用缓存的类成员和(2)潜在的竞态条件当写入磁盘上的同一位置/内存。第一个问题可以通过使用解决克隆()
创建* _output
在每个线程使用副本3除了HDF5矩阵,看到评论在这里。。然而,每个副本可能仍然读取和写入相同的磁盘/内存位置。此外,即使每个副本写入不同的行或列,他们不能保证影响记忆的不同部分。(存储稀疏矩阵的行,例如,依赖于前一行的性质。)因此调用函数的责任,以确保适当的访问被锁定,解锁跨多个线程,例如,通过# pragma omp至关重要
。