Вы можете использовать два отдельных распределения, но вам нужно убедиться, что количество выборок совпадает в граничной точке (r == 1
). Таким образом, вам нужно оценить необходимое количество выборок для левого (exp) и правого (1 / r) распределения. Интегралы по двум распределениям дают следующее:
Это означает, что вероятность для левого распределения в r = 1
равна exp(1) / 1.7183
, а для правого распределения - 1 / 6.9078
. Так что это дает соотношение ratio = left / right = 10.928
. Это означает, что вам нужно сгенерировать в ratio
раз больше значений в правом интервале, чем в левом, чтобы в итоге получилось одинаковое количество выборок на границе. Допустим, вы хотите сгенерировать N
выборок в общей сложности, это означает, что вам нужно сгенерировать N1 = N / (ratio + 1)
выборок в левом (exp) интервале и N2 = N * ratio / (ratio + 1)
выборок в правом (1 / r) интервале.
Вот пример кода:
import matplotlib.pyplot as plt
import numpy as np
r_max = 1000.0
integral_1 = np.exp(1.0) - 1.0 # 1.7183
integral_2 = np.log(r_max) # 6.9078
N = 2_000_000 # total number of samples
ratio = np.exp(1.0) / integral_1 * integral_2 # 10.928
N1 = int(N / (ratio + 1))
N2 = int(N * ratio / (ratio + 1))
# Use inverse transform sampling in the following.
s1 = np.log(integral_1 * np.random.random(size=N1) + 1.0)
s2 = np.exp(integral_2 * np.random.random(size=N2))
samples = np.concatenate((s1, s2))
np.random.shuffle(samples) # optionally shuffle the samples
plt.hist(samples, bins=int(20 * r_max))
plt.xlim([0, 5])
plt.show()
, который производит следующее распределение: