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
104vector<string> createFileHeader(vector<string> const& title,
105 vector<size_t> const& colSize,
106 vector<string> const& colName,
107 vector<string> const& colInfo,
108 char const& commentChar)
109{
110 size_t const stdWidth = 80;
111 vector<string> h;
112 if (!(colSize.size() == colName.size() &&
113 colName.size() == colInfo.size()))
114 {
115 throw runtime_error("ERROR: Could not create file header, column sizes"
116 " are not equal.\n");
117 }
118 size_t numCols = colSize.size();
119
120 // Separator line definition.
121 string sepLine(stdWidth, commentChar);
122 sepLine += '\n';
123 // Start string.
124 string startStr(1, commentChar);
125
126 // Add title lines.
127 h.push_back(sepLine);
128 for (vector<string>::const_iterator it = title.begin();
129 it != title.end(); ++it)
130 {
131 h.push_back(startStr + ' ' + (*it) + '\n');
132 }
133 h.push_back(sepLine);
134
135 // Determine maximum width of names.
136 size_t widthNames = 0;
137 for (vector<string>::const_iterator it = colName.begin();
138 it != colName.end(); ++it)
139 {
140 widthNames = max(widthNames, it->size());
141 }
142
143 // Column description section.
144 stringstream s;
145 s << startStr << ' '
146 << left << setw(4) << "Col" << ' '
147 << left << setw(widthNames) << "Name" << ' '
148 << left << "Description\n";
149 h.push_back(s.str());
150 h.push_back(sepLine);
151 for (size_t i = 0; i < numCols; ++i)
152 {
153 s.clear();
154 s.str(string());
155 s << startStr << ' '
156 << left << setw(4) << i + 1 << ' '
157 << left << setw(widthNames) << colName.at(i) << ' '
158 << colInfo.at(i) << '\n';
159 h.push_back(s.str());
160 }
161
162 // Determine total data width.
163 size_t widthData = 0;
164 for (vector<size_t>::const_iterator it = colSize.begin();
165 it != colSize.end(); ++it)
166 {
167 widthData += (*it) + 1;
168 }
169 widthData -= 1;
170
171 if (widthData > stdWidth)
172 {
173 // Long separator line.
174 h.push_back(string(widthData, commentChar) + "\n");
175 }
176 else
177 {
178 h.push_back(sepLine);
179 }
180
181 // Write column number.
182 s.clear();
183 s.str(string());
184 s << startStr;
185 for (size_t i = 0; i < numCols; ++i)
186 {
187 size_t n = colSize.at(i);
188 if (i == 0) n -= 2;
189 s << ' ' << right << setw(n) << i + 1;
190 }
191 s << '\n';
192 h.push_back(s.str());
193
194 // Write column name.
195 s.clear();
196 s.str(string());
197 s << startStr;
198 for (size_t i = 0; i < numCols; ++i)
199 {
200 size_t n = colSize.at(i);
201 if (i == 0) n -= 2;
202 string name = colName.at(i);
203 if (name.size() > n)
204 {
205 name.erase(n, string::npos);
206 }
207 s << ' ' << right << setw(n) << name;
208 }
209 s << '\n';
210 h.push_back(s.str());
211
212 // Long separator line.
213 h.push_back(string(widthData, commentChar) + "\n");
214
215 return h;
216}
217
218void appendLinesToFile(ofstream& file, vector<string> const lines)
219{
220 for (vector<string>::const_iterator it = lines.begin();
221 it != lines.end(); ++it)
222 {
223 file << (*it);
224 }
225
226 return;
227}
228
229void appendLinesToFile(FILE* const& file, vector<string> const lines)
230{
231 for (vector<string>::const_iterator it = lines.begin();
232 it != lines.end(); ++it)
233 {
234 fprintf(file, "%s", it->c_str());
235 }
236
237 return;
238}
239
240map<size_t, vector<double>> readColumnsFromFile(string fileName,
241 vector<size_t> columns,
242 char comment)
243{
244 map<size_t, vector<double>> result;
245
246 sort(columns.begin(), columns.end());
247 for (auto col : columns)
248 {
249 result[col] = vector<double>();
250 }
251
252 ifstream file;
253 file.open(fileName.c_str());
254 if (!file.is_open())
255 {
256 throw runtime_error("ERROR: Could not open file: \"" + fileName
257 + "\".\n");
258 }
259 string line;
260 while (getline(file, line))
261 {
262 if (line.size() == 0) continue;
263 if (line.at(0) != comment)
264 {
265 vector<string> splitLine = split(reduce(line));
266 for (auto col : columns)
267 {
268 if (col >= splitLine.size())
269 {
270 result[col].push_back(
271 std::numeric_limits<double>::quiet_NaN());
272 }
273 else
274 {
275 result[col].push_back(atof(splitLine.at(col).c_str()));
276 }
277 }
278 }
279 }
280 file.close();
281
282 return result;
283}
284
285double pow_int(double x, int n)
286{
287 // Need an unsigned integer for bit-shift divison.
288 unsigned int m;
289
290 // If negative exponent, take the inverse of x and change sign of n.
291 if (n < 0)
292 {
293 x = 1.0 / x;
294 m = -n;
295 }
296 else m = n;
297
298 // Exponentiation by squaring, "fast exponentiation algorithm"
299 double result = 1.0;
300 do
301 {
302 if (m & 1) result *= x;
303 // Division by 2.
304 m >>= 1;
305 x *= x;
306 }
307 while (m);
308
309 return result;
310}
311
312}
Definition: Atom.h:28
string pad(string const &input, size_t num, char fill, bool right)
Definition: utility.cpp:79
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:104
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:240
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:285
void appendLinesToFile(ofstream &file, vector< string > const lines)
Append multiple lines of strings to open file stream.
Definition: utility.cpp:218
#define STRPR_MAXBUF
Definition: utility.cpp:26