How to serialize armadillo's vector

后端 未结 3 809
轻奢々
轻奢々 2020-12-20 01:27

How can I serialize arma::Col? Below are a MWE and the error output.

MWE:

#include 
#i         


        
3条回答
  •  眼角桃花
    2020-12-20 02:09

    The real crux of the issue here is that you want to add a serialize() member function to the various Armadillo objects, but that doesn't appear to be possible... except that thanks to a clever use of the preprocessor in Armadillo, it is!

    Take a look at Mat_bones.hpp and Col_bones.hpp... you'll see something like this, inside of the class definitions of Mat and Col:

    public:
    
    #ifdef ARMA_EXTRA_COL_PROTO
      #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_PROTO)
    #endif
    

    It made me very happy when I found this, because now I can do something like define a file called Mat_extra_bones.hpp:

    //! Add a serialization operator.
    template
    void serialize(Archive& ar, const unsigned int version);
    

    and then Mat_extra_meat.hpp:

    // Add a serialization operator.
    template
    template
    void Mat::serialize(Archive& ar, const unsigned int /* version */)
    {
      using boost::serialization::make_nvp;
      using boost::serialization::make_array;
    
      const uword old_n_elem = n_elem;
    
      // This is accurate from Armadillo 3.6.0 onwards.
      // We can't use BOOST_SERIALIZATION_NVP() because of the access::rw() call.
      ar & make_nvp("n_rows", access::rw(n_rows));
      ar & make_nvp("n_cols", access::rw(n_cols));
      ar & make_nvp("n_elem", access::rw(n_elem));
      ar & make_nvp("vec_state", access::rw(vec_state));
    
      // mem_state will always be 0 on load, so we don't need to save it.
      if (Archive::is_loading::value)
      {
        // Don't free if local memory is being used.
        if (mem_state == 0 && mem != NULL && old_n_elem > arma_config::mat_prealloc)
        {
          memory::release(access::rw(mem));
        }
    
        access::rw(mem_state) = 0;
    
        // We also need to allocate the memory we're using.
        init_cold();
      }
    
      ar & make_array(access::rwp(mem), n_elem);
    }
    

    Then, in your program, all you need to do is

    #define ARMA_EXTRA_MAT_PROTO mat_extra_bones.hpp
    #define ARMA_EXTRA_MAT_MEAT mat_extra_meat.hpp
    

    and the serialize() function will be a member of the Mat class. You can easily adapt this solution for other Armadillo types.

    In fact this is exactly what the mlpack library (http://www.mlpack.org/) does, so if you are interested you can take a closer look at the exact solution I implemented there:

    https://github.com/mlpack/mlpack/tree/master/src/mlpack/core/arma_extend

提交回复
热议问题