การสร้างตัวอย่างแบบสุ่มจากการแจกแจงที่กำหนดเอง


16

ฉันกำลังพยายามสร้างตัวอย่างแบบสุ่มจาก pdf ที่กำหนดเองโดยใช้ R. ไฟล์ของฉันคือ:

fX(x)=32(1x2),0x1

ฉันสร้างตัวอย่างที่เหมือนกันแล้วลองแปลงเป็นการแจกแจงแบบกำหนดเองของฉัน ฉันไม่นี้โดยการหา CDF ของการกระจายของฉัน ( FX(x) ) และการตั้งค่าให้ตัวอย่างเครื่องแบบ ( ยู ) และการแก้สำหรับxx

FX(x)=Pr[Xx]=0x32(1y2)dy=32(xx33)

ในการสร้างตัวอย่างแบบสุ่มที่มีการแจกแจงข้างต้นให้หาตัวอย่างแบบสม่ำเสมอu[0,1]และหาค่าxใน

32(xx33)=u

ฉันใช้งานRและไม่ได้รับการกระจายที่คาดหวัง ใครสามารถชี้ให้เห็นข้อบกพร่องในการทำความเข้าใจของฉัน?

nsamples <- 1000;
x <- runif(nsamples);

f <- function(x, u) { 
  return(3/2*(x-x^3/3) - u);
}

z <- c();
for (i in 1:nsamples) {
  # find the root within (0,1) 
  r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root;
  z <- c(z, r);
}

1
ต้องเป็นรหัสผิดพลาด ฉันไม่ได้ใช้ R ดังนั้นฉันจึงไม่สามารถพูดได้ว่าความผิดพลาดนั้นเกิดขึ้นจริง แต่ฉันเพิ่งเขียนวิธีแก้ปัญหาของคุณ (ระวังที่จะให้รูตกลางของลูกบาศก์พหุนามซึ่งอยู่ระหว่าง 0 ถึง 1 เสมอ) และ ฉันได้รับข้อตกลงที่ดีระหว่างตัวอย่างและการแจกแจงที่คาดหวัง เป็นปัญหากับตัวค้นหารูทของคุณหรือไม่? เกิดอะไรขึ้นกับตัวอย่างที่คุณได้รับ?
jpillow

ฉันลองใช้รหัสของคุณ (ซึ่งไม่ได้มีประสิทธิภาพมากโดยวิธี) และได้รับการกระจายที่คาดหวัง
Aniko

@jpillow และ @Aniko ความผิดของฉัน เมื่อฉันใช้nsamples <- 1e6มันเป็นการจับคู่ที่ดี
อานันท์

2
@Anand วิธีหนึ่งคือการสังเกตได้ว่าช่วยให้การคำนวณโดยตรงของxในแง่ของมึง x=2sin(arcsin(u)/3)xu
whuber

คำตอบ:


11

ดูเหมือนว่าคุณจะพบว่าโค้ดของคุณใช้งานได้ แต่ @Aniko ชี้ให้เห็นว่าคุณสามารถปรับปรุงประสิทธิภาพได้ ความเร็วที่เพิ่มขึ้นที่ใหญ่ที่สุดของคุณอาจมาจากการจัดสรรหน่วยความจำไว้ล่วงหน้าzเพื่อที่คุณจะไม่เติบโตในวง สิ่งที่ชอบz <- rep(NA, nsamples)ควรทำเคล็ดลับ คุณอาจได้รับความเร็วเล็กน้อยจากการใช้vapply()(ซึ่งระบุประเภทตัวแปรที่ส่งคืน) แทนการวนซ้ำอย่างชัดเจน (มีคำถาม SOที่ยอดเยี่ยมเกี่ยวกับตระกูลใช้)

> nsamples <- 1E5
> x <- runif(nsamples)
> f <- function(x, u) 1.5 * (x - (x^3) / 3) - u
> z <- c()
> 
> # original version
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   z <- c(z, r)
+ }
+ })
   user  system elapsed 
  49.88    0.00   50.54 
> 
> # original version with pre-allocation
> z.pre <- rep(NA, nsamples)
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   z.pre[i] <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   }
+ })
   user  system elapsed 
   7.55    0.01    7.78 
> 
> 
> 
> # my version with sapply
> my.uniroot <- function(x) uniroot(f, c(0, 1), tol = 0.0001, u = x)$root
> system.time({
+   r <- vapply(x, my.uniroot, numeric(1))
+ })
   user  system elapsed 
   6.61    0.02    6.74 
> 
> # same results
> head(z)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(z.pre)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(r)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738

และคุณไม่จำเป็นต้องใช้;ในตอนท้ายของแต่ละบรรทัด (คุณเป็น MATLAB หรือเปล่า?)


vapplyขอบคุณสำหรับคำตอบของคุณอย่างละเอียดและชี้ให้เห็น ฉันได้รับการเข้ารหัสC/C++เป็นเวลานานมากและนั่นคือเหตุผลของ;ความทุกข์!
อานันท์

1
uniroot107
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.