QMCPACK
complex_help.hpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2021 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_COMPLEX_HELP_HPP
13 #define QMCPLUSPLUS_COMPLEX_HELP_HPP
14 
15 #include <type_traits>
16 #include <complex>
17 
18 namespace qmcplusplus
19 {
20 template<typename T>
21 struct IsComplex_t : public std::false_type
22 {};
23 template<typename T>
24 struct IsComplex_t<std::complex<T>> : public std::true_type
25 {};
26 
27 template<typename T>
28 using IsComplex = std::enable_if_t<IsComplex_t<T>::value, bool>;
29 
30 // for symmetry with IsComplex_t
31 template<typename T>
32 using IsReal_t = std::is_floating_point<T>;
33 
34 template<typename T>
35 using IsReal = std::enable_if_t<std::is_floating_point<T>::value, bool>;
36 
37 template<typename T, typename = bool>
39 {};
40 
41 template<typename T>
42 struct RealAlias_impl<T, IsReal<T>>
43 {
44  using value_type = T;
45 };
46 
47 template<typename T>
49 {
50  using value_type = typename T::value_type;
51 };
52 
53 /** If you have a function templated on a value that can be real or complex
54  * and you need to get the base Real type if its complex or just the real.
55  *
56  * If you try to do this on anything but a fp or a std::complex<fp> you will
57  * get a compilation error.
58  */
59 template<typename T>
61 
62 template<typename TREAL, typename TREF, typename = bool>
64 {};
65 
66 template<typename TREAL, typename TREF>
67 struct ValueAlias_impl<TREAL, TREF, IsReal<TREF>>
68 {
69  using value_type = TREAL;
70 };
71 
72 template<typename TREAL, typename TREF>
73 struct ValueAlias_impl<TREAL, TREF, IsComplex<TREF>>
74 {
75  using value_type = std::complex<TREAL>;
76 };
77 
78 /** If you need to make a value type of a given precision based on a reference value type
79  * set the desired POD float point type as TREAL and set the reference type as TREF.
80  * If TREF is real/complex, the generated Value type is real/complex.
81  */
82 template<typename TREAL, typename TREF, typename = std::enable_if_t<std::is_floating_point<TREAL>::value>>
84 
85 ///real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
86 inline float real(const float& c) { return c; }
87 inline double real(const double& c) { return c; }
88 inline float real(const std::complex<float>& c) { return c.real(); }
89 inline double real(const std::complex<double>& c) { return c.real(); }
90 ///imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs.
91 inline float imag(const float& c) { return 0; }
92 inline double imag(const double& c) { return 0; }
93 inline float imag(const std::complex<float>& c) { return c.imag(); }
94 inline double imag(const std::complex<double>& c) { return c.imag(); }
95 ///Workaround to allow conj on scalar to return real instead of complex
96 inline float conj(const float& c) { return c; }
97 inline double conj(const double& c) { return c; }
98 inline std::complex<float> conj(const std::complex<float>& c) { return std::conj(c); }
99 inline std::complex<double> conj(const std::complex<double>& c) { return std::conj(c); }
100 //These copy complex->complex, real->real as is. In event of complex->real, the imaginary part is ignored.
101 inline void copy_with_complex_cast(const std::complex<double>& source, std::complex<double>& dest) { dest = source; }
102 inline void copy_with_complex_cast(const std::complex<double>& source, double& dest) { dest = source.real(); }
103 inline void copy_with_complex_cast(const std::complex<float>& source, std::complex<float>& dest) { dest = source; }
104 inline void copy_with_complex_cast(const std::complex<float>& source, float& dest) { dest = source.real(); }
105 
106 } // namespace qmcplusplus
107 
108 #endif
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void copy_with_complex_cast(const std::complex< double > &source, std::complex< double > &dest)
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
std::enable_if_t< IsComplex_t< T >::value, bool > IsComplex
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
std::enable_if_t< std::is_floating_point< T >::value, bool > IsReal
float conj(const float &c)
Workaround to allow conj on scalar to return real instead of complex.
typename RealAlias_impl< T >::value_type RealAlias
If you have a function templated on a value that can be real or complex and you need to get the base ...
typename ValueAlias_impl< TREAL, TREF >::value_type ValueAlias
If you need to make a value type of a given precision based on a reference value type set the desired...
std::is_floating_point< T > IsReal_t
QMCTraits::FullPrecRealType value_type
std::complex< double > conj(const std::complex< double > &c)