47 if (!(model.
n && n_means))
50 if (d != model.
dim() || means.size() != n_means * d)
53 gravity *= alpha / n_means;
55 std::uniform_int_distribution<size_t> random_target(0, model.
n - 1);
58 for (
size_t iter = 0; iter < iters; ++iter) {
59 size_t tgt = random_target(data.
gen);
62 float best_sqdist = std::numeric_limits<float>::infinity();
65 for (
size_t mi = 0; mi < n_means; ++mi) {
68 for (
size_t di = 0; di < d; ++di)
69 sqd +=
sqr(means[di + d * mi] - model.
data[di + d * tgt]);
71 if (sqd < best_sqdist) {
78 for (
size_t mi = 0; mi < n_means; ++mi)
79 for (
size_t di = 0; di < d; ++di)
81 ((mi == best) ? alpha : gravity) *
82 (model.
data[di + d * tgt] - means[di + d * mi]);
99 const float nisqsigma = -1.0 / (sigma * sigma);
101 if (!(model.
n && n_neurons))
104 if (d != model.
dim() || neurons.size() != n_neurons * d ||
105 map.size() != n_neurons)
108 std::uniform_int_distribution<size_t> random_target(0, model.
n - 1);
111 for (
size_t iter = 0; iter < iters; ++iter) {
112 size_t tgt = random_target(data.
gen);
115 float best_sqdist = std::numeric_limits<float>::infinity();
118 for (
size_t ni = 0; ni < n_neurons; ++ni) {
121 for (
size_t di = 0; di < d; ++di)
122 sqd +=
sqr(neurons[di + d * ni] - model.
data[di + d * tgt]);
124 if (sqd < best_sqdist) {
131 for (
size_t ni = 0; ni < n_neurons; ++ni) {
133 alpha * exp(glm::dot(map[best] - map[ni], map[best] - map[ni]) *
136 for (
size_t di = 0; di < d; ++di)
137 neurons[di + d * ni] +=
138 r * (model.
data[di + d * tgt] - neurons[di + d * ni]);
void kmeans_landmark_step(KMeansData &data, const ScaledData &model, size_t iters, float alpha, float gravity, LandmarkModel &lm)
Run a k-means-like optimization of high-dimensional landmark positions.
constexpr float sqr(float x)
Helper functions for squaring floats.
void som_landmark_step(KMeansData &data, const ScaledData &model, size_t iters, float alpha, float sigma, LandmarkModel &lm)
Run a SOM to optimize high-dimensional landmark positions.
void touch()
Make the cache dirty.
Structure for storing the kmeans-style data.
std::default_random_engine gen
Random engine for picking the points for training.
Model of the high- and low-dimensional landmarks.
size_t n_landmarks() const
Reurns number of the 2D landmarks.
std::vector< glm::vec2 > lodim_vertices
Array storing two-dimensional landmark coordinates.
std::vector< float > hidim_vertices
One-dimensional array storing d-dimensional landmark coordinates in row-major order.
Storage of the scaled data.
std::vector< float > data
Scaled data in the same format as DataModel::data.
size_t dim() const
Returns dimension of the scaled data.