我有一个递归函数,它将树中节点中的一些打印为整数ids。将函数导出到R后,我无法将cout
输出用于任何事情(或者看起来似乎如此)。理想的是,如果(1)我可以将输出作为向量返回,或者(2)在不损失太多速度的情况下解析R中的cout
。
我会在这里插入一些代码,但我的功能特别通用。基本上我试图将Fibonacci序列作为向量而不是求和返回,但是通过递归函数而不使用全局或静态变量。
例如,fib(6)
将在R中返回:
[1] 0 1 1 2 3 5
所以可以,
y <- fib(6)
y[4]
和y[4:5]
将分别返回
[1] 2
[1] 2 3
提前感谢解决问题的见解和想法。使用静态变量就像我自己一样。
答案 0 :(得分:3)
我在Rcpp book的第一章中用R和C ++中的不同哈希和memoization实现详细讨论了这个问题。
答案 1 :(得分:1)
您应该阅读这本在线图书http://adv-r.had.co.nz/
,主要是您的问题部分回答http://adv-r.had.co.nz/Function-operators.html
的记忆部分:
只需添加函数fib3
,例如:
library(memoise)
fib2 <- memoise(function(n) {
if (n < 2) return(1)
fib2(n - 2) + fib2(n - 1)
})
fib3 <- memoise(function(n) sapply(1:n, fib2))
#> fib3(6)
#[1] 1 2 3 5 8 13
答案 2 :(得分:1)
只是为了好玩,使用std::generate_n
和函数对象(fseq
)代替sapply
的方法稍微复杂一点:
#include <Rcpp.h>
struct fseq {
public:
fseq() {
current = 0;
}
int operator()() {
int val = fib(current);
current++;
return val;
}
int fib(int n) {
if (n==0) return 0;
if (n==1) return 1;
return fib(n-2) + fib(n-1);
}
private:
int current;
};
// [[Rcpp::export(".fib")]]
int fib(int n) {
if (n==0) return 0;
if (n==1) return 1;
return fib(n-2) + fib(n-1);
}
// [[Rcpp::export]]
std::vector<int> fib_seq(const int n) {
if (n < 1) throw std::invalid_argument("n must be >= 1");
std::vector<int> seq;
seq.reserve(n);
std::generate_n(std::back_inserter(seq), n, fseq());
return seq;
}
library(microbenchmark)
##
R> fib_seq(6)
[1] 0 1 1 2 3 5
R> all.equal(fib_seq(6),.fib_seq(6))
[1] TRUE
.fib_seq <- function(n) sapply(0:(n-1), .fib)
##
R> microbenchmark(
fib_seq(6),.fib_seq(6),
times=1000L,unit="us")
Unit: microseconds
expr min lq mean median uq max neval
fib_seq(6) 1.561 1.9015 3.287824 2.108 2.3430 1046.021 1000
.fib_seq(6) 27.239 29.0615 35.538355 30.290 32.8065 1108.266 1000
R> microbenchmark(
fib_seq(15),.fib_seq(15),
times=100L,unit="us")
Unit: microseconds
expr min lq mean median uq max neval
fib_seq(15) 6.108 6.5875 7.46431 7.0795 7.7590 20.391 100
.fib_seq(15) 57.243 60.7195 72.97281 63.8120 73.4045 231.707 100
R> microbenchmark(
fib_seq(28),.fib_seq(28),
times=100L,unit="us")
Unit: microseconds
expr min lq mean median uq max neval
fib_seq(28) 2134.861 2143.489 2222.018 2167.364 2219.400 2650.854 100
.fib_seq(28) 3705.492 3721.586 3871.314 3745.956 3852.516 5040.827 100
请注意,这些函数已参数化以反映您的陈述
例如,fib(6)将在R内返回:
[1] 0 1 1 2 3 5