2017-12-15 98 views
6

में यादृच्छिक संख्या जनरेटर की आपूर्ति की मैं ऐसा लगता है किएक उपयोगकर्ता सीडिंग आर

set.seed(123, kind='user', normal.kind='user') 

वास्तव में उपयोगकर्ता परिभाषित RNG प्रारंभ करने के लिए 123 पास नहीं आर में एक उपयोगकर्ता परिभाषित RNG बोने के साथ कुछ समस्या हो रही है।

मैं ?Random.user पर उपलब्ध दस्तावेज पर वापस गया और वहां दिए गए उदाहरण कोड का प्रयास किया, जिसमें मामूली संशोधन के साथ मैंने user_unif_init फ़ंक्शन (नीचे पूर्ण कोड) को पारित बीज मुद्रित किया।

कदम पुन: पेश करने:

  1. पेस्ट नीचे कोड में urand.c
  2. भागो R CMD SHLIB urand.c
  3. ओपन R
  4. भागो निम्न कमांड:

    > dyn.load('urand.so') 
    > set.seed(123, kind='user', normal.kind='user') 
    Received seed: 720453763 
    Received seed: 303482705 // any other numbers than 123 
    

यहाँ पूर्ण कोड मैं urand.c में प्रयोग किया जाता है:

// ## Marsaglia's congruential PRNG 

#include <stdio.h> 
#include <R_ext/Random.h> 

static Int32 seed; 
static double res; 
static int nseed = 1; 

double * user_unif_rand() 
{ 
    seed = 69069 * seed + 1; 
    res = seed * 2.32830643653869e-10; 
    return &res; 
} 

void user_unif_init(Int32 seed_in) { 
    printf("Received seed: %u\n", seed_in); 
    seed = seed_in; 
} 
int * user_unif_nseed() { return &nseed; } 
int * user_unif_seedloc() { return (int *) &seed; } 

/* ratio-of-uniforms for normal */ 
#include <math.h> 
static double x; 

double * user_norm_rand() 
{ 
    double u, v, z; 
    do { 
     u = unif_rand(); 
     v = 0.857764 * (2. * unif_rand() - 1); 
     x = v/u; z = 0.25 * x * x; 
     if (z < 1. - u) break; 
     if (z > 0.259/u + 0.35) continue; 
    } while (z > -log(u)); 
    return &x; 
} 

किसी भी मदद की बहुत सराहना की जाएगी!

उत्तर

2

ऐसा लगता है कि आर के रूप में निम्नानुसार RNG.c में उपयोगकर्ता की आपूर्ति की बीज scrambles:

for(j = 0; j < 50; j++) 
    seed = (69069 * seed + 1) 

(link to source)

खोलना करने के लिए यह एक तरह से मूल बीज वापस पाने के लिए कोशिश कर रहा होगा।

अद्यतन

unscrambling इस प्रकार 69,069 की multiplicative inverse के माध्यम से किया जा सकता है:

Int32 unscramble(Int32 scrambled) 
{ 
        int j; 
        Int32 u = scrambled; 
        for (j=0; j<50; j++) { 
                u = ((u - 1) * 2783094533); 
        } 
        return u; 
} 

मेरी user_unif_init() समारोह में इस Plugging समस्या का हल।

1

आरएनजी को अग्रेषित किया गया बीज प्रदान किए गए बीज से अलग है, हालांकि, यह "सामान्य" वर्कफ़्लो का उपयोग होने पर पुन: उत्पन्न होता है। यह तो प्रतिलिपि प्रस्तुत करने योग्य यादृच्छिक संख्या देता है:

dyn.load('urand.so') 
RNGkind("user", "user") 
#> Received seed: 1844983443 
set.seed(123) 
#> Received seed: 303482705 
runif(10) 
#> [1] 0.42061954 0.77097033 0.14981063 0.27065365 0.77665767 0.96882090 
#> [7] 0.49077135 0.08621131 0.52903479 0.90398294 
set.seed(123) 
#> Received seed: 303482705 
runif(10) 
#> [1] 0.42061954 0.77097033 0.14981063 0.27065365 0.77665767 0.96882090 
#> [7] 0.49077135 0.08621131 0.52903479 0.90398294 

(ध्यान दें कि मैं अपने urand.c थोड़ा R_ext/Print.h से Rprintf उपयोग करने के लिए बदल दिया है।)


संपादित करें: आप बीज पर नियंत्रण की जरूरत है (क्यों?), आप इसे स्वयं कर सकते हैं: user_unif_init, user_unif_nseed और user_unif_seedloc

को प्रतिस्थापित करें

और यह स्पष्ट रूप से कहते हैं:

dyn.load('urand.so') 
RNGkind("user", "user") 
set_seed <- function(seed) { 
    invisible(.C("set_seed", seed_in = as.integer(seed))) 
} 
set_seed(123) 
#> Received seed: 123 
runif(10) 
#> [1] 0.00197801 0.61916849 0.34846373 0.04152509 0.09669026 0.29923760 
#> [7] 0.04184693 0.32557942 0.44473242 0.22339845 
set_seed(123) 
#> Received seed: 123 
runif(10) 
#> [1] 0.00197801 0.61916849 0.34846373 0.04152509 0.09669026 0.29923760 
#> [7] 0.04184693 0.32557942 0.44473242 0.22339845 

संपादित करें 2: https://svn.r-project.org/R/trunk/src/main/RNG.c पर स्रोत में alook है:

static void RNG_Init(RNGtype kind, Int32 seed) 
{ 
    int j; 

    BM_norm_keep = 0.0; /* zap Box-Muller history */ 

    /* Initial scrambling */ 
    for(j = 0; j < 50; j++) 
    seed = (69069 * seed + 1); 
    [...] 

ये 50 LCG राउंड अंतर के लिए जिम्मेदार हैं। मेरा अनुमान है कि आर के लेखकों का मानना ​​है कि विशिष्ट उपयोगकर्ता द्वारा प्रदान किए गए उपयोगकर्ता छोटे होते हैं और इसलिए बीज के लिए पर्याप्त यादृच्छिक नहीं होते हैं।

+0

एक नज़र डालने के लिए धन्यवाद! यह जानना अच्छा लगता है कि यह सुसंगत है, लेकिन यह वास्तव में मेरी समस्या का समाधान नहीं करता है। मुझे सी फ़ंक्शन में '123'' प्राप्त करने में सक्षम होना चाहिए। क्या ब्लैक जादू को बाईपास या पूर्ववत करने का कोई तरीका है कि आर इस प्रतीत होता है कि यह प्रतीत होता है? – GjjvdBurg

+0

अद्यतन के लिए धन्यवाद! मुझे एक विशिष्ट आवेदन के लिए बीज पर नियंत्रण की आवश्यकता है। आपका समाधान एक अच्छा काम है, लेकिन यह मेरे प्रश्न का काफी जवाब नहीं देता है। मुझे आश्चर्य है कि आर बीज के साथ क्या कर रहा है और किस उद्देश्य के लिए यह उपयोगी होगा। – GjjvdBurg

संबंधित मुद्दे