@@ -182,51 +182,44 @@ end
182
182
183
183
184
184
# update assignments and related quantities
185
- function _kmed_update_assignments! (dist:: AbstractMatrix{T} , # in: (n, n)
185
+ # returns the total cost and the number of assignment changes
186
+ function _kmed_update_assignments! (dist:: AbstractMatrix{<:Real} , # in: (n, n)
186
187
medoids:: AbstractVector{Int} , # in: (k,)
187
188
assignments:: Vector{Int} , # out: (n,)
188
189
groups:: Vector{Vector{Int}} , # out: (k,)
189
- costs:: Vector{T} , # out: (n,)
190
- isinit :: Bool ) where T # in
190
+ costs:: AbstractVector{<:Real} , # out: (n,)
191
+ initial :: Bool ) # in
191
192
n = size (dist, 1 )
192
193
k = length (medoids)
193
- ch = 0
194
194
195
- if ! isinit
196
- for i = 1 : k
197
- empty! (groups[i])
198
- end
199
- end
195
+ # reset cluster groups (note: assignments are not touched yet)
196
+ initial || foreach (empty!, groups)
200
197
201
198
tcost = 0.0
199
+ ch = 0
202
200
for j = 1 : n
203
- p = 1
201
+ p = 1 # initialize the closest medoid for j
204
202
mv = dist[medoids[1 ], j]
205
203
206
- for i = 2 : k
207
- v = dist[medoids[i], j]
204
+ # find the closest medoid for j
205
+ @inbounds for i = 2 : k
206
+ m = medoids[i]
207
+ v = dist[m, j]
208
+ # assign if current medoid is closer or if it is j itself
208
209
if v < mv
209
210
p = i
210
211
mv = v
211
212
end
212
213
end
213
214
214
- if isinit
215
- assignments[j] = p
216
- else
217
- a = assignments[j]
218
- if p != a
219
- ch += 1
220
- end
221
- assignments[j] = p
222
- end
223
-
215
+ ch += ! initial && (p != assignments[j])
216
+ assignments[j] = p
224
217
costs[j] = mv
225
218
tcost += mv
226
219
push! (groups[p], j)
227
220
end
228
221
229
- return (tcost, ch):: Tuple{Float64, Int}
222
+ return (tcost, ch)
230
223
end
231
224
232
225
0 commit comments