From 6e1983baa9eb48f2c66c5c86e1874cef5441458d Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 4 Jul 2018 14:37:33 +0200 Subject: [PATCH] rogueviz::kohonen:: additional options (save/load classify in binary format, visualize edges --- rogueviz-kohonen.cpp | 232 ++++++++++++++++++++++++++++++------------- rogueviz.h | 2 +- 2 files changed, 164 insertions(+), 70 deletions(-) diff --git a/rogueviz-kohonen.cpp b/rogueviz-kohonen.cpp index 8055e18e..6e6701ac 100644 --- a/rogueviz-kohonen.cpp +++ b/rogueviz-kohonen.cpp @@ -1,7 +1,7 @@ // Hyperbolic Rogue // Copyright (C) 2011-2018 Zeno and Tehora Rogue, see 'hyper.cpp' for details -// Kohonen's self-organizing networks. +// Kohonen's self-organizing maps. // This is a part of RogueViz, not a part of HyperRogue. namespace rogueviz { namespace kohonen { @@ -27,7 +27,8 @@ struct neuron { double udist; int lpbak; int col; - int samples, csample, bestsample; + int allsamples, drawn_samples, csample, bestsample; + neuron() { drawn_samples = allsamples = bestsample = 0; } }; vector colnames; @@ -182,7 +183,7 @@ void coloring() { vector listing; for(neuron& n: net) switch(c) { case -4: - listing.push_back(log(5+n.samples)); + listing.push_back(log(5+n.allsamples)); break; case -3: @@ -215,6 +216,32 @@ void coloring() { } } +void distribute_neurons() { + whowon.resize(samples); + + for(neuron& n: net) n.drawn_samples = 0; + + for(int s: samples_shown) { + auto& w = winner(s); + whowon[s] = &w; + w.drawn_samples++; + } + + ld rad = .25 * scalef; + + for(int id=0; idbase = w.where; + vdata[id].m->at = + spin(2*M_PI*w.csample / w.drawn_samples) * xpush(rad * (w.drawn_samples-1) / w.drawn_samples); + w.csample++; + } + + shmup::fixStorage(); + setindex(false); + } + void analyze() { setindex(true); @@ -233,31 +260,7 @@ void analyze() { maxudist = max(maxudist, n.udist); } - if(!noshow) { - - whowon.resize(samples); - - for(neuron& n: net) n.samples = 0; - - for(int id=0; idbase = w.where; - vdata[id].m->at = - spin(2*M_PI*w.csample / w.samples) * xpush(.25 * (w.samples-1) / w.samples); - w.csample++; - } - - shmup::fixStorage(); - setindex(false); - } + if(!noshow) distribute_neurons(); coloring(); } @@ -557,10 +560,29 @@ void uninit(int initto) { if(inited > initto) inited = initto; } -void showsample(int id) { - for(int ii: samples_shown) - if(ii == id) - return; +int max_group = 10; + +vector bdiffs; +vector bids; +vector bdiffn; + +int showsample(int id) { + for(int i=0; i= max_group) { + ld bdist = 1e18; + int whichid = -1; + for(int i=0; istore(); + return isize(samples_shown) - 1; } void showsample(string s) { @@ -584,13 +607,9 @@ void showsample(string s) { void showbestsamples() { vector samplesbak; for(auto& n: net) - if(n.samples) + if(n.allsamples) showsample(n.bestsample); analyze(); - for(auto& n: net) n.samples = 0; - for(int i=0; isamples++; } int kohrestrict = 1000000; @@ -685,7 +704,7 @@ void describe(cell *c) { if(cmode & sm::HELP) return; neuron *n = getNeuronSlow(c); if(!n) return; - help += "cell number: " + its(neuronId(*n)) + " (" + its(n->samples) + ")\n"; + help += "cell number: " + its(neuronId(*n)) + " (" + its(n->allsamples) + ")\n"; help += "parameters:"; for(int k=0; knet[k]); help += ", u-matrix = " + fts(n->udist); help += "\n"; @@ -923,39 +942,66 @@ void progress(string s) { } } +template void save_raw(string fname, const vector& v) { + FILE *f = fopen(fname.c_str(), "wb"); + fwrite(&v[0], sizeof(v[0]), v.size(), f); + fclose(f); + } + +template void load_raw(string fname, vector& v) { + FILE *f = fopen(fname.c_str(), "rb"); + if(!f) { fprintf(stderr, "file does not exist: %s\n", fname.c_str()); exit(1); } + fseek(f, 0, SEEK_END); + auto s = ftell(f); + rewind(f); + v.resize(s / sizeof(v[0])); + fread(&v[0], sizeof(v[0]), v.size(), f); + fclose(f); + } + +void do_classify() { + sominit(1); + if(bids.empty()) { + printf("Classifying...\n"); + bids.resize(samples, 0); + bdiffs.resize(samples, 1e20); + for(int s=0; s bdiffs(samples, 1e20); - vector bids(samples, 0); + do_classify(); - printf("Classifying...\n"); - - for(neuron& n: net) n.samples = 0; - - for(int s=0; s bdiffn(cells, 1e20); - - printf("Finding samples...\n"); - - for(int s=0; s> edgedata; + load_raw(fname_edges, edgedata); + int N = isize(edgedata); + if(pick > 0 && pick < N) { + for(int i=1; i> edgedata2; + for(auto p: edgedata) + edgedata2.emplace_back(showsample(p.first), showsample(p.second)); + distribute_neurons(); + for(auto p: edgedata2) + addedge(p.first, p.second, 0, false); } void klistsamples(const string& fname_samples, bool best, bool colorformat) { @@ -990,7 +1062,7 @@ void klistsamples(const string& fname_samples, bool best, bool colorformat) { if(!colorformat) fprintf(f, "%d\n", cols); if(best) for(int n=0; n