ALPSCore reference
valarray.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #ifndef ALPS_HDF5_STD_VALARRAY_HPP
8 #define ALPS_HDF5_STD_VALARRAY_HPP
9 
10 #include <alps/hdf5.hpp>
11 #include <alps/utilities/cast.hpp>
12 
13 #include <type_traits>
14 #include <valarray>
15 #include <iterator>
16 #include <algorithm>
17 
18 namespace alps {
19  namespace hdf5 {
20 
21  template<typename T> struct scalar_type<std::valarray<T> > {
22  typedef typename scalar_type<T>::type type;
23  };
24 
25  template<typename T> struct is_content_continuous<std::valarray<T> >
26  : public is_continuous<T>
27  {};
28 
29  template<typename T> struct has_complex_elements<std::valarray<T> >
30  : public has_complex_elements<typename alps::detail::remove_cvr<T>::type>
31  {};
32 
33  namespace detail {
34 
35  template<typename T> struct get_extent<std::valarray<T> > {
36  static std::vector<std::size_t> apply(std::valarray<T> const & value) {
38  std::vector<std::size_t> result(1, value.size());
39  if (value.size()) {
40  std::vector<std::size_t> extent(get_extent(const_cast<std::valarray<T> &>(value)[0]));
41  if (!std::is_scalar<T>::value)
42  for (std::size_t i = 1; i < value.size(); ++i)
43  if (!std::equal(extent.begin(), extent.end(), get_extent(const_cast<std::valarray<T> &>(value)[i]).begin()))
44  throw archive_error("no rectengual matrix" + ALPS_STACKTRACE);
45  std::copy(extent.begin(), extent.end(), std::back_inserter(result));
46  }
47  return result;
48  }
49  };
50 
51  template<typename T> struct set_extent<std::valarray<T> > {
52  static void apply(std::valarray<T> & value, std::vector<std::size_t> const & extent) {
54  value.resize(extent[0]);
55  if (extent.size() > 1)
56  for(std::size_t i = 0; i < value.size(); ++i)
57  set_extent(value[i], std::vector<std::size_t>(extent.begin() + 1, extent.end()));
58  else if (extent.size() == 0 && !std::is_same<typename scalar_type<T>::type, T>::value)
59  throw archive_error("dimensions do not match" + ALPS_STACKTRACE);
60  }
61  };
62 
63  template<typename T> struct is_vectorizable<std::valarray<T> > {
64  static bool apply(std::valarray<T> const & value) {
67  if (value.size()) {
68  if (!is_vectorizable(const_cast<std::valarray<T> &>(value)[0]))
69  return false;
70  std::vector<std::size_t> first(get_extent(const_cast<std::valarray<T> &>(value)[0]));
71  if (!std::is_scalar<T>::value) {
72  for(std::size_t i = 0; i < value.size(); ++i)
73  if (!is_vectorizable(const_cast<std::valarray<T> &>(value)[i])) {
74  return false;
75  } else {
76  std::vector<std::size_t> size(get_extent(const_cast<std::valarray<T> &>(value)[i]));
77  if (
78  first.size() != size.size()
79  || !std::equal(first.begin(), first.end(), size.begin())
80  ) {
81  return false;
82  }
83  }
84  }
85  }
86  return true;
87  }
88  };
89 
90  template<typename T> struct get_pointer<std::valarray<T> > {
91  static typename alps::hdf5::scalar_type<std::valarray<T> >::type * apply(std::valarray<T> & value) {
93  return get_pointer(value[0]);
94  }
95  };
96 
97  template<typename T> struct get_pointer<std::valarray<T> const> {
98  static typename alps::hdf5::scalar_type<std::valarray<T> >::type const * apply(std::valarray<T> const & value) {
100  return get_pointer(const_cast<std::valarray<T> &>(value)[0]);
101  }
102  };
103  }
104 
105  template<typename T> void save(
106  archive & ar
107  , std::string const & path
108  , std::valarray<T> const & value
109  , std::vector<std::size_t> size = std::vector<std::size_t>()
110  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
111  , std::vector<std::size_t> offset = std::vector<std::size_t>()
112  ) {
113  if (ar.is_group(path))
114  ar.delete_group(path);
115  if (is_continuous<T>::value && value.size() == 0)
116  ar.write(path, static_cast<typename scalar_type<std::valarray<T> >::type const *>(NULL), std::vector<std::size_t>());
117  else if (is_continuous<T>::value) {
118  std::vector<std::size_t> extent(get_extent(value));
119  std::copy(extent.begin(), extent.end(), std::back_inserter(size));
120  std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
121  std::fill_n(std::back_inserter(offset), extent.size(), 0);
122  ar.write(path, get_pointer(value), size, chunk, offset);
123  } else if (value.size() == 0)
124  ar.write(path, static_cast<int const *>(NULL), std::vector<std::size_t>());
125  else if (is_vectorizable(value)) {
126  size.push_back(value.size());
127  chunk.push_back(1);
128  offset.push_back(0);
129  for(std::size_t i = 0; i < value.size(); ++i) {
130  offset.back() = i;
131  save(ar, path, const_cast<std::valarray<T> &>(value)[i], size, chunk, offset);
132  }
133  } else {
134  if (ar.is_data(path))
135  ar.delete_data(path);
136  for(std::size_t i = 0; i < value.size(); ++i)
137  save(ar, ar.complete_path(path) + "/" + cast<std::string>(i), const_cast<std::valarray<T> &>(value)[i]);
138  }
139  }
140 
141  template<typename T> void load(
142  archive & ar
143  , std::string const & path
144  , std::valarray<T> & value
145  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
146  , std::vector<std::size_t> offset = std::vector<std::size_t>()
147  ) {
148  if (ar.is_group(path)) {
149  std::vector<std::string> children = ar.list_children(path);
150  value.resize(children.size());
151  for (typename std::vector<std::string>::const_iterator it = children.begin(); it != children.end(); ++it)
152  load(ar, ar.complete_path(path) + "/" + *it, value[cast<std::size_t>(*it)]);
153  } else {
155  throw archive_error("no complex value in archive" + ALPS_STACKTRACE);
156  std::vector<std::size_t> size(ar.extent(path));
158  set_extent(value, std::vector<std::size_t>(size.begin() + chunk.size(), size.end()));
159  std::copy(size.begin() + chunk.size(), size.end(), std::back_inserter(chunk));
160  std::fill_n(std::back_inserter(offset), size.size() - offset.size(), 0);
161  ar.read(path, get_pointer(value), chunk, offset);
162  } else {
163  set_extent(value, std::vector<std::size_t>(1, *(size.begin() + chunk.size())));
164  chunk.push_back(1);
165  offset.push_back(0);
166  for(std::size_t i = 0; i < value.size(); ++i) {
167  offset.back() = i;
168  load(ar, path, value[i], chunk, offset);
169  }
170  }
171  }
172  }
173  }
174 }
175 
176 #endif
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:309
bool is_vectorizable(T const &value)
Definition: archive.hpp:288
void set_extent(T &value, std::vector< std::size_t > const &size)
Definition: archive.hpp:284
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
bool is_data(std::string path) const
Definition: archive.cpp:170
STL namespace.
std::vector< std::size_t > get_extent(T const &value)
Definition: archive.hpp:280
void delete_data(std::string path) const
Definition: archive.cpp:364
void delete_group(std::string path) const
Definition: archive.cpp:376
scalar_type< T >::type * get_pointer(T &value)
Definition: archive.hpp:272
std::vector< std::size_t > extent(std::string path) const
Definition: archive.cpp:291
std::vector< std::string > list_children(std::string path) const
Definition: archive.cpp:259
auto read(std::string path, T *, std::vector< std::size_t >, std::vector< std::size_t >=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:163
auto write(std::string path, T const *value, std::vector< std::size_t > size, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t > offset=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:172
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
traits< Acc >::result_type result(const Acc &acc)
Definition: util.hpp:53
bool is_group(std::string path) const
Definition: archive.cpp:189
std::string complete_path(std::string path) const
Definition: archive.cpp:153
bool is_complex(std::string path) const
Definition: archive.cpp:242
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:292