TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
algorithms.hpp
Go to the documentation of this file.
1// Copyright (c) 2019--present, The Simons Foundation
2// This file is part of TRIQS/nda and is licensed under the Apache License, Version 2.0.
3// SPDX-License-Identifier: Apache-2.0
4// See LICENSE in the root of this distribution for details.
5
10
11#pragma once
12
13#include "./basic_functions.hpp"
14#include "./concepts.hpp"
15#include "./layout/for_each.hpp"
16#include "./layout/range.hpp"
17#include "./macros.hpp"
18#include "./map.hpp"
19#include "./traits.hpp"
20
21#include <algorithm>
22#include <array>
23#include <cmath>
24#include <cstdlib>
25#include <functional>
26#include <type_traits>
27#include <utility>
28#include <vector>
29
30namespace nda {
31
36
37 // FIXME : CHECK ORDER of the LOOP !
57 template <Array A, typename F, typename R>
58 auto fold(F f, A const &a, R r) {
59 // cast the initial value to the return type of f to avoid narrowing
60 using res_t = std::decay_t<decltype(make_regular(f(r, get_value_t<A>{})))>;
61 auto res = res_t{r};
62 nda::for_each(a.shape(), [&a, &res, &f](auto &&...args) { res = f(res, a(args...)); });
63 return res;
64 }
65
67 template <Array A, typename F>
68 auto fold(F f, A const &a) {
69 return fold(std::move(f), a, get_value_t<A>{});
70 }
71
87 template <Array A>
88 bool any(A const &a) {
89 static_assert(std::is_same_v<get_value_t<A>, bool>, "Error in nda::any: Value type of the array must be bool");
90 return fold([](bool r, auto const &x) -> bool { return r or bool(x); }, a, false);
91 }
92
108 template <Array A>
109 bool all(A const &a) {
110 static_assert(std::is_same_v<get_value_t<A>, bool>, "Error in nda::all: Value type of the array must be bool");
111 return fold([](bool r, auto const &x) -> bool { return r and bool(x); }, a, true);
112 }
113
123 template <Array A>
124 auto max_element(A const &a) {
125 return fold(
126 [](auto const &x, auto const &y) {
127 using std::max;
128 return max(x, y);
129 },
130 a, get_first_element(a));
131 }
132
142 template <Array A>
143 auto min_element(A const &a) {
144 return fold(
145 [](auto const &x, auto const &y) {
146 using std::min;
147 return min(x, y);
148 },
149 a, get_first_element(a));
150 }
151
160 template <ArrayOfRank<2> A>
161 double frobenius_norm(A const &a) {
162 return std::sqrt(fold(
163 [](double r, auto const &x) -> double {
164 auto ab = std::abs(x);
165 return r + ab * ab;
166 },
167 a, double(0)));
168 }
169
177 template <Array A, typename Value = get_value_t<A>>
178 auto sum(A const &a)
180 {
181 if constexpr (nda::Scalar<Value>) {
182 return fold(std::plus<>{}, a);
183 } else { // Array<Value>
184 return fold(std::plus<>{}, a, Value::zeros(get_first_element(a).shape()));
185 }
186 }
187
195 template <Array A, typename Value = get_value_t<A>>
196 auto product(A const &a)
198 {
199 if constexpr (nda::Scalar<Value>) {
200 return fold(std::multiplies<>{}, a, get_value_t<A>{1});
201 } else { // Array<Value>
202 return fold(std::multiplies<>{}, a, Value::ones(get_first_element(a).shape()));
203 }
204 }
205
215 template <Array A, Array B>
217 [[nodiscard]] constexpr auto hadamard(A &&a, B &&b) {
218 return nda::map([](auto const &x, auto const &y) { return x * y; })(std::forward<A>(a), std::forward<B>(b));
219 }
220
231 template <typename T, typename U, size_t R>
232 [[nodiscard]] constexpr auto hadamard(std::array<T, R> const &a, std::array<U, R> const &b) {
233 return a * b;
234 }
235
245 template <typename T, typename U>
246 [[nodiscard]] constexpr auto hadamard(std::vector<T> const &a, std::vector<U> const &b) {
247 using TU = decltype(std::declval<T>() * std::declval<U>());
248 EXPECTS(a.size() == b.size());
249
250 std::vector<TU> c(a.size());
251 for (auto i : range(c.size())) c[i] = a[i] * b[i];
252 return c;
253 }
254
264 constexpr auto hadamard(nda::Scalar auto a, nda::Scalar auto b) { return a * b; }
265
267
268} // namespace nda
Provides basic functions to create and manipulate arrays and views.
Check if a given type satisfies the array concept.
Definition concepts.hpp:230
Check if a given type is either an arithmetic or complex type.
Definition concepts.hpp:108
Provides concepts for the nda library.
Provides for_each functions for multi-dimensional arrays/views.
auto max_element(A const &a)
Find the maximum element of an array.
auto fold(F f, A const &a, R r)
Perform a fold operation on the given nda::Array object.
auto sum(A const &a)
Sum all the elements of an nda::Array object.
bool any(A const &a)
Does any of the elements of the array evaluate to true?
auto product(A const &a)
Multiply all the elements of an nda::Array object.
auto min_element(A const &a)
Find the minimum element of an array.
constexpr auto hadamard(A &&a, B &&b)
Hadamard product of two nda::Array objects.
bool all(A const &a)
Do all elements of the array evaluate to true?
decltype(auto) make_regular(A &&a)
Make a given object regular.
double frobenius_norm(A const &a)
Calculate the Frobenius norm of a 2-dimensional array.
mapped< F > map(F f)
Create a lazy function call expression on arrays/views.
Definition map.hpp:202
constexpr int get_rank
Constexpr variable that specifies the rank of an nda::Array or of a contiguous 1-dimensional range.
Definition traits.hpp:125
std::decay_t< decltype(get_first_element(std::declval< A const >()))> get_value_t
Get the value type of an array/view or a scalar type.
Definition traits.hpp:181
decltype(auto) get_first_element(A const &a)
Get the first element of an array/view or simply return the scalar if a scalar is given.
Definition traits.hpp:166
__inline__ void for_each(std::array< Int, R > const &shape, F &&f)
Loop over all possible index values of a given shape and apply a function to them.
Definition for_each.hpp:116
Macros used in the nda library.
Provides lazy function calls on arrays/views.
Includes the itertools header and provides some additional utilities.
Provides type traits for the nda library.