gpt4 book ai didi

c++ - Eigen 和 boost::serialize

转载 作者:可可西里 更新时间:2023-11-01 17:16:06 29 4
gpt4 key购买 nike

我尝试编写一个通用的序列化函数,它接受任何密集矩阵并将其序列化:其他一些有帮助但还没有结束的问题在这里: 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

当我尝试序列化 Eigen::Matrix<double,4,4>

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

编译器会不会匹配上面的模板?并给出以下错误:

/usr/local/include/boost/serialization/access.hpp|118|错误:“class Eigen::Matrix”没有名为“serialize”的成员|

最佳答案

我已经测试了你的代码,但当我试图编译它时它也没有工作。但是,根据 Boost Serialize 的文档,我的印象是它旨在与流运算符 << 一起使用。以下代码对我来说工作正常:

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());
}
}
}

int main (int argc, char* argv[]){
std::ofstream out("my_archive");
boost::archive::text_oarchive oa (out);

Eigen::Matrix <double, 4, 4> a;
out << a;
return 0;
}

文件 my_archive 是在工作文件夹中创建的,具有非零值(只是内存中未初始化的垃圾,带有上述过度简化的代码)。

编辑:我尝试在我自己的应用程序中使用上面的确切代码,发现我收到了与您相同的错误。老实说,我现在不明白为什么会这样。我找到的最简单的修复方法是替换 Eigen::EigenBase<Derived>使用实际的 Matrix 类型。我正在使用的当前代码是:

namespace boost{
namespace serialization {
template <class Archive, typename Scalar>
void serialize ( Archive & ar, Eigen::Matrix<Scalar, -1, -1, 0, -1, -1> & g, const unsigned int version ){ /* ... */ }
}
}

以上代码适用于任何标量类型(float、double、int)和动态/运行时大小的矩阵。对于静态尺寸,检查并相应地更新模板参数。

编辑 #2(2014 年 4 月 9 日):

尽管上面的代码看起来可以工作,但当我试图将它完全集成到我的代码中并通过适当的单元测试对其进行练习时,它停止了工作。不幸的是,我收到的错误消息——来自 Visual Studio 和 clang——最没有帮助。幸运的是,gcc 隐藏在可怕的错误消息中,引用了 CV 不匹配,这似乎让我能够完全解决这个问题。

下面的代码现在似乎可以成功编译和运行。我试图使格式清晰易读(无需横向滚动)——希望下面的代码是清晰的:

namespace boost{
namespace serialization{

template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void save(
Archive & ar,
const Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
int rows = g.rows();
int cols = g.cols();

ar & rows;
ar & cols;
ar & boost::serialization::make_array(g.data(), rows * cols);
}

template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void load(
Archive & ar,
Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
int rows, cols;
ar & rows;
ar & cols;
g.resize(rows, cols);
ar & boost::serialization::make_array(g.data(), rows * cols);
}

template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void serialize(
Archive & ar,
Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
split_free(ar, g, version);
}


} // namespace serialization
} // namespace boost

上面代码的几个关键点:

  • 此代码现在具有所有 Eigen 矩阵参数的模板化参数。这应该允许它处理所有类型的矩阵和 vector ,无论大小是在编译时还是运行时。这是对上述代码的重大改进

  • 必须将序列化代码拆分为单独的保存加载 函数。否则,反序列化代码不会调整矩阵的大小来保存原始数据。我相信 Boost::Serialize 确实提供了一些额外的函数,可以重载这些函数来执行序列化或反序列化操作,但这种方法更容易实现。

  • save 上的 const 限定符方法必不可少。在一个模糊的 g++ 错误让我意识到这一点之前,这就是我遇到麻烦的根源。

  • 我还不能说我已经对这段代码进行了全面的压力测试。如果您(或其他任何人)发现任何其他问题,请务必告诉我,我会尽力跟进我发现的任何其他问题。

相信这会有所帮助。

什穆尔

关于c++ - Eigen 和 boost::serialize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18382457/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com