1输出API的概述

本文档描述的使用beachmat在R矩阵API来存储数据。我们将演示API数字矩阵,虽然相同的语义用于矩阵的其他类型(如逻辑、整数、字符)。首先,我们包括相关的头文件:

# include“beachmat / numeric_matrix.h”

支持三种类型的输出矩阵——简单矩阵,* gCMatrixHDF5Matrix对象。例如,一个简单的数字输出矩阵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构造函数将默认为一个普通的矩阵。

2动态选择输出类型

另一个选择是允许函数来动态选择输出类型匹配现有的矩阵。这是用于自动选择一个输出格式,反映了输入格式的选择。例如,如果数据被提供给一个函数在一个简单的矩阵,将是合理的期望输出同样是小到可以存储为一个简单的矩阵。另一方面,如果输入文件备份,它表明,输出也可能非常大,因此需要文件备份存储。

动态的选择输出类型是通过使用来执行的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 ());

3方法来存储数据

3.1存储数据的列

set_col ()填列方法c与迭代器所指向的元素到一个Rcpp向量。c应该是一个0的整数[0,ncol)至少,应该有nrow访问元素,即*出* (+ nrow-1)应该有效的条目。

odptr - > set_col (c / * size_t * / / * Rcpp::向量::iterator * /);

可以迭代器吗Rcpp: NumericVector,Rcpp: LogicalVectorRcpp: 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 * /);

3.2存储数据的行

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 * /);

3.3将数据存储在单个细胞

设置()方法行填充矩阵的条目r和列c双精度值Y。这两个rc应该是0的整数[0,nrow)[0,ncol)分别。没有通过此方法返回的值。

odptr - >组(r / c * size_t * /, / * size_t * / Y / *双* /)

4返回一个对象到R矩阵

产量()方法返回一个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 - >产量();}

5读取数据的方法

访问方法也被用来实现的一个子集* _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 ())。

6其他类型的矩阵

支持逻辑、整数、字符输出矩阵通过改变类型的创造者函数(和它的变体):

/ /返回一个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: IntegerVectorRcpp: LogicalVector对象。整数和逻辑矩阵,Y应该是一个整数。对于字符矩阵,应的类型Rcpp: StringVector:: iteratorY应该是一个Rcpp:字符串对象。

额外的笔记

  • 类似于这个问题进行了讨论以前除了使用,它可能是不明智的Rcpp: LogicalVector:: iterator作为当存储数据logical_output。这是因为在c++级别类型转换将不会提供相同的结果作为转换在R级。

7并行化处理

API不是线程安全的,因为(i)使用缓存的类成员和(2)潜在的竞态条件当写入磁盘上的同一位置/内存。第一个问题可以通过使用解决克隆()创建* _output在每个线程使用副本3除了HDF5矩阵,看到评论在这里。然而,每个副本可能仍然读取和写入相同的磁盘/内存位置。此外,即使每个副本写入不同的行或列,他们不能保证影响记忆的不同部分。(存储稀疏矩阵的行,例如,依赖于前一行的性质。)因此调用函数的责任,以确保适当的访问被锁定,解锁跨多个线程,例如,通过# pragma omp至关重要