Mensimulasikan distribusi seragam pada disk

24

Saya mencoba mensimulasikan injeksi titik acak di dalam lingkaran, sehingga setiap bagian dari lingkaran memiliki kemungkinan yang sama memiliki cacat. Saya mengharapkan penghitungan per area dari distribusi yang dihasilkan untuk mengikuti distribusi Poisson jika saya memecah lingkaran menjadi persegi area yang sama.

Karena hanya membutuhkan penempatan titik dalam area melingkar, saya menyuntikkan dua distribusi acak seragam dalam koordinat polar: (radius) dan (sudut polar).Rθ

Tetapi setelah melakukan injeksi ini, saya jelas mendapatkan lebih banyak poin di tengah lingkaran dibandingkan dengan tepi.

masukkan deskripsi gambar di sini

Apa cara yang benar untuk melakukan injeksi ini di seluruh lingkaran sehingga titik-titik didistribusikan secara acak di seluruh lingkaran?

Jonjilla
sumber
Pertanyaan ini memiliki analog persis di forum Geometry: math.stackexchange.com/questions/87230/…
Aksakal

Jawaban:

35

Anda ingin proporsi titik sebanding secara proporsional dengan area daripada jarak ke titik asal. Karena luas sebanding dengan jarak kuadrat, hasilkan jari-jari acak yang seragam dan ambil akar kuadratnya. Kombinasikan itu dengan sudut kutub yang seragam.

Ini cepat dan mudah dikodekan, efisien dalam pelaksanaannya (terutama pada platform paralel), dan menghasilkan jumlah titik yang ditentukan dengan tepat.

Contoh

Ini adalah Rkode yang berfungsi untuk menggambarkan algoritma.

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")

masukkan deskripsi gambar di sini

whuber
sumber
3

Sampling Penolakan dapat digunakan. Ini berarti kami dapat mengambil sampel dari distribusi seragam 2D, dan memilih sampel yang memenuhi kondisi disk.

Berikut ini sebuah contoh.

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)

masukkan deskripsi gambar di sini

Haitao Du
sumber
3
Ini adalah alternatif yang baik untuk pendekatan yang diambil oleh OP. Sederhana dan efisien. Itu tidak benar-benar menjawab pertanyaan, yang menyangkut bagaimana memodifikasi metode koordinat kutub untuk menghasilkan variasi yang terdistribusi secara seragam. Mengapa kita peduli? Karena implikasinya: begitu Anda tahu cara menghasilkan titik yang terdistribusi secara merata dalam koordinat polar, Anda dapat menggunakan sampel penolakan (dan metode lain yang akrab) dalam koordinat polar untuk mengambil sampel dari daerah yang mungkin sangat rumit untuk sampel dalam koordinat Cartesian (pikirkan hipoklikloid , contohnya).
whuber
1
π/4
@whuber, terima kasih telah mendidik saya dengan mengomentari jawaban saya!
Haitao Du
3

Saya akan memberi Anda jawaban n-dimensi umum yang bekerja untuk kasus dua dimensi juga, tentu saja. Dalam tiga dimensi analog disk adalah volume bola padat (bola).

Ada dua pendekatan yang akan saya bahas. Salah satunya saya sebut "tepat" , dan Anda akan mendapatkan solusi lengkap dengan itu di R. Yang kedua saya sebut heuristik , dan itu hanya idenya, tidak ada solusi lengkap yang disediakan.

Solusi "Tepat"

Solusi saya didasarkan pada karya Marsaglia dan Muller . Pada dasarnya, itu terjadi sehingga vektor Gaussian dinormalisasi dengan normanya akan memberi Anda titik-titik yang terdistribusi secara merata pada hypersphere dimensi-d:

masukkan deskripsi gambar di sini

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")

masukkan deskripsi gambar di sini

Berikut cuplikan kode untuk case 3d, yaitu bola padat:

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])

masukkan deskripsi gambar di sini

Pendekatan heuristik

Vn(R)=πn2Γ(n2+1)Rn
Rn

saya=1dxsaya2<R2

1d+2

Aksakal
sumber
@Silverfish, Anda benar, saya memperbaiki bahasa
Aksakal
@Siverfish, lambat karena penggunaan varian Gaussian, tetapi bisa lebih cepat daripada sampel penolakan sederhana dalam kasus dimensi tinggi, yang tidak jelas bagi banyak orang, meskipun itu subjek yang berbeda
Aksakal
1/d,d
@whuber, saya menyalin paste, memperbaiki kesalahan ketik pada kekuatan kubus. Jika kami menggunakan Gaussian maka sampel penolakan tidak lebih baik, jadi kami harus menggunakan sesuatu yang berbentuk lonceng yang lebih cepat daripada Gaussian, Anda benar
Aksakal
0

Berikut adalah solusi alternatif di 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")

masukkan deskripsi gambar di sini

Q_Li
sumber
4
Bisakah Anda menjelaskan jawaban ini dalam bahasa Inggris yang sederhana? Kami sebenarnya bukan situs bantuan kode, & hanya jawaban kode yang harus dicegah.
gung - Reinstate Monica
5
01r <- seq(0, 1, by=1/10)
1
@whuber Terima kasih telah menunjukkan itu. Sebenarnya ini adalah ide utama saya untuk solusinya. Pendekatan saya adalah untuk menghasilkan banyak lingkaran seragam dengan jari-jari yang bervariasi, dan, untuk setiap lingkaran, jumlah titik sebanding dengan panjang jari-jarinya. Oleh karena itu, pada satuan panjang lingkaran dengan jari-jari berbeda, jumlah titiknya sama. Untuk menghindari sifat diskrit, kita dapat mengambil sampel rdari Uniform (0,1).
Q_Li