mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			230 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // analyze the SOM test results
 | |
| // Copyright (C) 2011-2022 Tehora and Zeno Rogue, see 'hyper.cpp' for details
 | |
| 
 | |
| #include "kohonen.h"
 | |
| 
 | |
| namespace rogueviz { 
 | |
| 
 | |
| namespace kohonen_test {
 | |
| extern string cg();
 | |
| extern int data_scale, embed_scale;
 | |
| extern int subdata_value;
 | |
| }
 | |
| 
 | |
| double UNKNOWN_RESULT = -3;
 | |
| 
 | |
| using namespace kohonen_test;
 | |
| 
 | |
| namespace analyzer {
 | |
| 
 | |
| using measures::manidata;
 | |
| using measures::MCOUNT;
 | |
| 
 | |
| struct maniset {
 | |
|   vector<string> names;
 | |
|   map<string, manidata> mdata;
 | |
|   };
 | |
| 
 | |
| maniset origs, embs;
 | |
| 
 | |
| void load_maniset(maniset& m, int scale) {
 | |
|   FILE *f = fopen((som_test_dir + "edgelists-" + its(scale) + ".txt").c_str(), "r");
 | |
|   while(true) {
 | |
|     char buf[200];
 | |
|     if(fscanf(f, "%s", buf) <= 0) break;
 | |
|     if(buf[0] != '#')
 | |
|       m.names.push_back(buf);
 | |
|     auto& md = m.mdata[buf];
 | |
|     int N, M;
 | |
|     hr::ignore(fscanf(f, "%d%d", &N, &M));
 | |
|     println(hlog, "reading ", buf, " of size ", N, " and ", M, " edges");
 | |
|     md.size = N;
 | |
|     auto& ed = md.edges;
 | |
|     for(int i=0; i<M; i++) {
 | |
|       int a, b;
 | |
|       hr::ignore(fscanf(f, "%d%d", &a, &b));
 | |
|       ed.emplace_back(a, b);
 | |
|       }
 | |
|     md.distances = measures::build_distance_matrix(N, md.edges);
 | |
|     }
 | |
|   fclose(f);
 | |
|   }
 | |
| 
 | |
| vector<pair<int, int> > vor_edges;
 | |
| 
 | |
| void analyze_test() {
 | |
| 
 | |
|   println(hlog, "loading original manifolds");
 | |
|   load_maniset(origs, data_scale);
 | |
|   println(hlog, "loading embedding manifolds");
 | |
|   load_maniset(embs, embed_scale);
 | |
| 
 | |
|   map<string, map<int, array<double, MCOUNT>>> results;
 | |
| 
 | |
|   string tablefile = som_test_dir + "table" + cg() + ".csv";
 | |
|   
 | |
|   if(1) {
 | |
|     
 | |
|     fhstream res(tablefile, "rt");
 | |
|     if(!res.f) { println(hlog, "table ", tablefile, " missing"); }
 | |
|     else {
 | |
|       println(hlog, "reading the old table ", tablefile);
 | |
|       string s = scanline(res);
 | |
|       while(true) {
 | |
|         s = scanline(res);
 | |
|         if(s == "") break;
 | |
|         int i = 0;
 | |
|         while(s[i] != ';') i++;
 | |
|         i++;
 | |
|         while(s[i] != ';') i++;
 | |
|         i++;
 | |
|         int id;
 | |
|         sscanf(s.c_str()+i, "%d", &id);
 | |
|         auto& res = results[s.substr(0, i-1)][id];
 | |
|         for(auto& d: res) d = UNKNOWN_RESULT;
 | |
|         sscanf(s.c_str()+i, "%d;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf", &id, &res[0], &res[1], &res[2], &res[3], &res[4], &res[5], &res[6], &res[7], &res[8], &res[9], &res[10], &res[11]);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   
 | |
|   for(string orig: origs.names) {
 | |
|     
 | |
|     string dir = som_test_dir + "pairs" + cg();
 | |
|   
 | |
|     for(string emb: embs.names) {
 | |
|       string fname = dir + "/" + orig + "-" + emb + ".txt";
 | |
|       if(!file_exists(fname)) continue;
 | |
|       FILE *f = fopen(fname.c_str(), "rt");
 | |
| 
 | |
|       string vorname = dir + "/" + orig + "-" + emb + ".vor";
 | |
|       if(!file_exists(vorname)) continue;
 | |
|       FILE *vor = fopen(vorname.c_str(), "rt");
 | |
| 
 | |
|       int No = origs.mdata[orig].size;
 | |
|       auto& edo = origs.mdata[orig].edges;
 | |
|       vector<pair<int, int>> edo_recreated;
 | |
|       
 | |
|       int new_results = 0;
 | |
| 
 | |
|       int current_row = -1;
 | |
| 
 | |
|       auto& res1 = results[orig + ";" + emb];
 | |
|       for(int it=0; it<100; it++) {
 | |
| 
 | |
|         bool know_result = res1.count(it);
 | |
|         auto& res = res1[it];
 | |
|         if(!know_result)
 | |
|           for(int kk=0; kk<MCOUNT; kk++)
 | |
|             res[kk] = UNKNOWN_RESULT;
 | |
| 
 | |
|         vector<int> mapp(No, -2);
 | |
|         for(int k=0; k<MCOUNT; k++) {        
 | |
|           bool recompute = false;
 | |
|           ld energy = 0;
 | |
|           if(res[k] == UNKNOWN_RESULT || recompute) {
 | |
| 
 | |
|             while(current_row < it) {
 | |
|               current_row++;
 | |
|               for(int i=0; i<No; i++) hr::ignore(fscanf(f, "%d", &mapp[i]));
 | |
|               int V = 0; hr::ignore(fscanf(vor, "%d", &V));
 | |
|               vor_edges.resize(V);
 | |
|               for(int i=0; i<V; i++) hr::ignore(fscanf(vor, "%d%d", &vor_edges[i].first, &vor_edges[i].second));
 | |
|               if(mapp.back() == -2) goto next_pair;
 | |
|               if(current_row == it)
 | |
|                 edo_recreated = measures::recreate_topology(mapp, edo);
 | |
|               }
 | |
| 
 | |
|             new_results++;
 | |
|             
 | |
|             energy = evaluate_measure(embs.mdata[emb], origs.mdata[orig], mapp, vor_edges, edo_recreated, k);
 | |
|             
 | |
|             if(recompute && res[k] != UNKNOWN_RESULT) {
 | |
|               if(abs(res[k] - energy) > 1e-5) {
 | |
|                 println(hlog, "ERROR in ", orig, "->", emb, " in ", cg(), " index ", it, " : was ", res[k], " is ", energy);
 | |
|                 if(subdata_value) res[k] = energy;
 | |
|                 }
 | |
|               }
 | |
|             else {
 | |
|               res[k] = energy;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       next_pair:
 | |
|       fclose(f);
 | |
|       
 | |
|       if(new_results) println(hlog, "computed ", new_results, " new results in ", cg(), " for ", orig, " -> ", emb);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|   fhstream o(som_test_dir + "summary" + cg() + ".html", "wt");
 | |
|   println(o, "<html><body>\n");
 | |
|   
 | |
|   if(1) {
 | |
|     println(o, "<table>\n");
 | |
|     
 | |
|     int manis = 0;
 | |
|     
 | |
|     for(string orig: origs.names) {
 | |
| 
 | |
|     print(o, "<tr><th>", orig, "</th>");
 | |
|     for(string emb: embs.names) print(o, "<th>", emb, "</th>");
 | |
|     print(o, "</tr>\n");
 | |
|     
 | |
|     for(int k: {0, 2, 4, 7, 8, 10, 11}) {
 | |
|       print(o, "<tr><td>", measures::catnames[k], "</td>");
 | |
|       
 | |
|       for(string emb: embs.names) {
 | |
|         ld tenergy = 0;
 | |
|         int att = 0;
 | |
|         auto& res1 = results[orig + ";" + emb];
 | |
| 
 | |
|         for(int it=0; it<100; it++) {
 | |
|           if(!res1.count(it)) continue;
 | |
|           auto& res = res1[it];
 | |
|           if(res[k] == UNKNOWN_RESULT) continue;
 | |
|           att++; tenergy += res[k];
 | |
|           }
 | |
|     
 | |
|         if(orig == emb)
 | |
|           print(o, "<td bgcolor=\"#C0FFFF\">");
 | |
|         else if(manis & 1)
 | |
|           print(o, "<td bgcolor=\"#FFFFC0\">");
 | |
|         else
 | |
|           print(o, "<td>");
 | |
|         if(att == 100)
 | |
|           print(o, tenergy * 1. / att);
 | |
|         else if(att)
 | |
|           print(o, tenergy * 1. / att, "?");
 | |
|         else
 | |
|           print(o, "???");
 | |
|         print(o, "</td>");
 | |
|         }
 | |
|       print(o, "</tr>\n");
 | |
|       }
 | |
|       manis++;
 | |
|       }
 | |
|     print(o, "</table>\n");
 | |
|     }
 | |
|   print(o, "</body></html>\n");
 | |
|   
 | |
|   fhstream res(som_test_dir + "table" + cg() + ".csv", "wt");
 | |
|   print(res, "orig;emb;index");
 | |
|   for(int i=0; i<MCOUNT; i++) print(res, ";", measures::catnames[i]); println(res);
 | |
|   
 | |
|   for(auto& p: results) {
 | |
|     for(auto& p2: p.second) {
 | |
|       auto &p3 = p2.second;
 | |
|       print(res, p.first, ";", p2.first);
 | |
|       for(int i=0; i<MCOUNT; i++) print(res, ";", p3[i]); println(res);
 | |
|       }
 | |
|     }  
 | |
|   }
 | |
| 
 | |
| auto khook = arg::add3("-analyze-test", analyze_test);
 | |
| 
 | |
| }}
 | |
| 
 | |
| 
 | |
|  
 | 
