2015-06-27 11 views
35

a recent investigation के दौरान कार्यों के भीतर यादृच्छिक बीज सेट करने के दौरान, मैं एक अजीब स्थिति में आया। कार्यों पर विचार करें f और g, जिनमें से प्रत्येक यादृच्छिक बीज सेट और फिर एक सरल यादृच्छिक कार्रवाई निष्पादित करता है: प्रत्येक कार्य यादृच्छिक बीज सेटएफ (जी (एक्स)) के साथ असंगत परिणाम

g <- function(size) { set.seed(1) ; runif(size) } 
f <- function(x) { set.seed(2) ; x*runif(length(x)) } 

वजह से, मैं प्रत्येक कार्य हमेशा एक ही वापसी मान दे दिया है की उम्मीद करेंगे एक ही इनपुट। इसका मतलब यह होगा कि f(g(2)) को x <- g(2) ; f(x) जैसी ही चीज़ वापस करनी चाहिए। मेरे आश्चर्य के लिए यह मामला नहीं है:

f(g(2)) 
# [1] 0.1520975 0.3379658 

x <- g(2) 
f(x) 
# [1] 0.04908784 0.26137017 

यहां क्या हो रहा है?

उत्तर

37

यह डबल-स्लिट आर प्रयोग का एक उदाहरण है। जब एक्स मनाया जाता है, यह एक कण के रूप में कार्य करता है; जब unobserved यह एक लहर के रूप में कार्य करता है। देखें

g <- function(size) { set.seed(1) ; runif(size) } 
f <- function(x) {set.seed(2) ; x*runif(length(x)) } 
f2 <- function(x) {print(x); set.seed(2) ; x*runif(length(x)) } 

f(g(2)) 
# [1] 0.1520975 0.3379658 

x <- g(2) 
f(x) 
# [1] 0.04908784 0.26137017 


f2(g(2)) 
# [1] 0.2655087 0.3721239 
# [1] 0.04908784 0.26137017 

x <- g(2) 
f2(x) 
# [1] 0.2655087 0.3721239 
# [1] 0.04908784 0.26137017 

मैं बस आपको जोसिस कर रहा हूं। printx को मजबूर कर रहा है। आप ऐसा कर सकते हैं स्पष्ट रूप से

f <- function(x) {force(x); set.seed(2) ; x*runif(length(x)) } 
x <- g(2) 
f(x) 
# [1] 0.04908784 0.26137017 

लेकिन इस

f(force(g(2))) 
# [1] 0.1520975 0.3379658 
+6

LOL। आर में डबल स्लिट प्रयोग! क्यूएम के रूप में आलसी मूल्यांकन। उत्तम। –

+1

एक क्रिया के रूप में 'josliber' का अच्छा उपयोग। –

+0

@ जोसेफवुड मुझे लगता है कि सभी उपवास उस के लिए थे – rawr

23

अपने f() समारोह के x तर्क केवल पल कि यह वास्तव में समारोह के अंदर प्रयोग किया जाता है पर मूल्यांकन किया जाता है। इसका अर्थ है कि set.seed(2)g() फ़ंक्शन के निष्पादन का मूल्यांकन करते समय set.seed(2) का मूल्यांकन किया जाता है जब आप f(g(2)) की गणना करने का प्रयास करते हैं।

> f(g(2)) 
[1] 0.1520975 0.3379658 

मूल रूप से के बराबर है:

> set.seed(2) 
> set.seed(1) 
> result <- runif(2) 
> result*runif(length(result)) 
[1] 0.1520975 0.3379658 
संबंधित मुद्दे