clann_real_type metric_hausdorff(const struct matrix *a, const struct matrix *b) { unsigned int i, j; clann_real_type inf, sup = 0, d, *x, *y; for (i = 0; i < a->rows; i++) { inf = (clann_real_type) INT_MAX; x = matrix_value(a, i, 0); for (j = 0; j < b->rows; j++) { y = matrix_value(b, j, 0); d = metric_euclidean(x, y, a->cols); if (d < inf) inf = d; } if (inf > sup) sup = inf; } return sup; }
PyObject* euclidean(PyObject *self, PyObject *args) { /** * Convert input */ PyObject *a = NULL, *b = NULL; if (!PyArg_ParseTuple(args, "OO", &a, &b)) return NULL; /** * Call the function */ clann_matrix_type *x = PyCObject_AsVoidPtr(a), *y = PyCObject_AsVoidPtr(b); if (x->cols != y->cols) { PyErr_SetString(PyExc_RuntimeError, "matrices does not have the same size"); return NULL; } clann_real_type v = metric_euclidean(x->values, y->values, x->cols); /** * Convert output */ return Py_BuildValue("d", (double) v); }
unsigned int metric_hausdorff_limit(const struct matrix *a, const struct matrix *b, clann_real_type limit) { unsigned int i, j, count = 0; clann_real_type inf, d, *x, *y; for (i = 0; i < a->rows; i++) { inf = (clann_real_type) INT_MAX; x = matrix_value(a, i, 0); for (j = 0; j < b->rows; j++) { y = matrix_value(b, j, 0); d = metric_euclidean(x, y, a->cols); if (d < inf) inf = d; } if (inf > limit) count++; } return count; }
clann_real_type som_compute_neighborhood_distance(struct som *ann, clann_real_type *p, clann_real_type *winner) { clann_real_type d = metric_euclidean(p, winner, ann->grid.dimension); return CLANN_EXP(- (d * d) / ann->actual_width); }
unsigned int metric_hausdorff_angle(const struct matrix *a, const struct matrix *b, clann_real_type limit) { unsigned int i, j, length; clann_real_type inf, angle, count = 0, d, *x, *y, a_c[2], b_c[2]; length = a->cols > b->cols ? b->cols - 1 : a->cols - 1; for (i = 0; i < a->rows; i++) { inf = (clann_real_type) INT_MAX; x = matrix_value(a, i, 0); for (j = 0; j < b->rows; j++) { y = matrix_value(b, j, 0); d = metric_euclidean(x, y, length); if (d < inf) { inf = d; angle = y[length]; } } a_c[0] = CLANN_COS(x[length]); a_c[1] = CLANN_SIN(x[length]); b_c[0] = CLANN_COS(angle); b_c[1] = CLANN_SIN(angle); d = metric_dot_product(a_c, b_c, 2); if (d < 1 - limit) count++; } return count; }
void som_find_winner_neuron(struct som *ann, clann_real_type *x, clann_real_type **winner) { clann_real_type *w, distance, minimun = (clann_real_type) INT_MAX; clann_size_type i; for (i = 0; i < ann->grid.n_neurons; i++) { w = matrix_value(&ann->grid.weights, i, 0); distance = metric_euclidean(x, w, ann->input_size); if (distance < minimun) { minimun = distance; *winner = matrix_value(&ann->grid.indexes, i, 0); } } }
clann_void_type kmeans_train(struct kmeans *ann, const clann_matrix_type *x, clann_real_type learning_rate) { clann_size_type s, i, *mess = malloc(sizeof(clann_size_type) * x->rows); clann_real_type e, distance, minimun, *sample, *winner = NULL; ann->old_centers = clann_matrix_copy_new(&ann->centers); /* * Index vector used to shuffle the input presentation sequence */ for (s = 0; s < x->rows; s++) mess[s] = s; do { /* * For each input in the shuffle list */ clann_shuffle((clann_int_type *) mess, x->rows); e = 0; for (s = 0; s < x->rows; s++) { sample = clann_matrix_value(x, mess[s], 0); /* * Find the center most closer to current input sample */ minimun = metric_euclidean(sample, clann_matrix_value(&ann->centers, 0, 0), ann->center_size); winner = clann_matrix_value(&ann->centers, 0, 0); for (i = 1; i < ann->n_centers; i++) { distance = metric_euclidean(sample, clann_matrix_value(&ann->centers, i, 0), ann->center_size); if (distance < minimun) { minimun = distance; winner = clann_matrix_value(&ann->centers, i, 0); } } /* * Adjust winning center positions */ for (i = 0; i < ann->center_size; i++) winner[i] += learning_rate * (sample[i] - winner[i]); } /* * Compute the mean of changes */ for (i = 0; i < ann->n_centers; i++) { e += metric_euclidean(clann_matrix_value(&ann->centers, i, 0), clann_matrix_value(ann->old_centers, i, 0), ann->center_size); } e = e / ann->n_centers; #if CLANN_VERBOSE printf("N. [KMEANS] Mean centers' update: " CLANN_PRINTF ".\n", e); #endif clann_matrix_copy(&ann->centers, ann->old_centers); } while (e > ann->noticeable_change_rate); free((clann_void_type *) ann->old_centers); ann->old_centers = NULL; }