Generate random numbers with logarithmic distribution and custom slope

serg

Im trying to generate random integers with logarithmic distribution. I use the following formula:

idx = Math.floor(Math.log((Math.random() * Math.pow(2.0, max)) + 1.0) / Math.log(2.0));

This works well and produces sequence like this for 1000 iterations (each number represents how many times that index was generated):

[525, 261, 119, 45, 29, 13, 5, 1, 1, 1]

Fiddle

I am now trying to adjust the slope of this distribution so it doesn't drop as quickly and produces something like:

[150, 120, 100, 80, 60, ...]

Blindly playing with coefficients didn't give me what I wanted. Any ideas how to achieve it?

Douglas Zare

You mention a logarithmic distribution, but it looks like your code is designed to generate a truncated geometric distribution instead, although it is flawed. There is more than one distribution called a logarithmic distribution and none of them are that common. Please clarify if you really do mean one of them.

You compute floor[log_2 U] where U is uniformly distributed from 1 to (2^max)+1. This has a 1/2^max chance to produce max, but you clamp that to max-1. So, you have a 1/2^max chance to produce 0, 2/2^max chance to produce 1, 4/2^max chance to produce 2, ... up to a 1/2 + 1/2^max chance to produce max-1.

Present in your code, but missing from the description in the question, is that you are flipping the computed index around with

idx = (max-idx) - 1

After this, your chance to produce 0 is 1/2 + 1/2^max, and your chance to produce a value of k is 1/2^(k+1).

I think it is a mistake to let U be uniform on [1,2^max+1]. Instead, I think you want U to be uniform on [1,2^max]. Then your chance to generate idx=k is 2^(max-k-1)/((2^max)-1).

idx = Math.floor(Math.log((Math.random()*(Math.pow(2.0, max)-1.0)) + 1.0) / Math.log(2.0));

zmii's comment that you could get a flatter distribution by replacing both 2.0s with a value closer to 1.0 is good. The reason it produced unsatisfactory results for small values of max was that you were sampling uniformly from [1,1.3^max+1] instead of [1,1.3^max]. The extra +1 made a larger difference when max was smaller and the base was smaller. Try the following:

var zmii = 1.3;
idx = Math.floor(Math.log((Math.random()*(Math.pow(zmii, max)-1.0))+1.0) / Math.log(zmii));

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Distribution of Random Numbers

Generate random numbers with a given (numerical) distribution

C++ - generate random numbers following normal distribution within range

Generate random numbers with a given distribution

Generating random numbers of exponential distribution

generate N random numbers from a skew normal distribution using numpy

Generate random number from custom distribution

Generate random numbers from lognormal distribution in python

How to generate n random numbers from a normal distribution using random-fu (Haskell)?

Generate random numbers with bivariate gamma distribution in R

Generate random numbers from exponential distribution and model using python

How to generate random numbers with predefined probability distribution?

Rcpp - generate multiple random observations from custom distribution

Generate random numbers from empirical cumulative distribution function in MATLAB

Generate random bytearray from a distribution

How to use numpy.random to generate random numbers from a certain distribution?

Random geometric distribution across numbers

How to generate random numbers with skewed normal distribution in R?

How to generate n random numbers from negative binomial distribution?

Generate random numbers with a numerical distribution in given intervals

Matlab: generate random numbers from normal distribution with given probability

Making a custom Distribution of Random Numbers

Generate random numbers with uniform distribution (getting same number in loop)

Generate random numbers between range using std::binomial_distribution

How to generate random numbers with a normal distribution based on endpoints in excel?

Generate random numbers from a normal distribution

Generate random numbers in a specific range using beta distribution

Given a mean and standard deviation generate random numbers based on a geometric distribution and binomial distribution

Generate random numbers from a distribution given by a list of numbers in python