Untuk beberapa tujuan, saya perlu menghasilkan angka acak (data) dari distribusi "seragam miring". "Kemiringan" dari distribusi ini dapat bervariasi dalam beberapa interval yang masuk akal, dan kemudian distribusi saya harus berubah dari seragam menjadi segitiga berdasarkan pada kemiringan. Inilah derivasi saya:
Mari kita membuatnya sederhana dan menghasilkan data dari hingga (biru, merah adalah distribusi seragam). Untuk mendapatkan fungsi kerapatan probabilitas garis biru, saya hanya perlu persamaan garis itu. Jadi:B
dan karena (gambar):
Kami memiliki itu:
Karena adalah PDF, CDF sama dengan:
Sekarang mari kita membuat generator data. Idenya adalah, bahwa jika saya akan memperbaiki , angka acak dapat dihitung jika saya akan mendapatkan angka dari dari distribusi seragam seperti dijelaskan di sini . Jadi, jika saya memerlukan 100 angka acak dari distribusi saya dengan fixed , maka untuk setiap dari distribusi seragam ada dari "distribusi miring", dan dapat dihitung sebagai:( 0 , 1 ) x i x
Dari teori ini saya membuat kode dalam Python yang terlihat seperti:
import numpy as np
import math
import random
def tan_choice():
x = random.uniform(-math.pi/3, math.pi/3)
tan = math.tan(x)
return tan
def rand_shape_unif(N, B, tg_fi):
res = []
n = 0
while N > n:
c = random.uniform(0,1)
a = tg_fi/2
b = 1/B - (tg_fi*B)/2
quadratic = np.poly1d([a,b,-c])
rots = quadratic.roots
rot = rots[(rots.imag == 0) & (rots.real >= 0) & (rots.real <= B)].real
rot = float(rot)
res.append(rot)
n += 1
return res
def rand_numb(N_, B_):
tan_ = tan_choice()
res = rand_shape_unif(N_, B_, tan_)
return res
Tetapi angka-angka yang dihasilkan dari rand_numb
sangat dekat dengan nol atau ke B (yang saya setel 25). Tidak ada perbedaan, ketika saya menghasilkan 100 angka, semuanya hampir 25 atau semuanya hampir nol. Dalam sekali jalan:
num = rand_numb(100, 25)
numb
Out[140]:
[0.1063241766836174,
0.011086243095907753,
0.05690217839063588,
0.08551031241199764,
0.03411227661295121,
0.10927087752739746,
0.1173334720516189,
0.14160616846114774,
0.020124543145515768,
0.10794924067959207]
Jadi pasti ada sesuatu yang sangat salah dalam kode saya. Adakah yang bisa membantu saya dengan derivasi atau kode saya? Saya tergila-gila dengan ini sekarang, saya tidak dapat melihat kesalahan apa pun. Saya kira kode R akan memberi saya hasil yang serupa.
B
theta
n
R
x<-runif(n,-1,1);x<-(ifelse(runif(n,-1,1)>theta*x,-x,x)+1)*(B/2)
Jawaban:
Deriviasi Anda baik-baik saja. Perhatikan bahwa untuk mendapatkan kepadatan positif pada , Anda harus membatasi Dalam kode Anda sehingga Anda harus mengambil antara , di situlah kode Anda gagal.(0,B)
Anda bisa (dan harus) menghindari menggunakan solver kuadrat, dan kemudian pilih akar antara 0 dan . Persamaan polinomial kuadrat dalam harus dipecahkan adalah dengan Dengan konstruksi dan ; juga meningkat pada .B x
Dari sini mudah untuk melihat bahwa jika , bagian parabola yang kami minati adalah bagian dari sisi kanan parabola, dan akar untuk dijaga adalah yang tertinggi dari dua akar, yang adalah Sebaliknya, jika , parabola terbalik, dan kami tertarik pada sisi kiri bagian. Akar untuk menjaga adalah yang terendah. Memperhatikan tanda , tampaknya ini adalah root yang sama (yaitu yang dengan ) daripada pada kasus pertama.tanϕ>0
Berikut adalah beberapa kode R.
Dan dengan :ϕ<0
sumber