BayesOpt
fileparser.cpp
1 /*
2 -------------------------------------------------------------------------
3  This file is part of BayesOpt, an efficient C++ library for
4  Bayesian optimization.
5 
6  Copyright (C) 2011-2015 Ruben Martinez-Cantin <rmcantin@unizar.es>
7 
8  BayesOpt is free software: you can redistribute it and/or modify it
9  under the terms of the GNU Affero General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  BayesOpt is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Affero General Public License for more details.
17 
18  You should have received a copy of the GNU Affero General Public License
19  along with BayesOpt. If not, see <http://www.gnu.org/licenses/>.
20 ------------------------------------------------------------------------
21 */
22 
23 #include "fileparser.hpp"
24 
25 namespace bayesopt
26 {
27  namespace utils
28  {
29  namespace ublas = boost::numeric::ublas;
30 
31  FileParser::FileParser(std::string filename, int prec)
32  : filename(filename), input(), output(){
33  setPrecision(prec);
34  }
35 
36  // For using to_value and to_string functions
37  FileParser::FileParser(int prec){
38  setPrecision(prec);
39  }
40 
41  FileParser::~FileParser(){
42  close();
43  }
44 
45  void FileParser::open(bool readMode){
46  if(readMode){
47  openInput();
48  }
49  else{
50  openOutput();
51  }
52  }
53  void FileParser::openOutput(){
54  close();
55  output.open(filename.c_str());
56  }
57  void FileParser::openInput(){
58  close();
59  input.open(filename.c_str());
60  }
61  void FileParser::close(){
62  output.close();
63  input.close();
64  currentLine = "";
65  }
66  /* Check fileparser mode */
67  bool FileParser::isReading(){
68  return input.is_open();
69  }
70 
71  bool FileParser::isWriting(){
72  return output.is_open();
73  }
74 
75  /* Changes output precision of real numbers */
76  void FileParser::setPrecision(int prec){
77  if(prec > 0){
78  precision = prec;
79  }
80  else{ // Default precision
81  precision = 10;
82  }
83  }
84 
85  /* Checks if a file exists */
86  bool FileParser::fileExists(){
87  std::ifstream ifile(filename.c_str());
88  return ifile.good();
89  }
90 
91  /* Data write/read function */
92  void FileParser::write(std::string name, std::string value){
93  output << name << "=" << value << std::endl;
94  }
95  void FileParser::read(std::string name, std::string &value){
96  //TODO: (Javier) use movePointer() returned bool, should be
97  //used to avoid &value = "" when not found
98  if(!movePointer(name,value))
99  {
100  std::cerr << "Variable: " << name
101  << " does not exist in file: " << filename
102  << std::endl;
103  }
104  }
105  std::string FileParser::read(std::string name){
106  std::string ret;
107  read(name, ret);
108  return ret;
109  }
110 
111  /* Array write/read function */
112  void FileParser::write(std::string name,
113  const std::vector<std::string> &arr,
114  const std::vector<int> &dims){
115  // Write dimensions
116  output << name << "=[";
117  for(std::vector<int>::const_iterator it = dims.begin(); it != dims.end(); ++it) {
118  if(it != dims.begin()){
119  output << ",";
120  }
121  output << *it;
122  }
123  output << "]";
124 
125  // Write array
126  output << "(";
127  for(std::vector<std::string>::const_iterator it = arr.begin(); it != arr.end(); ++it) {
128  if(it != arr.begin()){
129  output << ",";
130  }
131  output << *it;
132  }
133  output << ")" << std::endl;
134  }
135  void FileParser::read(std::string name, std::vector<std::string> &arr,
136  std::vector<int> &dims)
137  {
138  std::string contents;
139  if(movePointer(name,contents)){
140  parseArray(contents, arr, dims);
141  }
142  else{
143  std::cerr << "Variable: " << name
144  << " does not exist in file: " << filename
145  << std::endl;
146  }
147  }
148 
149  /*
150  * Non-templated functions (types that requires special treatment)
151  */
152  void FileParser::write_chars(std::string name, char* value){
153  std::string str(value);
154  write(name,str);
155  }
156  void FileParser::read_chars(std::string name, char* value){
157  std::string str;
158  read(name, str);
159  strcpy(value, str.c_str());
160  }
161 
162  void FileParser::readOrWrite(std::string name, char* value){
163  if(isReading()){
164  read_chars(name, value);
165  }
166  else if(isWriting()){
167  write_chars(name,value);
168  }
169  }
170 
171  void FileParser::write_ublas(std::string name,
172  ublas::vector<double> &values)
173  {
174  std::vector<int> dims;
175  dims.push_back(values.size());
176 
177  std::vector<std::string> arr;
178  for(ublas::vector<double>::iterator it = values.begin();
179  it != values.end(); ++it)
180  {
181  arr.push_back(to_string(*it));
182  }
183  write(name, arr, dims);
184  }
185  void FileParser::read_ublas(std::string name, ublas::vector<double> &values){
186  std::vector<std::string> arr;
187  std::vector<int> dims;
188  read(name, arr, dims);
189 
190  std::vector<double> doubles_arr;
191  for(std::vector<std::string>::iterator it = arr.begin(); it != arr.end(); ++it) {
192  doubles_arr.push_back(to_value<double>(*it));
193  }
194 
195  values.resize(arr.size(), false);
196  std::copy(doubles_arr.begin(), doubles_arr.end(), values.begin());
197  }
198  void FileParser::readOrWrite(std::string name, ublas::vector<double> &values){
199  if(isReading()){
200  read_ublas(name, values);
201  }
202  else if(isWriting()){
203  write_ublas(name,values);
204  }
205  }
206 
207  void FileParser::write_vecOfvec(std::string name,
208  std::vector<ublas::vector<double> > &values){
209  std::vector<int> dims;
210  dims.push_back(values.size());
211  dims.push_back(values.at(0).size());
212 
213  std::vector<std::string> arr;
214  for(size_t i=0; i<values.size(); i++){
215  ublas::vector<double> current = values.at(i);
216  for(ublas::vector<double>::iterator it = current.begin();
217  it != current.end(); ++it) {
218  arr.push_back(to_string(*it));
219  }
220  }
221  write(name, arr, dims);
222  }
223  void FileParser::read_vecOfvec(std::string name, std::vector<ublas::vector<double> > &values){
224  std::vector<int> dims;
225  std::vector<std::string> arr;
226  read(name, arr, dims);
227 
228  size_t sample_dim = dims.at(1);
229 
230  values.resize(dims.at(0));
231  for(size_t i=0; i<dims.at(0); i++){
232  values.at(i).resize(sample_dim);
233  for(size_t j=0; j<sample_dim; j++){
234  values.at(i)[j] = to_value<double>(arr.at(i*sample_dim + j));
235  }
236  }
237  }
238  void FileParser::readOrWrite(std::string name, std::vector<ublas::vector<double> > &values){
239  if(isReading()){
240  read_vecOfvec(name, values);
241  }
242  else if(isWriting()){
243  write_vecOfvec(name,values);
244  }
245  }
246 
247  void FileParser::write_double_array(std::string name, double values[], size_t length){
248  std::vector<std::string> arr;
249  std::vector<int> dims;
250  dims.push_back(length);
251  for(size_t i=0; i<length; i++){
252  arr.push_back(to_string(values[i]));
253  }
254  write(name, arr, dims);
255  }
256  void FileParser::read_double_array(std::string name, double values[], size_t length){
257  std::vector<std::string> arr;
258  std::vector<int> dims;
259  read(name, arr, dims);
260 
261  for(size_t i=0; i<length; i++){
262  values[i] = to_value<double>(arr.at(i));
263  }
264  }
265  void FileParser::readOrWrite(std::string name, double values[], size_t length){
266  if(isReading()){
267  read_double_array(name, values, length);
268  }
269  else if(isWriting()){
270  write_double_array(name,values, length);
271  }
272  }
273 
274  /* Search variables in file */
275  bool FileParser::movePointer(std::string name, std::string &contents){
276  if(currentLine.length() > 0 && startsWith(currentLine, name+"=")){
277  contents = currentLine.substr(name.length()+1);
278  return true;
279  }
280 
281  // TODO (Javier): detect when all the lines were read instead of 2 iterations over file
282  // Wrap the file around in the search of a variable
283  for(int i=0; i<2; i++){
284  while (getline( input, currentLine)){
285  if(currentLine.length() > 0 && startsWith(currentLine, name+"=")){
286  contents = currentLine.substr(name.length()+1);
287  return true;
288  }
289  }
290  input.clear();
291  input.seekg(0, std::ios::beg);
292  }
293  contents = "";
294  return false;
295 
296  }
297 
298  bool FileParser::startsWith(std::string all, std::string sub){
299  return all.rfind(sub, 0) == 0;
300  }
301 
302  void FileParser::parseArray(std::string contents,
303  std::vector<std::string> &arr,
304  std::vector<int> &dims){
305  // Parse data
306  size_t init_arr = contents.find("(")+1;
307  size_t end_arr = contents.find(")")-1;
308  std::string input = contents.substr(init_arr, end_arr - init_arr +1);
309  utils::split(input, ',', arr);
310 
311  // Parse dimensions
312  std::vector<std::string> dims_string;
313  size_t init_dims = contents.find("[")+1;
314  size_t end_dims = contents.find("]")-1;
315  input = contents.substr(init_dims, end_dims - init_dims +1);
316  utils::split(input, ',', dims_string);
317 
318  for(std::vector<std::string>::iterator it = dims_string.begin();
319  it != dims_string.end(); ++it) {
320  dims.push_back(to_value<size_t>(*it));
321  }
322  }
323 
324  } //namespace utils
325 } //namespace bayesopt
326 
Namespace of the library interface.
Definition: using.dox:1
void split(std::string &input, char delim, std::vector< std::string > &elems)
Splits the input string with a delimiter to extract elements.
Definition: parser.cpp:113
Functions to write and parse data files.