NeTrainSim 0.1.1 beta
The Open-Source Network Trains Simulator
 
Loading...
Searching...
No Matches
utils.h
Go to the documentation of this file.
1
6#ifndef UTILS_H
7#define UTILS_H
8
9#include <iostream>
10#include <iomanip> // Required for setprecision and fixed
11#include <locale> // Required for using thousands_separator
12#include <sstream> // Required for stringstream
13#include "vector.h"
14#include <fstream>
15#include <string>
16#include <regex>
17#include <chrono>
18#include <cmath>
19#include <tuple>
20#include <type_traits>
21#include <QVector>
22#include <type_traits>
23
24namespace Utils {
25
26 using namespace std;
27
28
38 inline std::pair<double, double> dot(Vector<Vector<double>> matrix, std::pair<double, double>& v) {
39 // The dot product of a matrix and a vector is calculated as follows:
40 // The first element is the sum of the products of the corresponding elements of the first row of the matrix and the vector
41 // The second element is the sum of the products of the corresponding elements of the second row of the matrix and the vector
42 return std::make_pair(matrix.at(0).at(0) * v.first + matrix.at(0).at(1) * v.second,
43 matrix.at(1).at(0) * v.first + matrix.at(1).at(1) * v.second);
44 }
45
55 inline double dot(std::pair<double, double> &u, std::pair<double, double> &v) {
56 // The dot product of two vectors is calculated as (u1*v1 + u2*v2)
57 return u.first * v.first + u.second * v.second;
58 }
59
69 inline double cross(std::pair<double, double> &u, std::pair<double, double> &v) {
70 // The cross product of two vectors in 2D (also known as the determinant, or pseudo cross product)
71 // is calculated as (u1*v2 - u2*v1)
72 return u.first * v.second - u.second * v.first;
73 }
74
83 inline double getDistanceByTwoCoordinates(const std::pair<double, double>& position1,
84 const std::pair<double, double>& position2) {
85 // Calculate differences in x and y coordinates
86 double xDiff = position1.first - position2.first;
87 double yDiff = position1.second - position2.second;
88
89 // Compute and return Euclidean distance
90 return std::sqrt(xDiff * xDiff + yDiff * yDiff);
91 }
92
104 inline double power(double base, int exponent) {
105 if (exponent == 0) {
106 return 1.0;
107 }
108 else if (exponent < 0) {
109 return 1.0 / power(base, -exponent);
110 }
111 else if (exponent % 2 == 0) {
112 double temp = power(base, exponent / 2);
113 return temp * temp;
114 }
115 else {
116 return base * power(base, exponent - 1);
117 }
118 }
119
120
121 template<typename T>
122 requires std::is_arithmetic<T>::value
135 inline std::string thousandSeparator(T n, int decimals = 3) {
136 // Get the sign of the number and remove it
137 int sign = (n < 0) ? -1 : 1;
138 double approx = power((double)10.0, decimals);
139 n *= sign;
140 // Get the integer part of the number
141 long long intPart = (long long)n;
142 // Check if the fractional part has any value
143 bool hasFracPart = (n - intPart > 0);
144 // Get the fractional part of the number and trim it to n decimal places
145 double fracPart = round((n - intPart) * (approx)) / (approx);
146 // Create a locale object to represent a specific localization
147 locale loc("");
148 // Set the thousand separator according to the localization
149 char separator = use_facet< numpunct<char> >(loc).thousands_sep();
150 // Convert the integer part to a string
151 string intStr = to_string(intPart);
152 // Insert the separator every 3 digits from the end
153 for (int i = intStr.length() - 3; i > 0; i -= 3) {
154 intStr.insert(i, 1, separator);
155 }
156 // Convert the fractional part to a string and trim it to n decimal places
157 stringstream stream;
158 if (hasFracPart) {
159 stream << fixed << setprecision(decimals) << fracPart;
160 }
161 string fracStr = (hasFracPart) ? stream.str().substr(1) : "";
162 // Combine the integer and fractional parts into a single string
163 string result = intStr + fracStr;
164 // Add the sign to the beginning of the string if the number was negative
165 if (sign == -1) {
166 result = "-" + result;
167 }
168 return result;
169 }
170
171
172 template<typename T>
173
186 inline std::string formatDuration(T seconds) {
187 int minutes = static_cast<int>(seconds) / 60;
188 int hours = minutes / 60;
189 int days = hours / 24;
190 int remainingSeconds = static_cast<int>(seconds) % 60;
191 int remainingMinutes = minutes % 60;
192 int remainingHours = hours % 24;
193 // Use stringstream to convert integer values to strings
194 std::stringstream ss;
195 ss << days << ":" << setw(2) << setfill('0') << remainingHours << ":" << setw(2) << setfill('0') << remainingMinutes << ":" << setw(2) << setfill('0') << remainingSeconds;
196 std::string result = ss.str();
197 return result;
198 }
199
200 inline std::string getFilenameWithoutExtension(std::string path) {
201 size_t pos = path.find_last_of("/\\");
202 string filename = (pos == string::npos) ? path : path.substr(pos + 1);
203 size_t dotPos = filename.find_last_of(".");
204 if (dotPos != string::npos) {
205 filename = filename.substr(0, dotPos);
206 }
207 return filename;
208 }
209
210 inline std::string getPrefix(std::string str) {
211 std::string prefix;
212 bool skipFirstChar = isupper(str[0]);
213 if (skipFirstChar) {
214 prefix += str[0];
215 }
216 for (size_t i = skipFirstChar ? 1 : 0; i < str.length(); i++) {
217 char c = str[i];
218 if (c == '_' || isalpha(c) || c == ' ') {
219 if (isupper(c) || c == ' ' || c == '_') {
220 break;
221 }
222 prefix += c;
223 }
224 }
225 return prefix;
226 }
227
228
240 inline Vector<double> splitStringToDoubleVector(const std::string& input, char delimiter = ',') {
241 Vector<double> result;
242 std::stringstream ss(input);
243 std::string item;
244 while (std::getline(ss, item, delimiter)) {
245 result.push_back(std::stod(item));
246 }
247 return result;
248 }
249
261 inline Vector<int> splitStringToIntVector(const std::string& str) {
262 Vector<int> intVector;
263 std::stringstream ss(str);
264 int temp;
265
266 while (ss >> temp) {
267 intVector.push_back(temp);
268 if (ss.peek() == ',') {
269 ss.ignore();
270 }
271 else if (ss.peek() != ' ') {
272 break;
273 }
274 }
275
276 return intVector;
277 }
278
291 inline Vector<std::string> split(const std::string& s, char delimiter)
292 {
293 Vector<std::string> tokens;
294 std::string token;
295 std::istringstream tokenStream(s);
296 while (std::getline(tokenStream, token, delimiter))
297 {
298 tokens.push_back(token);
299 }
300 return tokens;
301 }
302
303 inline Vector<int> convertStringVectorToIntVector(const std::vector<std::string>& stringVector) {
304 Vector<int> intVector;
305
306 for(const auto& str : stringVector) {
307 try {
308 intVector.push_back(std::stoi(str));
309 } catch(const std::exception& e) {
310 throw std::runtime_error("Error: unable to convert string " + str + " to integer.");
311 }
312 }
313
314 return intVector;
315 }
316
328 inline std::string trim(const std::string& str)
329 {
330 std::string s = str;
331 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
332 return !std::isspace(ch);
333 }));
334 s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
335 return !std::isspace(ch);
336 }).base(), s.end());
337 return s;
338 }
339
340 inline bool writeToFile(std::stringstream &s, std::string filename) {
341 std::ofstream outputFile(filename);
342 if (outputFile.is_open()) {
343 outputFile << s.rdbuf(); // Write stringstream contents to file
344 outputFile.close();
345 return true;
346 } else {
347 return false;
348 }
349 }
350
351 template <typename... Args>
352 inline std::stringstream convertTupleToStringStream(const std::tuple<Args...>& t, int limit, std::string delim = "\t");
353
354 template <typename Tuple, size_t... Indices>
355 inline void addTupleValuesToStreamImpl(const Tuple& t, std::stringstream& ss,
356 std::index_sequence<Indices...>, int limit, std::string delim);
357
358 template <typename T>
359 inline void writeToStream(const T& value, std::stringstream& ss, std::string delim);
360
361
362
363 template <typename... Args>
364 inline std::stringstream convertTupleToStringStream(const std::tuple<Args...>& t, int limit, std::string delim) {
365 std::stringstream ss;
366 addTupleValuesToStreamImpl(t, ss, std::index_sequence_for<Args...>(),
367 limit > 0 ? limit: std::tuple_size<std::tuple<Args...>>::value - std::abs(limit) -1, delim);
368 return ss;
369 }
370
371 template <typename Tuple, size_t... Indices>
372 inline void addTupleValuesToStreamImpl(const Tuple& t,
373 std::stringstream& ss,
374 std::index_sequence<Indices...>,
375 int limit, std::string delim) {
376 ((Indices < limit
377 ? Utils::writeToStream(std::get<Indices>(t), ss, delim) :
378 void()), ...);
379 ((Indices == limit
380 ? Utils::writeToStream(std::get<Indices>(t), ss, "") :
381 void()), ...);
382 }
383
384 template <typename T>
385 inline void writeToStream(const T& value,
386 std::stringstream& ss,
387 std::string delim) {
388 if constexpr (std::is_same_v<T, bool>) {
389 ss << (value ? "1" : "0") << delim;
390 } else {
391 ss << value << delim;
392 }
393 }
394
395 inline std::string removeLastWord(const std::string& originalString) {
396
397 size_t lastSpaceIndex = originalString.find_last_of(' ');
398
399 if (lastSpaceIndex != std::string::npos) {
400 std::string updatedString = originalString.substr(0, lastSpaceIndex);
401 return updatedString;
402 } else {
403 // Return the original string if there is no space
404 return originalString;
405 }
406 }
407
408 inline QVector<double> convertQStringVectorToDouble(const QVector<QString>& stringVector) {
409 QVector<double> doubleVector;
410 doubleVector.reserve(stringVector.size());
411
412 for (const QString& str : stringVector) {
413 bool ok;
414 double value = str.toDouble(&ok);
415 if (ok) {
416 doubleVector.append(value);
417 } else {
418 // Handle conversion error if necessary
419 }
420 }
421
422 return doubleVector;
423 }
424
425 inline QVector<double> subtractQVector(const QVector<double> l1, const QVector<double> l2) {
426 QVector<double> result;
427 if (l1.size() != l2.size()) {return result; }
428
429 for (int i = 0; i < l1.size(); i++ ) {
430 result.push_back(l1[i] - l2[i]);
431 }
432 return result;
433 }
434
435 inline QVector<double> factorQVector(const QVector<double> l1, const double factor) {
436 QVector<double> result;
437 if (l1.size() < 1) {return result; }
438
439 for (int i = 0; i < l1.size(); i++ ) {
440 result.push_back(l1[i] * factor);
441 }
442 return result;
443 }
444
445 inline Vector<std::pair<std::string, std::string>> splitStringStream(std::stringstream& ss, const std::string& delimiter = ":") {
447 std::string line;
448
449 while (std::getline(ss, line)) {
450 std::size_t delimiterPos = line.find(delimiter);
451 if (delimiterPos != std::string::npos) {
452 std::string first = line.substr(0, delimiterPos);
453 std::string second = line.substr(delimiterPos + delimiter.size());
454 result.emplace_back(first, second);
455 } else {
456 result.emplace_back(line, ""); // If delimiter is not found, add the entire line with an empty second part
457 }
458 }
459
460 return result;
461 }
462
463 inline std::string replaceAll(std::string str, const std::string& from, const std::string& to) {
464 size_t start_pos = 0;
465 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
466 str.replace(start_pos, from.length(), to);
467 start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
468 }
469 return str;
470 }
471
472
473}
474
475
476#endif // !UTILS_H
A vector.
Definition vector.h:24
Definition utils.h:24
QVector< double > subtractQVector(const QVector< double > l1, const QVector< double > l2)
Definition utils.h:425
std::string formatDuration(T seconds)
Format duration.
Definition utils.h:186
QVector< double > factorQVector(const QVector< double > l1, const double factor)
Definition utils.h:435
std::pair< double, double > dot(Vector< Vector< double > > matrix, std::pair< double, double > &v)
Compute the dot product of a 2x2 matrix and a 2D vector.
Definition utils.h:38
Vector< int > splitStringToIntVector(const std::string &str)
The function stringToIntVector takes a string as input and converts it into a Vector<int> by parsing ...
Definition utils.h:261
std::string getPrefix(std::string str)
Definition utils.h:210
void writeToStream(const T &value, std::stringstream &ss, std::string delim)
Definition utils.h:385
double power(double base, int exponent)
Powers.
Definition utils.h:104
::value std::string thousandSeparator(T n, int decimals=3)
Convert a plain numeric value to thousand separated value.
Definition utils.h:135
std::string replaceAll(std::string str, const std::string &from, const std::string &to)
Definition utils.h:463
Vector< int > convertStringVectorToIntVector(const std::vector< std::string > &stringVector)
Definition utils.h:303
std::string trim(const std::string &str)
This function trim takes in a string str and returns a copy of it with leading and trailing white spa...
Definition utils.h:328
Vector< double > splitStringToDoubleVector(const std::string &input, char delimiter=',')
Splits string to double vector.
Definition utils.h:240
void addTupleValuesToStreamImpl(const Tuple &t, std::stringstream &ss, std::index_sequence< Indices... >, int limit, std::string delim)
Definition utils.h:372
bool writeToFile(std::stringstream &s, std::string filename)
Definition utils.h:340
Vector< std::pair< std::string, std::string > > splitStringStream(std::stringstream &ss, const std::string &delimiter=":")
Definition utils.h:445
std::stringstream convertTupleToStringStream(const std::tuple< Args... > &t, int limit, std::string delim="\t")
Definition utils.h:364
double cross(std::pair< double, double > &u, std::pair< double, double > &v)
Compute the cross product of two 2D vectors.
Definition utils.h:69
double getDistanceByTwoCoordinates(const std::pair< double, double > &position1, const std::pair< double, double > &position2)
Computes the Euclidean distance between two coordinates.
Definition utils.h:83
std::string getFilenameWithoutExtension(std::string path)
Definition utils.h:200
QVector< double > convertQStringVectorToDouble(const QVector< QString > &stringVector)
Definition utils.h:408
Vector< std::string > split(const std::string &s, char delimiter)
This function is splitting a given string "s" into substrings using a delimiter "delimiter" and retur...
Definition utils.h:291
std::string removeLastWord(const std::string &originalString)
Definition utils.h:395