艾根和boost ::连载 [英] Eigen and boost::serialize

查看:181
本文介绍了艾根和boost ::连载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着写一个通用的序列化函数,它接受任何稠密矩阵和序列化它:
这有助于而不是最终的其他一些问题,在这里:
<一href=\"http://stackoverflow.com/questions/12851126/serializing-eigens-matrix-using-boost-serialization\">Question1 <一href=\"http://stackoverflow.com/questions/12580579/how-to-use-boostserialization-to-save-eigenmatrix\">Question2

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 Question2

我想这应该工作如下:

namespace boost {
namespace serialization {
    template<class Archive, typename Derived> void serialize(Archive & ar,  Eigen::EigenBase<Derived> & g, const unsigned int version)
    {
        ar & boost::serialization::make_array(g.derived().data(), g.size());
    }
    }; // namespace serialization
}; // namespace boost

当我尝试序列化征::矩阵和LT;双,4,4&GT;

Eigen::Matrix<double,4,4> a; 
boost::serialize(ar, a);

编译器能以某种方式无法比拟上述模板?
并给出了以下错误:

The compiler can somehow not match the template above? And the following errors are given :

/usr/local/include/boost/serialization/access.hpp|118|error:'类艾根::矩阵没有名为连载成员|

推荐答案

我使用的本征的基于插件扩展

/**
 * @file EigenDenseBaseAddons.h
 */
#ifndef EIGEN_DENSE_BASE_ADDONS_H_
#define EIGEN_DENSE_BASE_ADDONS_H_

friend class boost::serialization::access;
template<class Archive>
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<class Archive>
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<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {
  boost::serialization::split_member(ar, *this, file_version);
}

#endif // EIGEN_DENSE_BASE_ADDONS_H_

配置征使用此pulgin:(简单地包括任何艾根头文件之前定义宏)

Configure Eigen to use this pulgin:(simply define the macro before including any Eigen header)

#ifndef EIGEN_CONFIG_H_
#define EIGEN_CONFIG_H_

#include <boost/serialization/array.hpp>
#define EIGEN_DENSEBASE_PLUGIN "EigenDenseBaseAddons.h"

#include <Eigen/Core>

#endif // EIGEN_CONFIG_H_

虽然我还没有真正测试过这个throughly,它工作得很好,还可以处理数组或任何其他致密征的对象。这也完全适用于前pressions像vec.tail 4;>(),但可能会失败(没有任何编译错误)为前pression像mat.topRows 2>()或块操作。 (请参阅更新:现在为子矩阵也)

在相比其他目前的答案,这适用于更多的集前pression的,可能避免一些暂时的。一种非侵入式的版本也可能可以通过传递 PlainObjectBase&LT;衍生GT; 对象的序列化功能。

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<Derived> objects to the serialize functions..

/// Boost Serialization Helper

template <typename T>
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 <typename T>
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;
}

和一些测试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<Vector4f> b = boost::make_shared<Vector4f>(Vector4f::Random());
serialize(b, "b.tmp");
boost::shared_ptr<Vector4f> 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.

这篇关于艾根和boost ::连载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆