How can I generate a range of random floating point numbers in Julia?

Viewed 7072

I noticed that rand(x) where x is an integer gives me an array of random floating points. I want to know how I can generate an array of random float type variables within a certain range. I tried using a range as follows:

rand(.4:.6, 5, 5)

And I get:

 0.4  0.4  0.4  0.4  0.4
 0.4  0.4  0.4  0.4  0.4
 0.4  0.4  0.4  0.4  0.4
 0.4  0.4  0.4  0.4  0.4
 0.4  0.4  0.4  0.4  0.4

How can I get a range instead of the lowest number in the range?

4 Answers

Perhaps a bit more elegant, as you actually want to sample from a Uniform distribution, you can use the Distribution package:

julia> using Distributions
julia> rand(Uniform(0.4,0.6),5,5)
5×5 Array{Float64,2}:
 0.547602  0.513855  0.414453  0.511282  0.550517
 0.575946  0.520085  0.564056  0.478139  0.48139
 0.409698  0.596125  0.477438  0.53572   0.445147
 0.567152  0.585673  0.53824   0.597792  0.594287
 0.549916  0.56659   0.502528  0.550121  0.554276

The same method then applies from sampling from other well-known or user-defined distributions (just give the distribution as the first parameter to rand())

You need a step parameter:

rand(.4:.1:.6, 5, 5)

The .1 will provide a step for your range which is necessary for floating point numbers and not necessary for incrementing by 1. The issue is that it will assume 1 regardless of implicit precision. If you need the increment more precise than do the following:

rand(.4:.0001:.6, 5, 5)

This will give you a result that looks similar to:

 0.4587  0.557   0.586   0.4541  0.4686
 0.4545  0.4789  0.4921  0.4451  0.4212
 0.4373  0.5056  0.4229  0.5167  0.5504
 0.5494  0.4068  0.5316  0.4378  0.5495
 0.4368  0.4384  0.5265  0.5995  0.5231

You can do it with

julia> map(x->0.4+x*(0.6-0.4),rand(5,5))
5×5 Array{Float64,2}:
 0.455445  0.475007  0.518734  0.463064  0.400925
 0.509436  0.527338  0.566976  0.482812  0.501817
 0.405967  0.563425  0.574607  0.502343  0.483075
 0.50317   0.482894  0.54584   0.594157  0.528844
 0.50418   0.515788  0.5554    0.580199  0.505396

The general rule is

julia> map(  x -> start + x * (stop - start), rand(5,5)  )

where start is 0.4 and stop is 0.6

You can even generate a six sided dice this way by having x ranging from 1 to 7 that is 1 < x < 7 since the probability of x being exactly 1.0 or 7.0 is zero

julia> map(x->Integer(floor(1+x*(7-1))),rand(5,5))
5×5 Array{Int64,2}:
 2  6  6  3  2
 3  1  3  1  6
 5  4  6  1  5
 3  6  5  5  3
 3  4  3  5  4

or you can use

julia> rand(1:6,5,5)
5×5 Array{Int64,2}:
 3  6  3  5  5
 2  1  3  3  3
 1  5  4  1  5
 5  5  5  5  1
 3  2  1  5  6

Just another simple solution (using vectorized operations)

0.2 .* rand(5,5) .+ 0.4

And if efficiency matters...

@time 0.2 .* rand(10000, 10000) .+ 0.4
>> 0.798906 seconds (4 allocations: 1.490 GiB, 5.20% gc time)

@time map(x -> 0.4 + x * (0.6 - 0.4), rand(10000, 10000))
>> 0.836322 seconds (49.20 k allocations: 1.493 GiB, 7.08% gc time)

using Distributions 
@time rand(Uniform(0.4, 0.6), 10000, 10000)
>> 1.310401 seconds (2 allocations: 762.940 MiB, 1.51% gc time)

@time rand(0.2:0.000001:0.4, 10000, 10000)
>> 1.715034 seconds (2 allocations: 762.940 MiB, 6.24% gc time)
Related