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-2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Dominik Kiese, Olivier Parcollet, Nils Wentzell
16
22#pragma once
23
24#include "./basic_functions.hpp"
25#include "./concepts.hpp"
26#include "./layout/for_each.hpp"
27#include "./layout/range.hpp"
28#include "./macros.hpp"
29#include "./map.hpp"
30#include "./traits.hpp"
31
32#include <algorithm>
33#include <array>
34#include <cmath>
35#include <cstdlib>
36#include <functional>
37#include <type_traits>
38#include <utility>
39#include <vector>
40
41namespace nda {
42
48 // FIXME : CHECK ORDER of the LOOP !
68 template <Array A, typename F, typename R>
69 auto fold(F f, A const &a, R r) {
70 // cast the initial value to the return type of f to avoid narrowing
71 using res_t = std::decay_t<decltype(make_regular(f(r, get_value_t<A>{})))>;
72 auto res = res_t{r};
73 nda::for_each(a.shape(), [&a, &res, &f](auto &&...args) { res = f(res, a(args...)); });
74 return res;
75 }
76
78 template <Array A, typename F>
79 auto fold(F f, A const &a) {
80 return fold(std::move(f), a, get_value_t<A>{});
81 }
82
98 template <Array A>
99 bool any(A const &a) {
100 static_assert(std::is_same_v<get_value_t<A>, bool>, "Error in nda::any: Value type of the array must be bool");
101 return fold([](bool r, auto const &x) -> bool { return r or bool(x); }, a, false);
102 }
103
119 template <Array A>
120 bool all(A const &a) {
121 static_assert(std::is_same_v<get_value_t<A>, bool>, "Error in nda::all: Value type of the array must be bool");
122 return fold([](bool r, auto const &x) -> bool { return r and bool(x); }, a, true);
123 }
124
134 template <Array A>
135 auto max_element(A const &a) {
136 return fold(
137 [](auto const &x, auto const &y) {
138 using std::max;
139 return max(x, y);
140 },
141 a, get_first_element(a));
142 }
143
153 template <Array A>
154 auto min_element(A const &a) {
155 return fold(
156 [](auto const &x, auto const &y) {
157 using std::min;
158 return min(x, y);
159 },
160 a, get_first_element(a));
161 }
162
171 template <ArrayOfRank<2> A>
172 double frobenius_norm(A const &a) {
173 return std::sqrt(fold(
174 [](double r, auto const &x) -> double {
175 auto ab = std::abs(x);
176 return r + ab * ab;
177 },
178 a, double(0)));
179 }
180
188 template <Array A, typename Value = get_value_t<A>>
189 auto sum(A const &a)
191 {
192 if constexpr (nda::Scalar<Value>) {
193 return fold(std::plus<>{}, a);
194 } else { // Array<Value>
195 return fold(std::plus<>{}, a, Value::zeros(get_first_element(a).shape()));
196 }
197 }
198
206 template <Array A, typename Value = get_value_t<A>>
207 auto product(A const &a)
209 {
210 if constexpr (nda::Scalar<Value>) {
211 return fold(std::multiplies<>{}, a, get_value_t<A>{1});
212 } else { // Array<Value>
213 return fold(std::multiplies<>{}, a, Value::ones(get_first_element(a).shape()));
214 }
215 }
216
226 template <Array A, Array B>
228 [[nodiscard]] constexpr auto hadamard(A &&a, B &&b) {
229 return nda::map([](auto const &x, auto const &y) { return x * y; })(std::forward<A>(a), std::forward<B>(b));
230 }
231
242 template <typename T, typename U, size_t R>
243 [[nodiscard]] constexpr auto hadamard(std::array<T, R> const &a, std::array<U, R> const &b) {
244 return a * b;
245 }
246
256 template <typename T, typename U>
257 [[nodiscard]] constexpr auto hadamard(std::vector<T> const &a, std::vector<U> const &b) {
258 using TU = decltype(std::declval<T>() * std::declval<U>());
259 EXPECTS(a.size() == b.size());
260
261 std::vector<TU> c(a.size());
262 for (auto i : range(c.size())) c[i] = a[i] * b[i];
263 return c;
264 }
265
275 constexpr auto hadamard(nda::Scalar auto a, nda::Scalar auto b) { return a * b; }
276
279} // 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:119
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:213
constexpr int get_rank
Constexpr variable that specifies the rank of an nda::Array or of a contiguous 1-dimensional range.
Definition traits.hpp:136
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:192
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:177
__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:129
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.