TRIQS/nda 2.0.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
mapped_functions.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
11
12#pragma once
13
14#include "./concepts.hpp"
15#include "./macros.hpp"
16#include "./map.hpp"
17#include "./traits.hpp"
18
19#include <algorithm>
20#include <cmath>
21#include <complex>
22#include <cstdlib>
23#include <type_traits>
24#include <utility>
25
26namespace nda {
27
32
33 namespace detail {
34
35 // Get the real part of a scalar.
36 template <nda::Scalar S>
37 auto real(S x) {
38 if constexpr (is_complex_v<S>) {
39 return std::real(x);
40 } else {
41 return x;
42 }
43 }
44
45 // Get the complex conjugate of a scalar.
46 template <nda::Scalar S>
47 auto conj(S x) {
48 if constexpr (is_complex_v<S>) {
49 return std::conj(x);
50 } else {
51 return x;
52 }
53 }
54
55 // Get the squared absolute value with the return type of std::norm.
56 FORCEINLINE auto abs2(auto x) { return std::norm(x); }
57
58 // Check if a scalar or either component of a complex scalar is NaN.
59 template <Scalar S>
60 bool isnan(S const &x) {
61 if constexpr (is_complex_v<S>) {
62 return std::isnan(x.real()) or std::isnan(x.imag());
63 } else {
64 return std::isnan(x);
65 }
66 }
67
68 // Functor for nda::detail::conj.
69 struct conj_f {
70 auto operator()(auto const &x) const { return conj(x); };
71 };
72
73 } // namespace detail
74
75 // The scalar overloads of the <cmath> family are the std ones, brought in by using-declarations rather than
76 // nda function templates: libc++ declares generic templates like pow(A1, A2) in the global namespace, which would
77 // tie with such templates for unqualified calls under `using namespace nda`. The using-declarations must follow the
78 // <cmath>, <complex> and <cstdlib> includes, since they only capture overloads declared before them.
79#ifdef NDA_DOXYGEN
83 template <Scalar S, Scalar P>
84 auto pow(S s, P p);
85#endif
86 using std::pow;
87
97 template <Array A, Scalar S>
98 auto pow(A &&a, S p) {
99 return nda::map([p](auto const &x) { return pow(x, p); })(std::forward<A>(a));
100 }
101
111 template <ArrayOrScalar A>
112 decltype(auto) conj(A &&a) {
113 if constexpr (is_complex_v<get_value_t<A>>)
114 return nda::map(detail::conj_f{})(std::forward<A>(a));
115 else
116 return std::forward<A>(a);
117 }
118
127 template <ArrayOrScalar A>
128 auto reciprocal(A &&a) {
129 return nda::map([]<typename T>(T const &x) {
130 if constexpr (Scalar<T>) {
131 using real_t = remove_complex_t<T>;
132 if constexpr (std::is_floating_point_v<real_t>) {
133 return real_t{1} / x;
134 } else {
135 return 1.0 / x;
136 }
137 } else {
138 return nda::reciprocal(x);
139 }
140 })(std::forward<A>(a));
141 }
142
152 template <ArrayOrScalar A, ArrayOrScalar B>
153 requires(((Scalar<A> && Scalar<B>) || (Array<A> && Array<B> && get_rank<A> == get_rank<B>))
155 [[nodiscard]] auto max(A &&a, B &&b) {
156 return nda::map([](auto const &x, auto const &y) {
157 using std::max;
158 return max(x, y);
159 })(std::forward<A>(a), std::forward<B>(b));
160 }
161
171 template <ArrayOrScalar A, ArrayOrScalar B>
172 requires(((Scalar<A> && Scalar<B>) || (Array<A> && Array<B> && get_rank<A> == get_rank<B>))
174 [[nodiscard]] auto min(A &&a, B &&b) {
175 return nda::map([](auto const &x, auto const &y) {
176 using std::min;
177 return min(x, y);
178 })(std::forward<A>(a), std::forward<B>(b));
179 }
180
181#ifdef NDA_DOXYGEN
183 template <Scalar S>
184 auto abs(S s);
185#endif
186 using std::abs;
187
193 template <Array A>
194 auto abs(A &&a) {
195 return nda::map([](auto const &x) { return abs(x); })(std::forward<A>(a));
196 }
197
203 template <ArrayOrScalar A>
204 auto imag(A &&a) {
205 return nda::map([](auto const &x) {
206 using std::imag;
207 return imag(x);
208 })(std::forward<A>(a));
209 }
210
211#ifdef NDA_DOXYGEN
213 template <Scalar S>
214 auto floor(S s);
215#endif
216 using std::floor;
217
223 template <Array A>
224 auto floor(A &&a) {
225 return nda::map([](auto const &x) { return floor(x); })(std::forward<A>(a));
226 }
227
233 template <ArrayOrScalar A>
234 auto real(A &&a) {
235 return nda::map([](auto const &x) { return detail::real(x); })(std::forward<A>(a));
236 }
237
243 template <ArrayOrScalar A>
244 auto abs2(A &&a) {
245 return nda::map([](auto const &x) { return detail::abs2(x); })(std::forward<A>(a));
246 }
247
248#ifdef NDA_DOXYGEN
250 template <Scalar S>
251 requires(not is_complex_v<S>)
252 auto isnan(S s);
253#endif
254 using std::isnan;
255
265 template <typename A>
266 requires(Array<A> || is_complex_v<A>)
267 auto isnan(A &&a) {
268 return nda::map([](auto const &x) { return detail::isnan(x); })(std::forward<A>(a));
269 }
270
271#ifdef NDA_DOXYGEN
273 template <Scalar S>
274 auto exp(S s);
275#endif
276 using std::exp;
277
283 template <Array A>
284 auto exp(A &&a)
285 requires(get_algebra<A> != 'M')
286 {
287 return nda::map([](auto const &x) { return exp(x); })(std::forward<A>(a));
288 }
289
290#ifdef NDA_DOXYGEN
292 template <Scalar S>
293 auto cos(S s);
294#endif
295 using std::cos;
296
302 template <Array A>
303 auto cos(A &&a)
304 requires(get_algebra<A> != 'M')
305 {
306 return nda::map([](auto const &x) { return cos(x); })(std::forward<A>(a));
307 }
308
309#ifdef NDA_DOXYGEN
311 template <Scalar S>
312 auto sin(S s);
313#endif
314 using std::sin;
315
321 template <Array A>
322 auto sin(A &&a)
323 requires(get_algebra<A> != 'M')
324 {
325 return nda::map([](auto const &x) { return sin(x); })(std::forward<A>(a));
326 }
327
328#ifdef NDA_DOXYGEN
330 template <Scalar S>
331 auto tan(S s);
332#endif
333 using std::tan;
334
340 template <Array A>
341 auto tan(A &&a)
342 requires(get_algebra<A> != 'M')
343 {
344 return nda::map([](auto const &x) { return tan(x); })(std::forward<A>(a));
345 }
346
347#ifdef NDA_DOXYGEN
349 template <Scalar S>
350 auto cosh(S s);
351#endif
352 using std::cosh;
353
359 template <Array A>
360 auto cosh(A &&a)
361 requires(get_algebra<A> != 'M')
362 {
363 return nda::map([](auto const &x) { return cosh(x); })(std::forward<A>(a));
364 }
365
366#ifdef NDA_DOXYGEN
368 template <Scalar S>
369 auto sinh(S s);
370#endif
371 using std::sinh;
372
378 template <Array A>
379 auto sinh(A &&a)
380 requires(get_algebra<A> != 'M')
381 {
382 return nda::map([](auto const &x) { return sinh(x); })(std::forward<A>(a));
383 }
384
385#ifdef NDA_DOXYGEN
387 template <Scalar S>
388 auto tanh(S s);
389#endif
390 using std::tanh;
391
397 template <Array A>
398 auto tanh(A &&a)
399 requires(get_algebra<A> != 'M')
400 {
401 return nda::map([](auto const &x) { return tanh(x); })(std::forward<A>(a));
402 }
403
404#ifdef NDA_DOXYGEN
406 template <Scalar S>
407 auto acos(S s);
408#endif
409 using std::acos;
410
416 template <Array A>
417 auto acos(A &&a)
418 requires(get_algebra<A> != 'M')
419 {
420 return nda::map([](auto const &x) { return acos(x); })(std::forward<A>(a));
421 }
422
423#ifdef NDA_DOXYGEN
425 template <Scalar S>
426 auto asin(S s);
427#endif
428 using std::asin;
429
435 template <Array A>
436 auto asin(A &&a)
437 requires(get_algebra<A> != 'M')
438 {
439 return nda::map([](auto const &x) { return asin(x); })(std::forward<A>(a));
440 }
441
442#ifdef NDA_DOXYGEN
444 template <Scalar S>
445 auto atan(S s);
446#endif
447 using std::atan;
448
454 template <Array A>
455 auto atan(A &&a)
456 requires(get_algebra<A> != 'M')
457 {
458 return nda::map([](auto const &x) { return atan(x); })(std::forward<A>(a));
459 }
460
461#ifdef NDA_DOXYGEN
463 template <Scalar S>
464 auto log(S s);
465#endif
466 using std::log;
467
473 template <Array A>
474 auto log(A &&a)
475 requires(get_algebra<A> != 'M')
476 {
477 return nda::map([](auto const &x) { return log(x); })(std::forward<A>(a));
478 }
479
480#ifdef NDA_DOXYGEN
482 template <Scalar S>
483 auto sqrt(S s);
484#endif
485 using std::sqrt;
486
492 template <Array A>
493 auto sqrt(A &&a)
494 requires(get_algebra<A> != 'M')
495 {
496 return nda::map([](auto const &x) { return sqrt(x); })(std::forward<A>(a));
497 }
498
500
501} // namespace nda
Check if a given type satisfies the array concept.
Definition concepts.hpp:212
Check if a given type is either an arithmetic or complex type.
Definition concepts.hpp:83
Provides concepts for the nda library.
auto sinh(S s)
Function sinh for nda::Scalar types (uses std::sinh).
auto asin(S s)
Function asin for nda::Scalar types (uses std::asin).
auto atan(S s)
Function atan for nda::Scalar types (uses std::atan).
auto isnan(S s)
Function isnan for real nda::Scalar types (uses std::isnan).
auto tanh(S s)
Function tanh for nda::Scalar types (uses std::tanh).
auto sin(S s)
Function sin for nda::Scalar types (uses std::sin).
auto real(A &&a)
Function real for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
auto abs(S s)
Function abs for nda::Scalar types (uses std::abs).
auto floor(S s)
Function floor for nda::Scalar types (uses std::floor).
auto cosh(S s)
Function cosh for nda::Scalar types (uses std::cosh).
auto tan(S s)
Function tan for nda::Scalar types (uses std::tan).
auto acos(S s)
Function acos for nda::Scalar types (uses std::acos).
auto min(A &&a, B &&b)
Function min for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
auto imag(A &&a)
Function imag for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
auto abs2(A &&a)
Function abs2 for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
auto reciprocal(A &&a)
Reciprocal function for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
auto cos(S s)
Function cos for nda::Scalar types (uses std::cos).
auto max(A &&a, B &&b)
Function max for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types).
decltype(auto) conj(A &&a)
Function conj for nda::ArrayOrScalar types (lazy and coefficient-wise for nda::Array types with a com...
auto log(S s)
Function log for nda::Scalar types (uses std::log).
auto exp(S s)
Function exp for nda::Scalar types (uses std::exp).
mapped< F > map(F f)
Create a lazy function call expression on arrays/views.
Definition map.hpp:235
auto pow(S s, P p)
Function pow for nda::Scalar types (uses std::pow).
auto sqrt(S s)
Function sqrt for nda::Scalar types (uses std::sqrt).
constexpr char get_algebra
Constexpr variable that specifies the algebra of a type.
Definition traits.hpp:149
constexpr int get_rank
Constexpr variable that specifies the rank of an nda::Array or of a contiguous 1-dimensional range.
Definition traits.hpp:159
auto conj(A &&...__a)
Lazy version of std::conj.
Definition math.hpp:46
constexpr bool is_complex_v
Constexpr variable that is true if type T is a std::complex type.
Definition traits.hpp:65
typename remove_complex< T >::type remove_complex_t
Alias template for the nested type in nda::remove_complex.
Definition traits.hpp:125
Macros used in the nda library.
Provides lazy function calls on arrays/views.
Provides type traits for the nda library.