加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将动态向量从C返回到R

发布时间:2020-12-16 05:27:04 所属栏目:百科 来源:网络整理
导读:我在C中写一些代码可以从R动态调用. 该代码生成直到所需时间T的随机泊松过程的路径. 所以在每次调用我的C函数时,返回的向量的长度将根据生成的随机数而不同. 我必须创建什么R数据结构?一个LISTSXP?另一个? 如何创建它,如何追加?特别是如何把它还给R? 感
我在C中写一些代码可以从R动态调用.

该代码生成直到所需时间T的随机泊松过程的路径.
所以在每次调用我的C函数时,返回的向量的长度将根据生成的随机数而不同.

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

如何创建它,如何追加?特别是如何把它还给R?

感谢帮助.

解决方法

这真的取决于你想要用作临时结构,因为最终你必须为结果分配一个向量.所以无论你使用什么都不是你会回来的.有几种可能性:

>使用Calloc Realloc Free,它允许您根据需要扩展临时内存.一旦你有完整的集合,你分配结果向量并返回.
>如果您可以轻松地高估大小,则可以在返回结果向量之前过度分配结果向量并使用SETLENGTH.然而,这是有问题的,因为结果将保持超额分配,直到稍后重复.
>您可以使用所暗示的一个链接的向量块列表,即根据需要分配并保护一个对象,将您向量追加到尾部.最后,您分配返回向量并复制您分配的块的内容.这比上述更复杂.

每个人都有缺点和好处,所以它真的取决于你的应用程序选择最适合你的应用程序.

编辑:添加了使用对列表方法的示例.我仍然建议使用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;
 }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读