66 const std::vector<std::valarray<double>> &X) {
67 size_t num_points = X.size();
68 size_t num_features = X[0].size();
74 std::cerr <<
"Error opening file " << fname <<
": "
75 << std::strerror(errno) <<
"\n";
80 for (
int i = 0; i < num_points; i++) {
82 for (
int j = 0; j < num_features; j++) {
84 if (j < num_features - 1) {
88 if (i < num_points - 1) {
143 const std::vector<std::vector<std::valarray<double>>> &W) {
144 std::ofstream fp(fname);
146 std::cerr <<
"File error (" << fname <<
"): " << std::strerror(errno)
154 for (
int i = 0; i < W.size(); i++) {
155 for (
int j = 0; j < W[0].size(); j++) {
156 double distance = 0.f;
158 int from_x = std::max<int>(0, i - R);
159 int to_x = std::min<int>(W.size(), i + R + 1);
160 int from_y = std::max<int>(0, j - R);
161 int to_y = std::min<int>(W[0].size(), j + R + 1);
164#pragma omp parallel for reduction(+ : distance)
166 for (l = from_x; l < to_x; l++) {
167 for (m = from_y; m < to_y; m++) {
168 auto d = W[i][j] - W[l][m];
169 double d2 = std::pow(d, 2).sum();
170 distance += std::sqrt(d2);
177 if (j < W[0].size() - 1) {
181 if (i < W.size() - 1) {
201 std::vector<std::vector<std::valarray<double>>> *W,
202 std::vector<std::valarray<double>> *D,
double alpha,
205 int num_out_x =
static_cast<int>(W->size());
206 int num_out_y =
static_cast<int>(W[0][0].size());
215 for (x = 0; x < num_out_x; x++) {
216 for (y = 0; y < num_out_y; y++) {
220 auto d = ((*W)[x][y] - X);
221 (*D)[x][y] = (d * d).
sum();
222 (*D)[x][y] = std::sqrt((*D)[x][y]);
228 int d_min_x = 0, d_min_y = 0;
232 int from_x = std::max(0, d_min_x - R);
233 int to_x = std::min(num_out_x, d_min_x + R + 1);
234 int from_y = std::max(0, d_min_y - R);
235 int to_y = std::min(num_out_y, d_min_y + R + 1);
242 for (x = from_x; x < to_x; x++) {
243 for (y = from_y; y < to_y; y++) {
252 (d_min_x - x) * (d_min_x - x) + (d_min_y - y) * (d_min_y - y);
253 double scale_factor = std::exp(-d2 / (2.f * alpha * alpha));
255 (*W)[x][y] += (X - (*W)[x][y]) * alpha * scale_factor;
270 std::vector<std::vector<std::valarray<double>>> *W,
272 size_t num_samples = X.size();
274 size_t num_out = W->size();
275 size_t R = num_out >> 2, iter = 0;
278 std::vector<std::valarray<double>> D(num_out);
279 for (
int i = 0; i < num_out; i++) D[i] = std::valarray<double>(num_out);
282 double past_dmin = 1.f;
283 double dmin_ratio = 1.f;
286 for (; alpha > 0 && dmin_ratio > 1e-5; alpha -= 1e-4, iter++) {
288 for (
int sample = 0; sample < num_samples; sample++) {
294 if (iter % 300 == 0 && R > 1) {
301 dmin_ratio = (past_dmin - dmin) / past_dmin;
302 if (dmin_ratio < 0) {
307 std::cout <<
"iter: " << iter <<
"\t alpha: " << alpha <<
"\t R: " << R
308 <<
"\t d_min: " << dmin_ratio <<
"\r";
331 const int N =
data->size();
332 const double R = 0.3;
334 const int num_classes = 4;
335 std::array<std::array<double, 2>, num_classes> centres = {
337 std::array<double, 2>({.5, .5}),
338 std::array<double, 2>({.5, -.5}),
339 std::array<double, 2>({-.5, .5}),
340 std::array<double, 2>({-.5, -.5})
346 for (i = 0; i < N; i++) {
348 int cls = std::rand() % num_classes;
351 data[0][i][0] =
_random(centres[cls][0] - R, centres[cls][0] + R);
352 data[0][i][1] =
_random(centres[cls][1] - R, centres[cls][1] + R);
373 std::vector<std::valarray<double>> X(N);
374 std::vector<std::vector<std::valarray<double>>> W(num_out);
375 for (
int i = 0; i < std::max(num_out, N); i++) {
378 X[i] = std::valarray<double>(features);
381 W[i] = std::vector<std::valarray<double>>(num_out);
382 for (
int k = 0; k < num_out; k++) {
383 W[i][k] = std::valarray<double>(features);
387 for (j = 0; j < features; j++) {
397 save_u_matrix(
"w11.csv", W);
398 kohonen_som(X, &W, 1e-4);
399 save_u_matrix(
"w12.csv", W);
412 const size_t N =
data->size();
413 const double R = 0.3;
415 const int num_classes = 4;
416 const std::array<std::array<double, 3>, num_classes> centres = {
418 std::array<double, 3>({.5, .5, .5}),
419 std::array<double, 3>({.5, -.5, -.5}),
420 std::array<double, 3>({-.5, .5, .5}),
421 std::array<double, 3>({-.5, -.5 - .5})
427 for (i = 0; i < N; i++) {
429 int cls = std::rand() % num_classes;
432 data[0][i][0] =
_random(centres[cls][0] - R, centres[cls][0] + R);
433 data[0][i][1] =
_random(centres[cls][1] - R, centres[cls][1] + R);
434 data[0][i][2] =
_random(centres[cls][2] - R, centres[cls][2] + R);
455 std::vector<std::valarray<double>> X(N);
456 std::vector<std::vector<std::valarray<double>>> W(num_out);
457 for (
int i = 0; i < std::max(num_out, N); i++) {
460 X[i] = std::valarray<double>(features);
463 W[i] = std::vector<std::valarray<double>>(num_out);
464 for (
int k = 0; k < num_out; k++) {
465 W[i][k] = std::valarray<double>(features);
469 for (j = 0; j < features; j++) {
479 save_u_matrix(
"w21.csv", W);
480 kohonen_som(X, &W, 1e-4);
481 save_u_matrix(
"w22.csv", W);
494 const size_t N =
data->size();
495 const double R = 0.2;
497 const int num_classes = 8;
498 const std::array<std::array<double, 3>, num_classes> centres = {
500 std::array<double, 3>({.5, .5, .5}),
501 std::array<double, 3>({.5, .5, -.5}),
502 std::array<double, 3>({.5, -.5, .5}),
503 std::array<double, 3>({.5, -.5, -.5}),
504 std::array<double, 3>({-.5, .5, .5}),
505 std::array<double, 3>({-.5, .5, -.5}),
506 std::array<double, 3>({-.5, -.5, .5}),
507 std::array<double, 3>({-.5, -.5, -.5})
513 for (i = 0; i < N; i++) {
515 int cls = std::rand() % num_classes;
518 data[0][i][0] =
_random(centres[cls][0] - R, centres[cls][0] + R);
519 data[0][i][1] =
_random(centres[cls][1] - R, centres[cls][1] + R);
520 data[0][i][2] =
_random(centres[cls][2] - R, centres[cls][2] + R);
541 std::vector<std::valarray<double>> X(N);
542 std::vector<std::vector<std::valarray<double>>> W(num_out);
543 for (
int i = 0; i < std::max(num_out, N); i++) {
546 X[i] = std::valarray<double>(features);
549 W[i] = std::vector<std::valarray<double>>(num_out);
550 for (
int k = 0; k < num_out; k++) {
551 W[i][k] = std::valarray<double>(features);
555 for (j = 0; j < features; j++) {
565 save_u_matrix(
"w31.csv", W);
566 kohonen_som(X, &W, 1e-4);
567 save_u_matrix(
"w32.csv", W);