Menerapkan variabel acak Gaussian dengan menggunakan variabel acak seragam

11

Saya mencoba untuk menulis fungsi C ++ yang akan mengembalikan nilai acak Gaussian, dengan cara dan variansnya.

Ada fungsi perpustakaan rand(), yang mengembalikan angka acak antara 0dan RAND_MAX. RAND_MAXtidak memiliki nilai tetap, tetapi guarantied bahwa itu akan setidaknya . PDF-nya seragam.2151

Saya menggunakan Central Limit Theorem untuk mentransformasikannya rand()menjadi variabel Gaussian. Apa yang sebenarnya saya lakukan adalah memanggil rand()waktu yang ditentukan pengguna, lalu menjumlahkan nilai pengembaliannya, lalu menggeser artinya ke rata-rata yang ditentukan pengguna.

Gaussian PDF
Dalam merencanakan di atas, saya menelepon generator acak Gaussian saya untuk kali, dan memplot frekuensi nilai pengembaliannya. Seperti yang Anda lihat, variansnya sangat besar, karena ia dibuat dengan penjumlahan dari banyak nilai acak lainnya.107

Berhasil mengembalikan variabel Gaussian dengan Gaussian PDF dan dengan nilai rata-rata yang ditentukan. Namun, masalahnya adalah variansnya. Saya terjebak pada titik ini, karena saya tidak tahu bagaimana mengubah variansinya dengan nilai yang ditentukan pengguna.

Ini adalah kode saya (tidak lengkap untuk saat ini; parameter "Variance" diabaikan):

template <class T>
T Random::GetGaussian(T Mean /*= 0*/, T Variance /*= 1*/)
{
    T MeanOfSum = NUM_GAUSSIAN_SUMS / static_cast<T>(2);
    T Rand = 0;
    for (uint64_t i=0; i<NUM_GAUSSIAN_SUMS; i++)
    {
        Rand += static_cast<T>(rand()) / RAND_MAX;
    }
    return Rand - (MeanOfSum - Mean);
}

Asumsikan NUM_GAUSSIAN_SUMS100, dan RAND_MAX32767.

Saya ingin mengubah varians dari variabel acak sesuai dengan parameter fungsi. Pertanyaan saya adalah, bagaimana saya bisa mengubah varians dari variabel acak ini? Bagaimana saya bisa melakukannya?

hkBattousai
sumber
3
Ada cara yang lebih baik dan lebih cepat daripada teorema batas pusat untuk menghasilkan variabel acak Gaussian. Cari metode Box-Muller untuk satu; metode ziggurat dikatakan lebih baik.
Dilip Sarwate
3
Di masa lalu ketika waktu eksekusi merupakan pertimbangan penting, orang akan menjumlahkan U ( 0 , 1 ) variabel acak (bukan 100 ) dan mengurangi 6 untuk mendapatkan pendekatan sederhana ke standar N ( 0 , 1 ) variabel acak, dan kemudian skala Y = σ X + μ untuk mendapatkan variabel acak N ( μ , σ 2 ) . (Untuk alasan ini berhasil, lihat jawaban @ Hilmar). Untuk banyak aplikasi metode sederhana ini bekerja dengan sangat baik, tetapi nilainya terbatas pada kisaran12 U(0,1)1006N(0,1)Y=σX+μN(μ,σ2) dan ide sederhana ini dijatuhkan di pinggir jalan ketika Six-Sigma menjadi kata kunci. (μ-6σ,μ+6σ)
Dilip Sarwate
@DilipSarwate mungkin Anda harus memposting alternatif tersebut sebagai jawaban dengan alasan mengapa kami lebih suka
Ivo Flipse
@IvoFlipse Jawaban atas pertanyaan yang diajukan "Bagaimana cara saya memperbaiki varians setelah saya memperbaiki rerata?" pada dasarnya adalah apa yang diterima oleh Hilmar mengatakan, seperti yang dimodifikasi oleh komentar: perbaiki varians dengan penskalaan dan kemudian perbaiki kembali mean, atau lebih baik lagi, jangan mulai dengan memperbaiki mean terlebih dahulu karena Anda harus memperbaiki kembali nanti; perbaiki varians terlebih dahulu dengan penskalaan lalu perbaiki rerata. OP sama sekali tidak menunjukkan bahwa dia tertarik pada metode yang lebih baik dan bahkan belum memutakhirkan tautan nibot yang bahkan memiliki kode untuk metode Box-Muller. Jadi saya akan meninggalkan semuanya apa adanya.
Dilip Sarwate

Jawaban:

6

Algoritme awal Anda membuat variabel acak yang terdistribusi secara seragam antara 0 dan 1. Variannya 1/12. Jika Anda menjumlahkan NUM_GAUSSIAN_SUMScontoh variansnya NUM_GAUSSIAN_SUMS/12. Untuk mendapatkan varian target V,, Anda harus mengalikan variabel acak yang dijumlahkan dengan sqrt(V*12/NUM_GAUSSIAN_SUMS).

Sebagai catatan tambahan, templat akan bekerja dengan baik untuk float dan double tetapi akan ada masalah numerik yang signifikan dengan semua jenis titik tetap.

Hilmar
sumber
5

bagaimana saya bisa mengubah varians dari variabel acak ini?

cXcXc2X

Emre
sumber
cXcX
1
Pusat, skala ulang, lalu pulihkan rata-rata. Penskalaan variabel acak terpusat tidak akan memengaruhi rata-rata (nol).
Emre
1

Masih ada cara lain!

Pikirkan itu, bagaimana jika Anda menginginkan distribusi lain yang bertentangan dengan Gaussian? Dalam hal ini Anda tidak bisa menggunakan teorema Limit Pusat; bagaimana Anda mengatasinya?

Ada cara untuk mengubah variabel acak seragam menjadi PDF sewenang-wenang. Metode ini disebut Metode Transform Invers

U[0-1]

X=FX-1(U)

FX(x)

Oleh karena itu, yang perlu Anda lakukan adalah, terapkan fungsi CDF terbalik ke variabel yang telah Anda ambil dari sampel seragam rv.

Juga, tidak seperti metode sebelumnya - ini tidak akan memerlukan iterasi apa pun dan tidak akan bergantung pada berapa banyak iterasi yang akan diambil untuk membuat hasil lebih dekat dengan Gaussian.

Berikut adalah salah satu referensi yang memberikan bukti tentang ini.

Dipan Mehta
sumber
3
> Masih ada cara lain! Benar, tetapi tidak relevan dengan pertanyaan yang dipertimbangkan yang secara khusus tentang variabel acak Gaussian. Baik CDF Gaussian maupun kebalikannya tidak dapat diekspresikan dalam istilah elementer menggunakan jumlah operasi yang terbatas, sehingga metode yang disarankan tidak dapat digunakan.
Dilip Sarwate