let kmeans x c = let open MX in
let cpts0 = fst (draw_rows x c) in
let cpts1 = zeros c (col_num x) in
let assignment = Array.make (row_num x) (0, max_float) in
let _ = try for counter = 1 to 100 do
Log.info "iteration %i ..." counter; flush stdout;
iteri_rows (fun i v ->
iteri_rows (fun j u ->
let e = sum((v -@ u) **@ 2.) in
if e < snd assignment.(i) then assignment.(i) <- (j, e)
) cpts0
) x;
iteri_rows (fun j u ->
let l = UT.filteri_array (fun i y -> fst y = j, i) assignment in
let z = average_rows (rows x l) in
let _ = copy_row_to z cpts1 j in ()
) cpts0;
if cpts0 =@ cpts1 then failwith "converged" else ignore (cpts0 << cpts1)
done with exn -> () in
cpts1, UT.map_array fst assignment