Project
utils.h
Go to the documentation of this file.
1 #ifndef UTILS_H
2 #define UTILS_H
3 
11 #include "../extsrc/pugixml/src/pugixml.hpp"
13 #include "types/Profiles.h"
14 #include <matplot/matplot.h>
15 
16 #include "types/Category.h"
17 #include "types/Criteria.h"
18 #include "types/Perf.h"
19 #include <algorithm>
20 #include <chrono>
21 #include <fstream>
22 #include <iostream>
23 #include <numeric>
24 #include <random>
25 #include <set>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string>
29 #include <sys/stat.h>
30 #include <thread>
31 #include <time.h>
32 #include <typeinfo>
33 #include <unistd.h>
34 #include <unordered_map>
35 #include <utility>
36 #include <vector>
37 
45 template <typename T>
46 std::ostream &operator<<(std::ostream &out, const std::vector<T> &vec) {
47  out << "[";
48  for (std::size_t i = 0; i < vec.size(); i++) {
49  out << vec[i] << (i == vec.size() - 1 ? "" : ",");
50  }
51  out << "]";
52  return out;
53 }
54 
64 template <typename T>
65 std::vector<T> subVector(std::vector<T> const &v, int m, int n) {
66  auto first = v.begin() + m;
67  auto last = v.begin() + n + 1;
68  std::vector<T> vector(first, last);
69  return vector;
70 }
71 
78 struct simple_walker : pugi::xml_tree_walker {
79  virtual bool for_each(pugi::xml_node &node) {
80  for (int i = 0; i < depth(); ++i)
81  std::cout << " "; // indentation
82 
83  std::cout << node.type() << ": name='" << node.name() << "', value='"
84  << node.value() << "'\n";
85 
86  return true; // continue traversal
87  }
88 };
89 // ^^^^^^^^^^^^ HOW TO USE ^^^^^^^^^^^^
90 // pugi::xml_document doc;
91 // std::string path = data_dir + fileName;
92 // pugi::xml_parse_result result = doc.load_file(path.c_str());
93 
94 // simple_walker walker;
95 // doc.traverse(walker);
96 
97 inline bool fileExists(const std::string &name) {
98  struct stat buffer;
99  return (stat(name.c_str(), &buffer) == 0);
100 }
101 
111 inline int getRandomUniformInt(unsigned long int seed = 0, int min = 0,
112  int max = 100) {
113  std::mt19937 gen(seed);
114  std::uniform_int_distribution<> dis(min, max);
115  return dis(gen);
116 }
117 
127 inline float getRandomUniformFloat(unsigned long int seed = time(NULL),
128  float min = 0, float max = 1) {
129 
130  std::mt19937 gen(seed);
131  std::uniform_real_distribution<> dis(min, max);
132  return dis(gen);
133 }
134 
144 inline std::vector<float>
145 randomCategoriesLimits(int nbCategories, unsigned long int seed = time(NULL)) {
146  std::vector<float> catLimits;
147  for (int i = 0; i < nbCategories; i++) {
148  catLimits.push_back(getRandomUniformFloat(seed));
149  }
150  sort(catLimits.begin(), catLimits.end());
151  return catLimits;
152 }
153 
161 inline std::vector<std::string> getCriterionIds(std::vector<Perf> vectPerf) {
162  std::vector<std::string> criterionIds;
163  for (auto p : vectPerf) {
164  criterionIds.push_back(p.crit_);
165  }
166  return criterionIds;
167 };
168 
177 inline Perf getPerfOfCrit(std::vector<Perf> &vectPerf, std::string critId) {
178  for (Perf &p : vectPerf) {
179  if (p.crit_ == critId) {
180  return p;
181  }
182  }
183  throw std::invalid_argument("No performance for given criterion found");
184 }
185 
193 inline std::vector<std::string> getNameIds(std::vector<Perf> vectPerf) {
194  std::vector<std::string> NameIds;
195  for (auto p : vectPerf) {
196  NameIds.push_back(p.name_);
197  }
198  return NameIds;
199 };
200 
211 inline std::vector<Perf> createVectorPerf(std::string id, Criteria &criteria,
212  std::vector<float> &given_perf) {
213 
214  if (criteria.getCriterionVect().size() != given_perf.size()) {
215  throw std::invalid_argument(
216  "You must have the same number of performance value and criterias");
217  }
218  std::vector<Perf> vp;
219  std::vector<Criterion> criterion_vect = criteria.getCriterionVect();
220  for (int i = 0; i < criterion_vect.size(); i++) {
221  vp.push_back(Perf(id, criterion_vect[i].getId(), given_perf[i]));
222  }
223  return vp;
224 }
225 
235 inline std::vector<Perf> createVectorPerfWithNoPerf(std::string id,
236  Criteria &criteria) {
237  std::vector<Perf> vp;
238  std::vector<Criterion> criterion_vect = criteria.getCriterionVect();
239  for (int i = 0; i < criterion_vect.size(); i++) {
240  vp.push_back(Perf(id, criterion_vect[i].getId(), 0));
241  }
242  return vp;
243 }
244 
250 inline std::vector<double> getPerfFromPerfVect(std::vector<Perf> &p) {
251  std::vector<double> values;
252  for (auto perf : p) {
253  values.push_back(static_cast<double>(perf.value_));
254  }
255  return values;
256 }
257 
263 inline bool checkKey(std::unordered_map<int, int> &map, int key) {
264  // Key is not present
265  if (map.find(key) == map.end())
266  return 0;
267 
268  return 1;
269 }
279  matplot::cla();
280  // get all of the category ranks
281  std::unordered_map<std::string, Category> map =
283 
284  std::set<int> cat_set;
285  for (auto pair : map) {
286  cat_set.insert(pair.second.rank_);
287  }
288  // converting set to vector
289  std::vector<int> ranks;
290  ranks.assign(cat_set.begin(), cat_set.end());
291 
292  std::vector<std::vector<double>> performances;
293  std::unordered_map<int, int> index;
294  int nbCriteria = 0;
295  for (std::vector<Perf> &p : ap.getPerformanceTable()) {
296  int rank = map[p[0].name_].rank_;
297  if (nbCriteria == 0)
298  nbCriteria = p.size();
299  // if we have already seen this category yet
300  if (checkKey(index, rank)) {
301  std::vector<double> addPerf = getPerfFromPerfVect(p);
302  performances[index[rank]].insert(performances[index[rank]].end(),
303  addPerf.begin(), addPerf.end());
304  } else {
305  // create a new row for this new category and add Perf
306  performances.push_back(getPerfFromPerfVect(p));
307  // index of cat rank in the table
308  index[rank] = performances.size() - 1;
309  }
310  }
311  // creating reserve map
312  std::unordered_map<int, int> reverse_index;
313  for (auto pair : index) {
314  reverse_index[pair.second] = pair.first;
315  }
316 
317  int counter = 0;
318  for (auto catPerf : performances) {
319  int catRank = reverse_index[counter];
320  if (catPerf.size() % nbCriteria != 0) {
321  throw std::invalid_argument("Missing some criteria performance values in "
322  "AlternativePerformance object");
323  }
324  int nbRepetition = catPerf.size() / nbCriteria - 1;
325  std::vector<double> x(nbCriteria);
326  std::iota(std::begin(x), std::end(x), 1);
327  std::vector<double> x2 = x;
328  for (int i = 0; i < nbRepetition; ++i) {
329  x2.insert(std::end(x2), std::begin(x), std::end(x));
330  }
331 
332  auto l = matplot::scatter(x2, catPerf, 10);
333  l->marker_face(true);
334  l->marker_style(matplot::line_spec::marker_style::diamond);
335  l->display_name("Category " + std::to_string(catRank - 1));
336  matplot::hold(matplot::on);
337  counter++;
338  }
339  matplot::xlabel("Criteria");
340  matplot::ylabel("Performance Value");
341  matplot::title("Data Distribution Visualization");
342  matplot::legend();
343  matplot::show();
344 }
345 
353 inline void plotProfile(Profiles &p) {
354  matplot::cla();
355  // if (p.getMode() == "crit") {
356  // throw std::invalid_argument("Profile must be in alt mode");
357  // }
358 
359  std::vector<std::vector<double>> prof_performances;
360  for (std::vector<Perf> &perf : p.getPerformanceTable()) {
361  prof_performances.push_back(getPerfFromPerfVect(perf));
362  }
363  std::vector<double> x(prof_performances[0].size());
364  std::iota(std::begin(x), std::end(x), 1);
365 
366  int counter = 0;
367  for (auto proPerf : prof_performances) {
368 
369  auto l = matplot::plot(x, proPerf);
370  l->display_name("b" + std::to_string(counter));
371  matplot::hold(matplot::on);
372  counter++;
373  }
374  matplot::xlabel("Criteria");
375  matplot::ylabel("Performance Value");
376  matplot::title("Profile Visualization");
377  matplot::legend();
378  matplot::show();
379 }
380 
381 #endif
Dataset data structure.
Datastructure representing a category.
Datastructure representing a set of criterion.
Perf (single performance) data structure.
Profiles data structure.
Dataset datastructure.
Definition: AlternativesPerformance.h:35
std::unordered_map< std::string, Category > getAlternativesAssignments() const
Set of Criterion datastructure.
Definition: Criteria.h:25
std::vector< Criterion > getCriterionVect() const
Perf (single performance) data structure.
Definition: Perf.h:22
std::vector< std::vector< Perf > > getPerformanceTable() const
Profiles data structure.
Definition: Profiles.h:41
Definition: utils.h:78
std::vector< Perf > createVectorPerf(std::string id, Criteria &criteria, std::vector< float > &given_perf)
Definition: utils.h:211
void plotProfile(Profiles &p)
Definition: utils.h:353
float getRandomUniformFloat(unsigned long int seed=time(NULL), float min=0, float max=1)
Definition: utils.h:127
bool checkKey(std::unordered_map< int, int > &map, int key)
Definition: utils.h:263
Perf getPerfOfCrit(std::vector< Perf > &vectPerf, std::string critId)
Definition: utils.h:177
void plotGlobalData(AlternativesPerformance &ap)
Definition: utils.h:278
std::ostream & operator<<(std::ostream &out, const std::vector< T > &vec)
Definition: utils.h:46
std::vector< std::string > getCriterionIds(std::vector< Perf > vectPerf)
Definition: utils.h:161
int getRandomUniformInt(unsigned long int seed=0, int min=0, int max=100)
Definition: utils.h:111
std::vector< Perf > createVectorPerfWithNoPerf(std::string id, Criteria &criteria)
Definition: utils.h:235
std::vector< std::string > getNameIds(std::vector< Perf > vectPerf)
Definition: utils.h:193
std::vector< T > subVector(std::vector< T > const &v, int m, int n)
Definition: utils.h:65
std::vector< float > randomCategoriesLimits(int nbCategories, unsigned long int seed=time(NULL))
Definition: utils.h:145
std::vector< double > getPerfFromPerfVect(std::vector< Perf > &p)
Definition: utils.h:250