В Python с numpy для заданного натурального числа x мы хотели бы получить массив (скажем, 20×2 или любую другую форму) равномерно распределенных чисел с плавающей запятой в интервале [0,x]. Обратите внимание, что интервал закрыт.
Судя по http://stackoverflow.com/a/33359758, совершенно испорченный подход
x=10
print(np.reshape([int.from_bytes(os.urandom(8))*x/((1<<64)-1) for i in range(40)],(20,2)))
Однако результаты зависят от операционной системы. Я также не понимаю, могут ли полученные числа распределяться равномерно и почему.
Обратите внимание, что (другой) подход, заключающийся в том, чтобы каким-то образом получить унифицированные числа с плавающей запятой IEEE 754 из [0,1] и затем умножить их на x, потенциально ошибочен, потому что, если x не является степенью 2, ваши числители (с точки зрения представления как числитель * 2^{…}) всегда будет кратен x, тогда как все значения, не кратные x, никогда не появятся.
Любая помощь? Подойдут и псевдослучайные числа (при условии, что они распределены равномерно).
Вы также можете предположить, что x мало, скажем, x<2^8, если это поможет.
Ваш вопрос требует пояснения. С математической точки зрения использование открытого или закрытого интервала не имеет никакого значения, поскольку вероятность получить любое действительное число, включая границы, равна 0. Это может иметь значение, если вы можете сгенерировать только конечное число случайных чисел в этом интервале. Теперь от того, как вы генерируете эти числа, будет зависеть, возможно ли получить границы и какова будет вероятность их получения, и это должен быть ваш выбор. Но, как уже спрашивалось: почему именно это будет актуально?
@AndrewYim Ничего особенного. Иногда вы видите закрытые интервалы в исходной задаче (от вашего учителя/начальника/клиента), что затем приводит к минимальной задаче.
@ThierryLathuille В [0,x] существует только конечное число чисел с плавающей запятой IEEE.
Это моя точка зрения. Какой бы метод вы ни использовали, вы можете сгенерировать только ограниченное число возможных случайных чисел, и это зависит от используемого вами метода. Итак, вам придется конкретно выбрать один метод, и это определит вероятность получения верхней границы — если, опять же, это как-то актуально.
@ThierryLathuille Наша задача — найти метод, который действительно выдает верхнюю границу x и делает это с той же вероятностью, что и любое другое число с плавающей запятой в [0,x]. Поскольку измерение радиоактивного распада обычно невозможно, статистическая/практическая однородность вполне подойдет. Что вы думаете о решении jakevdp?
@AlMa1r: Процедура генерации, которая присваивает равную вероятность каждому числу с плавающей запятой в диапазоне [0, x], будет чрезвычайно смещена в сторону малых значений, поскольку маленьких чисел с плавающей запятой гораздо больше, чем больших.
Попытка сделать это сталкивается с проблемами как со стороны «идеальных распределений действительных чисел», так и со стороны «реальности с плавающей запятой». Что касается «идеальных распределений действительных чисел», равномерное распределение в интервале действительных чисел [0, x] присваивает выходному значению x вероятность 0 и функционально идентично равномерному распределению в интервале [0, x). Аппроксимации этих распределений с плавающей запятой будут идентичными.
Что касается «реальности плавающей запятой», numpy.random.uniform
на самом деле не обещает, что все числа с плавающей запятой в выходном диапазоне на самом деле будут возможными выходными данными. Для общих диапазонов выходных данных он не сможет выдавать все допустимые выходные данные. Это справедливо почти для каждой реализации аналогичной функциональности на разных языках и в библиотеках. Таким образом, даже с чем-то вроде ответа jakevdp нет никакой гарантии, что удастся получить на выходе нужное значение конечной точки.
@user2357112 user2357112 Хорошее замечание по поводу предвзятости к небольшим значениям. Это не то, чего мы действительно хотим. Мы хотим, чтобы равномерное распределение было аппроксимировано ближайшими значениями с плавающей запятой. В этом случае вероятность получения x не будет равна нулю, поскольку случайные числа, немного меньшие, чем x, будут аппроксимироваться к x. Я думаю о правильной математической формулировке; если он у вас есть, отредактируйте вопрос соответствующим образом.
Вы можете настроить конечную точку на следующее число с плавающей запятой после максимального:
import numpy as np
def uniform_with_endpoint(low=0, hi=1, size=None):
return np.random.uniform(low, np.nextafter(hi, np.inf), size=size)
Это дает равномерное распределение, в котором hi
входит в возможные результаты.
Спасибо! Я не знал о numpy.nextafter
.
Из любопытства, зачем вам верхний диапазон?