• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37539

pending completion
#37539

push

local

web-flow
add devdocs how to profile package precompilation with tracy (#49784)

1 of 1 new or added line in 1 file covered. (100.0%)

72624 of 83590 relevant lines covered (86.88%)

35576540.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/stdlib/Random/src/misc.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
## rand!(::BitArray) && bitrand
4

5
function rand!(rng::AbstractRNG, B::BitArray, ::SamplerType{Bool})
137,221✔
6
    isempty(B) && return B
137,221✔
7
    Bc = B.chunks
134,262✔
8
    rand!(rng, Bc)
134,262✔
9
    Bc[end] &= Base._msk_end(B)
134,262✔
10
    return B
134,262✔
11
end
12

13
"""
14
    bitrand([rng=default_rng()], [dims...])
15

16
Generate a `BitArray` of random boolean values.
17

18
# Examples
19
```jldoctest
20
julia> rng = MersenneTwister(1234);
21

22
julia> bitrand(rng, 10)
23
10-element BitVector:
24
 0
25
 0
26
 0
27
 0
28
 1
29
 0
30
 0
31
 0
32
 1
33
 1
34
```
35
"""
36
bitrand(r::AbstractRNG, dims::Dims)   = rand!(r, BitArray(undef, dims))
×
37
bitrand(r::AbstractRNG, dims::Integer...) = rand!(r, BitArray(undef, convert(Dims, dims)))
×
38

39
bitrand(dims::Dims)   = rand!(BitArray(undef, dims))
27✔
40
bitrand(dims::Integer...) = rand!(BitArray(undef, convert(Dims, dims)))
85,305✔
41

42

43
## randstring (often useful for temporary filenames/dirnames)
44

45
"""
46
    randstring([rng=default_rng()], [chars], [len=8])
47

48
Create a random string of length `len`, consisting of characters from
49
`chars`, which defaults to the set of upper- and lower-case letters
50
and the digits 0-9. The optional `rng` argument specifies a random
51
number generator, see [Random Numbers](@ref).
52

53
# Examples
54
```jldoctest
55
julia> Random.seed!(3); randstring()
56
"Lxz5hUwn"
57

58
julia> randstring(MersenneTwister(3), 'a':'z', 6)
59
"ocucay"
60

61
julia> randstring("ACGT")
62
"TGCTCCTC"
63
```
64

65
!!! note
66
    `chars` can be any collection of characters, of type `Char` or
67
    `UInt8` (more efficient), provided [`rand`](@ref) can randomly
68
    pick characters from it.
69
"""
70
function randstring end
71

72
let b = UInt8['0':'9';'A':'Z';'a':'z']
73
    global randstring
74

75
    function randstring(r::AbstractRNG, chars=b, n::Integer=8)
105,453✔
76
        T = eltype(chars)
105,453✔
77
        if T === UInt8
105,453✔
78
            str = Base._string_n(n)
105,371✔
79
            GC.@preserve str rand!(r, UnsafeView(pointer(str), n), chars)
105,371✔
80
            return str
105,371✔
81
        else
82
            v = Vector{T}(undef, n)
1,100✔
83
            rand!(r, v, chars)
1,100✔
84
            return String(v)
1,100✔
85
        end
86
    end
87

88
    randstring(r::AbstractRNG, n::Integer) = randstring(r, b, n)
1,100✔
89
    randstring(chars=b, n::Integer=8) = randstring(default_rng(), chars, n)
200,304✔
90
    randstring(n::Integer) = randstring(default_rng(), b, n)
4,119✔
91
end
92

93

94
## randsubseq & randsubseq!
95

96
# Fill S (resized as needed) with a random subsequence of A, where
97
# each element of A is included in S with independent probability p.
98
# (Note that this is different from the problem of finding a random
99
#  size-m subset of A where m is fixed!)
100
function randsubseq!(r::AbstractRNG, S::AbstractArray, A::AbstractArray, p::Real)
900✔
101
    require_one_based_indexing(S, A)
900✔
102
    0 <= p <= 1 || throw(ArgumentError("probability $p not in [0,1]"))
900✔
103
    n = length(A)
900✔
104
    p == 1 && return copyto!(resize!(S, n), A)
900✔
105
    empty!(S)
878✔
106
    p == 0 && return S
878✔
107
    nexpected = p * length(A)
872✔
108
    sizehint!(S, round(Int,nexpected + 5*sqrt(nexpected)))
872✔
109
    if p > 0.15 # empirical threshold for trivial O(n) algorithm to be better
872✔
110
        for i = 1:n
1,576✔
111
            rand(r) <= p && push!(S, A[i])
40,323,355✔
112
        end
80,645,922✔
113
    else
114
        # Skip through A, in order, from each element i to the next element i+s
115
        # included in S. The probability that the next included element is
116
        # s==k (k > 0) is (1-p)^(k-1) * p, and hence the probability (CDF) that
117
        # s is in {1,...,k} is 1-(1-p)^k = F(k).   Thus, we can draw the skip s
118
        # from this probability distribution via the discrete inverse-transform
119
        # method: s = ceil(F^{-1}(u)) where u = rand(), which is simply
120
        # s = ceil(log(rand()) / log1p(-p)).
121
        # -log(rand()) is an exponential variate, so can use randexp().
122
        L = -1 / log1p(-p) # L > 0
84✔
123
        i = 0
84✔
124
        while true
186,052✔
125
            s = randexp(r) * L
186,052✔
126
            s >= n - i && return S # compare before ceil to avoid overflow
186,052✔
127
            push!(S, A[i += ceil(Int,s)])
185,968✔
128
        end
185,968✔
129
        # [This algorithm is similar in spirit to, but much simpler than,
130
        #  the one by Vitter for a related problem in "Faster methods for
131
        #  random sampling," Comm. ACM Magazine 7, 703-718 (1984).]
132
    end
133
    return S
788✔
134
end
135

136
"""
137
    randsubseq!([rng=default_rng(),] S, A, p)
138

139
Like [`randsubseq`](@ref), but the results are stored in `S`
140
(which is resized as needed).
141

142
# Examples
143
```jldoctest
144
julia> rng = MersenneTwister(1234);
145

146
julia> S = Int64[];
147

148
julia> randsubseq!(rng, S, 1:8, 0.3)
149
2-element Vector{Int64}:
150
 7
151
 8
152

153
julia> S
154
2-element Vector{Int64}:
155
 7
156
 8
157
```
158
"""
159
randsubseq!(S::AbstractArray, A::AbstractArray, p::Real) = randsubseq!(default_rng(), S, A, p)
×
160

161
randsubseq(r::AbstractRNG, A::AbstractArray{T}, p::Real) where {T} =
900✔
162
    randsubseq!(r, T[], A, p)
163

164
"""
165
    randsubseq([rng=default_rng(),] A, p) -> Vector
166

167
Return a vector consisting of a random subsequence of the given array `A`, where each
168
element of `A` is included (in order) with independent probability `p`. (Complexity is
169
linear in `p*length(A)`, so this function is efficient even if `p` is small and `A` is
170
large.) Technically, this process is known as "Bernoulli sampling" of `A`.
171

172
# Examples
173
```jldoctest
174
julia> rng = MersenneTwister(1234);
175

176
julia> randsubseq(rng, 1:8, 0.3)
177
2-element Vector{Int64}:
178
 7
179
 8
180
```
181
"""
182
randsubseq(A::AbstractArray, p::Real) = randsubseq(default_rng(), A, p)
105✔
183

184

185
## rand Less Than Masked 52 bits (helper function)
186

187
"Return a sampler generating a random `Int` (masked with `mask`) in ``[0, n)``, when `n <= 2^52`."
188
ltm52(n::Int, mask::Int=nextpow(2, n)-1) = LessThan(n-1, Masked(mask, UInt52Raw(Int)))
35,698✔
189

190
## shuffle & shuffle!
191

192
"""
193
    shuffle!([rng=default_rng(),] v::AbstractArray)
194

195
In-place version of [`shuffle`](@ref): randomly permute `v` in-place,
196
optionally supplying the random-number generator `rng`.
197

198
# Examples
199
```jldoctest
200
julia> rng = MersenneTwister(1234);
201

202
julia> shuffle!(rng, Vector(1:16))
203
16-element Vector{Int64}:
204
  2
205
 15
206
  5
207
 14
208
  1
209
  9
210
 10
211
  6
212
 11
213
  3
214
 16
215
  7
216
  4
217
 12
218
  8
219
 13
220
```
221
"""
222
function shuffle!(r::AbstractRNG, a::AbstractArray)
5✔
223
    require_one_based_indexing(a)
5✔
224
    n = length(a)
5✔
225
    n <= 1 && return a # nextpow below won't work with n == 0
5✔
226
    @assert n <= Int64(2)^52
5✔
227
    mask = nextpow(2, n) - 1
5✔
228
    for i = n:-1:2
10✔
229
        (mask >> 1) == i && (mask >>= 1)
1,325✔
230
        j = 1 + rand(r, ltm52(i, mask))
1,325✔
231
        a[i], a[j] = a[j], a[i]
1,541✔
232
    end
2,645✔
233
    return a
5✔
234
end
235

236
shuffle!(a::AbstractArray) = shuffle!(default_rng(), a)
3✔
237

238
"""
239
    shuffle([rng=default_rng(),] v::AbstractArray)
240

241
Return a randomly permuted copy of `v`. The optional `rng` argument specifies a random
242
number generator (see [Random Numbers](@ref)).
243
To permute `v` in-place, see [`shuffle!`](@ref). To obtain randomly permuted
244
indices, see [`randperm`](@ref).
245

246
# Examples
247
```jldoctest
248
julia> rng = MersenneTwister(1234);
249

250
julia> shuffle(rng, Vector(1:10))
251
10-element Vector{Int64}:
252
  6
253
  1
254
 10
255
  2
256
  3
257
  9
258
  5
259
  7
260
  4
261
  8
262
```
263
"""
264
shuffle(r::AbstractRNG, a::AbstractArray) = shuffle!(r, copymutable(a))
2✔
265
shuffle(a::AbstractArray) = shuffle(default_rng(), a)
2✔
266

267
shuffle(r::AbstractRNG, a::Base.OneTo) = randperm(r, last(a))
×
268

269
## randperm & randperm!
270

271
"""
272
    randperm([rng=default_rng(),] n::Integer)
273

274
Construct a random permutation of length `n`. The optional `rng`
275
argument specifies a random number generator (see [Random
276
Numbers](@ref)). The element type of the result is the same as the type
277
of `n`.
278

279
To randomly permute an arbitrary vector, see [`shuffle`](@ref) or
280
[`shuffle!`](@ref).
281

282
!!! compat "Julia 1.1"
283
    In Julia 1.1 `randperm` returns a vector `v` with `eltype(v) == typeof(n)`
284
    while in Julia 1.0 `eltype(v) == Int`.
285

286
# Examples
287
```jldoctest
288
julia> randperm(MersenneTwister(1234), 4)
289
4-element Vector{Int64}:
290
 2
291
 1
292
 4
293
 3
294
```
295
"""
296
randperm(r::AbstractRNG, n::T) where {T <: Integer} = randperm!(r, Vector{T}(undef, n))
51✔
297
randperm(n::Integer) = randperm(default_rng(), n)
51✔
298

299
"""
300
    randperm!([rng=default_rng(),] A::Array{<:Integer})
301

302
Construct in `A` a random permutation of length `length(A)`. The
303
optional `rng` argument specifies a random number generator (see
304
[Random Numbers](@ref)). To randomly permute an arbitrary vector, see
305
[`shuffle`](@ref) or [`shuffle!`](@ref).
306

307
# Examples
308
```jldoctest
309
julia> randperm!(MersenneTwister(1234), Vector{Int}(undef, 4))
310
4-element Vector{Int64}:
311
 2
312
 1
313
 4
314
 3
315
```
316
"""
317
function randperm!(r::AbstractRNG, a::Array{<:Integer})
51✔
318
    n = length(a)
51✔
319
    @assert n <= Int64(2)^52
51✔
320
    n == 0 && return a
51✔
321
    a[1] = 1
51✔
322
    mask = 3
51✔
323
    @inbounds for i = 2:n
102✔
324
        j = 1 + rand(r, ltm52(i, mask))
34,175✔
325
        if i != j # a[i] is undef (and could be #undef)
34,175✔
326
            a[i] = a[j]
34,080✔
327
        end
328
        a[j] = i
34,175✔
329
        i == 1+mask && (mask = 2mask + 1)
34,175✔
330
    end
68,299✔
331
    return a
51✔
332
end
333

334
randperm!(a::Array{<:Integer}) = randperm!(default_rng(), a)
×
335

336

337
## randcycle & randcycle!
338

339
"""
340
    randcycle([rng=default_rng(),] n::Integer)
341

342
Construct a random cyclic permutation of length `n`. The optional `rng`
343
argument specifies a random number generator, see [Random Numbers](@ref).
344
The element type of the result is the same as the type of `n`.
345

346
!!! compat "Julia 1.1"
347
    In Julia 1.1 `randcycle` returns a vector `v` with `eltype(v) == typeof(n)`
348
    while in Julia 1.0 `eltype(v) == Int`.
349

350
# Examples
351
```jldoctest
352
julia> randcycle(MersenneTwister(1234), 6)
353
6-element Vector{Int64}:
354
 3
355
 5
356
 4
357
 6
358
 1
359
 2
360
```
361
"""
362
randcycle(r::AbstractRNG, n::T) where {T <: Integer} = randcycle!(r, Vector{T}(undef, n))
19✔
363
randcycle(n::Integer) = randcycle(default_rng(), n)
19✔
364

365
"""
366
    randcycle!([rng=default_rng(),] A::Array{<:Integer})
367

368
Construct in `A` a random cyclic permutation of length `length(A)`.
369
The optional `rng` argument specifies a random number generator, see
370
[Random Numbers](@ref).
371

372
# Examples
373
```jldoctest
374
julia> randcycle!(MersenneTwister(1234), Vector{Int}(undef, 6))
375
6-element Vector{Int64}:
376
 3
377
 5
378
 4
379
 6
380
 1
381
 2
382
```
383
"""
384
function randcycle!(r::AbstractRNG, a::Array{<:Integer})
19✔
385
    n = length(a)
19✔
386
    n == 0 && return a
19✔
387
    @assert n <= Int64(2)^52
19✔
388
    a[1] = 1
19✔
389
    mask = 3
19✔
390
    @inbounds for i = 2:n
38✔
391
        j = 1 + rand(r, ltm52(i-1, mask))
198✔
392
        a[i] = a[j]
198✔
393
        a[j] = i
198✔
394
        i == 1+mask && (mask = 2mask + 1)
198✔
395
    end
377✔
396
    return a
19✔
397
end
398

399
randcycle!(a::Array{<:Integer}) = randcycle!(default_rng(), a)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc