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-2023 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: 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
114 template <typename T, size_t R>
115 constexpr std::array<T, R> operator*(std::array<T, R> const &lhs, std::array<T, R> const &rhs) {
116 std::array<T, R> res;
117 for (int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
118 return res;
119 }
120
129 template <typename T, size_t R>
130 constexpr std::array<T, R> operator-(std::array<T, R> const &a) {
131 std::array<T, R> res;
132 for (int i = 0; i < R; ++i) res[i] = -a[i];
133 return res;
134 }
135
145 template <typename T, size_t R>
146 constexpr std::array<T, R> operator*(T s, std::array<T, R> const &a) {
147 std::array<T, R> res;
148 for (int i = 0; i < R; ++i) res[i] = s * a[i];
149 return res;
150 }
151
152} // namespace std
153
154namespace nda::stdutil {
155
164 template <size_t R, typename T>
165 constexpr std::array<T, R> make_initialized_array(T v) {
166 return [&v]<size_t... Is>(std::index_sequence<Is...>) {
167 return std::array<T, R>{(Is, v)...}; // NOLINT (always v, just a trick to have the pack)
168 }(std::make_index_sequence<R>{});
169 }
170
180 template <typename T, typename U, size_t R>
181 constexpr std::array<T, R> make_std_array(std::array<U, R> const &a) {
182 static_assert(std::is_constructible_v<T, U>, "Error in nda::stdutil::make_std_array: T must be constructible from U");
183 std::array<T, R> result = make_initialized_array<R>(T{});
184 for (int u = 0; u < R; ++u) result[u] = a[u];
185 return result;
186 }
187
196 template <typename T, size_t R>
197 constexpr std::vector<T> to_vector(std::array<T, R> const &a) {
198 std::vector<T> V(R);
199 for (int i = 0; i < R; ++i) V[i] = a[i];
200 return V;
201 }
202
213 template <typename T, auto R, typename U>
214 constexpr std::array<T, R + 1> append(std::array<T, R> const &a, U const &x) {
215 std::array<T, R + 1> res;
216 for (int i = 0; i < R; ++i) res[i] = a[i];
217 res[R] = x;
218 return res;
219 }
220
231 template <typename T, typename U, size_t R>
232 constexpr std::array<T, R + 1> front_append(std::array<T, R> const &a, U const &x) {
233 std::array<T, R + 1> res;
234 res[0] = x;
235 for (int i = 0; i < R; ++i) res[i + 1] = a[i];
236 return res;
237 }
238
248 template <int N, typename T, size_t R>
249 constexpr std::array<T, R - N> mpop(std::array<T, R> const &a) {
250 std::array<T, R - N> res;
251 for (int i = 0; i < R - N; ++i) res[i] = a[i];
252 return res;
253 }
254
263 template <typename T, size_t R>
264 constexpr std::array<T, R - 1> pop(std::array<T, R> const &a) {
265 return mpop<1>(a);
266 }
267
277 template <int N, typename T, size_t R>
278 constexpr std::array<T, R - N> front_mpop(std::array<T, R> const &a) {
279 std::array<T, R - N> res;
280 for (int i = N; i < R; ++i) res[i - N] = a[i];
281 return res;
282 }
283
292 template <typename T, size_t R>
293 constexpr std::array<T, R - 1> front_pop(std::array<T, R> const &a) {
294 return front_mpop<1>(a);
295 }
296
308 template <typename T, size_t R1, size_t R2>
309 constexpr std::array<T, R1 + R2> join(std::array<T, R1> const &a1, std::array<T, R2> const &a2) {
310 std::array<T, R1 + R2> res;
311 for (int i = 0; i < R1; ++i) res[i] = a1[i];
312 for (int i = 0; i < R2; ++i) res[R1 + i] = a2[i];
313 return res;
314 }
315
325 template <typename T, size_t R>
326 constexpr auto sum(std::array<T, R> const &a) {
327 if constexpr (R == 0)
328 return T{};
329 else {
330 auto res = a[0];
331 for (int i = 1; i < R; ++i) res += a[i];
332 return res;
333 }
334 }
335
344 template <typename T, size_t R>
345 constexpr auto product(std::array<T, R> const &a) {
346 static_assert(R > 0, "Error in nda::stdutil::product: Only defined for R > 0");
347 auto res = a[0];
348 for (int i = 1; i < R; ++i) res *= a[i];
349 return res;
350 }
351
365 template <typename T, typename U, size_t R>
366 constexpr auto dot_product(std::array<T, R> const &a1, std::array<U, R> const &a2) {
367 if constexpr (R == 0)
368 return T{};
369 else {
370 auto res = a1[0] * a2[0];
371 for (int i = 1; i < R; ++i) res += a1[i] * a2[i];
372 return res;
373 }
374 }
375
378} // namespace nda::stdutil
379
380#endif // STDUTILS_ARRAY_H
constexpr std::array< T, R > operator*(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Multiply two std::array objects element-wise.
Definition array.hpp:115
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:278
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:214
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:232
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:264
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:309
constexpr std::vector< T > to_vector(std::array< T, R > const &a)
Convert a std::array to a std::vector.
Definition array.hpp:197
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
Definition array.hpp:165
constexpr auto sum(std::array< T, R > const &a)
Calculate the sum of all elements in a std::array.
Definition array.hpp:326
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:181
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:293
constexpr auto product(std::array< T, R > const &a)
Calculate the product of all elements in a std::array.
Definition array.hpp:345
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:366
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:249