TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
array.hpp
Go to the documentation of this file.
1// Copyright (c) 2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2024 Simons Foundation
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0.txt
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17// Authors: Thomas Hahn, Dominik Kiese, Olivier Parcollet, Nils Wentzell
18
24#ifndef STDUTILS_ARRAY_H
25#define STDUTILS_ARRAY_H
26
27#include <array>
28#include <ostream>
29#include <sstream>
30#include <string>
31#include <type_traits>
32#include <vector>
33#include <utility>
34
35namespace std { // has to be in the right namespace for ADL
36
51 template <typename T, size_t R>
52 std::ostream &operator<<(std::ostream &out, std::array<T, R> const &a) {
53 return out << to_string(a);
54 }
55
64 template <typename T, size_t R>
65 std::string to_string(std::array<T, R> const &a) {
66 std::stringstream fs;
67 fs << "(";
68 for (int i = 0; i < R; ++i) fs << (i == 0 ? "" : " ") << a[i];
69 fs << ")";
70 return fs.str();
71 }
72
82 template <typename T, size_t R>
83 constexpr std::array<T, R> operator+(std::array<T, R> const &lhs, std::array<T, R> const &rhs) {
84 std::array<T, R> res;
85 for (int i = 0; i < R; ++i) res[i] = lhs[i] + rhs[i];
86 return res;
87 }
88
98 template <typename T, size_t R>
99 constexpr std::array<T, R> operator-(std::array<T, R> const &lhs, std::array<T, R> const &rhs) {
100 std::array<T, R> res;
101 for (int i = 0; i < R; ++i) res[i] = lhs[i] - rhs[i];
102 return res;
103 }
104
115 template <typename T, typename U, size_t R>
116 constexpr auto operator*(std::array<T, R> const &lhs, std::array<U, R> const &rhs) {
117 using TU = decltype(std::declval<T>() * std::declval<U>());
118
119 std::array<TU, R> res;
120 for (int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
121 return res;
122 }
123
132 template <typename T, size_t R>
133 constexpr std::array<T, R> operator-(std::array<T, R> const &a) {
134 std::array<T, R> res;
135 for (int i = 0; i < R; ++i) res[i] = -a[i];
136 return res;
137 }
138
148 template <typename T, size_t R>
149 constexpr std::array<T, R> operator*(T s, std::array<T, R> const &a) {
150 std::array<T, R> res;
151 for (int i = 0; i < R; ++i) res[i] = s * a[i];
152 return res;
153 }
154
155} // namespace std
156
157namespace nda::stdutil {
158
167 template <size_t R, typename T>
168 constexpr std::array<T, R> make_initialized_array(T v) {
169 return [&v]<size_t... Is>(std::index_sequence<Is...>) {
170 return std::array<T, R>{((void)Is, v)...}; // NOLINT (always v, just a trick to have the pack)
171 }(std::make_index_sequence<R>{});
172 }
173
183 template <typename T, typename U, size_t R>
184 constexpr std::array<T, R> make_std_array(std::array<U, R> const &a) {
185 static_assert(std::is_constructible_v<T, U>, "Error in nda::stdutil::make_std_array: T must be constructible from U");
186 std::array<T, R> result = make_initialized_array<R>(T{});
187 for (int u = 0; u < R; ++u) result[u] = a[u];
188 return result;
189 }
190
199 template <typename T, size_t R>
200 constexpr std::vector<T> to_vector(std::array<T, R> const &a) {
201 std::vector<T> V(R);
202 for (int i = 0; i < R; ++i) V[i] = a[i];
203 return V;
204 }
205
216 template <typename T, auto R, typename U>
217 constexpr std::array<T, R + 1> append(std::array<T, R> const &a, U const &x) {
218 std::array<T, R + 1> res;
219 for (int i = 0; i < R; ++i) res[i] = a[i];
220 res[R] = x;
221 return res;
222 }
223
234 template <typename T, typename U, size_t R>
235 constexpr std::array<T, R + 1> front_append(std::array<T, R> const &a, U const &x) {
236 std::array<T, R + 1> res;
237 res[0] = x;
238 for (int i = 0; i < R; ++i) res[i + 1] = a[i];
239 return res;
240 }
241
251 template <int N, typename T, size_t R>
252 constexpr std::array<T, R - N> mpop(std::array<T, R> const &a) {
253 std::array<T, R - N> res;
254 for (int i = 0; i < R - N; ++i) res[i] = a[i];
255 return res;
256 }
257
266 template <typename T, size_t R>
267 constexpr std::array<T, R - 1> pop(std::array<T, R> const &a) {
268 return mpop<1>(a);
269 }
270
280 template <int N, typename T, size_t R>
281 constexpr std::array<T, R - N> front_mpop(std::array<T, R> const &a) {
282 std::array<T, R - N> res;
283 for (int i = N; i < R; ++i) res[i - N] = a[i];
284 return res;
285 }
286
295 template <typename T, size_t R>
296 constexpr std::array<T, R - 1> front_pop(std::array<T, R> const &a) {
297 return front_mpop<1>(a);
298 }
299
311 template <typename T, size_t R1, size_t R2>
312 constexpr std::array<T, R1 + R2> join(std::array<T, R1> const &a1, std::array<T, R2> const &a2) {
313 std::array<T, R1 + R2> res;
314 for (int i = 0; i < R1; ++i) res[i] = a1[i];
315 for (int i = 0; i < R2; ++i) res[R1 + i] = a2[i];
316 return res;
317 }
318
328 template <typename T, size_t R>
329 constexpr auto sum(std::array<T, R> const &a) {
330 if constexpr (R == 0)
331 return T{};
332 else {
333 auto res = a[0];
334 for (int i = 1; i < R; ++i) res += a[i];
335 return res;
336 }
337 }
338
347 template <typename T, size_t R>
348 constexpr auto product(std::array<T, R> const &a) {
349 static_assert(R > 0, "Error in nda::stdutil::product: Only defined for R > 0");
350 auto res = a[0];
351 for (int i = 1; i < R; ++i) res *= a[i];
352 return res;
353 }
354
368 template <typename T, typename U, size_t R>
369 constexpr auto dot_product(std::array<T, R> const &a1, std::array<U, R> const &a2) {
370 if constexpr (R == 0)
371 return T{};
372 else {
373 auto res = a1[0] * a2[0];
374 for (int i = 1; i < R; ++i) res += a1[i] * a2[i];
375 return res;
376 }
377 }
378
381} // namespace nda::stdutil
382
383#endif // STDUTILS_ARRAY_H
constexpr auto operator*(std::array< T, R > const &lhs, std::array< U, R > const &rhs)
Multiply two std::array objects element-wise.
Definition array.hpp:116
std::ostream & operator<<(std::ostream &out, std::array< T, R > const &a)
Write a std::array to an output stream.
Definition array.hpp:52
constexpr std::array< T, R - N > front_mpop(std::array< T, R > const &a)
Make a new std::array by popping the first N elements of an existing std::array.
Definition array.hpp:281
constexpr std::array< T, R+1 > append(std::array< T, R > const &a, U const &x)
Make a new std::array by appending one element at the end to an existing std::array.
Definition array.hpp:217
constexpr std::array< T, R+1 > front_append(std::array< T, R > const &a, U const &x)
Make a new std::array by prepending one element at the front to an existing std::array.
Definition array.hpp:235
constexpr std::array< T, R - 1 > pop(std::array< T, R > const &a)
Make a new std::array by popping the last element of an existing std::array.
Definition array.hpp:267
constexpr std::array< T, R > operator+(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Add two std::array objects element-wise.
Definition array.hpp:83
constexpr std::array< T, R1+R2 > join(std::array< T, R1 > const &a1, std::array< T, R2 > const &a2)
Make a new std::array by joining two existing std::array objects.
Definition array.hpp:312
constexpr std::vector< T > to_vector(std::array< T, R > const &a)
Convert a std::array to a std::vector.
Definition array.hpp:200
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
Definition array.hpp:168
constexpr auto sum(std::array< T, R > const &a)
Calculate the sum of all elements in a std::array.
Definition array.hpp:329
std::string to_string(std::array< T, R > const &a)
Get a string representation of a std::array.
Definition array.hpp:65
constexpr std::array< T, R > operator-(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Subtract two std::array objects element-wise.
Definition array.hpp:99
constexpr std::array< T, R > make_std_array(std::array< U, R > const &a)
Convert a std::array with value type U to a std::array with value type T.
Definition array.hpp:184
constexpr std::array< T, R - 1 > front_pop(std::array< T, R > const &a)
Make a new std::array by popping the first element of an existing std::array.
Definition array.hpp:296
constexpr auto product(std::array< T, R > const &a)
Calculate the product of all elements in a std::array.
Definition array.hpp:348
constexpr auto dot_product(std::array< T, R > const &a1, std::array< U, R > const &a2)
Calculate the dot product of two std::array objects.
Definition array.hpp:369
constexpr std::array< T, R - N > mpop(std::array< T, R > const &a)
Make a new std::array by popping the last N elements of an existing std::array.
Definition array.hpp:252