mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Grid tensor serialisation fully implemented and tested
This commit is contained in:
		@@ -198,7 +198,7 @@ namespace Grid {
 | 
			
		||||
      typedef typename vsimd::scalar_type scalar;\
 | 
			
		||||
      return Comparison(functor<scalar,scalar>(),lhs,rhs);\
 | 
			
		||||
    }\
 | 
			
		||||
  template<class vsimd>\
 | 
			
		||||
  template<class vsimd,IfSimd<vsimd> = 0>\
 | 
			
		||||
    inline vInteger operator op(const iScalar<vsimd> &lhs,const iScalar<vsimd> &rhs)\
 | 
			
		||||
    {									\
 | 
			
		||||
      return lhs._internal op rhs._internal;				\
 | 
			
		||||
 
 | 
			
		||||
@@ -32,178 +32,9 @@ Author: Guido Cossu <guido.cossu@ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <Grid/tensors/Tensors.h>
 | 
			
		||||
#include <Grid/serialisation/VectorUtils.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  // Grid scalar tensors to nested std::vectors //////////////////////////////////
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct TensorToVec
 | 
			
		||||
  {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct TensorToVec<iScalar<T>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename TensorToVec<T>::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  struct TensorToVec<iVector<T, N>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename std::vector<typename TensorToVec<T>::type> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  struct TensorToVec<iMatrix<T, N>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename std::vector<std::vector<typename TensorToVec<T>::type>> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TensorToVec<T>::type tensorToVec(const T &t)
 | 
			
		||||
  {
 | 
			
		||||
    return t;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TensorToVec<iScalar<T>>::type tensorToVec(const iScalar<T>& t)
 | 
			
		||||
  {
 | 
			
		||||
    return tensorToVec(t._internal);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  typename TensorToVec<iVector<T, N>>::type tensorToVec(const iVector<T, N>& t)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iVector<T, N>>::type v;
 | 
			
		||||
 | 
			
		||||
    v.resize(N);
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++) 
 | 
			
		||||
    {
 | 
			
		||||
      v[i] = tensorToVec(t._internal[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  typename TensorToVec<iMatrix<T, N>>::type tensorToVec(const iMatrix<T, N>& t)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iMatrix<T, N>>::type v;
 | 
			
		||||
 | 
			
		||||
    v.resize(N);
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++)
 | 
			
		||||
    {
 | 
			
		||||
      v[i].resize(N);
 | 
			
		||||
      for (unsigned int j = 0; j < N; j++) 
 | 
			
		||||
      {
 | 
			
		||||
        v[i][j] = tensorToVec(t._internal[i][j]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void vecToTensor(T &t, const typename TensorToVec<T>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    t = v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void vecToTensor(iScalar<T> &t, const typename TensorToVec<iScalar<T>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    vecToTensor(t._internal, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void vecToTensor(iVector<T, N> &t, const typename TensorToVec<iVector<T, N>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++) 
 | 
			
		||||
    {
 | 
			
		||||
      vecToTensor(t._internal[i], v[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void vecToTensor(iMatrix<T, N> &t, const typename TensorToVec<iMatrix<T, N>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++)
 | 
			
		||||
    for (unsigned int j = 0; j < N; j++)
 | 
			
		||||
    {
 | 
			
		||||
      vecToTensor(t._internal[i][j], v[i][j]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Vector element trait //////////////////////////////////////////////////////  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct element
 | 
			
		||||
  {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
    static constexpr bool is_number = false;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct element<std::vector<T>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename element<T>::type type;
 | 
			
		||||
    static constexpr bool is_number = std::is_arithmetic<T>::value
 | 
			
		||||
                                      or is_complex<T>::value
 | 
			
		||||
                                      or element<T>::is_number;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Vector flattening utility class ////////////////////////////////////////////
 | 
			
		||||
  // Class to flatten a multidimensional std::vector
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  class Flatten
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef typename element<V>::type Element;
 | 
			
		||||
  public:
 | 
			
		||||
    explicit                     Flatten(const V &vector);
 | 
			
		||||
    const V &                    getVector(void);
 | 
			
		||||
    const std::vector<Element> & getFlatVector(void);
 | 
			
		||||
    const std::vector<size_t>  & getDim(void);
 | 
			
		||||
  private:
 | 
			
		||||
    void accumulate(const Element &e);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void accumulate(const W &v);
 | 
			
		||||
    void accumulateDim(const Element &e);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void accumulateDim(const W &v);
 | 
			
		||||
  private:
 | 
			
		||||
    const V              &vector_;
 | 
			
		||||
    std::vector<Element> flatVector_;
 | 
			
		||||
    std::vector<size_t>  dim_;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Class to reconstruct a multidimensional std::vector
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  class Reconstruct
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef typename element<V>::type Element;
 | 
			
		||||
  public:
 | 
			
		||||
    Reconstruct(const std::vector<Element> &flatVector,
 | 
			
		||||
                const std::vector<size_t> &dim);
 | 
			
		||||
    const V &                    getVector(void);
 | 
			
		||||
    const std::vector<Element> & getFlatVector(void);
 | 
			
		||||
    const std::vector<size_t>  & getDim(void);
 | 
			
		||||
  private:
 | 
			
		||||
    void fill(std::vector<Element> &v);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void fill(W &v);
 | 
			
		||||
    void resize(std::vector<Element> &v, const unsigned int dim);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void resize(W &v, const unsigned int dim);
 | 
			
		||||
  private:
 | 
			
		||||
    V                          vector_;
 | 
			
		||||
    const std::vector<Element> &flatVector_;
 | 
			
		||||
    std::vector<size_t>        dim_;
 | 
			
		||||
    size_t                     ind_{0};
 | 
			
		||||
    unsigned int               dimInd_{0};
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Pair IO utilities /////////////////////////////////////////////////////////
 | 
			
		||||
  // helper function to parse input in the format "<obj1 obj2>"
 | 
			
		||||
  template <typename T1, typename T2>
 | 
			
		||||
@@ -252,42 +83,6 @@ namespace Grid {
 | 
			
		||||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Vector IO utilities ///////////////////////////////////////////////////////
 | 
			
		||||
  // helper function to read space-separated values
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  std::vector<T> strToVec(const std::string s)
 | 
			
		||||
  {
 | 
			
		||||
    std::istringstream sstr(s);
 | 
			
		||||
    T                  buf;
 | 
			
		||||
    std::vector<T>     v;
 | 
			
		||||
    
 | 
			
		||||
    while(!sstr.eof())
 | 
			
		||||
    {
 | 
			
		||||
      sstr >> buf;
 | 
			
		||||
      v.push_back(buf);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // output to streams for vectors
 | 
			
		||||
  template < class T >
 | 
			
		||||
  inline std::ostream & operator<<(std::ostream &os, const std::vector<T> &v)
 | 
			
		||||
  {
 | 
			
		||||
    os << "[";
 | 
			
		||||
    for (auto &x: v)
 | 
			
		||||
    {
 | 
			
		||||
      os << x << " ";
 | 
			
		||||
    }
 | 
			
		||||
    if (v.size() > 0)
 | 
			
		||||
    {
 | 
			
		||||
      os << "\b";
 | 
			
		||||
    }
 | 
			
		||||
    os << "]";
 | 
			
		||||
    
 | 
			
		||||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Abstract writer/reader classes ////////////////////////////////////////////
 | 
			
		||||
  // static polymorphism implemented using CRTP idiom
 | 
			
		||||
  class Serializable;
 | 
			
		||||
@@ -307,6 +102,12 @@ namespace Grid {
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
 | 
			
		||||
    write(const std::string& s, const U &output);
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    void write(const std::string &s, const iScalar<U> &output);
 | 
			
		||||
    template <typename U, int N>
 | 
			
		||||
    void write(const std::string &s, const iVector<U, N> &output);
 | 
			
		||||
    template <typename U, int N>
 | 
			
		||||
    void write(const std::string &s, const iMatrix<U, N> &output);
 | 
			
		||||
  private:
 | 
			
		||||
    T *upcast;
 | 
			
		||||
  };
 | 
			
		||||
@@ -326,6 +127,12 @@ namespace Grid {
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
 | 
			
		||||
    read(const std::string& s, U &output);
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    void read(const std::string &s, iScalar<U> &output);
 | 
			
		||||
    template <typename U, int N>
 | 
			
		||||
    void read(const std::string &s, iVector<U, N> &output);
 | 
			
		||||
    template <typename U, int N>
 | 
			
		||||
    void read(const std::string &s, iMatrix<U, N> &output);
 | 
			
		||||
  protected:
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    void fromString(U &output, const std::string &s);
 | 
			
		||||
@@ -341,201 +148,7 @@ namespace Grid {
 | 
			
		||||
    static const bool value = false;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Generic writer interface
 | 
			
		||||
  // serializable base class
 | 
			
		||||
  class Serializable
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static inline void write(Writer<T> &WR,const std::string &s,
 | 
			
		||||
                             const Serializable &obj)
 | 
			
		||||
    {}
 | 
			
		||||
    
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static inline void read(Reader<T> &RD,const std::string &s,
 | 
			
		||||
                            Serializable &obj)
 | 
			
		||||
    {}
 | 
			
		||||
    
 | 
			
		||||
    friend inline std::ostream & operator<<(std::ostream &os,
 | 
			
		||||
                                            const Serializable &obj)
 | 
			
		||||
    {
 | 
			
		||||
      return os;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Flatten class template implementation /////////////////////////////////////
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Flatten<V>::accumulate(const Element &e)
 | 
			
		||||
  {
 | 
			
		||||
    flatVector_.push_back(e);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Flatten<V>::accumulate(const W &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      accumulate(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Flatten<V>::accumulateDim(const Element &e) {};
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Flatten<V>::accumulateDim(const W &v)
 | 
			
		||||
  {
 | 
			
		||||
    dim_.push_back(v.size());
 | 
			
		||||
    accumulateDim(v[0]);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  Flatten<V>::Flatten(const V &vector)
 | 
			
		||||
  : vector_(vector)
 | 
			
		||||
  {
 | 
			
		||||
    accumulate(vector_);
 | 
			
		||||
    accumulateDim(vector_);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const V & Flatten<V>::getVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return vector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<typename Flatten<V>::Element> &
 | 
			
		||||
  Flatten<V>::getFlatVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return flatVector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<size_t> & Flatten<V>::getDim(void)
 | 
			
		||||
  {
 | 
			
		||||
    return dim_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Reconstruct class template implementation /////////////////////////////////
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Reconstruct<V>::fill(std::vector<Element> &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      e = flatVector_[ind_++];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Reconstruct<V>::fill(W &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      fill(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Reconstruct<V>::resize(std::vector<Element> &v, const unsigned int dim)
 | 
			
		||||
  {
 | 
			
		||||
    v.resize(dim_[dim]);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Reconstruct<V>::resize(W &v, const unsigned int dim)
 | 
			
		||||
  {
 | 
			
		||||
    v.resize(dim_[dim]);
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      resize(e, dim + 1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  Reconstruct<V>::Reconstruct(const std::vector<Element> &flatVector,
 | 
			
		||||
                              const std::vector<size_t> &dim)
 | 
			
		||||
  : flatVector_(flatVector)
 | 
			
		||||
  , dim_(dim)
 | 
			
		||||
  {
 | 
			
		||||
    resize(vector_, 0);
 | 
			
		||||
    fill(vector_);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const V & Reconstruct<V>::getVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return vector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<typename Reconstruct<V>::Element> &
 | 
			
		||||
  Reconstruct<V>::getFlatVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return flatVector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<size_t> & Reconstruct<V>::getDim(void)
 | 
			
		||||
  {
 | 
			
		||||
    return dim_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Generic writer interface //////////////////////////////////////////////////
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void push(Writer<T> &w, const std::string &s) {
 | 
			
		||||
    w.push(s);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void push(Writer<T> &w, const char *s)
 | 
			
		||||
  {
 | 
			
		||||
    w.push(std::string(s));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void pop(Writer<T> &w)
 | 
			
		||||
  {
 | 
			
		||||
    w.pop();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T, typename U>
 | 
			
		||||
  inline void write(Writer<T> &w, const std::string& s, const U &output)
 | 
			
		||||
  {
 | 
			
		||||
    w.write(s, output);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Generic reader interface
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline bool push(Reader<T> &r, const std::string &s)
 | 
			
		||||
  {
 | 
			
		||||
    return r.push(s);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline bool push(Reader<T> &r, const char *s)
 | 
			
		||||
  {
 | 
			
		||||
    return r.push(std::string(s));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void pop(Reader<T> &r)
 | 
			
		||||
  {
 | 
			
		||||
    r.pop();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T, typename U>
 | 
			
		||||
  inline void read(Reader<T> &r, const std::string &s, U &output)
 | 
			
		||||
  {
 | 
			
		||||
    r.read(s, output);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Writer template implementation ////////////////////////////////////////////
 | 
			
		||||
  // Writer template implementation
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  Writer<T>::Writer(void)
 | 
			
		||||
  {
 | 
			
		||||
@@ -570,6 +183,27 @@ namespace Grid {
 | 
			
		||||
    upcast->writeDefault(s, output);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U>
 | 
			
		||||
  void Writer<T>::write(const std::string &s, const iScalar<U> &output)
 | 
			
		||||
  {
 | 
			
		||||
    upcast->writeDefault(s, tensorToVec(output));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U, int N>
 | 
			
		||||
  void Writer<T>::write(const std::string &s, const iVector<U, N> &output)
 | 
			
		||||
  {
 | 
			
		||||
    upcast->writeDefault(s, tensorToVec(output));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U, int N>
 | 
			
		||||
  void Writer<T>::write(const std::string &s, const iMatrix<U, N> &output)
 | 
			
		||||
  {
 | 
			
		||||
    upcast->writeDefault(s, tensorToVec(output));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Reader template implementation
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  Reader<T>::Reader(void)
 | 
			
		||||
@@ -605,6 +239,36 @@ namespace Grid {
 | 
			
		||||
    upcast->readDefault(s, output);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U>
 | 
			
		||||
  void Reader<T>::read(const std::string &s, iScalar<U> &output)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iScalar<U>>::type v;
 | 
			
		||||
 | 
			
		||||
    upcast->readDefault(s, v);
 | 
			
		||||
    vecToTensor(output, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U, int N>
 | 
			
		||||
  void Reader<T>::read(const std::string &s, iVector<U, N> &output)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iVector<U, N>>::type v;
 | 
			
		||||
    
 | 
			
		||||
    upcast->readDefault(s, v);
 | 
			
		||||
    vecToTensor(output, v);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U, int N>
 | 
			
		||||
  void Reader<T>::read(const std::string &s, iMatrix<U, N> &output)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iMatrix<U, N>>::type v;
 | 
			
		||||
    
 | 
			
		||||
    upcast->readDefault(s, v);
 | 
			
		||||
    vecToTensor(output, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  template <typename U>
 | 
			
		||||
  void Reader<T>::fromString(U &output, const std::string &s)
 | 
			
		||||
@@ -623,6 +287,76 @@ namespace Grid {
 | 
			
		||||
      abort();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // serializable base class ///////////////////////////////////////////////////
 | 
			
		||||
  class Serializable
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static inline void write(Writer<T> &WR,const std::string &s,
 | 
			
		||||
                             const Serializable &obj)
 | 
			
		||||
    {}
 | 
			
		||||
    
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static inline void read(Reader<T> &RD,const std::string &s,
 | 
			
		||||
                            Serializable &obj)
 | 
			
		||||
    {}
 | 
			
		||||
    
 | 
			
		||||
    friend inline std::ostream & operator<<(std::ostream &os,
 | 
			
		||||
                                            const Serializable &obj)
 | 
			
		||||
    {
 | 
			
		||||
      return os;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Generic writer interface //////////////////////////////////////////////////
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void push(Writer<T> &w, const std::string &s) {
 | 
			
		||||
    w.push(s);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void push(Writer<T> &w, const char *s)
 | 
			
		||||
  {
 | 
			
		||||
    w.push(std::string(s));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void pop(Writer<T> &w)
 | 
			
		||||
  {
 | 
			
		||||
    w.pop();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T, typename U>
 | 
			
		||||
  inline void write(Writer<T> &w, const std::string& s, const U &output)
 | 
			
		||||
  {
 | 
			
		||||
    w.write(s, output);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Generic reader interface //////////////////////////////////////////////////
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline bool push(Reader<T> &r, const std::string &s)
 | 
			
		||||
  {
 | 
			
		||||
    return r.push(s);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline bool push(Reader<T> &r, const char *s)
 | 
			
		||||
  {
 | 
			
		||||
    return r.push(std::string(s));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  inline void pop(Reader<T> &r)
 | 
			
		||||
  {
 | 
			
		||||
    r.pop();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T, typename U>
 | 
			
		||||
  inline void read(Reader<T> &r, const std::string &s, U &output)
 | 
			
		||||
  {
 | 
			
		||||
    r.read(s, output);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -38,12 +38,6 @@ namespace Grid
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
 | 
			
		||||
    writeDefault(const std::string &s, const std::vector<U> &x);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void writeDefault(const std::string &s, const iScalar<T> &t);
 | 
			
		||||
    template <typename T, int N>
 | 
			
		||||
    void writeDefault(const std::string &s, const iVector<T, N> &t);
 | 
			
		||||
    template <typename T, int N>
 | 
			
		||||
    void writeDefault(const std::string &s, const iMatrix<T, N> &t);
 | 
			
		||||
  private:
 | 
			
		||||
    template <typename U>
 | 
			
		||||
    void writeSingleAttribute(const U &x, const std::string &name,
 | 
			
		||||
@@ -155,24 +149,6 @@ namespace Grid
 | 
			
		||||
    pop();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void Hdf5Writer::writeDefault(const std::string &s, const iScalar<T> &t)
 | 
			
		||||
  {
 | 
			
		||||
    writeDefault(s, tensorToVec(t));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void Hdf5Writer::writeDefault(const std::string &s, const iVector<T, N> &t)
 | 
			
		||||
  {
 | 
			
		||||
    writeDefault(s, tensorToVec(t));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void Hdf5Writer::writeDefault(const std::string &s, const iMatrix<T, N> &t)
 | 
			
		||||
  {
 | 
			
		||||
    writeDefault(s, tensorToVec(t));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Reader template implementation ////////////////////////////////////////////
 | 
			
		||||
  template <typename U>
 | 
			
		||||
  void Hdf5Reader::readSingleAttribute(U &x, const std::string &name,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										336
									
								
								lib/serialisation/VectorUtils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								lib/serialisation/VectorUtils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,336 @@
 | 
			
		||||
#ifndef GRID_SERIALISATION_VECTORUTILS_H
 | 
			
		||||
#define GRID_SERIALISATION_VECTORUTILS_H
 | 
			
		||||
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <Grid/tensors/Tensors.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  // Grid scalar tensors to nested std::vectors //////////////////////////////////
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct TensorToVec
 | 
			
		||||
  {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct TensorToVec<iScalar<T>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename TensorToVec<T>::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  struct TensorToVec<iVector<T, N>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename std::vector<typename TensorToVec<T>::type> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  struct TensorToVec<iMatrix<T, N>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename std::vector<std::vector<typename TensorToVec<T>::type>> type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TensorToVec<T>::type tensorToVec(const T &t)
 | 
			
		||||
  {
 | 
			
		||||
    return t;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TensorToVec<iScalar<T>>::type tensorToVec(const iScalar<T>& t)
 | 
			
		||||
  {
 | 
			
		||||
    return tensorToVec(t._internal);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  typename TensorToVec<iVector<T, N>>::type tensorToVec(const iVector<T, N>& t)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iVector<T, N>>::type v;
 | 
			
		||||
 | 
			
		||||
    v.resize(N);
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++) 
 | 
			
		||||
    {
 | 
			
		||||
      v[i] = tensorToVec(t._internal[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  typename TensorToVec<iMatrix<T, N>>::type tensorToVec(const iMatrix<T, N>& t)
 | 
			
		||||
  {
 | 
			
		||||
    typename TensorToVec<iMatrix<T, N>>::type v;
 | 
			
		||||
 | 
			
		||||
    v.resize(N);
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++)
 | 
			
		||||
    {
 | 
			
		||||
      v[i].resize(N);
 | 
			
		||||
      for (unsigned int j = 0; j < N; j++) 
 | 
			
		||||
      {
 | 
			
		||||
        v[i][j] = tensorToVec(t._internal[i][j]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void vecToTensor(T &t, const typename TensorToVec<T>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    t = v;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void vecToTensor(iScalar<T> &t, const typename TensorToVec<iScalar<T>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    vecToTensor(t._internal, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void vecToTensor(iVector<T, N> &t, const typename TensorToVec<iVector<T, N>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++) 
 | 
			
		||||
    {
 | 
			
		||||
      vecToTensor(t._internal[i], v[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, int N>
 | 
			
		||||
  void vecToTensor(iMatrix<T, N> &t, const typename TensorToVec<iMatrix<T, N>>::type &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (unsigned int i = 0; i < N; i++)
 | 
			
		||||
    for (unsigned int j = 0; j < N; j++)
 | 
			
		||||
    {
 | 
			
		||||
      vecToTensor(t._internal[i][j], v[i][j]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Vector element trait //////////////////////////////////////////////////////  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct element
 | 
			
		||||
  {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
    static constexpr bool is_number = false;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct element<std::vector<T>>
 | 
			
		||||
  {
 | 
			
		||||
    typedef typename element<T>::type type;
 | 
			
		||||
    static constexpr bool is_number = std::is_arithmetic<T>::value
 | 
			
		||||
                                      or is_complex<T>::value
 | 
			
		||||
                                      or element<T>::is_number;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Vector flattening utility class ////////////////////////////////////////////
 | 
			
		||||
  // Class to flatten a multidimensional std::vector
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  class Flatten
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef typename element<V>::type Element;
 | 
			
		||||
  public:
 | 
			
		||||
    explicit                     Flatten(const V &vector);
 | 
			
		||||
    const V &                    getVector(void);
 | 
			
		||||
    const std::vector<Element> & getFlatVector(void);
 | 
			
		||||
    const std::vector<size_t>  & getDim(void);
 | 
			
		||||
  private:
 | 
			
		||||
    void accumulate(const Element &e);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void accumulate(const W &v);
 | 
			
		||||
    void accumulateDim(const Element &e);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void accumulateDim(const W &v);
 | 
			
		||||
  private:
 | 
			
		||||
    const V              &vector_;
 | 
			
		||||
    std::vector<Element> flatVector_;
 | 
			
		||||
    std::vector<size_t>  dim_;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // Class to reconstruct a multidimensional std::vector
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  class Reconstruct
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef typename element<V>::type Element;
 | 
			
		||||
  public:
 | 
			
		||||
    Reconstruct(const std::vector<Element> &flatVector,
 | 
			
		||||
                const std::vector<size_t> &dim);
 | 
			
		||||
    const V &                    getVector(void);
 | 
			
		||||
    const std::vector<Element> & getFlatVector(void);
 | 
			
		||||
    const std::vector<size_t>  & getDim(void);
 | 
			
		||||
  private:
 | 
			
		||||
    void fill(std::vector<Element> &v);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void fill(W &v);
 | 
			
		||||
    void resize(std::vector<Element> &v, const unsigned int dim);
 | 
			
		||||
    template <typename W>
 | 
			
		||||
    void resize(W &v, const unsigned int dim);
 | 
			
		||||
  private:
 | 
			
		||||
    V                          vector_;
 | 
			
		||||
    const std::vector<Element> &flatVector_;
 | 
			
		||||
    std::vector<size_t>        dim_;
 | 
			
		||||
    size_t                     ind_{0};
 | 
			
		||||
    unsigned int               dimInd_{0};
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Flatten class template implementation
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Flatten<V>::accumulate(const Element &e)
 | 
			
		||||
  {
 | 
			
		||||
    flatVector_.push_back(e);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Flatten<V>::accumulate(const W &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      accumulate(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Flatten<V>::accumulateDim(const Element &e) {};
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Flatten<V>::accumulateDim(const W &v)
 | 
			
		||||
  {
 | 
			
		||||
    dim_.push_back(v.size());
 | 
			
		||||
    accumulateDim(v[0]);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  Flatten<V>::Flatten(const V &vector)
 | 
			
		||||
  : vector_(vector)
 | 
			
		||||
  {
 | 
			
		||||
    accumulate(vector_);
 | 
			
		||||
    accumulateDim(vector_);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const V & Flatten<V>::getVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return vector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<typename Flatten<V>::Element> &
 | 
			
		||||
  Flatten<V>::getFlatVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return flatVector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<size_t> & Flatten<V>::getDim(void)
 | 
			
		||||
  {
 | 
			
		||||
    return dim_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Reconstruct class template implementation
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Reconstruct<V>::fill(std::vector<Element> &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      e = flatVector_[ind_++];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Reconstruct<V>::fill(W &v)
 | 
			
		||||
  {
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      fill(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  void Reconstruct<V>::resize(std::vector<Element> &v, const unsigned int dim)
 | 
			
		||||
  {
 | 
			
		||||
    v.resize(dim_[dim]);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  template <typename W>
 | 
			
		||||
  void Reconstruct<V>::resize(W &v, const unsigned int dim)
 | 
			
		||||
  {
 | 
			
		||||
    v.resize(dim_[dim]);
 | 
			
		||||
    for (auto &e: v)
 | 
			
		||||
    {
 | 
			
		||||
      resize(e, dim + 1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  Reconstruct<V>::Reconstruct(const std::vector<Element> &flatVector,
 | 
			
		||||
                              const std::vector<size_t> &dim)
 | 
			
		||||
  : flatVector_(flatVector)
 | 
			
		||||
  , dim_(dim)
 | 
			
		||||
  {
 | 
			
		||||
    resize(vector_, 0);
 | 
			
		||||
    fill(vector_);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const V & Reconstruct<V>::getVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return vector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<typename Reconstruct<V>::Element> &
 | 
			
		||||
  Reconstruct<V>::getFlatVector(void)
 | 
			
		||||
  {
 | 
			
		||||
    return flatVector_;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename V>
 | 
			
		||||
  const std::vector<size_t> & Reconstruct<V>::getDim(void)
 | 
			
		||||
  {
 | 
			
		||||
    return dim_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Vector IO utilities ///////////////////////////////////////////////////////
 | 
			
		||||
  // helper function to read space-separated values
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  std::vector<T> strToVec(const std::string s)
 | 
			
		||||
  {
 | 
			
		||||
    std::istringstream sstr(s);
 | 
			
		||||
    T                  buf;
 | 
			
		||||
    std::vector<T>     v;
 | 
			
		||||
    
 | 
			
		||||
    while(!sstr.eof())
 | 
			
		||||
    {
 | 
			
		||||
      sstr >> buf;
 | 
			
		||||
      v.push_back(buf);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return v;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // output to streams for vectors
 | 
			
		||||
  template < class T >
 | 
			
		||||
  inline std::ostream & operator<<(std::ostream &os, const std::vector<T> &v)
 | 
			
		||||
  {
 | 
			
		||||
    os << "[";
 | 
			
		||||
    for (auto &x: v)
 | 
			
		||||
    {
 | 
			
		||||
      os << x << " ";
 | 
			
		||||
    }
 | 
			
		||||
    if (v.size() > 0)
 | 
			
		||||
    {
 | 
			
		||||
      os << "\b";
 | 
			
		||||
    }
 | 
			
		||||
    os << "]";
 | 
			
		||||
    
 | 
			
		||||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -55,5 +55,38 @@ LOGICAL_BINOP(&);
 | 
			
		||||
LOGICAL_BINOP(||);
 | 
			
		||||
LOGICAL_BINOP(&&);
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
strong_inline bool operator==(const iScalar<T> &t1, const iScalar<T> &t2)
 | 
			
		||||
{
 | 
			
		||||
  return (t1._internal == t2._internal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T, int N>
 | 
			
		||||
strong_inline bool operator==(const iVector<T, N> &t1, const iVector<T, N> &t2)
 | 
			
		||||
{
 | 
			
		||||
  bool res = true;
 | 
			
		||||
 | 
			
		||||
  for (unsigned int i = 0; i < N; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    res = (res && (t1._internal[i] == t2._internal[i]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T, int N>
 | 
			
		||||
strong_inline bool operator==(const iMatrix<T, N> &t1, const iMatrix<T, N> &t2)
 | 
			
		||||
{
 | 
			
		||||
  bool res = true;
 | 
			
		||||
 | 
			
		||||
  for (unsigned int i = 0; i < N; ++i)
 | 
			
		||||
  for (unsigned int j = 0; j < N; ++j)
 | 
			
		||||
  {
 | 
			
		||||
    res = (res && (t1._internal[i][j] == t2._internal[i][j]));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,8 @@ public:
 | 
			
		||||
                          bool , b,
 | 
			
		||||
                          std::vector<double>, array,
 | 
			
		||||
                          std::vector<std::vector<double> >, twodimarray,
 | 
			
		||||
                          std::vector<std::vector<std::vector<Complex> > >, cmplx3darray
 | 
			
		||||
                          std::vector<std::vector<std::vector<Complex> > >, cmplx3darray,
 | 
			
		||||
                          SpinColourMatrix, scm
 | 
			
		||||
                          );
 | 
			
		||||
  myclass() {}
 | 
			
		||||
  myclass(int i)
 | 
			
		||||
@@ -59,6 +60,12 @@ public:
 | 
			
		||||
    y=2*i;
 | 
			
		||||
    b=true;
 | 
			
		||||
    name="bother said pooh";
 | 
			
		||||
    scm()(0, 1)(2, 1) = 2.356;
 | 
			
		||||
    scm()(3, 0)(1, 1) = 1.323;
 | 
			
		||||
    scm()(2, 1)(0, 1) = 5.3336;
 | 
			
		||||
    scm()(0, 2)(1, 1) = 6.336;
 | 
			
		||||
    scm()(2, 1)(2, 2) = 7.344;
 | 
			
		||||
    scm()(1, 1)(2, 0) = 8.3534;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -113,6 +120,10 @@ void tensorConvTestFn(GridSerialRNG &rng, const std::string label)
 | 
			
		||||
 | 
			
		||||
int main(int argc,char **argv)
 | 
			
		||||
{
 | 
			
		||||
  GridSerialRNG    rng;
 | 
			
		||||
 | 
			
		||||
  rng.SeedFixedIntegers(std::vector<int>({42,10,81,9}));
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "==== basic IO" << std::endl;
 | 
			
		||||
  XmlWriter WR("bother.xml");
 | 
			
		||||
 | 
			
		||||
@@ -138,7 +149,7 @@ int main(int argc,char **argv)
 | 
			
		||||
  std::cout << "-- serialisable class writing to 'bother.xml'..." << std::endl;
 | 
			
		||||
  write(WR,"obj",obj);
 | 
			
		||||
  WR.write("obj2", obj);
 | 
			
		||||
  vec.push_back(myclass(1234));
 | 
			
		||||
  vec.push_back(obj);
 | 
			
		||||
  vec.push_back(myclass(5678));
 | 
			
		||||
  vec.push_back(myclass(3838));
 | 
			
		||||
  pair = std::make_pair(myenum::red, myenum::blue);
 | 
			
		||||
@@ -149,8 +160,6 @@ int main(int argc,char **argv)
 | 
			
		||||
  std::cout << "-- serialisable class comparison:" << std::endl;
 | 
			
		||||
  std::cout << "vec[0] == obj: " << ((vec[0] == obj) ? "true" : "false") << std::endl;
 | 
			
		||||
  std::cout << "vec[1] == obj: " << ((vec[1] == obj) ? "true" : "false") << std::endl;
 | 
			
		||||
 | 
			
		||||
  write(WR, "objpair", pair);
 | 
			
		||||
  std::cout << "-- pair writing to std::cout:" << std::endl;
 | 
			
		||||
  std::cout << pair << std::endl;
 | 
			
		||||
 | 
			
		||||
@@ -159,26 +168,20 @@ int main(int argc,char **argv)
 | 
			
		||||
  //// XML
 | 
			
		||||
  ioTest<XmlWriter, XmlReader>("iotest.xml", obj, "XML    (object)           ");
 | 
			
		||||
  ioTest<XmlWriter, XmlReader>("iotest.xml", vec, "XML    (vector of objects)");
 | 
			
		||||
  ioTest<XmlWriter, XmlReader>("iotest.xml", pair, "XML    (pair of objects)");
 | 
			
		||||
  //// binary
 | 
			
		||||
  ioTest<BinaryWriter, BinaryReader>("iotest.bin", obj, "binary (object)           ");
 | 
			
		||||
  ioTest<BinaryWriter, BinaryReader>("iotest.bin", vec, "binary (vector of objects)");
 | 
			
		||||
  ioTest<BinaryWriter, BinaryReader>("iotest.bin", pair, "binary (pair of objects)");
 | 
			
		||||
  //// text
 | 
			
		||||
  ioTest<TextWriter, TextReader>("iotest.dat", obj, "text   (object)           ");
 | 
			
		||||
  ioTest<TextWriter, TextReader>("iotest.dat", vec, "text   (vector of objects)");
 | 
			
		||||
  ioTest<TextWriter, TextReader>("iotest.dat", pair, "text   (pair of objects)");
 | 
			
		||||
  //// text
 | 
			
		||||
  ioTest<JSONWriter, JSONReader>("iotest.json", obj,  "JSON   (object)           ");
 | 
			
		||||
  ioTest<JSONWriter, JSONReader>("iotest.json", vec,  "JSON   (vector of objects)");
 | 
			
		||||
  ioTest<JSONWriter, JSONReader>("iotest.json", pair, "JSON   (pair of objects)");
 | 
			
		||||
 | 
			
		||||
  //// HDF5
 | 
			
		||||
#undef HAVE_HDF5
 | 
			
		||||
#ifdef HAVE_HDF5
 | 
			
		||||
  ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", obj, "HDF5   (object)           ");
 | 
			
		||||
  ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", vec, "HDF5   (vector of objects)");
 | 
			
		||||
  ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", pair, "HDF5   (pair of objects)");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  std::cout << "\n==== vector flattening/reconstruction" << std::endl;
 | 
			
		||||
@@ -216,10 +219,6 @@ int main(int argc,char **argv)
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  std::cout << "==== Grid tensor to vector test" << std::endl;
 | 
			
		||||
 | 
			
		||||
  GridSerialRNG    rng;
 | 
			
		||||
 | 
			
		||||
  rng.SeedFixedIntegers(std::vector<int>({42,10,81,9}));
 | 
			
		||||
  tensorConvTest(rng, SpinColourMatrix);
 | 
			
		||||
  tensorConvTest(rng, SpinColourVector);
 | 
			
		||||
  tensorConvTest(rng, ColourMatrix);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user