IgANet
IGAnets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
container.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <array>
18#include <initializer_list>
19#include <vector>
20
22
23namespace iganet::utils {
24
30template <std::size_t N, typename T>
31inline std::array<T, N> to_array(std::vector<T> &&vector) {
32 if (vector.size() != N)
33 throw std::invalid_argument("Cannot convert std::vector to std::array: size mismatch");
34
35 std::array<T, N> array;
36 std::move(vector.begin(), vector.end(), array.begin());
37 return array;
38}
39
45template <typename T, std::size_t N>
46inline std::vector<T> to_vector(std::array<T, N> &&array) {
47 std::vector<T> vector(N);
48 std::move(array.begin(), array.end(), vector.begin());
49 return vector;
50}
51
56template <typename... Args> inline auto to_array(Args &&...args) {
57 return std::array<std::common_type_t<Args...>, sizeof...(Args)>{
58 std::move(args)...};
59}
60
65template <typename... Args> inline auto to_vector(Args &&...args) {
66 return std::vector<std::common_type_t<Args...>>{std::move(args)...};
67}
68
77template <typename T, std::size_t N>
78inline auto
79to_tensor(const std::array<T, N> &array,
80 torch::IntArrayRef sizes = torch::IntArrayRef{-1},
81 const iganet::Options<T> &options = iganet::Options<T>{}) {
82 if (options.device() == torch::kCPU)
83 return torch::from_blob(const_cast<T *>(std::data(array)),
84 (sizes == torch::IntArrayRef{-1}) ? array.size()
85 : sizes,
86 options)
87 .detach()
88 .clone()
89 .requires_grad_(options.requires_grad());
90 else
91 return torch::from_blob(const_cast<T *>(std::data(array)),
92 (sizes == torch::IntArrayRef{-1}) ? array.size()
93 : sizes,
94 options.device(torch::kCPU))
95 .detach()
96 .clone()
97 .to(options.device())
98 .requires_grad_(options.requires_grad());
99}
100
107template <typename T, std::size_t N>
108inline auto to_tensor(const std::array<T, N> &array,
109 const iganet::Options<T> &options) {
110 if (options.device() == torch::kCPU)
111 return torch::from_blob(const_cast<T *>(std::data(array)), array.size(),
112 options)
113 .detach()
114 .clone()
115 .requires_grad_(options.requires_grad());
116 else
117 return torch::from_blob(const_cast<T *>(std::data(array)), array.size(),
118 options.device(torch::kCPU))
119 .detach()
120 .clone()
121 .to(options.device())
122 .requires_grad_(options.requires_grad());
123}
125
133template <typename T>
134inline auto
135to_tensor(std::initializer_list<T> list,
136 torch::IntArrayRef sizes = torch::IntArrayRef{-1},
137 const iganet::Options<T> &options = iganet::Options<T>{}) {
138 if (options.device() == torch::kCPU)
139 return torch::from_blob(
140 const_cast<T *>(std::data(list)),
141 (sizes == torch::IntArrayRef{-1}) ? list.size() : sizes, options)
142 .detach()
143 .clone()
144 .requires_grad_(options.requires_grad());
145 else
146 return torch::from_blob(const_cast<T *>(std::data(list)),
147 (sizes == torch::IntArrayRef{-1}) ? list.size()
148 : sizes,
149 options.device(torch::kCPU))
150 .detach()
151 .clone()
152 .to(options.device())
153 .requires_grad_(options.requires_grad());
154}
155
161template <typename T>
162inline auto to_tensor(std::initializer_list<T> &list,
163 const iganet::Options<T> &options) {
164 if (options.device() == torch::kCPU)
165 return torch::from_blob(const_cast<T *>(std::data(list)), list.size(),
166 options)
167 .detach()
168 .clone()
169 .requires_grad_(options.requires_grad());
170 else
171 return torch::from_blob(const_cast<T *>(std::data(list)), list.size(),
172 options.device(torch::kCPU))
173 .detach()
174 .clone()
175 .to(options.device())
176 .requires_grad_(options.requires_grad());
177}
179
187template <typename T>
188inline auto
189to_tensor(const std::vector<T> &vector,
190 torch::IntArrayRef sizes = torch::IntArrayRef{-1},
191 const iganet::Options<T> &options = iganet::Options<T>{}) {
192 if (options.device() == torch::kCPU)
193 return torch::from_blob(const_cast<T *>(std::data(vector)),
194 (sizes == torch::IntArrayRef{-1}) ? vector.size()
195 : sizes,
196 options)
197 .detach()
198 .clone()
199 .requires_grad_(options.requires_grad());
200 else
201 return torch::from_blob(const_cast<T *>(std::data(vector)),
202 (sizes == torch::IntArrayRef{-1}) ? vector.size()
203 : sizes,
204 options.device(torch::kCPU))
205 .detach()
206 .clone()
207 .to(options.device())
208 .requires_grad_(options.requires_grad());
209}
210
216template <typename T>
217inline auto to_tensor(const std::vector<T> &vector,
218 const iganet::Options<T> &options) {
219 if (options.device() == torch::kCPU)
220 return torch::from_blob(const_cast<T *>(std::data(vector)), vector.size(),
221 options)
222 .detach()
223 .clone()
224 .requires_grad_(options.requires_grad());
225 else
226 return torch::from_blob(const_cast<T *>(std::data(vector)), vector.size(),
227 options.device(torch::kCPU))
228 .detach()
229 .clone()
230 .to(options.device())
231 .requires_grad_(options.requires_grad());
232}
234
240template <typename T, std::size_t N>
241inline auto to_ArrayRef(const std::array<T, N> &array) {
242 return at::ArrayRef<T>{array};
243}
244
251template <typename T, std::size_t... N>
252inline auto concat(const std::array<T, N> &...arrays) {
253 std::array<T, (N + ...)> result;
254 std::size_t index{};
255
256 ((std::copy_n(arrays.begin(), N, result.begin() + index), index += N), ...);
257
258 return result;
259}
260
266template <typename T, std::size_t... N>
267inline auto concat(std::array<T, N> &&...arrays) {
268 std::array<T, (N + ...)> result;
269 std::size_t index{};
270
271 ((std::copy_n(std::make_move_iterator(arrays.begin()), N,
272 result.begin() + index),
273 index += N),
274 ...);
275
276 return result;
277}
279
285template <typename... Ts>
286inline auto concat(const std::vector<Ts> &...vectors) {
287 std::vector<std::common_type_t<Ts...>> result;
288
289 (result.insert(result.end(), vectors.begin(), vectors.end()), ...);
290
291 return result;
292}
293
298template <typename... Ts> inline auto concat(std::vector<Ts> &&...vectors) {
299 std::vector<std::common_type_t<Ts...>> result;
300
301 (result.insert(result.end(), std::make_move_iterator(vectors.begin()),
302 std::make_move_iterator(vectors.end())),
303 ...);
304
305 return result;
306}
308
314template <typename T>
315inline constexpr auto operator+(torch::ArrayRef<T> array, T data) {
316 std::vector<T> result{array.vec()};
317 result.push_back(data);
318 return result;
319}
320
327template <typename T, std::size_t N>
328inline constexpr auto operator+(std::array<T, N> array, T data) {
329 std::array<T, N + 1> result;
330 for (std::size_t i = 0; i < N; ++i)
331 result[i] = array[i];
332 result[N] = data;
333 return result;
334}
335
341template <typename T>
342inline constexpr auto operator+(std::vector<T> vector, T data) {
343 std::vector<T> result{vector};
344 result.push_back(data);
345 return result;
346}
347
353template <typename T>
354inline constexpr auto operator+(T data, torch::ArrayRef<T> array) {
355 std::vector<T> result{array.vec()};
356 result.insert(result.begin(), data);
357 return result;
358}
359
366template <typename T, std::size_t N>
367inline constexpr auto operator+(T data, std::array<T, N> array) {
368 std::array<T, N + 1> result;
369 result[0] = data;
370 for (std::size_t i = 0; i < N; ++i)
371 result[i + 1] = array[i];
372 return result;
373}
374
380template <typename T>
381inline constexpr auto operator+(T data, std::vector<T> vector) {
382 std::vector<T> result{vector};
383 result.insert(result.begin(), data);
384 return result;
385}
386
392template <typename T, std::size_t N> inline constexpr auto make_array(T value) {
393 std::array<T, N> result;
394 result.fill(value);
395 return result;
396}
397
404template <typename T, typename U, std::size_t N>
405inline constexpr std::array<T, N> make_array(std::array<U, N> array) {
406 std::array<T, N> result;
407 for (std::size_t i = 0; i < N; ++i)
408 result[i] = static_cast<T>(array[i]);
409 return result;
410}
411
417template <typename T, std::size_t N>
418inline constexpr std::array<T, N> operator-(std::array<T, N> array) {
419 std::array<T, N> result;
420 for (std::size_t i = 0; i < N; ++i)
421 result[i] = -array[i];
422 return result;
423}
424
431template <typename T, std::size_t N>
432inline constexpr std::array<T, N> operator+(std::array<T, N> lhs,
433 std::array<T, N> rhs) {
434 std::array<T, N> result;
435 for (std::size_t i = 0; i < N; ++i)
436 result[i] = lhs[i] + rhs[i];
437 return result;
438}
439
446template <typename T, std::size_t N>
447inline constexpr std::array<T, N> operator-(std::array<T, N> lhs,
448 std::array<T, N> rhs) {
449 std::array<T, N> result;
450 for (std::size_t i = 0; i < N; ++i)
451 result[i] = lhs[i] - rhs[i];
452 return result;
453}
454
461template <typename T, std::size_t N>
462inline constexpr std::array<T, N> operator*(std::array<T, N> lhs,
463 std::array<T, N> rhs) {
464 std::array<T, N> result;
465 for (std::size_t i = 0; i < N; ++i)
466 result[i] = lhs[i] * rhs[i];
467 return result;
468}
469
476template <typename T, std::size_t N>
477inline constexpr std::array<T, N> operator/(std::array<T, N> lhs,
478 std::array<T, N> rhs) {
479 std::array<T, N> result;
480 for (std::size_t i = 0; i < N; ++i)
481 result[i] = lhs[i] / rhs[i];
482 return result;
483}
484
492template <typename T, std::size_t N, std::size_t M = 1>
493inline constexpr std::array<T, N - M>
494remove_from_front(std::array<T, N> array) {
495
496 std::array<T, N - M> result;
497 for (std::size_t i = 0; i < N - M; ++i)
498 result[i] = array[i + M];
499 return result;
500}
501
509template <typename T, std::size_t N, std::size_t M = 1>
510inline constexpr std::array<T, N - M> remove_from_back(std::array<T, N> array) {
511
512 std::array<T, N - M> result;
513 for (std::size_t i = 0; i < N - M; ++i)
514 result[i] = array[i];
515 return result;
516}
517
518} // namespace iganet::utils
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:47
torch::Device device() const noexcept
Returns the device property.
Definition options.hpp:90
bool requires_grad() const noexcept
Returns the requires_grad property.
Definition options.hpp:110
Definition blocktensor.hpp:24
auto operator-(const BlockTensor< T, Dims... > &lhs, const BlockTensor< U, Dims... > &rhs)
Subtracts one compile-time block tensor from another and returns a new compile-time block tensor.
Definition blocktensor.hpp:1810
constexpr auto make_array(T value)
Creates a std::array object filled with a constant.
Definition container.hpp:392
auto to_tensor(const std::array< T, N > &array, torch::IntArrayRef sizes=torch::IntArrayRef{-1}, const iganet::Options< T > &options=iganet::Options< T >{})
Converts a std::array to torch::Tensor.
Definition container.hpp:79
auto concat(const std::array< T, N > &...arrays)
Concatenates multiple std::array objects.
Definition container.hpp:252
constexpr std::array< T, N - M > remove_from_front(std::array< T, N > array)
Derives a std::array object from a given std::array object dropping the first M entries.
Definition container.hpp:494
std::array< T, N > to_array(std::vector< T > &&vector)
Converts a std::vector object into std::array.
Definition container.hpp:31
std::vector< T > to_vector(std::array< T, N > &&array)
Converts a std::array object into std::vector.
Definition container.hpp:46
constexpr std::array< T, N > operator/(std::array< T, N > lhs, std::array< T, N > rhs)
Divides one std::array by another std::array.
Definition container.hpp:477
constexpr std::array< T, N - M > remove_from_back(std::array< T, N > array)
Derives a std::array object from a given std::array object dropping the last M entries.
Definition container.hpp:510
auto to_ArrayRef(const std::array< T, N > &array)
Converts a std::array<int64_t, N> to an at::IntArrayRef object.
Definition container.hpp:241
auto operator*(const BlockTensor< T, Rows, Common > &lhs, const BlockTensor< U, Common, Cols > &rhs)
Multiplies one compile-time rank-2 block tensor with another compile-time rank-2 block tensor.
Definition blocktensor.hpp:958
constexpr auto operator+(deriv lhs, deriv rhs)
Adds two enumerators for specifying the derivative of B-spline evaluation.
Definition bspline.hpp:93
Definition optimizer.hpp:61
Options.