-
Notifications
You must be signed in to change notification settings - Fork 16
/
random.jl
94 lines (86 loc) · 3.11 KB
/
random.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
gbrand(typeorrange, nrows, ncols, density; kwargs...)::GBMatrix
gbrand(rng::AbstractRNG, typeorrange, nrows, ncols, density; kwargs...)::GBMatrix
Construct a random `GBMatrix`, analogous to `sprand` from SparseArrays
# Arguments
- `rng::AbstractRNG`: Random number generator for both values and indices.
- `typeorrange`: Either a type such as `Float64`, or a range such as `1:10`.
Any input which supports `eltype(typeorrange)`.
- `nrows::Integer`, `ncols::Integer`: Dimensions of the result.
- `density::AbstractFloat`: The approximate density of result.
# Keywords
- `symmetric::Bool`: The result matrix is symmetric, Aᵀ = A.
- `pattern::Bool`: The result matrix consists solely of `one(eltype(typeorrange))`.
- `skewsymmetric::Bool`: The result matrix is skew-symmetric, Aᵀ = -A.
- `hermitian::Bool`: The result matrix is hermitian, aᵢⱼ = āⱼᵢ.
- `nodiagonal::Bool`: The result matrix has no values on the diagonal.
# Returns
- `GBMatrix`
"""
function gbrand(
rng::AbstractRNG, fn::F, typeorrange, nrows::Integer, ncols::Integer, density::AbstractFloat;
symmetric=false, pattern=false, skewsymmetric=false, hermitian=false, nodiagonal=false
) where F
type = eltype(typeorrange)
A = GBMatrix{type}(nrows, ncols)
(type <: Unsigned || type == Bool) && (skewsymmetric = false)
if nrows != ncols
symmetric = false
skewsymmetric = false
hermitian = false
end
if pattern || symmetric
skewsymmetric = false
hermitian = false
end
if skewsymmetric
hermitian = false
nodiagonal = false
end
if !(type <: Complex)
hermitian = false
end
# TODO: switch from A[i, j] = x, to COO->build
for _ ∈ 1:round(Int64, nrows * ncols * density)
i = rand(rng, 1:nrows)
j = rand(rng, 1:ncols)
nodiagonal && (i == j) && continue
if pattern
x = one(type)
else
x = fn(rng, typeorrange)
end
A[i, j] = x
symmetric && (A[j, i] = x)
skewsymmetric && (A[j, i] = -x)
hermitian && (A[j, i] = conj(x))
end
return A
end
function gbrand(
typeorrange, nrows::Integer, ncols::Integer, density::AbstractFloat;
symmetric=false, pattern=false, skewsymmetric=false, hermitian=false, nodiagonal=false
)
return gbrand(
default_rng(), rand, typeorrange, nrows, ncols, density;
symmetric, pattern, skewsymmetric, hermitian, nodiagonal
)
end
function gbrandn(
rng::AbstractRNG, type::DataType, nrows::Integer, ncols::Integer, density::AbstractFloat;
symmetric=false, pattern=false, skewsymmetric=false, hermitian=false, nodiagonal=false
)
return gbrand(
rng, randn, type, nrows, ncols, density;
symmetric, pattern, skewsymmetric, hermitian, nodiagonal
)
end
function gbrandn(
type::DataType, nrows::Integer, ncols::Integer, density::AbstractFloat;
symmetric=false, pattern=false, skewsymmetric=false, hermitian=false, nodiagonal=false
)
return gbrand(
default_rng(), randn, type, nrows, ncols, density;
symmetric, pattern, skewsymmetric, hermitian, nodiagonal
)
end