src/Util.jl

changeset 33
a60d2f12ef93
parent 29
69242e8598eb
equal deleted inserted replaced
31:186b0a286431 33:a60d2f12ef93
10 # Our exports 10 # Our exports
11 ############## 11 ##############
12 12
13 export map_first_slice!, 13 export map_first_slice!,
14 reduce_first_slice, 14 reduce_first_slice,
15 norm₁, 15 ⬿
16 norm₂,
17 γnorm₂,
18 norm₂w,
19 norm₂²,
20 norm₂w²,
21 norm₂₁,
22 γnorm₂₁,
23 dot,
24 mean,
25 proj_norm₂₁ball!,
26 proj_nonneg!,
27 curry,
28 ⬿,
29 @threadsif,
30 @background,
31 @backgroundif
32
33
34 ##########
35 # Threads
36 ##########
37
38 macro threadsif(threads, loop)
39 return esc(:(if $threads
40 Threads.@threads $loop
41 else
42 $loop
43 end))
44 end
45
46 macro background(bgtask, fgtask)
47 return :(t = Threads.@spawn $(esc(bgtask));
48 $(esc(fgtask));
49 wait(t))
50 end
51
52 macro backgroundif(threads, bgtask, fgtask)
53 return :(if $(esc(threads))
54 @background $(esc(bgtask)) $(esc(fgtask))
55 else
56 $(esc(bgtask))
57 $(esc(fgtask))
58 end)
59 end
60
61 ########################
62 # Functional programming
63 #########################
64
65 curry = (f::Function,y...)->(z...)->f(y...,z...)
66 16
67 ############################### 17 ###############################
68 # For working with NamedTuples 18 # For working with NamedTuples
69 ############################### 19 ###############################
70 20
92 @inbounds accum=f(accum, @view(y[:, i])) 42 @inbounds accum=f(accum, @view(y[:, i]))
93 end 43 end
94 return accum 44 return accum
95 end 45 end
96 46
97 ###########################
98 # Norms and inner products
99 ###########################
100
101 @inline function dot(x, y)
102 @assert(length(x)==length(y))
103
104 accum=0
105 for i=1:length(y)
106 @inbounds accum += x[i]*y[i]
107 end
108 return accum
109 end
110
111 @inline function norm₂w²(y, w)
112 #Insane memory allocs
113 #return @inbounds sum(i -> y[i]*y[i]*w[i], 1:length(y))
114 accum=0
115 for i=1:length(y)
116 @inbounds accum=accum+y[i]*y[i]*w[i]
117 end
118 return accum
119 end
120
121 @inline function norm₂w(y, w)
122 return √(norm₂w²(y, w))
123 end
124
125 @inline function norm₂²(y)
126 #Insane memory allocs
127 #return @inbounds sum(i -> y[i]*y[i], 1:length(y))
128 accum=0
129 for i=1:length(y)
130 @inbounds accum=accum+y[i]*y[i]
131 end
132 return accum
133 end
134
135 @inline function norm₂(y)
136 return √(norm₂²(y))
137 end
138
139 @inline function norm₁(y)
140 accum=0
141 for i=1:length(y)
142 @inbounds accum=accum+abs(y[i])
143 end
144 return accum
145 end
146
147 @inline function γnorm₂(y, γ)
148 hubersq = xsq -> begin
149 x=√xsq
150 return if x > γ
151 x-γ/2
152 elseif x<-γ
153 -x-γ/2
154 else
155 xsq/(2γ)
156 end
157 end
158
159 if γ==0
160 return norm₂(y)
161 else
162 return hubersq(norm₂²(y))
163 end
164 end
165
166 function norm₂₁(y)
167 return reduce_first_slice((s, x) -> s+norm₂(x), y)
168 end
169
170 function γnorm₂₁(y,γ)
171 return reduce_first_slice((s, x) -> s+γnorm₂(x, γ), y)
172 end
173
174 function mean(v)
175 return sum(v)/prod(size(v))
176 end
177
178 @inline function proj_norm₂₁ball!(y, α)
179 α²=α*α
180
181 if ndims(y)==3 && size(y, 1)==2
182 @inbounds for i=1:size(y, 2)
183 @simd for j=1:size(y, 3)
184 n² = y[1,i,j]*y[1,i,j]+y[2,i,j]*y[2,i,j]
185 if n²>α²
186 v = α/√n²
187 y[1, i, j] *= v
188 y[2, i, j] *= v
189 end
190 end
191 end
192 else
193 y′=reshape(y, (size(y, 1), prod(size(y)[2:end])))
194
195 @inbounds @simd for i=1:size(y′, 2)# in CartesianIndices(size(y)[2:end])
196 n² = norm₂²(@view(y′[:, i]))
197 if n²>α²
198 @views y′[:, i] .*= (α/√n²)
199 end
200 end
201 end
202 end
203
204 @inline function proj_nonneg!(y)
205 @inbounds @simd for i=1:length(y)
206 if y[i] < 0
207 y[i] = 0
208 end
209 end
210 return y
211 end
212
213 end # Module 47 end # Module
214 48

mercurial