void svoGNGEuLearn(svo_gng_eu_t *gng_eu) { const bor_vec_t *input_signal; bor_net_node_t *nn; svo_gng_eu_node_t *n1, *n2, *n; bor_net_edge_t *nedge; svo_gng_eu_edge_t *edge; bor_real_t dist2; bor_list_t *list, *item, *item_tmp; if (gng_eu->step > gng_eu->params.lambda){ gng_eu->cycle += 1L; gng_eu->step = 1; } // 1. Get input signal input_signal = gng_eu->ops.input_signal(gng_eu->ops.input_signal_data); // 2. Find two nearest nodes to input signal svoGNGEuNearest(gng_eu, input_signal, &n1, &n2); // 3. Create connection between n1 and n2 if doesn't exist and set age // to zero svoGNGEuHebbianLearning(gng_eu, n1, n2); // 4. Increase error counter of winner node dist2 = svoGNGEuDist2(gng_eu, input_signal, n1); svoGNGEuNodeIncError(gng_eu, n1, dist2 * gng_eu->beta_n[gng_eu->params.lambda - gng_eu->step]); // 5. Adapt nodes to input signal using fractions eb and en // + 6. Increment age of all edges by one // + 7. Remove edges with age higher than age_max svoGNGEuMoveTowards(gng_eu, n1, input_signal, gng_eu->params.eb); // adapt also direct topological neighbors of winner node list = borNetNodeEdges(&n1->node); BOR_LIST_FOR_EACH_SAFE(list, item, item_tmp){ nedge = borNetEdgeFromNodeList(item); edge = bor_container_of(nedge, svo_gng_eu_edge_t, edge); nn = borNetEdgeOtherNode(&edge->edge, &n1->node); n = bor_container_of(nn, svo_gng_eu_node_t, node); // increase age (6.) edge->age += 1; // remove edge if it has age higher than age_max (7.) if (edge->age > gng_eu->params.age_max){ svoGNGEuEdgeDel(gng_eu, edge); if (borNetNodeEdgesLen(nn) == 0){ // remove node if not connected into net anymore svoGNGEuNodeDel(gng_eu, n); n = NULL; } } // move node (5.) if (n){ svoGNGEuMoveTowards(gng_eu, n, input_signal, gng_eu->params.en); } }
static void test2(bor_rand_mt_t *rand, bor_nn_t *n, bor_list_t *list, size_t num) { bor_nn_el_t *nn[10]; bor_list_t *nn2[10]; el_t *el, *el2; bor_vec2_t p; size_t len, len2, i; borVec2Set(&p, borRandMT(rand, -3, 3), borRandMT(rand, -3, 3)); len = borNNNearest(n, (const bor_vec_t *)&p, num, nn); len2 = borNearestLinear(list, (void *)&p, dist2, nn2, num, NULL); assertEquals(len, num); assertEquals(len2, num); for (i = 0; i < num; i++){ el = bor_container_of(nn[i], el_t, el); el2 = bor_container_of(nn2[i], el_t, list); if (el == el2){ assertEquals(el, el2); }else{ fprintf(stderr, "%.30f %.30f [%.30f] - %.30f %.30f [%.30f]\n", borVec2X(&el->w), borVec2Y(&el->w), borVec2Dist(&el->w, &p), borVec2X(&el2->w), borVec2Y(&el2->w), borVec2Dist(&el2->w, &p)); } } }
static int ltEl(const bor_pairheap_node_t *n1, const bor_pairheap_node_t *n2, void *_) { el_t *el1, *el2; el1 = bor_container_of(n1, el_t, node); el2 = bor_container_of(n2, el_t, node); return el1->val < el2->val; }
static void checkCorrect3(int ID, size_t num) { el_t *els, *el; int *ids; bor_pairheap_t *heap; bor_pairheap_node_t *n; size_t i; FILE *fout1, *fout2; char fn[300]; bor_rand_t r; borRandInit(&r); sprintf(fn, "regressions/tmp.TSPairHeap.rand-%d.out", ID); fout1 = fopen(fn, "w"); sprintf(fn, "regressions/TSPairHeap.rand-%d.out", ID); fout2 = fopen(fn, "w"); els = randomEls(num); ids = BOR_ALLOC_ARR(int, num); heap = borPairHeapNew(ltEl, NULL); for (i = 0; i < num; i++){ borPairHeapAdd(heap, &els[i].node); } for (i = 0; i < num; i += 10){ els[i].val += borRand(&r, 1, 100); borPairHeapUpdate(heap, &els[i].node); } i = 0; while (!borPairHeapEmpty(heap)){ n = borPairHeapExtractMin(heap); el = bor_container_of(n, el_t, node); fprintf(fout1, "%d\n", el->val); el = bor_container_of(n, el_t, node); ids[i] = el->id; i++; } qsort(els, num, sizeof(el_t), cmpIncEl); for (i = 0; i < num; i++){ fprintf(fout2, "%d\n", els[i].val); } borPairHeapDel(heap); free(els); free(ids); fclose(fout1); fclose(fout2); }
static bor_real_t dist62(void *item1, bor_list_t *item2, void *_) { el6_t *el2; bor_vec_t *v; v = (bor_vec_t *)item1; el2 = bor_container_of(item2, el6_t, list); return borVecDist2(6, v, el2->v); }
void borFiboRemove(bor_fibo_t *f, bor_fibo_node_t *n) { bor_list_t *list, *item, *item_tmp; bor_fibo_node_t *c; __borFiboCutCascade(f, n); // remove all its children list = &n->children; BOR_LIST_FOR_EACH_SAFE(list, item, item_tmp){ c = bor_container_of(item, bor_fibo_node_t, list); __borFiboCut(f, c, n); }
static void checkOrder(bor_rbtree_t *rbtree, el_t *els, size_t num) { int *vals, curval; size_t i; bor_rbtree_node_t *node; el_t *el; vals = BOR_ALLOC_ARR(int, num); for (i = 0; i < num; ++i){ vals[i] = els[i].val; } borSort(vals, num, sizeof(int), sortCmpAsc, NULL); node = borRBTreeMin(rbtree); el = bor_container_of(node, el_t, node); i = 0; BOR_RBTREE_FOR_EACH(rbtree, node){ curval = vals[i]; el = bor_container_of(node, el_t, node); assertEquals(el->val, curval); for (++i; i < num && vals[i] == curval; ++i); }
static void testCorrect(void) { bor_nn_params_t params; bor_real_t range[4] = { -15., 15., -18., 17. }; el_t *ns, *near[3]; bor_nn_el_t *el_linear[50], *el_gug[50], *el_vp[50]; int i, j, k; int len_linear, len_gug, len_vp; int incorrect; bor_vec2_t v; borNNParamsInit(¶ms); borNNParamsSetDim(¶ms, 2); params.gug.num_cells = 0; params.gug.max_dens = 1; params.gug.expand_rate = 2.; params.gug.aabb = range; params.type = BOR_NN_LINEAR; linear = borNNNew(¶ms); params.type = BOR_NN_GUG; gug = borNNNew(¶ms); params.type = BOR_NN_VPTREE; vp = borNNNew(¶ms); ns = elsNew(arr_len); for (k = 0; k < nearest_len; k++){ incorrect = 0; for (i=0; i < loops; i++){ fprintf(stderr, "[%d] %08d / %08d\r", (int)k, (int)i, (int)loops); borVec2Set(&v, borRand(&r, -10., 10.), borRand(&r, -10, 10)); len_linear = borNNNearest(linear, (const bor_vec_t *)&v, k + 1, el_linear); len_gug = borNNNearest(gug, (const bor_vec_t *)&v, k + 1, el_gug); len_vp = borNNNearest(vp, (const bor_vec_t *)&v, k + 1, el_vp); if (len_linear != len_gug || len_linear != len_vp || len_vp != len_gug || len_linear != k + 1){ incorrect = 1; } for (j = 0; j < k + 1; j++){ near[0] = bor_container_of(el_linear[j], el_t, linear); near[1] = bor_container_of(el_gug[j], el_t, gug); near[2] = bor_container_of(el_vp[j], el_t, vp); if (near[0] != near[1] || near[0] != near[2] || near[1] != near[2]){ incorrect = 1; } } } if (incorrect){ fprintf(stderr, "[%d] %08d / %08d FAIL\n", (int)k, (int)i, (int)loops); }else{ fprintf(stderr, "[%d] %08d / %08d OK\n", (int)k, (int)i, (int)loops); } } BOR_FREE(ns); borNNDel(linear); borNNDel(gug); borNNDel(vp); }
static void bench(void) { bor_nn_params_t params; bor_real_t range[4] = { -15., 15., -18., 17. }; el_t *ns, *near; bor_nn_el_t *el[50]; int i, j, k; bor_vec2_t v; int devnull; bor_timer_t timer; devnull = open("/dev/null", O_WRONLY); if (devnull < 0){ perror("Error: "); return; } borNNParamsInit(¶ms); borNNParamsSetDim(¶ms, 2); params.gug.num_cells = 0; params.gug.max_dens = 1; params.gug.expand_rate = 2.; params.gug.aabb = range; params.type = BOR_NN_LINEAR; linear = borNNNew(¶ms); params.type = BOR_NN_GUG; gug = borNNNew(¶ms); params.type = BOR_NN_VPTREE; vp = borNNNew(¶ms); ns = elsNew(arr_len); for (k = 0; k < nearest_len; k++){ borTimerStart(&timer); for (i=0; i < loops; i++){ //fprintf(stderr, "[%d] %08d / %08d\r", (int)k, (int)i, (int)loops); borVec2Set(&v, borRand(&r, -10., 10.), borRand(&r, -10, 10)); borNNNearest(linear, (const bor_vec_t *)&v, k + 1, el); for (j = 0; j < k + 1; j++){ near = bor_container_of(el[j], el_t, linear); write(devnull, &near->v, 1); } } borTimerStop(&timer); borTimerPrintElapsed(&timer, stderr, " - [%d] - linear - \n", k); borTimerStart(&timer); for (i=0; i < loops; i++){ //fprintf(stderr, "[%d] %08d / %08d\r", (int)k, (int)i, (int)loops); borVec2Set(&v, borRand(&r, -10., 10.), borRand(&r, -10, 10)); borNNNearest(gug, (const bor_vec_t *)&v, k + 1, el); for (j = 0; j < k + 1; j++){ near = bor_container_of(el[j], el_t, gug); write(devnull, &near->v, 1); } } borTimerStop(&timer); borTimerPrintElapsed(&timer, stderr, " - [%d] - gug - \n", k); borTimerStart(&timer); for (i=0; i < loops; i++){ //fprintf(stderr, "[%d] %08d / %08d\r", (int)k, (int)i, (int)loops); borVec2Set(&v, borRand(&r, -10., 10.), borRand(&r, -10, 10)); borNNNearest(vp, (const bor_vec_t *)&v, k + 1, el); for (j = 0; j < k + 1; j++){ near = bor_container_of(el[j], el_t, vp); write(devnull, &near->v, 1); } } borTimerStop(&timer); borTimerPrintElapsed(&timer, stderr, " - [%d] - vptree - \n", k); } BOR_FREE(ns); borNNDel(linear); borNNDel(gug); borNNDel(vp); close(devnull); }
static void clearFn(bor_pairheap_node_t *node, void *data) { el_t *el = bor_container_of(node, el_t, node); BOR_FREE(el); }
static void _svoGNGLearn(svo_gng_t *gng, size_t step) { const void *input_signal; bor_net_node_t *nn; svo_gng_node_t *n1, *n2, *n; bor_net_edge_t *nedge; svo_gng_edge_t *edge; bor_real_t dist2; bor_list_t *list, *item, *item_tmp; // 1. Get input signal input_signal = OPS(gng, input_signal)(OPS_DATA(gng, input_signal)); // 2. Find two nearest nodes to input signal OPS(gng, nearest)(input_signal, &n1, &n2, OPS_DATA(gng, nearest)); // 3. Create connection between n1 and n2 if doesn't exist and set age // to zero nedge = borNetNodeCommonEdge(&n1->node, &n2->node); if (!nedge){ edge = edgeNew(gng, n1, n2); }else{ edge = bor_container_of(nedge, svo_gng_edge_t, edge); } edge->age = 0; // 4. Increase error counter of winner node dist2 = OPS(gng, dist2)(input_signal, n1, OPS_DATA(gng, dist2)); nodeIncError(gng, n1, dist2 * gng->beta_n[gng->params.lambda - step]); // 5. Adapt nodes to input signal using fractions eb and en // + 6. Increment age of all edges by one // + 7. Remove edges with age higher than age_max OPS(gng, move_towards)(n1, input_signal, gng->params.eb, OPS_DATA(gng, move_towards)); // adapt also direct topological neighbors of winner node list = borNetNodeEdges(&n1->node); BOR_LIST_FOR_EACH_SAFE(list, item, item_tmp){ nedge = borNetEdgeFromNodeList(item); edge = bor_container_of(nedge, svo_gng_edge_t, edge); nn = borNetEdgeOtherNode(&edge->edge, &n1->node); n = bor_container_of(nn, svo_gng_node_t, node); // increase age (6.) edge->age += 1; // remove edge if it has age higher than age_max (7.) if (edge->age > gng->params.age_max){ edgeDel(gng, edge); if (borNetNodeEdgesLen(nn) == 0){ // remove node if not connected into net anymore nodeRemove(gng, n); n = NULL; } } // move node (5.) if (n){ OPS(gng, move_towards)(n, input_signal, gng->params.en, OPS_DATA(gng, move_towards)); } }