I tried to write a generic serialize function which takes any dense matrix and serializes it: Some other questions which help but not to the end are here: Question1 Question
I make use of Eigen's plugin based extension:
/**
* @file EigenDenseBaseAddons.h
*/
#ifndef EIGEN_DENSE_BASE_ADDONS_H_
#define EIGEN_DENSE_BASE_ADDONS_H_
friend class boost::serialization::access;
template
void save(Archive & ar, const unsigned int version) const {
derived().eval();
const Index rows = derived().rows(), cols = derived().cols();
ar & rows;
ar & cols;
for (Index j = 0; j < cols; ++j )
for (Index i = 0; i < rows; ++i )
ar & derived().coeff(i, j);
}
template
void load(Archive & ar, const unsigned int version) {
Index rows, cols;
ar & rows;
ar & cols;
if (rows != derived().rows() || cols != derived().cols() )
derived().resize(rows, cols);
ar & boost::serialization::make_array(derived().data(), derived().size());
}
template
void serialize(Archive & ar, const unsigned int file_version) {
boost::serialization::split_member(ar, *this, file_version);
}
#endif // EIGEN_DENSE_BASE_ADDONS_H_
Configure Eigen to use this pulgin:(simply define the macro before including any Eigen header)
#ifndef EIGEN_CONFIG_H_
#define EIGEN_CONFIG_H_
#include
#define EIGEN_DENSEBASE_PLUGIN "EigenDenseBaseAddons.h"
#include
#endif // EIGEN_CONFIG_H_
Though I have not really tested this throughly, it works well and can also deal with Array or any other dense Eigen objects. It also works perfectly for expressions like vec.tail<4>() but may fail (without any compile error) for expression like mat.topRows<2>() or block operations. (See update: now works for sub matrices also)
In comparison to the other current answer, this works for more set of expression and might avoid some temporary. A non-intrusive version is also probably possible by passing PlainObjectBase
objects to the serialize functions..
/// Boost Serialization Helper
template
bool serialize(const T& data, const std::string& filename) {
std::ofstream ofs(filename.c_str(), std::ios::out);
if (!ofs.is_open())
return false;
{
boost::archive::binary_oarchive oa(ofs);
oa << data;
}
ofs.close();
return true;
}
template
bool deSerialize(T& data, const std::string& filename) {
std::ifstream ifs(filename.c_str(), std::ios::in);
if (!ifs.is_open())
return false;
{
boost::archive::binary_iarchive ia(ifs);
ia >> data;
}
ifs.close();
return true;
}
And some test code:
VectorXf vec(100);
vec.setRandom();
serializeText(vec.tail<5>(), "vec.txt");
MatrixXf vec_in;
deSerialize(vec_in, "vec.bin");
assert(vec_in.isApprox(vec.tail<5>()));
serialize(Vector2f(0.5f,0.5f), "a.bin");
Vector2f a2f;
deSerializeBinary(a2f, "a.bin");
assert(a2f.isApprox(Vector2f(0.5f,0.5f)));
VectorXf axf;
deSerialize(axf, "a.bin");
assert(aXf.isApprox(Vector2f(0.5f,0.5f)));
boost::shared_ptr b = boost::make_shared(Vector4f::Random());
serialize(b, "b.tmp");
boost::shared_ptr b_in;
deSerialize(b_in, "b.tmp");
BOOST_CHECK_EQUAL(*b, *b_in);
Matrix4f m(Matrix4f::Random());
serialize(m.topRows<2>(), "m.bin");
deSerialize(m_in, "m.bin");
Update: I made some minor modifications,now serialization of sub matrices also works.