-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.jl
136 lines (116 loc) · 3 KB
/
util.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
using Distributions
"""
partialsum(xs)
Return an array `ps` where `ps[i] = sum(xs[1:i])`
"""
function partialsum(xs)
if isempty(xs)
return []
end
ps = similar(xs)
ps[1] = xs[1]
for i = 2:lastindex(xs)
ps[i] = xs[i] + ps[i-1]
end
return ps
end
"""
fdiff(xs::Array)
Returns an array of length `length(xs) - 1` whose `i`th entry is `x[i+1] - x[i]`.
This is (almost) the inverse of `partialsum`.
"""
function fdiff(xs::Array)
if length(xs) < 2
return []
end
res = zeros(eltype(xs), length(xs) - 1)
xcurr = xs[1]
for i = 2:length(xs)
res[i-1] = xs[i] - xcurr
xcurr = xs[i]
end
return res
end
"""
weightedmedian(xs; residual=false)
Return the index `imin` where the residual `sum(xs[i:end]) - sum(xs[1:i])`
is smallest, but still greater than 0. This is a discrete analogue of the
median of a probability density function.
If `residual` is `false`, returns `imin`; if `true`, returns `(imin, residual)`
"""
function weightedmedian(xs; residual=false)
ps = partialsum(xs)
resmin = Inf
imin = 0
# TODO: could do binary search here?
for i = 1:lastindex(ps)
below = ps[i] - xs[i]
above = ps[end] - (i==1 ? 0 : ps[i-1])
res = above - below
if res < 0
break
elseif res < resmin
resmin = res
imin = i
end
end
@assert(imin != 0 && isfinite(resmin))
return residual ? (imin, resmin) : imin
end
function normalize!(xs::Array)
if isempty(xs)
return
end
m = minimum(xs)
M = maximum(xs)
if m == M
fill!(xs, 0)
else
map!(x->(x-m)/(M-m), xs, xs)
end
end
function normalize_audio!(xs::Array{T}) where T<:AbstractFloat
if isempty(xs)
return
end
m = minimum(xs)
M = maximum(xs)
if m == M
fill!(xs, T(0.))
else
s = LinearScale(m, M, T(-1.), T(1.))
map!(s, xs, xs)
end
end
struct LinearScale{T<:AbstractFloat}
fromlow::T
fromhigh::T
tolow::T
tohigh::T
end
function evaluate(s::LinearScale{T}, t::T) where T<:AbstractFloat
param = (t-s.fromlow)/(s.fromhigh-s.fromlow)
return s.tolow + param * (s.tohigh - s.tolow)
end
function invert(s::LinearScale{T}, t::T) where T<:AbstractFloat
param = (t-s.tolow)/(s.tohigh-s.tolow)
return s.fromlow + param * (s.fromhigh - s.fromlow)
end
function (s::LinearScale{T})(t::T) where T<:AbstractFloat
evaluate(s, t)
end
function bernoulli(p::Number)
Int(rand() < p)
end
function gaussian(u=0.0, s=1.0)
return rand(Normal(u,s))
end
function gaussianpulse(x::Real; u=0.0, s=1.0, shift=0.0, height=1.0)
scale = height * s * sqrt(2pi)
return shift + scale * pdf(Normal(u, s), x)
end
function threshold!(xs::AbstractArray, threshold::Number)
for i = 1:lastindex(xs)
xs[i] = xs[i] >= threshold ? 1 : 0
end
end