จำลองการแจกแจงแบบสม่ำเสมอบนแผ่นดิสก์


24

ฉันพยายามจำลองการฉีดของจุดสุ่มภายในวงกลมเช่นว่าส่วนใดส่วนหนึ่งของวงกลมมีความน่าจะเป็นเหมือนกันที่จะมีข้อบกพร่อง ฉันคาดว่าจำนวนนับต่อพื้นที่ของการแจกแจงแบบผลลัพธ์จะเป็นไปตามการแจกแจงแบบปัวซองหากฉันแยกวงกลมออกเป็นสี่เหลี่ยมมุมฉากที่เท่ากัน

เนื่องจากมันต้องการเพียงจุดวางภายในพื้นที่วงกลมฉันจึงฉีดการแจกแจงแบบสุ่มสองชุดในพิกัดเชิงขั้ว: (รัศมี) และθ (มุมขั้ว)Rθ

แต่หลังจากฉีดนี้ฉันได้รับคะแนนมากขึ้นในจุดศูนย์กลางของวงกลมเมื่อเทียบกับขอบ

ป้อนคำอธิบายรูปภาพที่นี่

อะไรจะเป็นวิธีที่ถูกต้องในการฉีดนี้ข้ามวงกลมเพื่อให้คะแนนถูกกระจายแบบสุ่มไปทั่ว cirlce


คำถามนี้มีระบบอะนาล็อกที่แน่นอนในฟอรัม Geometry: math.stackexchange.com/questions/87230/…
Aksakal

คำตอบ:


35

คุณต้องการให้สัดส่วนของคะแนนเป็นสัดส่วนอย่างสม่ำเสมอกับพื้นที่มากกว่าระยะทางกับจุดกำเนิด เนื่องจากพื้นที่เป็นสัดส่วนกับระยะกำลังสองสร้างรัศมีสุ่มและใช้รากที่สองของพวกเขา รวมเข้ากับมุมขั้วที่สม่ำเสมอ

นี่เป็นรหัสที่ง่ายและรวดเร็วมีประสิทธิภาพในการดำเนินการ (โดยเฉพาะบนแพลตฟอร์มคู่ขนาน) และสร้างจำนวนคะแนนตามที่กำหนดไว้อย่างแน่นอน

ตัวอย่าง

นี่เป็นRโค้ดที่ใช้งานได้เพื่อแสดงอัลกอริทึม

n <- 1e4
rho <- sqrt(runif(n))
theta <- runif(n, 0, 2*pi)
x <- rho * cos(theta)
y <- rho * sin(theta)
plot(x, y, pch=19, cex=0.6, col="#00000020")

ป้อนคำอธิบายรูปภาพที่นี่


3

การสุ่มตัวอย่างการปฏิเสธสามารถใช้การได้ ซึ่งหมายความว่าเราสามารถสุ่มตัวอย่างจากการกระจายแบบสองมิติและเลือกตัวอย่างที่ตรงตามเงื่อนไขของดิสก์

นี่คือตัวอย่าง

x=runif(1e4,-1,1)
y=runif(1e4,-1,1)

d=data.frame(x=x,y=y)
disc_sample=d[d$x^2+d$y^2<1,]
plot(disc_sample)

ป้อนคำอธิบายรูปภาพที่นี่


3
นี่เป็นทางเลือกที่ดีสำหรับวิธีการที่ใช้โดย OP ง่ายและมีประสิทธิภาพ มันไม่ได้ตอบคำถามจริงๆซึ่งเกี่ยวข้องกับวิธีการแก้ไขพิกัดเชิงขั้วเพื่อสร้างความแปรปรวนแบบกระจาย ทำไมเราถึงสนใจ เนื่องจากความหมาย: เมื่อคุณรู้วิธีสร้างจุดกระจายอย่างสม่ำเสมอในพิกัดเชิงขั้วคุณสามารถใช้การสุ่มตัวอย่างการปฏิเสธ (และวิธีการที่คุ้นเคยอื่น ๆ ) ในพิกัดขั้วโลกเพื่อสุ่มตัวอย่างจากภูมิภาคที่อาจซับซ้อนอย่างห้ามตัวอย่างในพิกัดคาร์ทีเซียน (คิดถึง hypocycloids ตัวอย่างเช่น)
whuber

1
π/4

@whuber ขอบคุณที่ให้การศึกษาฉันโดยการแสดงความคิดเห็นคำตอบของฉัน!
Haitao Du

3

ฉันจะให้คำตอบทั่วไป n- มิติที่เหมาะกับกรณีสองมิติด้วย ในสามมิติอะนาล็อกของดิสก์คือปริมาตรของลูกบอลทึบ (ทรงกลม)

มีสองวิธีที่ฉันจะพูดถึง หนึ่งในนั้นที่ฉันเรียกว่า"แม่นยำ"และคุณจะได้คำตอบที่สมบูรณ์ในอาร์ตัวที่สองที่ฉันเรียกว่าฮิวริสติกกและเป็นเพียงความคิดเท่านั้นไม่มีวิธีแก้ปัญหาที่สมบูรณ์

โซลูชัน "แม่นยำ"

ทางออกของฉันอยู่บนพื้นฐานของMarsaglia และมุลเลอร์ผลงาน โดยทั่วไปมันเกิดขึ้นเพื่อให้เวกเตอร์เกาส์นอร์มัลไลซ์ตามปกติของมันจะให้จุดกระจายอย่างสม่ำเสมอบนไฮเปอร์สเฟียร์ d-มิติ:

ป้อนคำอธิบายรูปภาพที่นี่

d1/d

n <- 1e4
rho <- sqrt(runif(n))
# d - # of dimensions of hyperdisk
d = 2
r = matrix(rnorm(n*d),nrow=n,ncol=d)
x = r/rep(sqrt(rowSums(r^2))/rho,1)
plot(x[,1], x[,2], pch=19, cex=0.6, col="#00000020")

ป้อนคำอธิบายรูปภาพที่นี่

นี่คือข้อมูลโค้ดสำหรับกรณี 3 มิตินั่นคือลูกบอลทึบ:

library(scatterplot3d)
n <- 1e3
# d - # of dimensions of hyperdisk

d=3
rho <- (runif(n))^(1/d)
r = matrix(rnorm(n*d),nrow=n,ncol=d)
x = r/rep(sqrt(rowSums(r^2))/rho,1)

scatterplot3d(x[,1], x[,2], x[,3])

ป้อนคำอธิบายรูปภาพที่นี่

วิธีการแก้ปัญหา

Vn(R)=πn2Γ(n2+1)Rn
Rnในการเรียนรู้ของเครื่อง

Σผม=1dxผม2<R2 2ปัญหาคือว่าสำหรับมิติที่สูง d เกือบทุกจุดจะอยู่นอกวง! คุณจะต้องทิ้งตัวอย่างส่วนใหญ่ของคุณ

1d+2 2ดังนั้นแทนที่จะเลือกจุดอย่างสม่ำเสมอจากลูกบาศก์เราจะสุ่มตัวอย่างพิกัดคาร์ทีเซียนโดยใช้ Gaussian จากนั้นใช้การสุ่มตัวอย่างปฏิเสธกับพวกมัน ด้วยวิธีนี้เราจะไม่ต้องสูญเสียความหลากหลายที่สร้างขึ้นแบบสุ่ม นี่จะเป็นรูปแบบของเทคนิคการสุ่มตัวอย่างที่สำคัญ


@Silverfish คุณพูดถูกฉันคงภาษา
Aksakal

@Silverfish มันช้าเนื่องจากการใช้ตัวแปร Gaussian แต่อาจเร็วกว่าการสุ่มตัวอย่างการปฏิเสธอย่างง่าย ๆ ในกรณีที่มีมิติสูงซึ่งไม่ชัดเจนสำหรับคนจำนวนมากถึงแม้ว่ามันจะเป็นเรื่องที่แตกต่างกัน
Aksakal

(1) ในตัวอย่าง 3 มิติทำไมคุณถึงนำสแควร์รูทของชุดรูปแบบที่ต่างกันสำหรับรัศมีและไม่ใช่รูทคิวบ์ (2) ดูเหมือนว่าคุณกำลังอ้างว่าใครควรยกกำลังสองของรัศมี1/d,แต่คุณไม่ได้หมายถึงรัศมีเองใช่ไหม? (3) วิธีการสุ่มตัวอย่างแบบปฏิเสธคือวิธีใดดีกว่าวิธีก่อนหน้าซึ่งต้องการเพียงอย่างเดียวdiid Gaussian ผันแปร (โดยไม่มีการปฏิเสธ)?
whuber

@ โฮเบอร์ฉันกำลังคัดลอกวางแก้ไขการพิมพ์ดีดโดยใช้พลังคิวบ์ ถ้าเราใช้ Gaussian การสุ่มตัวอย่างการปฏิเสธนั้นไม่ดีกว่าดังนั้นเราต้องใช้บางรูประฆังที่เร็วกว่า Gaussian คุณพูดถูก
Aksakal

0

นี่คือทางเลือกอื่นในR:

n <- 1e4
## r <- seq(0, 1, by=1/1000)
r <- runif(n)
rho <- sample(r, size=n, replace=T, prob=r)
theta <- runif(n, 0, 2*pi)
x <- rho * cos(theta)
y <- rho * sin(theta)
plot(x, y, pch=19, cex=0.6, col="#00000020")

ป้อนคำอธิบายรูปภาพที่นี่


4
คุณช่วยอธิบายคำตอบนี้เป็นภาษาอังกฤษธรรมดาได้ไหม? เราไม่ได้เป็นไซต์ช่วยเหลือรหัสจริง ๆ และควรให้คำตอบเฉพาะรหัสเท่านั้น
gung - Reinstate Monica

5
วิธีนี้เป็นวิธีที่น่าสนใจ น่าเสียดายที่มันไม่ถูกต้องนักถึงแม้ว่าเนื้อเรื่องจะดูดี เหตุผลก็คือมัน จำกัด รัศมีในตัวอย่างไปยังชุดของค่าที่ไม่ต่อเนื่องที่เว้นระยะเท่ากันระหว่าง0 และ 1. สิ่งนี้ไม่เหมือนกับการแจกแจงที่ตั้งใจไว้ โดยเฉพาะอย่างยิ่งมันเป็นเอกพจน์ : มันไม่มีแม้แต่ PDF! หากคุณไม่มั่นใจให้ลองรันใหม่อีกครั้งr <- seq(0, 1, by=1/10)เพื่อดูธรรมชาติที่ไม่ต่อเนื่องของมันให้ชัดเจนยิ่งขึ้น
whuber

1
@whuber ขอบคุณสำหรับการชี้ให้เห็นว่า จริงๆแล้วมันเป็นแนวคิดหลักของฉันในการแก้ปัญหา วิธีการของฉันคือการสร้างวงกลมที่มีหลายชุดด้วยรัศมีที่แตกต่างกันและสำหรับแต่ละวงกลมจำนวนของคะแนนนั้นแปรผันตามความยาวของรัศมี ดังนั้นในหน่วยความยาวของวงกลมที่มีรัศมีแตกต่างกันจำนวนของจุดจึงเท่ากัน เพื่อหลีกเลี่ยงลักษณะที่ไม่ต่อเนื่องเราสามารถสุ่มตัวอย่างrจาก Uniform (0,1)
Q_Li
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.