TiledArray  0.7.0
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/type_traits.h>
30 
31 namespace TiledArray {
32  namespace detail {
33 
34 
36 
42  template <typename R,
43  typename std::enable_if<! is_complex<R>::value>::type* = nullptr>
44  TILEDARRAY_FORCE_INLINE R conj(const R r) {
45  return r;
46  }
47 
49 
53  template <typename R>
54  TILEDARRAY_FORCE_INLINE std::complex<R> conj(const std::complex<R> z) {
55  return std::conj(z);
56  }
57 
59 
63  template <typename L, typename R,
64  typename std::enable_if<! is_complex<L>::value>::type* = nullptr>
65  TILEDARRAY_FORCE_INLINE auto inner_product(const L l, const R r) {
66  return l * r;
67  }
68 
70 
74  template <typename L, typename R,
75  typename std::enable_if<is_complex<L>::value>::type* = nullptr>
76  TILEDARRAY_FORCE_INLINE auto inner_product(const L l, const R r) {
77  return TiledArray::detail::conj(l) * r;
78  }
79 
81 
87  template <typename R,
88  typename std::enable_if<! is_complex<R>::value>::type* = nullptr>
89  TILEDARRAY_FORCE_INLINE R norm(const R r) {
90  return r * r;
91  }
92 
94 
101  template <typename R>
102  TILEDARRAY_FORCE_INLINE R norm(const std::complex<R> z) {
103  const R real = z.real();
104  const R imag = z.imag();
105  return real * real + imag * imag;
106  }
107 
111  template <typename S>
113  S factor_;
114 
115  public:
116  ComplexConjugate(const S factor) : factor_(factor) { }
117 
118  TILEDARRAY_FORCE_INLINE S factor() const { return factor_; }
119 
120  TILEDARRAY_FORCE_INLINE ComplexConjugate<S> operator-() const {
121  return ComplexConjugate<S>(-factor_);
122  }
123 
124  friend std::ostream& operator<<(std::ostream& os, const ComplexConjugate<S>& cc) {
125  os << "conj()] [" << cc.factor_;
126  return os;
127  }
128  };
129 
130 
131  struct ComplexNegTag { };
132 
134  template <>
135  class ComplexConjugate<void> {
136  public:
137 
139 
140  friend std::ostream&
141  operator<<(std::ostream& os, const ComplexConjugate<void>& cc) {
142  os << "conj()";
143  return os;
144  }
145  };
146 
148  template <>
150  public:
151 
152  inline ComplexConjugate<void> operator-() const;
153 
154  friend std::ostream&
155  operator<<(std::ostream& os, const ComplexConjugate<ComplexNegTag>& cc) {
156  os << "conj()] [-1";
157  return os;
158  }
159  };
160 
161 
162  inline ComplexConjugate<void>
164  return ComplexConjugate<void>();
165  }
166 
170  }
171 
172  template <typename S>
173  struct is_numeric<ComplexConjugate<S> > : public std::true_type { };
174 
176 
180  template <typename S>
181  inline ComplexConjugate<S> conj_op(const S factor) {
182  return ComplexConjugate<S>(factor);
183  }
184 
186 
189  return ComplexConjugate<void>();
190  }
191 
192  template <typename L, typename R>
193  TILEDARRAY_FORCE_INLINE auto
194  operator*(const L value, const ComplexConjugate<R> op)
195  { return TiledArray::detail::conj(value) * op.factor(); }
196 
197  template <typename L>
198  TILEDARRAY_FORCE_INLINE auto
199  operator*(const L value, const ComplexConjugate<void>&)
200  { return TiledArray::detail::conj(value); }
201 
202  template <typename L>
203  TILEDARRAY_FORCE_INLINE auto
205  { return -TiledArray::detail::conj(value); }
206 
207 
208  template <typename L, typename R>
209  TILEDARRAY_FORCE_INLINE auto
210  operator*(const ComplexConjugate<L> op, const R value)
211  { return TiledArray::detail::conj(value) * op.factor(); }
212 
213  template <typename R>
214  TILEDARRAY_FORCE_INLINE auto
215  operator*(const ComplexConjugate<void>, const R value)
216  { return TiledArray::detail::conj(value); }
217 
218  template <typename R>
219  TILEDARRAY_FORCE_INLINE auto
221  { return -TiledArray::detail::conj(value); }
222 
223 
224  template <typename L, typename R,
225  typename std::enable_if<! std::is_void<R>::value>::type* = nullptr>
226  TILEDARRAY_FORCE_INLINE L&
227  operator*=(L& value, const ComplexConjugate<R> op) {
228  value = TiledArray::detail::conj(value) * op.factor();
229  return value;
230  }
231 
232  template <typename L>
233  TILEDARRAY_FORCE_INLINE L&
234  operator*=(L& value, const ComplexConjugate<void>&) {
235  value = TiledArray::detail::conj(value);
236  return value;
237  }
238 
239  template <typename L>
240  TILEDARRAY_FORCE_INLINE L&
242  value = -TiledArray::detail::conj(value);
243  return value;
244  }
245 
246  template<typename T>
247  inline auto abs(const ComplexConjugate<T>& a){
248  return std::abs(a.factor());
249  }
250 
251  inline int abs(const ComplexConjugate<void>& a){
252  return 1;
253  }
254 
255  } // namespace detail
256 } // namespace TiledArray
257 
258 #endif // TILEDARRAY_SRC_TILEDARRAY_TENSOR_COMPLEX_H__INCLUDED
int abs(const ComplexConjugate< void > &a)
Definition: complex.h:251
TILEDARRAY_FORCE_INLINE S factor() const
Definition: complex.h:118
TILEDARRAY_FORCE_INLINE ComplexConjugate< S > operator-() const
Definition: complex.h:120
TILEDARRAY_FORCE_INLINE R norm(const R r)
Wrapper function for std::norm
Definition: complex.h:89
auto abs(const ComplexConjugate< T > &a)
Definition: complex.h:247
TILEDARRAY_FORCE_INLINE std::complex< R > conj(const std::complex< R > z)
Wrapper function for std::conj.
Definition: complex.h:54
TILEDARRAY_FORCE_INLINE L & operator*=(L &value, const ComplexConjugate< R > op)
Definition: complex.h:227
TILEDARRAY_FORCE_INLINE R conj(const R r)
Wrapper function for std::conj
Definition: complex.h:44
std::vector< T > operator*(const Permutation &perm, const SizeArray< T > &orig)
Definition: size_array.h:437
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:181
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:65
Specialization of ComplexConjugate<S> for the case of a negative unit/identity factor.
Definition: complex.h:149
Specialization of ComplexConjugate<S> for the case of a unit/identity factor.
Definition: complex.h:135