PaGMO  1.1.5
serialization.h
1 /*****************************************************************************
2  * Copyright (C) 2004-2015 The PaGMO development team, *
3  * Advanced Concepts Team (ACT), European Space Agency (ESA) *
4  * *
5  * https://github.com/esa/pagmo *
6  * *
7  * act@esa.int *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23  *****************************************************************************/
24 
25 #ifndef PAGMO_SERIALIZATION_H
26 #define PAGMO_SERIALIZATION_H
27 
28 #include "adj_list_serialize_bug_fix.hpp"
29 
30 // Headers needed for serialization purposes.
31 #include <boost/archive/binary_iarchive.hpp>
32 #include <boost/archive/binary_oarchive.hpp>
33 #include <boost/archive/text_iarchive.hpp>
34 #include <boost/archive/text_oarchive.hpp>
35 #include <boost/graph/adjacency_list.hpp>
36 #include <boost/lexical_cast.hpp>
37 #include <boost/math/special_functions/fpclassify.hpp>
38 #include <boost/serialization/assume_abstract.hpp>
39 #include <boost/serialization/base_object.hpp>
40 #include <boost/serialization/export.hpp>
41 #include <boost/serialization/serialization.hpp>
42 #include <boost/serialization/shared_ptr.hpp>
43 #include <boost/serialization/split_free.hpp>
44 #include <boost/serialization/split_member.hpp>
45 #include <boost/serialization/string.hpp>
46 #include <boost/serialization/utility.hpp>
47 #include <boost/serialization/vector.hpp>
48 #include <boost/serialization/version.hpp>
49 #include <limits>
50 
51 // Serialization of circular buffer, unordered map.
52 // TODO: serialize the functors.. allocator, Hash, Pred, etc.
53 #include <boost/circular_buffer.hpp>
54 #include <boost/unordered_map.hpp>
55 #include <boost/random/normal_distribution.hpp>
56 #include <boost/random/uniform_real_distribution.hpp>
57 #include <string>
58 #include <utility>
59 #include <vector>
60 
61 #include "Eigen/Dense"
62 
63 namespace pagmo {
64 
66 template <class Archive>
67 void custom_vector_double_save(Archive &ar, const std::vector<double> &v, const unsigned int)
68 {
69  const std::vector<double>::size_type size = v.size();
70  // Save size.
71  ar << size;
72  // Save elements.
73  std::string tmp;
74  for (std::vector<double>::size_type i = 0; i < size; ++i) {
75  if (boost::math::isnan(v[i])) {
76  tmp = "nan";
77  } else if (boost::math::isinf(v[i])) {
78  if (v[i] > 0) {
79  tmp = "inf";
80  } else {
81  tmp = "-inf";
82  }
83  } else {
84  tmp = boost::lexical_cast<std::string>(v[i]);
85  }
86  ar << tmp;
87  }
88 }
89 
91 template <class Archive>
92 void custom_vector_double_load(Archive &ar, std::vector<double> &v, const unsigned int)
93 {
94  std::vector<double>::size_type size = 0;
95  // Load size.
96  ar >> size;
97  v.resize(size);
98  std::string tmp;
99  for (std::vector<double>::size_type i = 0; i < size; ++i) {
100  ar >> tmp;
101  if (tmp == "nan") {
102  v[i] = std::numeric_limits<double>::quiet_NaN();
103  } else if (tmp == "inf") {
104  v[i] = std::numeric_limits<double>::infinity();
105  } else if (tmp == "-inf") {
106  v[i] = -std::numeric_limits<double>::infinity();
107  } else {
108  v[i] = boost::lexical_cast<double>(tmp);
109  }
110  }
111 }
112 
113 }
114 
115 namespace boost { namespace serialization {
116 
117 template <class Archive>
118 void save(Archive &ar, const boost::circular_buffer<std::vector<double> > &cb, unsigned int version)
119 {
120  // Let's first save capacity and size.
121  typedef typename boost::circular_buffer<std::vector<double> >::capacity_type capacity_type;
122  typedef typename boost::circular_buffer<std::vector<double> >::size_type size_type;
123  capacity_type capacity = cb.capacity();
124  ar << capacity;
125  size_type size = cb.size();
126  ar << size;
127  // Save the content.
128  for (size_type i = 0; i < size; ++i) {
129  pagmo::custom_vector_double_save(ar,cb[i],version);
130  }
131 }
132 
133 template <class Archive>
134 void load(Archive &ar, boost::circular_buffer<std::vector<double> > &cb, unsigned int version)
135 {
136  typedef typename boost::circular_buffer<std::vector<double> >::capacity_type capacity_type;
137  typedef typename boost::circular_buffer<std::vector<double> >::size_type size_type;
138  // Restore capacity.
139  capacity_type capacity;
140  ar >> capacity;
141  cb.set_capacity(capacity);
142  // Restore size.
143  size_type size;
144  ar >> size;
145  cb.resize(size);
146  // Restore elements.
147  for (size_type i = 0; i < size; ++i) {
148  pagmo::custom_vector_double_load(ar,cb[i],version);
149  }
150 }
151 
152 template <class Archive, class T>
153 void serialize(Archive &ar, boost::circular_buffer<T> &cb, const unsigned int version)
154 {
155  split_free(ar, cb, version);
156 }
157 
158 template <class Archive, class Key, class Mapped, class Hash, class Pred, class Alloc>
159 void save(Archive &ar, const boost::unordered_map<Key,Mapped,Hash,Pred,Alloc> &um, unsigned int)
160 {
161  typedef typename boost::unordered_map<Key,Mapped,Hash,Pred,Alloc>::size_type size_type;
162  typedef typename boost::unordered_map<Key,Mapped,Hash,Pred,Alloc>::const_iterator const_iterator;
163  // Save size.
164  const size_type size = um.size();
165  ar << size;
166  for (const_iterator it = um.begin(); it != um.end(); ++it) {
167  ar << *it;
168  }
169 }
170 
171 template <class Archive, class Key, class Mapped, class Hash, class Pred, class Alloc>
172 void load(Archive &ar, boost::unordered_map<Key,Mapped,Hash,Pred,Alloc> &um, unsigned int)
173 {
174  typedef typename boost::unordered_map<Key,Mapped,Hash,Pred,Alloc>::size_type size_type;
175  // Empty the map.
176  um.clear();
177  // Recover size.
178  size_type size;
179  ar >> size;
180  for (size_type i = 0; i < size; ++i) {
181  std::pair<Key, Mapped> value;
182  ar >> value;
183  um[value.first] = value.second;
184  }
185 }
186 
187 
188 template <class Archive, class Key, class Mapped, class Hash, class Pred, class Alloc>
189 void serialize(Archive &ar, boost::unordered_map<Key,Mapped,Hash,Pred,Alloc> &um, unsigned int version)
190 {
191  split_free(ar, um, version);
192 }
193 
194 template <class Archive>
195 void save(Archive &ar, const Eigen::MatrixXd &cb, unsigned int)
196 {
197  // Let's first save the dimension
198  std::size_t nrows = cb.rows(), ncols = cb.cols();
199  ar << nrows;
200  ar << ncols;
201  //And then the numbers
202  for (unsigned int i = 0; i < (unsigned int)cb.rows(); ++i) {
203  for (unsigned int j = 0; j < (unsigned int)cb.cols(); ++j) {
204  ar << cb(i,j);
205  }
206  }
207 }
208 
209 template <class Archive>
210 void load(Archive &ar, Eigen::MatrixXd &cb, unsigned int)
211 {
212  std::size_t rows, cols;
213  // Let's first restore the dimension
214  ar >> rows;
215  ar >> cols;
216  cb.resize(rows,cols);
217  //And then the numbers
218  for (unsigned int i = 0; i < (unsigned int)cb.rows(); ++i) {
219  for (std::size_t j = 0; j < (unsigned int)cb.cols(); ++j) {
220  ar >> cb(i,j);
221  }
222  }
223 }
224 
225 template <class Archive>
226 void serialize(Archive &ar, Eigen::MatrixXd &cb, const unsigned int version)
227 {
228  split_free(ar, cb, version);
229 }
230 
231 template <class Archive>
232 void save(Archive &ar, const Eigen::VectorXd &cb, unsigned int)
233 {
234  std::size_t nrows = cb.rows();
235  // Let's first save the dimension
236  ar << nrows;
237  //And then the numbers
238  for (unsigned int i = 0; i < (unsigned int)cb.rows(); ++i) {
239  ar << cb(i);
240  }
241 }
242 
243 template <class Archive>
244 void load(Archive &ar, Eigen::VectorXd &cb, unsigned int)
245 {
246  std::size_t rows;
247  // Let's first restore the dimension
248  ar >> rows;
249  cb.resize(rows);
250  //And then the numbers
251  for (unsigned int i = 0; i < (unsigned int)cb.rows(); ++i) {
252  ar >> cb(i);
253  }
254 }
255 
256 template <class Archive>
257 void serialize(Archive &ar, Eigen::VectorXd &cb, const unsigned int version)
258 {
259  split_free(ar, cb, version);
260 }
261 
262 template <class Archive>
263 void serialize(Archive &ar, boost::vecS &cb, const unsigned int version)
264 {
265  (void)(ar);
266  (void)(cb);
267  (void)(version);
268 }
269 
270 
271 // ---------- boost::normal_distribution<double> ----------
272 // Serialization of boost::normal_distribution<double> exploits the fact that the
273 // state of Boost distributions can be sent/received to/from standard streams.
274 template <class Archive>
275 void save(Archive &ar, const boost::normal_distribution<double> &cb, const unsigned int)
276 {
277  std::stringstream ss;
278  ss << cb;
279  std::string tmp(ss.str());
280  ar << tmp;
281 }
282 
283 template <class Archive>
284 void load(Archive &ar, boost::normal_distribution<double> &cb, const unsigned int)
285 {
286  std::string tmp;
287  ar >> tmp;
288  std::stringstream ss(tmp);
289  ss >> cb;
290 }
291 
292 template <class Archive>
293 void serialize(Archive &ar, boost::normal_distribution<double> &cb, const unsigned int version)
294 {
295  split_free(ar, cb, version);
296 }
297 
298 // ---------- boost::uniform_real_distribution -----------
299 // Serialization of boost::uniform_real_distribution exploits the fact that the
300 // state of Boost distributions can be sent/received to/from standard streams.
301 template <class Archive>
302 void save(Archive &ar, const boost::random::uniform_real_distribution<double> &cb, const unsigned int)
303 {
304  std::stringstream ss;
305  ss << cb;
306  std::string tmp(ss.str());
307  ar << tmp;
308 }
309 
310 template <class Archive>
311 void load(Archive &ar, boost::random::uniform_real_distribution<double> &cb, const unsigned int)
312 {
313  std::string tmp;
314  ar >> tmp;
315  std::stringstream ss(tmp);
316  ss >> cb;
317 }
318 
319 template <class Archive>
320 void serialize(Archive &ar, boost::random::uniform_real_distribution<double> &cb, const unsigned int version)
321 {
322  split_free(ar, cb, version);
323 }
324 
325 }}
326 
327 #endif
Root PaGMO namespace.
void custom_vector_double_save(Archive &ar, const std::vector< double > &v, const unsigned int)
Custom save function for the serialization of vector of doubles that handle also inf and NaN...
Definition: serialization.h:67
void custom_vector_double_load(Archive &ar, std::vector< double > &v, const unsigned int)
Custom load function for the serialization of vector of doubles that handle also inf and NaN...
Definition: serialization.h:92