/
apply.jl
153 lines (135 loc) · 3.84 KB
/
apply.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""
The `apply2list` function applies the function `fun`, the first argument, for
each element on `list` but avoiding `getfield` calls inside the loop.
The second argument of the macro is the `PairwiseListMatrix` that will be
iterated. `fun` should take two arguments; the first is the `list` field of
the `PairwiseListMatrix`, and the second is the index over that list at a
given iteration.
```jldoctest
julia> using PairwiseListMatrices
julia> plm = PairwiseListMatrix([1,2,3], false)
3×3 PairwiseListMatrix{Int64,false,Array{Int64,1}}:
0 1 2
1 0 3
2 3 0
julia> apply2list((list, k) -> println(list[k]), plm)
1
2
3
```
"""
function apply2list(fun, plm)
list = plm.list
for k in 1:length(list)
fun(list, k)
end
end
"""
The `apply2diag` function applies the function `fun`, the first argument,
for each element on the `diag` field of a`PairwiseListMatrix{T,false,VT}`
but avoiding `getfield` calls inside the loop. The second argument of the
macro is the `PairwiseListMatrix` that will be iterated. `fun` should take
two arguments; the first is the `diag` field of the `PairwiseListMatrix`,
and the second is the index over that vector of diagonal elements at a
given iteration.
```jldoctest
julia> using PairwiseListMatrices
julia> plm = PairwiseListMatrix([1,2,3], false)
3×3 PairwiseListMatrix{Int64,false,Array{Int64,1}}:
0 1 2
1 0 3
2 3 0
julia>apply2diag((diag, k) -> diag[k] += 10k, plm)
julia> plm
3×3 PairwiseListMatrix{Int64,false,Array{Int64,1}}:
10 1 2
1 20 3
2 3 30
```
"""
function apply2diag(fun, plm::PairwiseListMatrix{T,false,VT}) where {T, VT}
diag = plm.diag
for k in 1:length(diag)
fun(diag, k)
end
end
"""
The `apply2upper` function applies the `fun` function over the upper triangular
part of the `PairwiseListMatrix`. Set `use_diag` to `true` if the diagonal
needs to be included in the iteration. The function should take four
arguments, first the `list` and diag fields of the `PairwiseListMatrix`,
the second is the index `k` over that `list`, and the third and fourth are
the `i` and `j` indexes for the position `k` in the upper triangular
part of the matrix.
```jldoctest
julia> using PairwiseListMatrices
julia> plm = PairwiseListMatrix([1,2,3], true)
2×2 PairwiseListMatrix{Int64,true,Array{Int64,1}}:
1 2
2 3
julia> mat = zeros(Int, 2, 2)
2×2 Array{Int64,2}:
0 0
0 0
julia> apply2upper((list, k, i, j) -> mat[i, j] = list[k], plm; use_diag = true)
julia> mat
2×2 Array{Int64,2}:
1 2
0 3
```
"""
function apply2upper(fun, plm::PairwiseListMatrix{T,false,VT}; use_diag::Bool=false) where {T, VT}
N = plm.nelements
if use_diag
k = 0
diag = plm.diag
list = plm.list
for i in 1:N
for j in i:N
if i != j
k += 1
fun(list, k, i, j)
else
let list = diag, k = i
fun(list, k, i, j)
end
end
end
end
else
k = 0
list = plm.list
for i in 1:(N-1)
for j in (i+1):N
k += 1
fun(list, k, i, j)
end
end
end
end
function apply2upper(fun, plm::PairwiseListMatrix{T,true,VT}; use_diag::Bool=false) where {T, VT}
N = plm.nelements
if hasdiagonal(plm)
if use_diag
k = 0
list = plm.list
for i in 1:N
for j in i:N
k += 1
fun(list, k, i, j)
end
end
else
k = 0
list = plm.list
for i in 1:N
for j in i:N
k += 1
if i != j
fun(list, k, i, j)
end
end
end
end
end
end