यूनिट सर्कल और यूनिट स्क्वायर के बीच कुशलता से अंक उत्पन्न करें


17

मैं यहाँ परिभाषित नीले क्षेत्र से नमूने उत्पन्न करना चाहता हूँ:

यहाँ छवि विवरण दर्ज करें

भोली समाधान इकाई वर्ग में अस्वीकृति नमूने का उपयोग करना है, लेकिन यह केवल 1π/4 (~ 21.4%) दक्षता प्रदान करता है।

क्या कोई तरीका है जिससे मैं और अधिक कुशलता से नमूना ले सकता हूं?


6
संकेत : अपनी दक्षता को तुच्छ रूप से दोगुना करने के लिए समरूपता का उपयोग करें।
कार्डिनल

3
ओह पसंद करें: यदि मान (0,0) है, तो इसे (1,1) मैप किया जा सकता है? मुझे वह विचार बहुत पसंद है
Cam.Davidson.Pilon

@cardinal यह 4x दक्षता नहीं होना चाहिए? आप में नमूना ले सकते हैं [0,,1]×[0,,1]और फिर इसे x- अक्ष, y- अक्ष और मूल में दर्पण कर सकते हैं।
मार्टिन क्रैमर

1
@ मर्टिन: चार सममित क्षेत्रों के पार, आपके पास ओवरलैप है, जिसे आपको अधिक सावधानी से निपटना होगा।
कार्डिनल

3
@ मॉर्टिन: यदि आप समझ रहे हैं कि आप क्या वर्णन कर रहे हैं, तो इससे दक्षता में वृद्धि नहीं होती है । (आपको एक बिंदु मिला, और अब तीन अन्य को जानते हैं --- एक क्षेत्र में चार गुना आकार --- जो या तो इकाई डिस्क के भीतर एक या एक के साथ झूठ नहीं बोलते हैं कि क्या (x,y) है। क्या यह मदद करता है?) बढ़ती दक्षता का बिंदु उत्पन्न होने वाले प्रत्येक लिए स्वीकृति की संभावना को बढ़ाना है (x,y)। शायद मैं सघन हो रहा हूं?
कार्डिनल

जवाबों:


10

क्या प्रति सेकंड दो मिलियन अंक मिलेंगे?

वितरण सममित है: हमें केवल पूर्ण वृत्त के एक-आठवें भाग के लिए वितरण की आवश्यकता है और फिर इसे अन्य अष्टकों के आसपास कॉपी करें। ध्रुवीय निर्देशांक में , कोण की संचयी बंटन Θ यादृच्छिक स्थान के लिए ( एक्स , वाई ) मूल्य पर θ त्रिकोण के बीच के क्षेत्र द्वारा दिया जाता है ( 0 , 0 ) , ( 1 , 0 ) , ( 1 , तन θ ) और से विस्तार वृत्त के चाप ((r,θ)Θ(X,Y)θ(0,0),(1,0),(1,tanθ) के लिए ( क्योंकि θ , पाप θ ) । यह आनुपातिक है(1,0)(cosθ,sinθ)

FΘ(θ)=Pr(Θθ)12tan(θ)θ2,

जिसका घनत्व है

fΘ(θ)=ddθFΘ(θ)tan2(θ).

हम इस घनत्व से नमूनाकरण कर सकता है का उपयोग करते हुए, कहते हैं, एक अस्वीकृति विधि (जो दक्षता )।8/π254.6479%

रेडियल समन्वय की सशर्त घनत्व के लिए आनुपातिक है आर डी आर के बीच आर = 1 और आर = सेकंड θ । यह सीडीएफ के एक आसान उलटा के साथ नमूना लिया जा सकता है।Rrdrr=1r=secθ

यदि हम स्वतंत्र नमूने उत्पन्न , रूपांतरण वापस कार्तीय निर्देशांक के लिए ( एक्स मैं , y मैं ) नमूने इस ओक्टांट। क्योंकि नमूने स्वतंत्र हैं, यादृच्छिक रूप से निर्देशांक की अदला-बदली करने से वांछित के रूप में पहले क्वाड्रंट से एक स्वतंत्र यादृच्छिक नमूना उत्पन्न होता है। (यादृच्छिक स्वैपों को स्वैप करने के लिए कितने बोधों को निर्धारित करने के लिए केवल एक द्विपद चर बनाने की आवश्यकता होती है।)(ri,θi)(xi,yi)

से प्रत्येक इस तरह के अहसास , की आवश्यकता है औसत, एक समान variate पर (के लिए आर ) प्लस 1 / ( 8 π - 2 ) बार दो वर्दी (के लिए variates Θ ) और (तेज) गणना की एक छोटी राशि। ऐसा इसलिए है 4 / ( π - 4 ) 4.66 बिंदु (जो, ज़ाहिर है, दो निर्देशांक) प्रति variates। पूर्ण विवरण नीचे दिए गए कोड उदाहरण में हैं। यह आंकड़ा उत्पन्न एक आधे मिलियन से अधिक अंकों में से 10,000 प्लॉट करता है।(X,Y)R1/(8π2)Θ4/(π4)4.66

Figure

यहाँ वह Rकोड है जिसने इस सिमुलेशन का निर्माण किया और इसे समयबद्ध किया।

n.sim <- 1e6
x.time <- system.time({
  # Generate trial angles `theta`
  theta <- sqrt(runif(n.sim)) * pi/4
  # Rejection step.
  theta <- theta[runif(n.sim) * 4 * theta <= pi * tan(theta)^2]
  # Generate radial coordinates `r`.
  n <- length(theta)
  r <- sqrt(1 + runif(n) * tan(theta)^2)
  # Convert to Cartesian coordinates.
  # (The products will generate a full circle)
  x <- r * cos(theta) #* c(1,1,-1,-1)
  y <- r * sin(theta) #* c(1,-1,1,-1)
  # Swap approximately half the coordinates.
  k <- rbinom(1, n, 1/2)
  if (k > 0) {
    z <- y[1:k]
    y[1:k] <- x[1:k]
    x[1:k] <- z
  }
})
message(signif(x.time[3] * 1e6/n, 2), " seconds per million points.")
#
# Plot the result to confirm.
#
plot(c(0,1), c(0,1), type="n", bty="n", asp=1, xlab="x", ylab="y")
rect(-1, -1, 1, 1, col="White", border="#00000040")
m <- sample.int(n, min(n, 1e4))
points(x[m],y[m], pch=19, cex=1/2, col="#0000e010")

1
मैं इस वाक्य को नहीं समझता: "क्योंकि नमूने स्वतंत्र हैं, व्यवस्थित रूप से निर्देशांक की अदला-बदली करते हुए हर दूसरे नमूने को पहले चतुर्थांश से एक स्वतंत्र यादृच्छिक नमूना बनाते हैं, जैसा कि वांछित है।" यह मुझे लगता है कि व्यवस्थित रूप से निर्देशांक स्वैपिंग हर दूसरा नमूना अत्यधिक निर्भर नमूने का उत्पादन करता है। उदाहरण के लिए, मुझे ऐसा लगता है कि कोड में आपका कार्यान्वयन समान ऑक्टेंट से एक पंक्ति में आधा मिलियन नमूने उत्पन्न करता है?
ए। रेक्स

7
कड़ाई से बोलना, यह दृष्टिकोण काफी काम नहीं करता है (आईआईडी बिंदुओं के लिए) क्योंकि यह दो ऑक्टेंट्स में समान संख्या में नमूने उत्पन्न करता है: नमूना बिंदु इस प्रकार, निर्भर हैं। अब, यदि आप प्रत्येक नमूने के लिए अष्टक निर्धारित करने के लिए निष्पक्ष सिक्कों को फ्लिप करते हैं ...
कार्डिनल

1
@ कार्डिनल आप सही हैं; मैं इसे ठीक कर दूँगा - (asymptotically) उत्पन्न करने के लिए यादृच्छिक चर की संख्या में वृद्धि!
whuber

2
n2n

2
2sin(θ)2(4π)/(π2)75%

13

मैं निम्नलिखित समाधान प्रस्तावित करता हूं, जो अब तक @cardinal, @whuber और @ stephan-kolassa द्वारा अन्य soutions की तुलना में सरल, अधिक कुशल और / या कम्प्यूटेशनल रूप से सस्ता होना चाहिए।

इसमें निम्नलिखित सरल चरण शामिल हैं:

u1Unif(0,1)u2Unif(0,1).

min{u1,u2},max{u1,u2}

[xy]=[11]+[2212210][min{u1,u2}max{u1,u2}].

xyu1>u2

x2+y2<1.

इस एल्गोरिथ्म के पीछे अंतर्ज्ञान चित्र में दिखाया गया है। यहाँ छवि विवरण दर्ज करें

चरण 2a और 2b को एक ही चरण में मिलाया जा सकता है:

2) कतरनी परिवर्तन लागू करें और स्वैप करें

x=1+22min(u1,u2)u2y=1+22min(u1,u2)u1

निम्न कोड ऊपर एल्गोरिथ्म को लागू करता है (और @ व्ह्यूसर कोड का उपयोग करके इसका परीक्षण करता है)।

n.sim <- 1e6
x.time <- system.time({
    # Draw two standard uniform samples
    u_1 <- runif(n.sim)
    u_2 <- runif(n.sim)
    # Apply shear transformation and swap
    tmp <- 1 + sqrt(2)/2 * pmin(u_1, u_2)
    x <- tmp - u_2
    y <- tmp - u_1
    # Reject if inside circle
    accept <- x^2 + y^2 > 1
    x <- x[accept]
    y <- y[accept]
    n <- length(x)
})
message(signif(x.time[3] * 1e6/n, 2), " seconds per million points.")
#
# Plot the result to confirm.
#
plot(c(0,1), c(0,1), type="n", bty="n", asp=1, xlab="x", ylab="y")
rect(-1, -1, 1, 1, col="White", border="#00000040")
m <- sample.int(n, min(n, 1e4))
points(x[m],y[m], pch=19, cex=1/2, col="#0000e010")

कुछ त्वरित परीक्षण निम्नलिखित परिणाम देते हैं।

एल्गोरिथ्म /stats//a/258349 । 3 का सर्वश्रेष्ठ: 0.33 सेकंड प्रति मिलियन अंक।

यह एल्गोरिथ्म। 3 का सर्वश्रेष्ठ: 0.18 सेकंड प्रति मिलियन अंक।


3
+1 बहुत अच्छा किया! एक विचारशील, चतुर और सरल समाधान साझा करने के लिए धन्यवाद।
whuber

महान विचार! मैं यूनिट से इस हिस्से के लिए मैपिंग के बारे में सोच रहा था, लेकिन अपूर्ण मैपिंग और फिर अस्वीकृति योजना के बारे में नहीं सोचा । मेरे मन का विस्तार करने के लिए धन्यवाद!
Cam.Davidson.Pilon

7

खैर, अधिक कुशलता से किया जा सकता है, लेकिन मुझे यकीन है कि उम्मीद है कि आप तेजी से नहीं देख रहे हैं ।

xx

f(x)=11x2.

वोल्फ्रम आपको एकीकृत करने में मदद करता है :

0xf(y)dy=12x1x2+x12arcsinx.

F01f(y)dy

xt01xF(x)=t

xy1x21

x

अगर आप कुछ सोच-समझकर निवेश करते हैं तो आप शायद CDF को थोड़ा बहुत उलटा कर सकते हैं। फिर सोचती है, दर्द होता है। मैं व्यक्तिगत रूप से अस्वीकृति नमूने के लिए जाऊंगा, जो तेज और बहुत कम त्रुटि वाला है, जब तक कि मेरे पास बहुत अच्छे कारण नहीं थे।

epsilon <- 1e-6
xx <- seq(0,1,by=epsilon)
x.cdf <- function(x) x-(x*sqrt(1-x^2)+asin(x))/2
xx.cdf <- x.cdf(xx)/x.cdf(1)

nn <- 1e4
rr <- matrix(nrow=nn,ncol=2)
set.seed(1)
pb <- winProgressBar(max=nn)
for ( ii in 1:nn ) {
    setWinProgressBar(pb,ii,paste(ii,"of",nn))
    x <- max(xx[xx.cdf<runif(1)])
    y <- runif(1,sqrt(1-x^2),1)
    rr[ii,] <- c(x,y)
}
close(pb)

plot(rr,pch=19,cex=.3,xlab="",ylab="")

randoms


मुझे आश्चर्य है कि सीडीएफ को अनुमानित करने के लिए चेबीशेव पोलिनेम्स का उपयोग करने से मूल्यांकन की गति में सुधार होगा।
साइकोरैक्स का कहना है कि मोनिका

@ साइकोरेक्स, संशोधनों के बिना नहीं; उदाहरण के लिए , समापन बिंदु पर बीजीय विलक्षणताओं के चबुन उपचार को देखें ।
जेएम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.