Petter Thowsen
Petter Thowsen

Reputation: 1727

Java Random.nextGaussian between 0 and 1

I'm working on an image editor and I'm about to implement filters. I decided to go with some kind of blur or noise.

Anyway, I decided I wanted a uniform filter so I read up on Random.nextGaussian().

However, since I'm working with RGB values that range from 0 to 255. How can I scale this random double value to fit within 0 and 255?

The random value returned by the nextGaussian() can range from -1 to 1 I believe.

So, I want to preserve the relative difference between the random values. "Scale" or "move the number range" if that makes sense.

I know it's possible but I can't figure it out. Thanks in advance.

Essentially, I need it to be a number between 0 and 1.

Upvotes: 4

Views: 4320

Answers (3)

Filip Pavičić
Filip Pavičić

Reputation: 71

You can fit Normal (Gaussian) distribution between ~[0,1] with adjusting mean and std. For example, use mean = 0.5, std = 0.15, and you will get value between [0,1] with total probability of 99.91%. In the end, you can ensure that value is strictly between [0,1].

N(0.5,1.15)

Supplier<Double> alphaSupplier = new Supplier<Double>() {
        
        @Override
        public Double get() {
            double value = new Random().nextGaussian() * 0.15 + 0.5;
            return Math.max(0, Math.min(1, value));
        }
    };
    
double random value = alphaSupplier.get();

Upvotes: 1

Merve Kaymak
Merve Kaymak

Reputation: 1

You can use nextGaussian() with Math.abs() so that you can obtain positive values of Gaussian distribution.

Random random = new Random();
double positiveRandomValue = Math.abs(random.nextGaussian());

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476534

In that case you should use nextDouble().

The Gaussian distribution is a distribution that ranges over the entire collection of double values (mathematically speaking, from minus infinity to positive infinity) with a peak around zero. The Gaussian distribution is thus not uniform.

The nextDouble() method draws numbers uniformly between 0 and 1 (0 included, 1 excluded).

You can thus draw a number randomly between 0 and 255 (both inclusive) using the following code:

Random rand = new Random();
int value = (int) math.floor(256.0*rand.nextDouble());

A faster algorithm is however masking a random integer (Random.nextInt):

Random rand = new Random();
int value = rand.nextInt()&0xff;

This algorithm isn't faster in big-oh analysis, but it saves one the more expensive nextDouble method call as well as a floating point multiplication and a float-to-int conversion.

Upvotes: 3

Related Questions