Tatooine
static_multidim_array.h
Go to the documentation of this file.
1#ifndef TATOOINE_STATIC_MULTIDIM_ARRAY_H
2#define TATOOINE_STATIC_MULTIDIM_ARRAY_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/linspace.h>
9#include <tatooine/png.h>
10#include <tatooine/random.h>
11#include <tatooine/reflection.h>
12#include <tatooine/tags.h>
14//==============================================================================
15namespace tatooine {
16//==============================================================================
17template <typename ValueType, index_order IndexOrder, memory_location MemLoc,
18 std::size_t... Resolution>
20 //============================================================================
21 // typedefs
22 //============================================================================
23 public:
24 using size_type = static_multidim_size<IndexOrder, Resolution...>;
25 using value_type = ValueType;
26 using this_type =
27 static_multidim_array<ValueType, IndexOrder, MemLoc, Resolution...>;
28 static std::size_t constexpr num_components() {return size_type::num_components();}
29 static std::size_t constexpr num_dimensions() {return size_type::num_dimensions();}
30 static auto constexpr size() {return size_type::size();}
31 static auto constexpr plain_index(integral auto const... indices) requires(
32 sizeof...(indices) == num_dimensions()) {
33 return size_type::plain_index(indices...);
34 }
35 static auto plain_index(integral_range auto const& indices) {
36 return size_type::plain_index(indices);
37 }
38 static auto constexpr in_range(integral auto const... indices) requires(
39 sizeof...(indices) == num_dimensions()) {
40 return size_type::in_range(indices...);
41 }
43 std::conditional_t<std::is_same<MemLoc, stack>::value,
44 std::array<ValueType, num_components()>,
45 std::vector<ValueType>>;
46
47 //============================================================================
48 // static methods
49 //============================================================================
50 private:
51 static constexpr auto init_data(ValueType const init = ValueType{}) {
52 if constexpr (std::is_same<MemLoc, stack>::value) {
53 return make_array<num_components()>(init);
54 } else {
55 return std::vector(num_components(), init);
56 }
57 }
58 //============================================================================
59 // factories
60 //============================================================================
61 public:
62 static constexpr auto zeros() { return this_type{tag::zeros}; }
63 //------------------------------------------------------------------------------
64 static constexpr auto ones() { return this_type{tag::ones}; }
65 //------------------------------------------------------------------------------
66 template <typename S>
67 static constexpr auto fill(S&& s) {
68 return this_type{tag::fill<std::decay_t<S>>{std::forward<S>(s)}};
69 }
70 //------------------------------------------------------------------------------
71 template <typename RandEng = std::mt19937_64>
72 static auto randu(ValueType min = 0, ValueType max = 1,
73 RandEng&& eng = RandEng{std::random_device{}()}) requires
75 return this_type{random::uniform{min, max, std::forward<RandEng>(eng)}};
76 }
77 //----------------------------------------------------------------------------
78 template <typename RandEng = std::mt19937_64>
79 static auto randn(ValueType mean = 0, ValueType stddev = 1,
80 RandEng&& eng = RandEng{std::random_device{}()}) requires
82 return this_type{random::normal{mean, stddev, std::forward<RandEng>(eng)}};
83 }
84 //============================================================================
85 // members
86 //============================================================================
87 private:
89 //============================================================================
90 // ctors
91 //============================================================================
92 public:
93 constexpr static_multidim_array(static_multidim_array const& other) = default;
94 constexpr static_multidim_array(static_multidim_array&& other) noexcept =
95 default;
96 //----------------------------------------------------------------------------
97 constexpr auto operator =(static_multidim_array const& other)
98 -> static_multidim_array& = default;
99 constexpr auto operator =(static_multidim_array&& other) noexcept
100 -> static_multidim_array& = default;
101 //----------------------------------------------------------------------------
103 //----------------------------------------------------------------------------
104 template <typename OtherT, typename OtherIndexing, typename OtherMemLoc>
105 explicit constexpr static_multidim_array(
106 static_multidim_array<OtherT, OtherIndexing, OtherMemLoc,
107 Resolution...> const& other)
109 for (auto is : static_multidim(Resolution...)) {
110 at(is) = other(is);
111 }
112 }
113 //----------------------------------------------------------------------------
114 template <typename OtherT, typename OtherIndexing, typename OtherMemLoc>
115 constexpr auto operator=(
116 static_multidim_array<OtherT, OtherIndexing, OtherMemLoc,
117 Resolution...> const& other)
119 for (auto is : size_type{}) {
120 at(is) = other(is);
121 }
122 return *this;
123 }
124 //----------------------------------------------------------------------------
125 explicit constexpr static_multidim_array(
126 convertible_to<ValueType> auto&&... ts)
127 : m_data_container{static_cast<ValueType>(ts)...} {
128 static_assert(sizeof...(ts) == num_components());
129 }
130 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132 : m_data_container(init_data(ValueType{})) {}
133 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
134 template <typename S>
135 explicit constexpr static_multidim_array(tag::fill<S> const& f)
136 : m_data_container(init_data(static_cast<ValueType>(f.value))) {}
137 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138 explicit constexpr static_multidim_array(tag::zeros_t /*z*/) requires
140 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
141 explicit constexpr static_multidim_array(tag::ones_t /*o*/) requires
143 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
144 explicit static_multidim_array(std::vector<ValueType> const& data)
146 assert(data.size() == num_components());
147 }
148 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149 explicit constexpr static_multidim_array(
150 std::array<ValueType, num_components()> const& data)
152 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
153 explicit constexpr static_multidim_array(
154 std::array<ValueType, num_components()>&& data) requires
155 is_same<MemLoc, stack> : m_data_container(std::move(data)) {}
156 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
157 explicit constexpr static_multidim_array(
158 std::vector<ValueType>&& data) requires is_same<MemLoc, heap>
159 : m_data_container(std::move(data)) {
160 assert(num_components() == data.size());
161 }
162 //----------------------------------------------------------------------------
163 template <typename RandomReal, typename Engine>
164 explicit constexpr static_multidim_array(
167 this->unary_operation(
168 [&](auto const& /*c*/) { return static_cast<ValueType>(rand()); });
169 }
170 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
171 template <typename RandomReal, typename Engine>
172 explicit constexpr static_multidim_array(
175 this->unary_operation(
176 [&](auto const& /*c*/) { return static_cast<ValueType>(rand()); });
177 }
178 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
179 template <typename RandomReal, typename Engine>
180 explicit constexpr static_multidim_array(
183 this->unary_operation(
184 [&](auto const& /*c*/) { return static_cast<ValueType>(rand()); });
185 }
186 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
187 template <typename RandomReal, typename Engine>
188 explicit constexpr static_multidim_array(
191 this->unary_operation(
192 [&](auto const& /*c*/) { return static_cast<ValueType>(rand()); });
193 }
194 //============================================================================
195 // methods
196 //============================================================================
197 public:
198 [[nodiscard]] constexpr auto at(integral auto const... is) const -> const
199 auto& requires(sizeof...(is) == num_dimensions()) {
200 assert(in_range(is...));
201 return m_data_container[plain_index(is...)];
202 }
203 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
204 constexpr auto at(integral auto const... is)
205 -> auto& requires(sizeof...(is) == num_dimensions()) {
206 assert(in_range(is...));
207 return m_data_container[plain_index(is...)];
208 }
209 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
210 constexpr auto at(integral_range auto const& indices) const -> auto const& {
211 assert(indices.size() == num_dimensions());
212 return m_data_container[plain_index(indices)];
213 }
214 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215 constexpr auto at(integral_range auto const& indices) -> auto& {
216 assert(indices.size() == num_dimensions());
217 return m_data_container[plain_index(indices)];
218 }
219 //----------------------------------------------------------------------------
220 [[nodiscard]] constexpr auto operator()(integral auto const... is) const
221 -> auto const& requires(sizeof...(is) == num_dimensions()) {
222 assert(in_range(is...));
223 return m_data_container[plain_index(is...)];
224 }
225 //----------------------------------------------------------------------------
226 constexpr auto operator()(integral auto const... is) -> auto& {
227 static_assert(sizeof...(is) == num_dimensions());
228 assert(in_range(is...));
229 return m_data_container[plain_index(is...)];
230 }
231 //----------------------------------------------------------------------------
232 constexpr auto operator()(integral_range auto const& indices) const -> const
233 auto& {
234 assert(indices.size() == num_dimensions());
235 return m_data_container[plain_index(indices)];
236 }
237 //----------------------------------------------------------------------------
238 constexpr auto operator()(integral_range auto const& indices) -> auto& {
239 assert(indices.size() == num_dimensions());
240 return m_data_container[plain_index(indices)];
241 }
242 //----------------------------------------------------------------------------
243 [[nodiscard]] constexpr auto operator[](std::size_t i) -> auto& {
244 assert(i < num_components());
245 return m_data_container[i];
246 }
247 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
248 [[nodiscard]] constexpr auto operator[](std::size_t i) const -> auto const& {
249 assert(i < num_components());
250 return m_data_container[i];
251 }
252 //----------------------------------------------------------------------------
253 [[nodiscard]] constexpr auto internal_container() -> auto& {
254 return m_data_container;
255 }
256 [[nodiscard]] constexpr auto internal_container() const -> auto const& {
257 return m_data_container;
258 }
259 //----------------------------------------------------------------------------
260 [[nodiscard]] constexpr auto data() -> ValueType* {
261 return m_data_container.data();
262 }
263 [[nodiscard]] constexpr auto data() const -> ValueType const* {
264 return m_data_container.data();
265 }
266 //============================================================================
267 template <typename F>
268 constexpr void unary_operation(F&& f) {
269 for (auto indices : size_type{}) {
270 at(indices) = f(at(indices));
271 }
272 }
273 //----------------------------------------------------------------------------
274 template <typename F, typename OtherT, typename OtherIndexing,
275 typename OtherMemLoc>
276 constexpr void binary_operation(
277 F&& f, static_multidim_array<OtherT, OtherIndexing, OtherMemLoc,
278 Resolution...> const& other) {
279 for (auto const& i : size_type{}) {
280 at(i) = f(at(i), other(i));
281 }
282 }
283};
284//==============================================================================
285//namespace reflection {
286//template <typename ValueType, typename IndexOrder, typename MemLoc,
287// std::size_t... Resolution>
288//TATOOINE_MAKE_TEMPLATED_ADT_REFLECTABLE(
289// (static_multidim_array<ValueType, IndexOrder, MemLoc, Resolution...>),
290// TATOOINE_REFLECTION_INSERT_METHOD(data, data()))
291//} // namespace reflection
292//==============================================================================
293template <typename MemLocOut = stack, typename IndexingOut = x_fastest,
294 typename T0, typename T1, typename Indexing0, typename Indexing1,
295 typename MemLoc0, typename MemLoc1, typename FReal,
296 std::size_t... Resolution>
300 FReal factor) {
301 static_multidim_array<common_type<T0, T1>, IndexingOut, MemLocOut,
302 Resolution...>
303 interpolated{arr0};
304
305 if constexpr (sizeof...(Resolution) == 2) {
306#ifndef NDEBUG
307#pragma omp parallel for collapse(2)
308#endif
309 for (std::size_t iy = 0; iy < interpolated.size(1); ++iy) {
310 for (std::size_t ix = 0; ix < interpolated.size(0); ++ix) {
311 interpolated(ix, iy) =
312 interpolated.data(ix, iy) * (1 - factor) + arr1(ix, iy) * factor;
313 }
314 }
315 } else if constexpr (sizeof...(Resolution) == 3) {
316#ifndef NDEBUG
317#pragma omp parallel for collapse(3)
318#endif
319 for (std::size_t iz = 0; iz < interpolated.size(2); ++iz) {
320 for (std::size_t iy = 0; iy < interpolated.size(1); ++iy) {
321 for (std::size_t ix = 0; ix < interpolated.size(0); ++ix) {
322 interpolated(ix, iy, iz) = interpolated(ix, iy, iz) * (1 - factor) +
323 arr1(ix, iy, iz) * factor;
324 }
325 }
326 }
327 } else {
328 for (std::size_t is : interpolated.indices()) {
329 interpolated(is) = interpolated(is) * (1 - factor) + arr1(is) * factor;
330 }
331 }
332 return interpolated;
333}
334// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
335template <typename MemLocOut = stack, typename IndexingOut = x_fastest,
336 typename T0, typename T1, typename Indexing0, typename Indexing1,
337 typename MemLoc0, typename MemLoc1, typename LinReal, typename TReal,
338 std::size_t... Resolution>
342 linspace<LinReal> const& ts, TReal t) {
343 return interpolate<MemLocOut, IndexingOut>(
344 arr0, arr1, (t - ts.front()) / (ts.back() - ts.front()));
345}
346//#include "vtk_legacy.h"
347// template <typename ValueType, typename IndexOrder, typename MemLoc,
348// std::size_t... Resolution> void write_vtk(
349// static_multidim_array<ValueType, IndexOrder, MemLoc, Resolution...> const&
350// arr, std::string const& filepath, vec<double, 3> const& origin,
351// vec<double, 3> const& spacing,
352// std::string const& data_name = "tatooine data") {
353// vtk::legacy_file_writer writer(filepath, vtk::STRUCTURED_POINTS);
354// if (writer.is_open()) {
355// writer.set_title("tatooine");
356// writer.write_header();
357//
358// auto const res = arr.size();
359// writer.write_dimensions(res[0], res[1], res[2]);
360// writer.write_origin(origin(0), origin(1), origin(2));
361// writer.write_spacing(spacing(0), spacing(1), spacing(2));
362// writer.write_point_data(arr.num_components());
363//
364// writer.write_scalars(data_name, arr.data());
365// writer.close();
366// }
367//}
368//==============================================================================
369} // namespace tatooine
370//==============================================================================
371#endif
Definition: static_multidim_array.h:19
static std::size_t constexpr num_components()
Definition: static_multidim_array.h:28
static std::size_t constexpr num_dimensions()
Definition: static_multidim_array.h:29
constexpr auto at(integral auto const ... is) -> auto &requires(sizeof...(is)==num_dimensions())
Definition: static_multidim_array.h:204
constexpr static_multidim_array(tag::zeros_t)
Definition: static_multidim_array.h:138
static auto constexpr size()
Definition: static_multidim_array.h:30
static auto plain_index(integral_range auto const &indices)
Definition: static_multidim_array.h:35
constexpr auto operator()(integral auto const ... is) const -> auto const &requires(sizeof...(is)==num_dimensions())
Definition: static_multidim_array.h:220
constexpr auto operator[](std::size_t i) -> auto &
Definition: static_multidim_array.h:243
constexpr auto operator=(static_multidim_array< OtherT, OtherIndexing, OtherMemLoc, Resolution... > const &other) -> static_multidim_array &
Definition: static_multidim_array.h:115
constexpr static_multidim_array(tag::fill< S > const &f)
Definition: static_multidim_array.h:135
static_multidim_array(std::vector< ValueType > const &data)
Definition: static_multidim_array.h:144
constexpr auto at(integral_range auto const &indices) const -> auto const &
Definition: static_multidim_array.h:210
constexpr static_multidim_array()
Definition: static_multidim_array.h:131
constexpr auto operator()(integral_range auto const &indices) -> auto &
Definition: static_multidim_array.h:238
constexpr auto operator()(integral_range auto const &indices) const -> const auto &
Definition: static_multidim_array.h:232
constexpr static_multidim_array(static_multidim_array &&other) noexcept=default
constexpr static_multidim_array(std::vector< ValueType > &&data)
Definition: static_multidim_array.h:157
static constexpr auto zeros()
Definition: static_multidim_array.h:62
constexpr static_multidim_array(random::uniform< RandomReal, Engine > &rand)
Definition: static_multidim_array.h:164
constexpr static_multidim_array(convertible_to< ValueType > auto &&... ts)
Definition: static_multidim_array.h:125
static constexpr auto fill(S &&s)
Definition: static_multidim_array.h:67
static auto randn(ValueType mean=0, ValueType stddev=1, RandEng &&eng=RandEng{std::random_device{}()})
Definition: static_multidim_array.h:79
constexpr auto operator()(integral auto const ... is) -> auto &
Definition: static_multidim_array.h:226
constexpr auto at(integral auto const ... is) const -> const auto &requires(sizeof...(is)==num_dimensions())
Definition: static_multidim_array.h:198
constexpr void binary_operation(F &&f, static_multidim_array< OtherT, OtherIndexing, OtherMemLoc, Resolution... > const &other)
Definition: static_multidim_array.h:276
constexpr static_multidim_array(random::normal< RandomReal, Engine > &rand)
Definition: static_multidim_array.h:188
constexpr static_multidim_array(static_multidim_array< OtherT, OtherIndexing, OtherMemLoc, Resolution... > const &other)
Definition: static_multidim_array.h:105
static_multidim_array< ValueType, IndexOrder, MemLoc, Resolution... > this_type
Definition: static_multidim_array.h:27
static constexpr auto ones()
Definition: static_multidim_array.h:64
constexpr static_multidim_array(std::array< ValueType, num_components()> const &data)
Definition: static_multidim_array.h:149
container_type m_data_container
Definition: static_multidim_array.h:88
constexpr auto internal_container() -> auto &
Definition: static_multidim_array.h:253
static constexpr auto init_data(ValueType const init=ValueType{})
Definition: static_multidim_array.h:51
constexpr auto at(integral_range auto const &indices) -> auto &
Definition: static_multidim_array.h:215
constexpr auto data() const -> ValueType const *
Definition: static_multidim_array.h:263
static auto constexpr in_range(integral auto const ... indices)
Definition: static_multidim_array.h:38
constexpr static_multidim_array(static_multidim_array const &other)=default
constexpr auto data() -> ValueType *
Definition: static_multidim_array.h:260
constexpr void unary_operation(F &&f)
Definition: static_multidim_array.h:268
constexpr static_multidim_array(random::uniform< RandomReal, Engine > &&rand)
Definition: static_multidim_array.h:172
constexpr auto internal_container() const -> auto const &
Definition: static_multidim_array.h:256
static auto randu(ValueType min=0, ValueType max=1, RandEng &&eng=RandEng{std::random_device{}()})
Definition: static_multidim_array.h:72
constexpr auto operator[](std::size_t i) const -> auto const &
Definition: static_multidim_array.h:248
ValueType value_type
Definition: static_multidim_array.h:25
constexpr static_multidim_array(tag::ones_t)
Definition: static_multidim_array.h:141
constexpr auto operator=(static_multidim_array const &other) -> static_multidim_array &=default
constexpr static_multidim_array(std::array< ValueType, num_components()> &&data)
Definition: static_multidim_array.h:153
constexpr static_multidim_array(random::normal< RandomReal, Engine > &&rand)
Definition: static_multidim_array.h:180
static auto constexpr plain_index(integral auto const ... indices)
Definition: static_multidim_array.h:31
std::conditional_t< std::is_same< MemLoc, stack >::value, std::array< ValueType, num_components()>, std::vector< ValueType > > container_type
Definition: static_multidim_array.h:45
Definition: concepts.h:33
Definition: concepts.h:39
Definition: concepts.h:91
Definition: concepts.h:21
static constexpr zeros_t zeros
Definition: tags.h:103
static constexpr ones_t ones
Definition: tags.h:106
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
auto interpolate(dynamic_multidim_array< T0, Indexing0 > const &arr0, dynamic_multidim_array< T1, Indexing1 > const &arr1, FReal factor)
Definition: dynamic_multidim_array.h:376
constexpr auto plain_index() const -> auto const &
Definition: vertex_handle.h:37
Definition: linspace.h:26
constexpr auto back() const
Definition: linspace.h:95
constexpr auto front() const
Definition: linspace.h:93
Definition: random.h:97
Definition: random.h:15
Definition: static_multidim_size.h:81
static auto constexpr in_range(integral auto const ... indices)
Definition: static_multidim_size.h:89
static auto constexpr num_dimensions()
Definition: static_multidim_size.h:82
static auto constexpr size()
Definition: static_multidim_size.h:85
static auto constexpr num_components()
Definition: static_multidim_size.h:83
Definition: tags.h:96
Definition: tags.h:105
Definition: tags.h:102