@@ -4,30 +4,56 @@ const UniFinArr = UnivariateFiniteArray
4
4
5
5
Base. size (u:: UniFinArr , args... ) =
6
6
size (first (values (u. prob_given_ref)), args... )
7
-
8
- function Base. getindex (u:: UniFinArr{<:Any,<:Any,R,P,N} ,
9
- i:: Integer... ) where {R,P,N}
10
- prob_given_ref = LittleDict {R,P} ()
11
- for ref in keys (u. prob_given_ref)
12
- prob_given_ref[ref] = getindex (u. prob_given_ref[ref], i... )
7
+
8
+ function Base. getindex (u:: UniFinArr{<:Any,<:Any,R, P} , i... ) where {R, P}
9
+ # It's faster to generate `Array`s of `refs` and indexed `ref_probs`
10
+ # and pass them to the `LittleDict` constructor.
11
+ # The first element of `u.prob_given_ref` is used to get the dimensions
12
+ # for allocating these arrays.
13
+ u_dict = u. prob_given_ref
14
+ a, rest = Iterators. peel (u_dict)
15
+ # `a` is of the form `key => value`.
16
+ a_ref, a_prob = first (a), getindex (last (a), i... )
17
+
18
+ # Preallocate Arrays using the key and value of the first
19
+ # element (i.e `a`) of `u_dict`.
20
+ n_refs = length (u_dict)
21
+ refs = Vector {R} (undef, n_refs)
22
+ if a_prob isa AbstractArray
23
+ ref_probs = Vector {Array{P, ndims(a_prob)}} (undef, n_refs)
24
+ unf_constructor = UniFinArr
25
+ else
26
+ ref_probs = Vector {P} (undef, n_refs)
27
+ unf_constructor = UnivariateFinite
13
28
end
14
- return UnivariateFinite (u. scitype, u. decoder, prob_given_ref)
29
+
30
+ # Fill in the first elements
31
+ # Both `refs` and `ref_probs` are both of type `Vector` and hence support
32
+ # linear indexing with index starting at `1`
33
+ refs[1 ] = a_ref
34
+ ref_probs[1 ] = a_prob
35
+
36
+ # Fill in the rest
37
+ iter = 2
38
+ for (ref, ref_prob) in rest
39
+ refs[iter] = ref
40
+ ref_probs[iter] = getindex (ref_prob, i... )
41
+ iter += 1
42
+ end
43
+
44
+ # `keytype(prob_given_ref)` is always same as `keytype(u_dict)`.
45
+ # But `ndims(valtype(prob_given_ref))` might not be the same
46
+ # as `ndims(valtype(u_dict))`.
47
+ prob_given_ref = LittleDict {R, eltype(ref_probs)} (refs, ref_probs)
48
+
49
+ return unf_constructor (u. scitype, u. decoder, prob_given_ref)
15
50
end
16
51
17
52
function Base. getindex (u:: UniFinArr , idx:: CartesianIndex )
18
53
checkbounds (u, idx)
19
54
return u[Tuple (idx)... ]
20
55
end
21
56
22
- function Base. getindex (u:: UniFinArr{<:Any,<:Any,R,P,N} ,
23
- I... ) where {R,P,N}
24
- prob_given_ref = LittleDict {R,Array{P,N}} ()
25
- for ref in keys (u. prob_given_ref)
26
- prob_given_ref[ref] = getindex (u. prob_given_ref[ref], I... )
27
- end
28
- return UniFinArr (u. scitype, u. decoder, prob_given_ref)
29
- end
30
-
31
57
function Base. setindex! (u:: UniFinArr{S,V,R,P,N} ,
32
58
v:: UnivariateFinite{S,V,R,P} ,
33
59
i:: Integer... ) where {S,V,R,P,N}
0 commit comments