mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	rogueviz:: added a header for kohonen.cpp and (newly added) embeddings.cpp
This commit is contained in:
		
							
								
								
									
										227
									
								
								rogueviz/embeddings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								rogueviz/embeddings.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,227 @@ | ||||
| #include "kohonen.h" | ||||
|  | ||||
| namespace rogueviz { | ||||
|  | ||||
| namespace embeddings { | ||||
|  | ||||
| embedding_type etype = eNatural; | ||||
|  | ||||
| /** landscape embedding */ | ||||
|  | ||||
| map<cell*, kohvec> landscape_at; | ||||
|  | ||||
| map<cellwalker, kohvec> delta_at; | ||||
|  | ||||
| void init_landscape(int dimensions) { | ||||
|   etype = eLandscape; | ||||
|   landscape_at.clear(); | ||||
|   delta_at.clear(); | ||||
|   landscape_at[currentmap->gamestart()].resize(dimensions, 0); | ||||
|   println(hlog, "initialized for ", currentmap->gamestart()); | ||||
|   } | ||||
|  | ||||
| void normalize(cellwalker& cw) { | ||||
|   int d = celldist(cw.at); | ||||
|   back: | ||||
|   if(GDIM == 3) { | ||||
|     auto& da = currentmap->dirdist(cw.at); | ||||
|     for(int j=0; j<S7; j++) if(da[j] == 1) { | ||||
|       cellwalker str = currentmap->strafe(cw, j); | ||||
|       int d1 = celldist(str.at); | ||||
|       if(d1 == d+1) continue; | ||||
|       else if(d1 == d-1) { d = d1; cw = str; goto back; } | ||||
|       else println(hlog, tie(d, d1)); | ||||
|       } | ||||
|     } | ||||
|   else if(S3 == OINF) return; | ||||
|   else if(S3 == 4) for(int s: {1, -1}) { | ||||
|     cellwalker str = (cw + s) + wstep + s; | ||||
|     int d1 = celldist(str.at); | ||||
|     if(d1 < d) { d = d1; cw = str; goto back; } | ||||
|     } | ||||
|   else { | ||||
|     while(true) { | ||||
|       cellwalker str = (cw + 1) + wstep + 2; | ||||
|       int d1 = celldist(str.at); | ||||
|       if(d1 > d) break; | ||||
|       d = d1; cw = str; | ||||
|       }     | ||||
|     while(true) { | ||||
|       cellwalker str = (cw - 2) + wstep - 1; | ||||
|       int d1 = celldist(str.at); | ||||
|       if(d1 > d) break; | ||||
|       d = d1; cw = str; | ||||
|       }     | ||||
|     } | ||||
|   } | ||||
|  | ||||
| ld gaussian_random() { | ||||
|   return (hrand(1000) + hrand(1000) - hrand(1000) - hrand(1000)) / 1000.; | ||||
|   } | ||||
|  | ||||
| void apply_delta(cellwalker cw, kohvec& v) { | ||||
|   normalize(cw); | ||||
|  | ||||
|   auto& da = delta_at[cw]; | ||||
|   if(da.empty()) { | ||||
|     da.resize(isize(v)); | ||||
|     for(auto& x: da) x = gaussian_random(); | ||||
|     } | ||||
|  | ||||
|   for(int i=0; i<isize(v); i++) v[i] += da[i]; | ||||
|   } | ||||
|  | ||||
| kohvec& get_landscape_at(cell *h) { | ||||
|   if(landscape_at.count(h)) return landscape_at[h]; | ||||
|  | ||||
|   int hd = celldist(h); | ||||
|   // if(hd > 2) exit(1); | ||||
|   for(int i=0; i<h->type; i++) { | ||||
|     cell *h1 = h->cmove(i); | ||||
|     auto hd1 = celldist(h1); | ||||
|     if(hd1 < hd) { | ||||
|       cellwalker cw(h, i); | ||||
|       auto& res = landscape_at[h]; | ||||
|       res = get_landscape_at(h1); | ||||
|       if(S3 == 3) { | ||||
|         apply_delta(cw, res); | ||||
|         apply_delta(cw+1, res); | ||||
|         } | ||||
|       else | ||||
|         apply_delta(cw, res); | ||||
|       break; | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   return landscape_at[h]; | ||||
|   } | ||||
|  | ||||
| /** signposts embedding */ | ||||
|  | ||||
| vector<cell*> signposts; | ||||
|  | ||||
| void mark_signposts(bool full, const vector<cell*>& ac) { | ||||
|   etype = eSignpost; | ||||
|   println(hlog, "marking signposts");   | ||||
|   signposts.clear(); | ||||
|   int maxd = 0; | ||||
|   if(!bounded) | ||||
|     for(cell *c: ac) maxd = max(celldist(c), maxd); | ||||
|   for(cell *c: ac) | ||||
|     if(full || c->type != 6) | ||||
|     if(bounded || celldist(c) == maxd) | ||||
|       signposts.push_back(c); | ||||
|   } | ||||
|  | ||||
| /** rug embedding */ | ||||
|  | ||||
| map<cell*, hyperpoint> rug_coordinates; | ||||
|  | ||||
| void generate_rug(int i, bool close) { | ||||
|   etype = eHypersian; | ||||
|   rug::init(); | ||||
|   while(rug::precision_increases < i) rug::physics(); | ||||
|   if(close) rug::close(); | ||||
|   for(auto p: rug::rug_map) | ||||
|     rug_coordinates[p.first] = p.second->native; | ||||
|   } | ||||
|  | ||||
| /** main function */ | ||||
|  | ||||
| void get_coordinates(kohvec& v, cell *c, cell *c0) { | ||||
|  | ||||
|   switch(etype) { | ||||
|     case eLandscape: {       | ||||
|       v = get_landscape_at(c); | ||||
|       columns = isize(v); | ||||
|       break; | ||||
|       } | ||||
|      | ||||
|     case eSignpost: | ||||
|       columns = isize(signposts); | ||||
|       alloc(v); | ||||
|       for(int i=0; i<isize(signposts); i++)  | ||||
|         v[i] = celldistance(signposts[i], c); | ||||
|       break; | ||||
|      | ||||
|     case eHypersian: { | ||||
|       columns = 3; | ||||
|       alloc(v); | ||||
|       auto h = rug_coordinates.at(c); | ||||
|       for(int i=0; i<3; i++) v[i] = h[i]; | ||||
|       break; | ||||
|       }     | ||||
|      | ||||
|     case eNatural: { | ||||
|       hyperpoint h = calc_relative_matrix(c, c0, C0) * C0;   | ||||
|  | ||||
|       using namespace euc; | ||||
|       auto& T0 = eu_input.user_axes; | ||||
|  | ||||
|       if(sphere) {       | ||||
|         columns = MDIM; | ||||
|         alloc(v); | ||||
|         for(int i=0; i<MDIM; i++) | ||||
|           v[i] = h[i]; | ||||
|         } | ||||
|       else if(euclid && bounded && WDIM == 2 && T0[0][1] == 0 && T0[1][0] == 0 && T0[0][0] == T0[1][1]) { | ||||
|         columns = 6; | ||||
|         alloc(v); | ||||
|         int s = T0[0][0]; | ||||
|         for(int i=0; i<3; i++) { | ||||
|           hyperpoint h1 = spin(120*degree*i) * h; | ||||
|           ld x = h1[1]; | ||||
|           ld alpha = 2 * M_PI * x / s / (sqrt(3) / 2); | ||||
|           println(hlog, kz(x), " -> ", kz(alpha)); | ||||
|           v[2*i] = cos(alpha); | ||||
|           v[2*i+1] = sin(alpha); | ||||
|           } | ||||
|         println(hlog, kz(h), " -> ", v); | ||||
|         } | ||||
|       else if(euclid && bounded && WDIM == 2) { | ||||
|         columns = 4; | ||||
|         alloc(v); | ||||
|         rug::clifford_torus ct; | ||||
|         h = ct.torus_to_s4(ct.actual_to_torus(h)); | ||||
|         for(int i=0; i<4; i++) | ||||
|           v[i] = h[i]; | ||||
|         } | ||||
|       else if(euclid && bounded && WDIM == 3) { | ||||
|         columns = 6; | ||||
|         alloc(v); | ||||
|         using namespace euc; | ||||
|         auto& T0 = eu_input.user_axes; | ||||
|         for(int i=0; i<3; i++) { | ||||
|           int s = T0[i][i]; | ||||
|           ld alpha = 2 * M_PI * h[i] / s; | ||||
|           v[2*i] = cos(alpha) * s; | ||||
|           v[2*i+1] = sin(alpha) * s; | ||||
|           } | ||||
|         } | ||||
|       else if(euclid && !quotient) { | ||||
|         columns = WDIM; | ||||
|         alloc(v); | ||||
|         for(int i=0; i<WDIM; i++) | ||||
|           v[i] = h[i]; | ||||
|         } | ||||
|       else { | ||||
|         println(hlog, "error: unknown geometry to get coordinates from"); | ||||
|         exit(1); | ||||
|         } | ||||
|       break; | ||||
|       } | ||||
|      | ||||
|     case eProjection: { | ||||
|       hyperpoint h = calc_relative_matrix(c, c0, C0) * C0;   | ||||
|       hyperpoint res; | ||||
|       applymodel(shiftless(h), res); | ||||
|       columns = WDIM; | ||||
|       if(models::is_3d(pconf)) columns = 3; | ||||
|       alloc(v); | ||||
|       for(int i=0; i<columns; i++) v[i] = res[i]; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| } | ||||
| @@ -4,27 +4,12 @@ | ||||
| // Kohonen's self-organizing maps.  | ||||
| // This is a part of RogueViz, not a part of HyperRogue. | ||||
|  | ||||
| #include "rogueviz.h" | ||||
| #include "kohonen.h" | ||||
|  | ||||
| namespace rogueviz { namespace kohonen { | ||||
|  | ||||
| void initialize_neurons(); | ||||
| void initialize_neurons_initial(); | ||||
| void initialize_dispersion(); | ||||
| void initialize_samples_to_show(); | ||||
| void clear(); | ||||
| void create_neurons(); | ||||
|  | ||||
|  | ||||
| int columns; | ||||
|  | ||||
| typedef vector<double> kohvec; | ||||
|  | ||||
| struct sample { | ||||
|   kohvec val; | ||||
|   string name; | ||||
|   }; | ||||
|  | ||||
| vector<sample> data; | ||||
|  | ||||
| map<int, int> sample_vdata_id; | ||||
| @@ -33,17 +18,6 @@ int whattodraw[3] = {-2,-2,-2}; | ||||
|  | ||||
| int min_group = 10, max_group = 10; | ||||
|  | ||||
| struct neuron { | ||||
|   kohvec net; | ||||
|   cell *where; | ||||
|   double udist; | ||||
|   int lpbak; | ||||
|   color_t col; | ||||
|   int allsamples, drawn_samples, csample, bestsample, max_group_here; | ||||
|   int debug; | ||||
|   neuron() { drawn_samples = allsamples = bestsample = 0; max_group_here = max_group; debug = 0; } | ||||
|   }; | ||||
|  | ||||
| vector<string> colnames; | ||||
|  | ||||
| kohvec weights; | ||||
| @@ -52,8 +26,6 @@ vector<neuron> net; | ||||
|  | ||||
| int neuronId(neuron& n) { return &n - &(net[0]); } | ||||
|  | ||||
| void alloc(kohvec& k) { k.resize(columns); } | ||||
|  | ||||
| bool neurons_indexed = false; | ||||
|  | ||||
| int samples; | ||||
| @@ -710,12 +682,6 @@ void step() { | ||||
|  | ||||
| int initdiv = 1; | ||||
|  | ||||
| flagtype KS_ROGUEVIZ = 1; | ||||
| flagtype KS_NEURONS = 2; | ||||
| flagtype KS_DISPERSION = 4; | ||||
| flagtype KS_SAMPLES = 8; | ||||
| flagtype KS_NEURONS_INI = 16; | ||||
|  | ||||
| flagtype state = 0; | ||||
|  | ||||
| vector<double> bdiffs; | ||||
|   | ||||
							
								
								
									
										95
									
								
								rogueviz/kohonen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								rogueviz/kohonen.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* a header file for kohonen and embedding */ | ||||
| #ifndef _KOHONEN_H_ | ||||
| #define _KOHONEN_H_ | ||||
|  | ||||
| #include "rogueviz.h" | ||||
|  | ||||
| namespace rogueviz { | ||||
|  | ||||
| namespace kohonen { | ||||
|  | ||||
| typedef vector<double> kohvec; | ||||
|  | ||||
| static const flagtype KS_ROGUEVIZ = 1; | ||||
| static const flagtype KS_NEURONS = 2; | ||||
| static const flagtype KS_DISPERSION = 4; | ||||
| static const flagtype KS_SAMPLES = 8; | ||||
| static const flagtype KS_NEURONS_INI = 16; | ||||
|  | ||||
| extern flagtype state; | ||||
|  | ||||
| extern int tmax; | ||||
| extern int samples; | ||||
| extern int t, tmax, lpct, cells; | ||||
| extern int gaussian; | ||||
|  | ||||
| extern int krad, kqty, kohrestrict; | ||||
| extern int qpct; | ||||
| extern int columns; | ||||
| extern double dispersion_end_at; | ||||
| extern int dispersion_count; | ||||
| extern double learning_factor, distmul; | ||||
| extern double ttpower; | ||||
| extern int min_group, max_group, columns; | ||||
|  | ||||
| struct neuron { | ||||
|   kohvec net; | ||||
|   cell *where; | ||||
|   double udist; | ||||
|   int lpbak; | ||||
|   color_t col; | ||||
|   int allsamples, drawn_samples, csample, bestsample, max_group_here; | ||||
|   int debug; | ||||
|   neuron() { drawn_samples = allsamples = bestsample = 0; max_group_here = max_group; debug = 0; } | ||||
|   }; | ||||
|  | ||||
| struct sample { | ||||
|   kohvec val; | ||||
|   string name; | ||||
|   }; | ||||
|  | ||||
| inline void alloc(kohvec& k) { k.resize(columns); } | ||||
|  | ||||
| extern kohvec weights; | ||||
| extern vector<sample> data; | ||||
| extern vector<int> samples_to_show; | ||||
| extern vector<neuron> net; | ||||
| extern vector<string> colnames; | ||||
|  | ||||
| void initialize_neurons(); | ||||
| void initialize_neurons_initial(); | ||||
| void initialize_dispersion(); | ||||
| void initialize_samples_to_show(); | ||||
| void clear(); | ||||
| void create_neurons(); | ||||
| void analyze(); | ||||
| void step(); | ||||
| void initialize_rv(); | ||||
| void set_neuron_initial(); | ||||
| bool finished(); | ||||
|  | ||||
| vector<cell*> gen_neuron_cells(); | ||||
| neuron& winner(int id); | ||||
| } | ||||
|  | ||||
| namespace embeddings { | ||||
|  | ||||
| using kohonen::columns; | ||||
| using kohonen::kohvec; | ||||
| using kohonen::alloc; | ||||
|  | ||||
| enum embedding_type { eProjection, eNatural, eLandscape, eSignpost, eHypersian }; | ||||
| extern embedding_type etype; | ||||
| void mark_signposts(bool full, const vector<cell*>& ac); | ||||
| void generate_rug(int i, bool close); | ||||
| void init_landscape(int dimensions); | ||||
|  | ||||
| extern map<cell*, hyperpoint> rug_coordinates; | ||||
| extern void get_coordinates(kohvec& v, cell *c, cell *c0); | ||||
|  | ||||
| } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif | ||||
| @@ -6,7 +6,6 @@ | ||||
| #include "objmodels.cpp" | ||||
| #include "smoothcam.cpp" | ||||
|  | ||||
| #include "kohonen.cpp" | ||||
| #include "staircase.cpp" | ||||
| #include "banachtarski.cpp" | ||||
| #include "pentagonal.cpp" | ||||
| @@ -55,5 +54,7 @@ | ||||
| #endif | ||||
| #include "highdim-demo.cpp" | ||||
|  | ||||
| #include "kohonen.cpp" | ||||
| #include "embeddings.cpp" | ||||
| //#endif | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue