static void nv_lbgu_u(nv_matrix_t *u, const nv_matrix_t *means, const nv_matrix_t *data, const nv_matrix_t *labels, const nv_matrix_t *count) { int m; nv_matrix_t *scale = nv_matrix_alloc(1, count->m); nv_matrix_zero(u); for (m = 0; m < count->m; ++m) { NV_MAT_V(scale, m, 0) = 1.0f / NV_MAT_V(count, m, 0); } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1) #endif for (m = 0; m < data->m; ++m) { int k; float diff, min_error = FLT_MAX; int i = NV_MAT_VI(labels, m, 0); for (k = 0; k < means->m; ++k) { float dist; if (k == i) { continue; } dist = nv_euclidean2(means, k, data, m); if (min_error > dist) { min_error = dist; } } diff = min_error - nv_euclidean2(means, i, data, m); #ifdef _OPENMP #pragma omp critical (nv_lbgu_u) #endif { NV_MAT_V(u, i, 0) += diff; } } nv_matrix_free(&scale); }
static float nv_lbgu_e(nv_matrix_t *e, const nv_matrix_t *means, const nv_matrix_t *data, const nv_matrix_t *labels, const nv_matrix_t *count) { int m; float rmse = 0.0f; nv_matrix_zero(e); for (m = 0; m < data->m; ++m) { int i = NV_MAT_VI(labels, m, 0); float dist = nv_euclidean2(means, i, data, m); { NV_MAT_V(e, i, 0) += dist; rmse += dist; } } return rmse / data->m; }
// Euclidean distance float nv_euclidean(const nv_matrix_t *vec1, int m1, const nv_matrix_t *vec2, int m2) { return sqrtf(nv_euclidean2(vec1, m1, vec2, m2)); }