c - 将动态 vector 从 C 返回到 R

标签 c r data-structures random poisson

我正在用 C 编写一些代码,以便从 R 动态调用。

此代码生成随机泊松过程的路径,直至所需时间 T。 因此,在每次调用我的 C 函数时,返回的 vector 的长度将根据生成的随机数而有所不同。

我必须创建什么 R 数据结构? LISTSXP?另一个?

我如何创建它,如何附加到它?尤其是我怎样才能把它还给 R?

感谢您的帮助。

最佳答案

将什么用作临时结构完全取决于您,因为最终您无论如何都必须为结果分配一个 vector 。因此,无论您将使用什么,都不会返回。有几种可能:

  1. 使用Calloc + Realloc + Free 允许您根据需要扩展临时内存。获得完整集合后,分配结果 vector 并将其返回。
  2. 如果您可以轻易地高估大小,则可以过度分配结果 vector 并在返回之前使用 SETLENGTH。但是,这存在一些问题,因为结果将保持过度分配,直到稍后复制。
  3. 您可以使用您所暗示的 vector block 链表,即分配和保护一对列表,您可以根据需要将 vector 附加到尾部。最后,您分配返回 vector 并复制您分配的 block 的内容。这比上述两者都更复杂。

它们各有优缺点,因此真正取决于您的应用来选择最适合您的。

编辑:添加了一个使用配对列表方法的示例。我仍然会推荐 Realloc 方法,因为它更容易,但是:

#define BLOCK_SIZE xxx /* some reasonable size for increments - could be adaptive, too */ 
SEXP block; /* last vector block */
SEXP root = PROTECT(list1(block = allocVector(REALSXP, BLOCK_SIZE)));
SEXP tail = root;
double *values = REAL(block);
int count = 0, total = 0;
do { /* your code to generate values - if you want to add one 
        first try to add it to the existing block, otherwise allocate new one */
    if (count == BLOCK_SIZE) { /* add a new block when needed */
        tail = SETCDR(tail, list1(block = allocVector(REALSXP, BLOCK_SIZE)));
        values = REAL(block);
        total += count;
        count = 0;
    }
    values[count++] = next_value;
} while (...);
total += count;
/* when done, we need to create the result vector */
{
    SEXP res = allocVector(REALSXP, total);
    double *res_values = REAL(res);
    while (root != R_NilValue) {
        int size = (CDR(root) == R_NilValue) ? count : BLOCK_SIZE;
        memcpy(res_values, REAL(CAR(root)), sizeof(double) * size);
        res_values += size;
        root = CDR(root);
    }
    UNPROTECT(1);
    return res;
 }

关于c - 将动态 vector 从 C 返回到 R,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8796675/

相关文章:

algorithm - 分块 map 的数据结构

algorithm - 当维基百科说在动态数组末尾插入一个项目的复杂性是 O(1) 摊销时,它是什么意思?

c - 一个 socket 双堆栈

C 期望标识符或 ‘(’ 在 ‘{’ 之前

c - 使用自定义系统调用时出现 undefined reference 错误

r - 让 facet_grid 中的每个图都有自己的 Y 轴值

r - 初始化 data.frames()

r - 空行作为 block 数据分隔符

C - 在word中搜索一个字母

c# - 填充数组以避免索引超出数组错误边界的方法