Kernel Quantum Probability Library
The KQP library aims at providing tools for working with quantums probabilities
serialization.hpp
1 /*
2  This file is part of the Kernel Quantum Probability library (KQP).
3 
4  KQP 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  KQP 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 KQP. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef _KQP_SERIALIZATION_H
19 #define _KQP_SERIALIZATION_H
20 
21 #include <boost/serialization/level.hpp>
22 // #include <boost/serialization/version.hpp>
23 #include <boost/serialization/split_free.hpp>
24 // serialization::split_free(ar, t, file_version);
25 
26 
27 #include <boost/preprocessor/comma.hpp>
28 #include <kqp/decomposition.hpp>
29 #include <kqp/feature_matrix/dense.hpp>
30 #include <kqp/feature_matrix/sparse_dense.hpp>
31 
32 
33 namespace boost
34 {
35  // namespace serialization
36  // {
37  // template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
38  // struct implementation_level<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>>
39  // {
40  // typedef mpl::integral_c_tag tag;
41  // typedef mpl::int_<object_serializable> type;
42  // BOOST_STATIC_CONSTANT(int, value = level_type::object_serializable);
43  // };
44  // }
45  //
46  using namespace kqp;
47 
48 
49 
51 template<typename Archive, typename T>
52 struct Loader {
53  static inline T load(Archive & ar) {
54  T t;
55  ar & t;
56  return t;
57  }
58 };
59 
60 // -- Eigen matrix
61 template<class Archive, typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
62 inline void serialize(
63  Archive & ar,
64  Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> & t,
65  const unsigned int /*file_version*/
66 )
67 {
68  Index rows = t.rows(), cols = t.cols();
69  ar & rows;
70  ar & cols;
71 
72  if( rows != t.rows() || cols != t.cols() )
73  t.resize( rows, cols );
74 
75  for(Index i=0; i<t.size(); i++)
76  ar & t.data()[i];
77 }
78 
79 namespace serialization
80 {
81 template<typename Scalar, typename Matrix>
82 struct implementation_level<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>,Matrix>>
83 {
84  typedef mpl::integral_c_tag tag;
85  typedef mpl::int_<object_serializable> type;
86  BOOST_STATIC_CONSTANT(
87  int,
88  value = level_type::object_serializable
89  );
90 };
91 
92 template<typename Scalar, typename Matrix>
93 struct tracking_level<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>,Matrix>>
94 {
95  typedef mpl::integral_c_tag tag;
96  typedef mpl::int_<track_never> type;
97  BOOST_STATIC_CONSTANT(
98  int,
99  value = tracking_type::track_never
100  );
101 };
102 }
103 
104 
105 template<class Archive, typename Scalar, typename Matrix>
106 inline void save(
107  Archive & ar,
108  const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>, Matrix> & t,
109  const unsigned int /*file_version*/
110 )
111 {
112  size_t rows = t.rows(), cols = t.cols();
113  ar & rows;
114  ar & cols;
115 
116  Scalar value = t.coeff(0,0);
117  ar & value;
118 }
119 
120 
121 template<typename Archive, typename Scalar, typename Matrix>
122 struct Loader<Archive, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>, Matrix>> {
123  static inline Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>, Matrix> load(Archive &ar)
124  {
125  size_t rows, cols;
126  Scalar value;
127 
128  ar & rows;
129  ar & cols;
130  ar & value;
131 
132  return Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>, Matrix>(rows, cols, value);
133  }
134 };
135 
136 template<class Archive, typename Scalar, typename Matrix>
137 inline void serialize(
138  Archive & ar,
139  Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<Scalar>, Matrix> & t,
140  const unsigned int file_version
141 )
142 {
143  serialization::split_free(ar, t, file_version);
144 }
145 
146 
147 
148 
149 // -- Alt matrix
150 
151 template<class Archive, typename T1, typename T2>
152 inline void save(
153  Archive & ar,
154  const kqp::AltMatrix<T1, T2>& t,
155  const unsigned int /*file_version*/
156 )
157 {
158  bool isT1 = t.isT1();
159  ar & isT1;
160 
161  if (isT1) {
162  const T1 & t1 = t.t1();
163  ar & t1;
164  } else {
165  const T2 & t2 = t.t2();
166  ar & t2;
167  }
168 }
169 
170 
171 
172 
173 template<class Archive, typename T1, typename T2>
174 inline void load(
175  Archive & ar,
177  const unsigned int /*file_version*/
178 )
179 {
180  bool isT1;
181  ar & isT1;
182 
183  if (isT1)
184  {
185  // std::cerr << "LOADING " << KQP_DEMANGLE(T1) << "/" << KQP_DEMANGLE(t) << std::endl;
186  t = Loader<Archive, T1>::load(ar);
187  }
188  else
189  {
190  // std::cerr << "LOADING " << KQP_DEMANGLE(T2) << "/" << KQP_DEMANGLE(t) << std::endl;
191  t = Loader<Archive, T2>::load(ar);
192  }
193 
194 }
195 
196 
197 
198 template<class Archive, typename T1, typename T2>
199 inline void serialize(
200  Archive & ar,
202  const unsigned int file_version
203 )
204 {
205  serialization::split_free(ar, t, file_version);
206 }
207 
208 
209 
210 
211 
212 // --- Feature Matrix
213 
214 template<class Archive, typename Scalar>
215 inline void save(
216  Archive & ar,
217  const boost::shared_ptr<FeatureMatrixBase<Scalar>> &m,
218  const unsigned int /*file_version*/
219 )
220 {
221  std::string type;
222 
223  if (dynamic_cast<kqp::Dense<Scalar>*>(m.get()) != 0)
224  {
225  type = "dense";
226  ar << type;
227  ar & dynamic_cast<kqp::Dense<Scalar>&>(*m).getMatrix();
228  }
229  else if (dynamic_cast<kqp::SparseDense<Scalar>*>(m.get()) != 0)
230  {
231  type = "sparse-dense";
232  ar << type;
233  ar & dynamic_cast<kqp::SparseDense<Scalar>&>(*m);
234  }
235  else
236  {
237  KQP_THROW_EXCEPTION_F(kqp::not_implemented_exception, "Cannot serialize feature matrix of type %s", %KQP_DEMANGLE(*m.get()));
238  }
239 }
240 
241 template<class Archive, typename Scalar>
242 inline void load(
243  Archive & ar,
244  boost::shared_ptr<FeatureMatrixBase<Scalar>> &t,
245  const unsigned int /*file_version*/
246 )
247 {
248  std::string type;
249  ar & type;
250 
251  if (type == "dense")
252  {
254  ar & m;
255  t = kqp::Dense<Scalar>::create(std::move(m));
256  }
257  else if (type == "sparse-dense")
258  {
259  boost::shared_ptr<SparseDense<Scalar>> p(new kqp::SparseDense<Scalar>());
260  ar & *p;
261  t = p;
262  }
263  else
264  {
265  KQP_THROW_EXCEPTION_F(kqp::not_implemented_exception, "Cannot unserialize feature matrix of type %s", %type);
266  }
267 }
268 
269 template<class Archive, typename Scalar>
270 inline void serialize(
271  Archive & ar,
272  boost::shared_ptr<FeatureMatrixBase<Scalar>> &t,
273  const unsigned int file_version
274 )
275 {
276  serialization::split_free(ar, t, file_version);
277 }
278 
279 } // ns(boost)
280 
281 
282 
283 #endif