void spawn_kitten(KittenManager * litter, gboolean ** seen_grid) { GArray * available; EntitySet * others; Level world; unsigned int ri; unsigned int * pending; unsigned int * chosen; others = litter->child->others; world = litter->child->world; available = available_squares(world, others); chosen = NULL; while (chosen == NULL) { ri = random_uint(available->len); pending = g_array_index(available, unsigned int *, ri); if (!seen_grid[pending[0]][pending[1]]) { chosen = pending; } } clone_kitten(litter, (float) chosen[0], (float) chosen[1]); free_available(available); }
// quick sort: requires n>1 static void qsort_map_array(map_elem_t *a, uint32_t n) { uint32_t i, j; map_elem_t x, y; // x = random pivot i = random_uint(n); x = a[i]; // swap a[i] and a[0] a[i] = a[0]; a[0] = x; i = 0; j = n; do { j--; } while (a[j].index > x.index); do { i++; } while (i <= j && a[i].index < x.index); while (i < j) { // swap a[i] and a[j] y = a[i]; a[i] = a[j]; a[j] = y; do { j--; } while (a[j].index > x.index); do { i++; } while (a[i].index < x.index); } // swap a[0] = x and a[j] a[0] = a[j]; a[j] = x; // recursive sort sort_map_array(a, j); j ++; sort_map_array(a + j, n - j); }
static void qsort_composite_array(composite_t **a, uint32_t n) { uint32_t i, j; composite_t *x, *y; // x = random pivot i = random_uint(n); x = a[i]; // swap x and a[0] a[i] = a[0]; a[0] = x; i = 0; j = n; do { j--; } while (a[j]->id > x->id); do { i++; } while (i <= j && a[i]->id < x->id); while (i < j) { y = a[i]; a[i] = a[j]; a[j] = y; do { j--; } while (a[j]->id > x->id); do { i++; } while (a[i]->id < x->id); } // pivot goes into a[j] a[0] = a[j]; a[j] = x; // sort a[0...j-1] and a[j+1 .. n-1] sort_composite_array(a, j); j++; sort_composite_array(a + j, n - j); }
/* * Quick sort: * - preconditions: high - low > 1 * - a[high] exists and is at least as large as all elements in a[low ... high-1]. * - sorting cannot cause memory leaks so we don't use the assignment or swap functions * from rationals.h */ static void quick_sort_monarray2(monomial_t *a, void *data, var_cmp_fun_t cmp, uint32_t low, uint32_t high) { uint32_t i, j, p; monomial_t pivot, aux; assert(high - low > 1); // random pivot i = low + random_uint(high - low); assert(low <= i && i < high); pivot = a[i]; p = pivot.var; // swap pivot and a[low] a[i] = a[low]; a[low] = pivot; i = low; j = high; for (;;) { do { j--; } while (cmp(data, p, a[j].var)); do { i++; } while (cmp(data, a[i].var, p)); if (i >= j) break; // swap a[i] and a[j] aux = a[i]; a[i] = a[j]; a[j] = aux; } // swap a[j] and a[low] = pivot a[low] = a[j]; a[j] = pivot; if (j > low + 1) quick_sort_monarray2(a, data, cmp, low, j); j ++; if (high > j + 1) quick_sort_monarray2(a, data, cmp, j, high); }
/* * Quick sort array a[low .. high-1] * - high - low must be larger than 1 * - a[high] must exist and have a larger index that all monomials in a[low ... high-1] * - sorting cannot cause memory leaks so we don't use the assignment or swap functions * from rationals.h. */ static void quick_sort_monarray(monomial_t *a, uint32_t low, uint32_t high) { uint32_t i, j, p; monomial_t pivot, aux; assert(high - low > 1); // random pivot i = low + random_uint(high - low); assert(low <= i && i < high); pivot = a[i]; p = pivot.var; // move pivot into a[low] a[i] = a[low]; a[low] = pivot; i = low; j = high; for (;;) { do { j--; } while (p < a[j].var); do { i++; } while (p > a[i].var); if (i >= j) break; // swap a[i] and a[j] aux = a[i]; a[i] = a[j]; a[j] = aux; } // swap a[j] and a[low] = pivot a[low] = a[j]; a[j] = pivot; if (j > low + 1) quick_sort_monarray(a, low, j); j ++; if (high > j + 1) quick_sort_monarray(a, j, high); }
static sexp sexp_random_uint_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { sexp res; if (! sexp_exact_integerp(arg0)) return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0); res = sexp_make_unsigned_integer(ctx, random_uint(sexp_uint_value(arg0))); return res; }
void test_seeding(unsigned int num) { struct random *p1, *p2; unsigned int seed[] = { 1, 2, 3, 4 }; int err; p1 = random_new(); p2 = random_new(); assert(p1); assert(p2); err = random_set_seed(p1, seed, ARRAY_SIZE(seed)); assert(err == 0); err = random_set_seed(p2, seed, ARRAY_SIZE(seed)); assert(err == 0); while(num--) assert(random_uint(p1) == random_uint(p2)); random_delete(p1); random_delete(p2); }
// quick sort: requires n > 1 static void qsort_ptr_array2(void **a, uint32_t n, void *data, ptr_cmp_fun_t cmp) { uint32_t i, j; void *x, *y; // x = random pivot i = random_uint(n); x = a[i]; // swap x and a[0] a[i] = a[0]; a[0] = x; i = 0; j = n; do { j--; } while (cmp(data, x, a[j])); // do { j--; } while (x < a[j]); do { i++; } while (i <= j && cmp(data, a[i], x)); // do { i++; } while (a[i] < x); while (i < j) { y = a[i]; a[i] = a[j]; a[j] = y; do { j--; } while (cmp(data, x, a[j])); // do { j--; } while (x < a[j]); do { i++; } while (cmp(data, a[i], x)); // do { j++; } while (a[i] < x); } // the pivot goes into a[j] a[0] = a[j]; a[j] = x; // sort a[0...j-1] and a[j+1 .. n-1] sort_ptr_array2(a, j, data, cmp); j++; sort_ptr_array2(a + j, n - j, data, cmp); }
void test_randomness(void) { struct random *rand; unsigned int n, i, num; rand = random_new(); assert(rand); num = 100; for(i = 0; i < num; ++i) { n = random_uint(rand); fprintf(stdout, "%-10u\t", n); if((i % 3) == 0) fprintf(stdout, "\n"); } fprintf(stdout, "\n"); random_delete(rand); }
static void qsort_varexp_array(varexp_t *a, uint32_t n) { uint32_t i, j; int32_t pivot; varexp_t aux; // random pivot i = random_uint(n); aux = a[i]; pivot = a[i].var; // swap with a[0]; a[i] = a[0]; a[0] = aux; i = 0; j = n; // test i <= j in second loop is required for termination // if all elements are smaller than the pivot. do { j--; } while (a[j].var > pivot); do { i++; } while (i <= j && a[i].var < pivot); while (i < j) { aux = a[i]; a[i] = a[j]; a[j] = aux; do { j--; } while (a[j].var > pivot); do { i++; } while (a[i].var < pivot); } // swap pivot = a[0] and a[j] aux = a[0]; a[0] = a[j]; a[j] = aux; // sort a[0 ... j-1] and a[j+1 ... n-1] sort_varexp_array(a, j); j ++; sort_varexp_array(a + j, n - j); }
static void qsort_terms(uint32_t n, term_t *a) { uint32_t i, j, r; term_t x, y; // assert(n > 1); // if (n <= 1) return; // random pivot i = random_uint(n); x = a[i]; r = bool_rank(x); // swap with a[0] a[i] = a[0]; a[0] = x; i = 0; j = n; do { j--; } while (bool_rank(a[j]) > r); do { i++; } while (i <= j && bool_rank(a[i]) < r); while (i < j) { y = a[i]; a[i] = a[j]; a[j] = y; do { j--; } while (bool_rank(a[j]) > r); do { i++; } while (bool_rank(a[i]) < r); } // place pivot a[0] = a[j]; a[j] = x; sort_terms(j, a); // a[0 ... j-1] j ++; sort_terms(n - j, a + j); // a[j+1 .. n-1] }
void test_duplicates(unsigned int num) { const struct map_config map_conf = { .size = MAP_DEFAULT_SIZE, .lower_bound = MAP_DEFAULT_LOWER_BOUND, .upper_bound = MAP_DEFAULT_UPPER_BOUND, .static_size = false, .key_compare = &compare_int, .key_hash = &hash_uint, .data_delete = NULL, }; struct map *m; struct random *random; unsigned int i, n, dups1, dups2;; int err; m = map_new(&map_conf); random = random_new(); assert(m); assert(random); dups1 = 0; for(i = 0; i < num; ++i) { n = random_uint(random); if(map_contains(m, (void *)(long) n)) { dups1 += 1; } else { err = map_insert(m, (void *)(long) n, (void *)(long) n); if(err < 0) { fprintf(stderr, "Warning: " "Map unable to insert %u in %uth iteration: %s\n", n, i, strerror(-err)); } } } random_delete(random); map_clear(m); srand(time(NULL)); dups2 = 0; for(i = 0; i < num; ++i) { n = rand(); if(map_contains(m, (void *)(long) n)) { dups2 += 1; } else { err = map_insert(m, (void *)(long) n, (void *)(long) n); if(err < 0) { fprintf(stderr, "Warning: " "Map unable to insert %u in %uth iteration: %s\n", n, i, strerror(-err)); } } } map_delete(m); fprintf(stdout, "random: After %u iterations there are %u (%lf %%) duplicates\n" "rand(): After %u iterations there are %u (%lf %%) duplicates\n", num, dups1, (double) dups1 / num, num, dups2, (double) dups2 / num); } void test_range(unsigned int num) { struct random *rand; unsigned int i, n; rand = random_new(); assert(rand); for(i = 0; i < num; ++i) { n = random_uint_range(rand, 0, 100); assert(n <= 100); n = random_uint_range(rand, 1000, 10000); assert(n >= 1000 && n <= 10000); n = random_uint_range(rand, 99999, 123456); assert(n >= 99999 && n <= 123456); n = random_uint_range(rand, (unsigned int) 1e6 + 1, (unsigned int) 1e8); assert(n >= (unsigned int) 1e6 + 1 && n <= (unsigned int) 1e8); n = random_uint_range(rand, 0, 0); assert(n == 0); n = random_uint_range(rand, 100, 100); assert(n == 100); } random_delete(rand); } int main(int argc, char *argv[]) { unsigned int num; if(argc == 2) num = atoi(argv[1]); else num = 0; test_randomness(); if(num) { test_seeding(num); test_duplicates(num); test_range(num); } fprintf(stdout, "Tests finished\n"); return EXIT_SUCCESS; }
/** Train the unsupervised SOM network. * * The network is initialized with random (non-graduate) values. It is then * trained with the image pixels (RGB). Once the network is done training the * centroids of the resulting clusters is returned. * * @note The length of the clusters depends on the parameter 'n'. The greatest * n, the more colors in the clusters, the less posterized the image. * * @param[out] res The resulting R, G and B clusters centroids. * @param[in] imgPixels The original image pixels. * @param[in] nbPixels The number of pixels of th image (height * width). * @param[in] nbNeurons The posterization leveldefined by its number of * neurons. * @param[in] noEpoch Number of training passes (a too small number of epochs * won't be enough for the network to correctly know the image but a too high * value will force the network to modify the wieghts so much that the image * can actually looks "ugly"). * @param[in] thresh The threshold value. The SOM delta parameter and the * training rate are dicreasing from one epoch to the next. The treshold value * set a stop condifition in case the value has fallen under this minimum * value. * * @return SOM_OK if everything goes right or SOM_NO_MEMORY if a memory * allocation (malloc) fail. */ int som_train(float **res, float **imgPixels, unsigned int nbPixels, int nbNeurons, int noEpoch, float thresh){ int mapWidth = // Map width. This can be calculated from its (int)sqrt(nbNeurons); // number of neurons as the map is square. int mapHeight = // Map height. This can be calculated from its (int)sqrt(nbNeurons); // number of neurons as the map is square. float delta = INT_MAX; // Start with an almost impossible value int it = 0; // Count the network iterations unsigned int pick; // The choosen input pixel float rad; // Neighbooring radius (keep dicreasing) float eta; // Learning rate (keep dicreasing) float pickRGB[3] = {0}; // Contains the choosen input RGB vector size_t choosen; // Best Matching Unit (BMU) int choosen_x; // BMU abscissa int choosen_y; // BMU ordinate float *neigh = // Neighbooring mask malloc(sizeof(float) * nbNeurons); if(neigh == NULL){ return SOM_NO_MEMORY; } memset(neigh, 0, nbNeurons); float *WR = // RED part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(WR == NULL){ return SOM_NO_MEMORY; } memset(WR, 0, nbNeurons); float *WG = // GREEN part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(WG == NULL){ return SOM_NO_MEMORY; } memset(WG, 0, nbNeurons); float *WB = // BLUE part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(WB == NULL){ return SOM_NO_MEMORY; } memset(WB, 0, nbNeurons); float *deltaR = // New RED part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(deltaR == NULL){ return SOM_NO_MEMORY; } memset(deltaR, 0, nbNeurons); float *deltaG = // New GREEN part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(deltaG == NULL){ return SOM_NO_MEMORY; } memset(deltaG, 0, nbNeurons); float *deltaB = // New BLUE part of the network weight vectors malloc(sizeof(float) * nbNeurons); if(deltaB == NULL){ return SOM_NO_MEMORY; } memset(deltaB, 0, nbNeurons); float *absDeltaR = // Absolute value of deltaR malloc(sizeof(float) * nbNeurons); if(absDeltaR == NULL){ return SOM_NO_MEMORY; } memset(absDeltaR, 0, nbNeurons); float *absDeltaG = // Absolute value of deltaG malloc(sizeof(float) * nbNeurons); if(absDeltaG == NULL){ return SOM_NO_MEMORY; } memset(absDeltaG, 0, nbNeurons); float *absDeltaB = // Absolute value of deltaB malloc(sizeof(float) * nbNeurons); if(absDeltaB == NULL){ return SOM_NO_MEMORY; } memset(absDeltaB, 0, nbNeurons); float *dists = // Vectors euclidian distances from input form malloc(sizeof(float) * nbNeurons); if(dists == NULL){ return SOM_NO_MEMORY; } memset(dists, 0, nbNeurons); /* Randomly initialize weight vectors */ srand(time(NULL)); random_sample(WR, nbNeurons); random_sample(WG, nbNeurons); random_sample(WB, nbNeurons); while(it < noEpoch && delta >= thresh){ /* Randomly choose an input form */ pick = random_uint(nbPixels); pickRGB[0] = imgPixels[pick][0]; pickRGB[1] = imgPixels[pick][1]; pickRGB[2] = imgPixels[pick][2]; /* Compute every vectors euclidian distance from the input form */ euclidian(dists, nbNeurons, WR, WG, WB, pickRGB); /* Determine the BMU */ choosen = arr_min_idx(dists, nbNeurons); choosen_x = (int)choosen % mapWidth; choosen_y = choosen / mapHeight; /* Compute the new neighbooring radius */ rad = som_radius(it, noEpoch, mapWidth, mapHeight); /* Find the BMU neighboors */ som_neighbourhood(neigh, choosen_x, choosen_y, rad, mapWidth, mapHeight); /* Compute the new learning rate */ eta = som_learning_rate(it, noEpoch); /* Compute new value of the network weight vectors */ compute_delta(deltaR, eta, neigh, nbNeurons, pickRGB[0], WR); compute_delta(deltaG, eta, neigh, nbNeurons, pickRGB[1], WG); compute_delta(deltaB, eta, neigh, nbNeurons, pickRGB[2], WB); /* Update the network weight vectors values */ arr_add(WR, deltaR, nbNeurons); arr_add(WG, deltaG, nbNeurons); arr_add(WB, deltaB, nbNeurons); arr_abs(absDeltaR, deltaR, nbNeurons); arr_abs(absDeltaG, deltaG, nbNeurons); arr_abs(absDeltaB, deltaB, nbNeurons); delta = arr_sum(absDeltaR, nbNeurons) + arr_sum(absDeltaG, nbNeurons) + arr_sum(absDeltaB, nbNeurons); it++; } res[0] = WR; res[1] = WG; res[2] = WB; free(dists); free(deltaR); free(deltaG); free(deltaB); free(absDeltaR); free(absDeltaG); free(absDeltaB); free(neigh); return SOM_OK; }
/* Block a random amount of time between min seconds and max seconds */ void sleep_within (int min, int max) { unsigned int cut_time = random_uint(max - min) + min; sleep(cut_time); }