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 0
dan RAND_MAX
. RAND_MAX
tidak memiliki nilai tetap, tetapi guarantied bahwa itu akan setidaknya . PDF-nya seragam.
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.
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.
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_SUMS
100, dan RAND_MAX
32767.
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?
Jawaban:
Algoritme awal Anda membuat variabel acak yang terdistribusi secara seragam antara 0 dan 1. Variannya 1/12. Jika Anda menjumlahkan
NUM_GAUSSIAN_SUMS
contoh variansnyaNUM_GAUSSIAN_SUMS/12
. Untuk mendapatkan varian targetV
,, Anda harus mengalikan variabel acak yang dijumlahkan dengansqrt(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.
sumber
sumber
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
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.
sumber