gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 16:49:02 24 4
gpt4 key购买 nike

我正在用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com