complex.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2015 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * complex.h
22  * Dec 11, 2015
23  *
24  */
25 
26 #ifndef TILEDARRAY_SRC_TILEDARRAY_TENSOR_COMPLEX_H__INCLUDED
27 #define TILEDARRAY_SRC_TILEDARRAY_TENSOR_COMPLEX_H__INCLUDED
28 
29 #include <TiledArray/config.h>
30 #include <TiledArray/type_traits.h>
31 
32 namespace TiledArray {
33 namespace detail {
34 
36 
42 template <typename R,
43  typename std::enable_if<is_numeric_v<R> &&
44  !is_complex<R>::value>::type* = nullptr>
45 TILEDARRAY_FORCE_INLINE R conj(const R r) {
46  return r;
47 }
48 
50 
54 template <typename R>
55 TILEDARRAY_FORCE_INLINE std::complex<R> conj(const std::complex<R> z) {
56  return std::conj(z);
57 }
58 
60 
64 template <typename L, typename R,
65  typename std::enable_if<is_numeric_v<L> &&
66  !is_complex<L>::value>::type* = nullptr>
67 TILEDARRAY_FORCE_INLINE auto inner_product(const L l, const R r) {
68  return l * r;
69 }
70 
72 
76 template <typename L, typename R,
77  typename std::enable_if<is_numeric_v<L> &&
78  is_complex<L>::value>::type* = nullptr>
79 TILEDARRAY_FORCE_INLINE auto inner_product(const L l, const R r) {
80  return TiledArray::detail::conj(l) * r;
81 }
82 
84 
90 template <typename R,
91  typename std::enable_if<is_numeric_v<R> &&
92  !is_complex<R>::value>::type* = nullptr>
93 TILEDARRAY_FORCE_INLINE R norm(const R r) {
94  return r * r;
95 }
96 
98 
105 template <typename R>
106 TILEDARRAY_FORCE_INLINE R norm(const std::complex<R> z) {
107  const R real = z.real();
108  const R imag = z.imag();
109  return real * real + imag * imag;
110 }
111 
115 template <typename S>
117  S factor_;
118 
119  public:
120  ComplexConjugate(const S factor) : factor_(factor) {}
121 
122  TILEDARRAY_FORCE_INLINE S factor() const { return factor_; }
123 
124  TILEDARRAY_FORCE_INLINE ComplexConjugate<S> operator-() const {
125  return ComplexConjugate<S>(-factor_);
126  }
127 
128  friend std::ostream& operator<<(std::ostream& os,
129  const ComplexConjugate<S>& cc) {
130  os << "conj()] [" << cc.factor_;
131  return os;
132  }
133 
134  bool operator==(const ComplexConjugate<S>& other) const {
135  return factor() == other.factor();
136  }
137 };
138 
139 struct ComplexNegTag {};
140 
142 template <>
143 class ComplexConjugate<void> {
144  public:
145  ComplexConjugate() = default;
146 
148  template <typename Numeric,
149  typename = std::enable_if_t<
150  detail::is_numeric_v<Numeric> &&
151  !std::is_same_v<Numeric, ComplexConjugate<void>>>>
152  explicit ComplexConjugate(const Numeric factor) {
153  TA_ASSERT(factor == Numeric(1));
154  }
155 
157 
158  friend std::ostream& operator<<(std::ostream& os,
159  const ComplexConjugate<void>& cc) {
160  os << "conj()";
161  return os;
162  }
163 
164  bool operator==(const ComplexConjugate<void>& other) const { return true; }
165 };
166 
169 template <>
171  public:
172  inline ComplexConjugate<void> operator-() const;
173 
174  friend std::ostream& operator<<(std::ostream& os,
176  os << "conj()] [-1";
177  return os;
178  }
179 
180  bool operator==(const ComplexConjugate<ComplexNegTag>& other) const {
181  return true;
182  }
183 };
184 
186  const {
187  return ComplexConjugate<void>();
188 }
189 
191  const {
193 }
194 
195 template <typename S>
196 struct is_numeric<ComplexConjugate<S>> : public std::true_type {};
197 
199 
203 template <typename S>
204 inline ComplexConjugate<S> conj_op(const S factor) {
205  return ComplexConjugate<S>(factor);
206 }
207 
209 
212 
213 template <typename L, typename R>
214 TILEDARRAY_FORCE_INLINE auto operator*(const L value,
215  const ComplexConjugate<R> op) {
216  return TiledArray::detail::conj(value) * op.factor();
217 }
218 
219 template <typename L>
220 TILEDARRAY_FORCE_INLINE auto operator*(const L value,
221  const ComplexConjugate<void>&) {
222  return TiledArray::detail::conj(value);
223 }
224 
225 template <typename L>
226 TILEDARRAY_FORCE_INLINE auto operator*(const L value,
228  return -TiledArray::detail::conj(value);
229 }
230 
231 template <typename L, typename R>
232 TILEDARRAY_FORCE_INLINE auto operator*(const ComplexConjugate<L> op,
233  const R value) {
234  return TiledArray::detail::conj(value) * op.factor();
235 }
236 
237 template <typename R>
238 TILEDARRAY_FORCE_INLINE auto operator*(const ComplexConjugate<void>,
239  const R value) {
240  return TiledArray::detail::conj(value);
241 }
242 
243 template <typename R>
244 TILEDARRAY_FORCE_INLINE auto operator*(const ComplexConjugate<ComplexNegTag>,
245  const R value) {
246  return -TiledArray::detail::conj(value);
247 }
248 
249 template <typename L, typename R,
250  typename std::enable_if<!std::is_void<R>::value>::type* = nullptr>
251 TILEDARRAY_FORCE_INLINE L& operator*=(L& value, const ComplexConjugate<R> op) {
252  value = TiledArray::detail::conj(value) * op.factor();
253  return value;
254 }
255 
256 template <typename L>
257 TILEDARRAY_FORCE_INLINE L& operator*=(L& value, const ComplexConjugate<void>&) {
258  value = TiledArray::detail::conj(value);
259  return value;
260 }
261 
262 template <typename L>
263 TILEDARRAY_FORCE_INLINE L& operator*=(L& value,
265  value = -TiledArray::detail::conj(value);
266  return value;
267 }
268 
269 template <typename T>
270 inline auto abs(const ComplexConjugate<T>& a) {
271  return std::abs(a.factor());
272 }
273 
274 inline int abs(const ComplexConjugate<void>& a) { return 1; }
275 
276 } // namespace detail
277 } // namespace TiledArray
278 
279 #endif // TILEDARRAY_SRC_TILEDARRAY_TENSOR_COMPLEX_H__INCLUDED
int abs(const ComplexConjugate< void > &a)
Definition: complex.h:274
bool operator==(const ComplexConjugate< void > &other) const
Definition: complex.h:164
TILEDARRAY_FORCE_INLINE S factor() const
Definition: complex.h:122
std::vector< T > operator*(const Permutation &perm, const SizeArray< T > &orig)
Definition: size_array.h:432
friend std::ostream & operator<<(std::ostream &os, const ComplexConjugate< void > &cc)
Definition: complex.h:158
friend std::ostream & operator<<(std::ostream &os, const ComplexConjugate< ComplexNegTag > &cc)
Definition: complex.h:174
ComplexConjugate(const Numeric factor)
can construct from the identity object of any numeric type
Definition: complex.h:152
TILEDARRAY_FORCE_INLINE auto inner_product(const L l, const R r)
Inner product of a real value and a numeric value.
Definition: complex.h:67
bool operator==(const ComplexConjugate< S > &other) const
Definition: complex.h:134
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
bool operator==(const ComplexConjugate< ComplexNegTag > &other) const
Definition: complex.h:180
friend std::ostream & operator<<(std::ostream &os, const ComplexConjugate< S > &cc)
Definition: complex.h:128
TILEDARRAY_FORCE_INLINE L & operator*=(L &value, const ComplexConjugate< R > op)
Definition: complex.h:251
auto abs(const ComplexConjugate< T > &a)
Definition: complex.h:270
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:204
Specialization of ComplexConjugate for the case of a unit/identity factor.
Definition: complex.h:143
TILEDARRAY_FORCE_INLINE R norm(const R r)
Wrapper function for std::norm
Definition: complex.h:93
TILEDARRAY_FORCE_INLINE std::complex< R > conj(const std::complex< R > z)
Wrapper function for std::conj.
Definition: complex.h:55
TILEDARRAY_FORCE_INLINE R conj(const R r)
Wrapper function for std::conj
Definition: complex.h:45
TILEDARRAY_FORCE_INLINE ComplexConjugate< S > operator-() const
Definition: complex.h:124