З якоюсь метою мені потрібно генерувати випадкові числа (дані) з "похилого рівномірного" розподілу. "Нахил" цього розподілу може змінюватись в якийсь розумний інтервал, і тоді мій розподіл повинен змінюватися від рівномірного до трикутного на основі схилу. Ось моя деривація:
Давайте спростимо та сформуємо дані від до (синій, червоний - рівномірний розподіл). Для отримання функції щільності ймовірності синьої лінії мені потрібно лише рівняння цієї лінії. Таким чином:
і відтоді (фотографія):
У нас це є:
Оскільки - PDF, CDF дорівнює:
Тепер давайте зробимо генератор даних. Ідея полягає в тому, що якщо я виправляю , випадкові числа можна обчислити, якщо я отримаю числа від рівномірного розподілу, як описано тут . Таким чином, якщо мені потрібно 100 випадкових чисел з мого розподілу з фіксованим , то для будь-якого з рівномірного розподілу існує від "похилого розподілу", а можна обчислити як:
З цієї теорії я зробив код у Python, який виглядає так:
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
Але згенеровані числа rand_numb
дуже близькі до нуля або до B (яке я встановив як 25). Немає різниці, коли я генерую 100 чисел, всі вони близькі до 25 або всі близькі до нуля. За один пробіг:
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]
Тому в моєму коді має бути щось дуже неправильне. Чи може хто-небудь допомогти мені з моїм виведенням або кодом? Зараз я божевільний, я не бачу жодної помилки. Я думаю, що код R дасть мені подібні результати.
B
theta
n
R
x<-runif(n,-1,1);x<-(ifelse(runif(n,-1,1)>theta*x,-x,x)+1)*(B/2)