n2p2 - A neural network potential package
utility.cpp
Go to the documentation of this file.
1// n2p2 - A neural network potential package
2// Copyright (C) 2018 Andreas Singraber (University of Vienna)
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17#include "utility.h"
18#include <algorithm> // std::max
19#include <cstdio> // vsprintf
20#include <cstdarg> // va_list, va_start, va_end
21#include <iomanip> // std::setw
22#include <limits> // std::numeric_limits
23#include <sstream> // std::istringstream
24#include <stdexcept> // std::runtime_error
25
26#define STRPR_MAXBUF 1024
27
28using namespace std;
29
30namespace nnp
31{
32
33vector<string> split(string const& input, char delimiter)
34{
35 vector<string> parts;
36 stringstream ss;
37
38 ss.str(input);
39 string item;
40 while (getline(ss, item, delimiter)) {
41 parts.push_back(item);
42 }
43
44 return parts;
45}
46
47string trim(string const& line, string const& whitespace)
48{
49 size_t const begin = line.find_first_not_of(whitespace);
50 if (begin == string::npos)
51 {
52 return "";
53 }
54 size_t const end = line.find_last_not_of(whitespace);
55 size_t const range = end - begin + 1;
56
57 return line.substr(begin, range);
58}
59
60string reduce(string const& line,
61 string const& whitespace,
62 string const& fill)
63{
64 string result = trim(line, whitespace);
65
66 size_t begin = result.find_first_of(whitespace);
67 while (begin != string::npos)
68 {
69 size_t const end = result.find_first_not_of(whitespace, begin);
70 size_t const range = end - begin;
71 result.replace(begin, range, fill);
72 size_t const newBegin = begin + fill.length();
73 begin = result.find_first_of(whitespace, newBegin);
74 }
75
76 return result;
77}
78
79string pad(string const& input, size_t num, char fill, bool right)
80{
81 string result = input;
82
83 if (input.size() >= num) return result;
84
85 string pad(num - input.size(), fill);
86 if (right) return result + pad;
87 else return pad + result;
88}
89
90string strpr(const char* format, ...)
91{
92 char buffer[STRPR_MAXBUF];
93
94 va_list args;
95 va_start(args, format);
96 vsprintf(buffer, format, args);
97 va_end(args);
98
99 string s(buffer);
100
101 return s;
102}
103
104string cap(string word)
105{
106 word[0] = toupper(word[0]);
107
108 return word;
109}
110
111vector<string> createFileHeader(vector<string> const& title,
112 vector<size_t> const& colSize,
113 vector<string> const& colName,
114 vector<string> const& colInfo,
115 char const& commentChar)
116{
117 size_t const stdWidth = 80;
118 vector<string> h;
119 if (!(colSize.size() == colName.size() &&
120 colName.size() == colInfo.size()))
121 {
122 throw runtime_error("ERROR: Could not create file header, column sizes"
123 " are not equal.\n");
124 }
125 size_t numCols = colSize.size();
126
127 // Separator line definition.
128 string sepLine(stdWidth, commentChar);
129 sepLine += '\n';
130 // Start string.
131 string startStr(1, commentChar);
132
133 // Add title lines.
134 h.push_back(sepLine);
135 for (vector<string>::const_iterator it = title.begin();
136 it != title.end(); ++it)
137 {
138 h.push_back(startStr + ' ' + (*it) + '\n');
139 }
140 h.push_back(sepLine);
141
142 // Determine maximum width of names.
143 size_t widthNames = 0;
144 for (vector<string>::const_iterator it = colName.begin();
145 it != colName.end(); ++it)
146 {
147 widthNames = max(widthNames, it->size());
148 }
149
150 // Column description section.
151 stringstream s;
152 s << startStr << ' '
153 << left << setw(4) << "Col" << ' '
154 << left << setw(widthNames) << "Name" << ' '
155 << left << "Description\n";
156 h.push_back(s.str());
157 h.push_back(sepLine);
158 for (size_t i = 0; i < numCols; ++i)
159 {
160 s.clear();
161 s.str(string());
162 s << startStr << ' '
163 << left << setw(4) << i + 1 << ' '
164 << left << setw(widthNames) << colName.at(i) << ' '
165 << colInfo.at(i) << '\n';
166 h.push_back(s.str());
167 }
168
169 // Determine total data width.
170 size_t widthData = 0;
171 for (vector<size_t>::const_iterator it = colSize.begin();
172 it != colSize.end(); ++it)
173 {
174 widthData += (*it) + 1;
175 }
176 widthData -= 1;
177
178 if (widthData > stdWidth)
179 {
180 // Long separator line.
181 h.push_back(string(widthData, commentChar) + "\n");
182 }
183 else
184 {
185 h.push_back(sepLine);
186 }
187
188 // Write column number.
189 s.clear();
190 s.str(string());
191 s << startStr;
192 for (size_t i = 0; i < numCols; ++i)
193 {
194 size_t n = colSize.at(i);
195 if (i == 0) n -= 2;
196 s << ' ' << right << setw(n) << i + 1;
197 }
198 s << '\n';
199 h.push_back(s.str());
200
201 // Write column name.
202 s.clear();
203 s.str(string());
204 s << startStr;
205 for (size_t i = 0; i < numCols; ++i)
206 {
207 size_t n = colSize.at(i);
208 if (i == 0) n -= 2;
209 string name = colName.at(i);
210 if (name.size() > n)
211 {
212 name.erase(n, string::npos);
213 }
214 s << ' ' << right << setw(n) << name;
215 }
216 s << '\n';
217 h.push_back(s.str());
218
219 // Long separator line.
220 h.push_back(string(widthData, commentChar) + "\n");
221
222 return h;
223}
224
225void appendLinesToFile(ofstream& file, vector<string> const lines)
226{
227 for (vector<string>::const_iterator it = lines.begin();
228 it != lines.end(); ++it)
229 {
230 file << (*it);
231 }
232
233 return;
234}
235
236void appendLinesToFile(FILE* const& file, vector<string> const lines)
237{
238 for (vector<string>::const_iterator it = lines.begin();
239 it != lines.end(); ++it)
240 {
241 fprintf(file, "%s", it->c_str());
242 }
243
244 return;
245}
246
247map<size_t, vector<double>> readColumnsFromFile(string fileName,
248 vector<size_t> columns,
249 char comment)
250{
251 map<size_t, vector<double>> result;
252
253 sort(columns.begin(), columns.end());
254 for (auto col : columns)
255 {
256 result[col] = vector<double>();
257 }
258
259 ifstream file;
260 file.open(fileName.c_str());
261 if (!file.is_open())
262 {
263 throw runtime_error("ERROR: Could not open file: \"" + fileName
264 + "\".\n");
265 }
266 string line;
267 while (getline(file, line))
268 {
269 if (line.size() == 0) continue;
270 if (line.at(0) != comment)
271 {
272 vector<string> splitLine = split(reduce(line));
273 for (auto col : columns)
274 {
275 if (col >= splitLine.size())
276 {
277 result[col].push_back(
278 std::numeric_limits<double>::quiet_NaN());
279 }
280 else
281 {
282 result[col].push_back(atof(splitLine.at(col).c_str()));
283 }
284 }
285 }
286 }
287 file.close();
288
289 return result;
290}
291
292double pow_int(double x, int n)
293{
294 // Need an unsigned integer for bit-shift divison.
295 unsigned int m;
296
297 // If negative exponent, take the inverse of x and change sign of n.
298 if (n < 0)
299 {
300 x = 1.0 / x;
301 m = -n;
302 }
303 else m = n;
304
305 // Exponentiation by squaring, "fast exponentiation algorithm"
306 double result = 1.0;
307 do
308 {
309 if (m & 1) result *= x;
310 // Division by 2.
311 m >>= 1;
312 x *= x;
313 }
314 while (m);
315
316 return result;
317}
318
319}
Definition: Atom.h:29
string pad(string const &input, size_t num, char fill, bool right)
Definition: utility.cpp:79
string cap(string word)
Capitalize first letter of word.
Definition: utility.cpp:104
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90
vector< string > createFileHeader(vector< string > const &title, vector< size_t > const &colSize, vector< string > const &colName, vector< string > const &colInfo, char const &commentChar)
Definition: utility.cpp:111
string trim(string const &line, string const &whitespace)
Remove leading and trailing whitespaces from string.
Definition: utility.cpp:47
vector< string > split(string const &input, char delimiter)
Split string at each delimiter.
Definition: utility.cpp:33
map< size_t, vector< double > > readColumnsFromFile(string fileName, vector< size_t > columns, char comment)
Definition: utility.cpp:247
string reduce(string const &line, string const &whitespace, string const &fill)
Replace multiple whitespaces with fill.
Definition: utility.cpp:60
double pow_int(double x, int n)
Integer version of power function, "fast exponentiation algorithm".
Definition: utility.cpp:292
void appendLinesToFile(ofstream &file, vector< string > const lines)
Append multiple lines of strings to open file stream.
Definition: utility.cpp:225
#define STRPR_MAXBUF
Definition: utility.cpp:26