2012-12-29 39 views
5

Tôi đang tạo C trong mã R.Gửi hạt giống/Đặt hạt/C trong mã R

Trong mã C của tôi, tôi đang sử dụng hàm rand() để tạo số ngẫu nhiên. R-ext.pdf nói rằng tôi phải thiết lập một hạt giống bằng cách sử dụng các lệnh;

GetRNGstate(); 
    PutRNGstate(); 

Mặc dù tôi đang sử dụng các lệnh này ở trên, tôi vẫn nhận được các giá trị khác nhau cho cùng một hạt giống. Bạn có thể cho tôi bất kỳ sự giúp đỡ nào không?

Ví dụ tối thiểu là:

Trong C:

# include <R.h> 
# include <Rinternals.h> 
# include <Rmath.h> 
# include <R_ext/Linpack.h> 

SEXP example(){ 

    SEXP output; 
    GetRNGstate(); 
    PROTECT(output = allocVector(INTSXP, 1)); 
    INTEGER(output)[0] = rand() % 50; 
    PutRNGstate(); 
    UNPROTECT(1); 
    return(output); 
} 

Trong R:

dyn.load("example.so") 
## The following codes return different values at ever run 
set.seed(1) 
.Call("example") 

Cảm ơn trước.

Trả lời

7

Đó là một lỗi logic trong suy nghĩ của bạn - bạn đúng thiết lập giống, khởi R RNG từ mã ... nhưng sau đó gọi hệ thống RNG thay vì R RNG.

Thay thế rand() bằng unif_rand() (hoặc norm_rand()) và bạn nên đặt.

Rcpp làm cho tất cả điều này dễ dàng hơn và cung cấp cho bạn quyền truy cập vectơ để rút ra từ các chức năng phân phối khác nhau (nhưng tất nhiên bạn cũng có thể làm tất cả điều này bằng tay nếu bạn muốn).

Bằng cách sử dụng cppFunction() từ Rcpp, chúng tôi bây giờ cũng chăm sóc RNGScope mà lần lượt cung cấp GetRNGstate()/PutRNGstate() (trong khi ví dụ cũ vẫn hiển thị instantiation của RNGScope; thêm nó không có hại vì nó không tương đương tính tham khảo).

Vì vậy, nó thực sự là một one-liner để xác định, tính năng tự động gia hạn, biên dịch, và tải này:

R> cppFunction("double myrand() { return norm_rand(); }") 
R> for (i in 1:5) { set.seed(42); cat(i, " -- ", myrand(), "\n") } 
1 -- 1.37096 
2 -- 1.37096 
3 -- 1.37096 
4 -- 1.37096 
5 -- 1.37096 
R> 

trong khi nếu không có sự tái seeding chúng tôi nhận

R> for (i in 1:5) { cat(i, " -- ", myrand(), "\n") } 
1 -- -0.564698 
2 -- 0.363128 
3 -- 0.632863 
4 -- 0.404268 
5 -- -0.106125 
R> 

Cuối cùng, nếu bạn thực sự muốn bạn tất nhiên có thể tiếp tục sử dụng rand() (nhưng xem tài liệu về hiệu suất sucky của nó) nhưng sau đó sử dụng chức năng hạt giống của nó thay vì thay vì của R.

+0

Một lớp lót! thực sự mạnh mẽ! – agstudy

+0

Có, mặc dù 'cppFunction()' thực hiện một số phép thuật đằng sau hậu trường để làm cho dòng đó hoạt động - nó được mở rộng. Nhưng đối với chúng tôi để sử dụng, nó là khá gần với ma thuật ;-) –

+0

Nhưng tôi là nó tốt hơn để sử dụng sourceCpp (ít nhất là cho mục đích gỡ lỗi)? – agstudy

Các vấn đề liên quan