HILA
Loading...
Searching...
No Matches
u1.h
1#ifndef U1_H_
2#define U1_H_
3
4#include <type_traits>
5#include <sstream>
6#include "plumbing/defs.h"
7#include "datatypes/cmplx.h"
8
9////////////////////////////////////////////////////////////////
10/// Type U1 as a phase angle - interface is analogous to (square) matrix,
11/// in order to facilitate compatible templates
12////////////////////////////////////////////////////////////////
13template <typename T>
14class U1 {
15 public:
16 static_assert(hila::is_arithmetic<T>::value, "U1 requires arithmetic type");
17 // content is just the phase angle
18 T phase;
19
20 /// std incantation for field types
21 using base_type = hila::arithmetic_type<T>;
22 using argument_type = T;
23
24 /// define default constructors to ensure std::is_trivial
25 U1() = default;
26 ~U1() = default;
27 U1(const U1 &v) = default;
28
29 // and make non-explicit constructor from 0
30 inline U1(const std::nullptr_t &z) {
31 phase = 0;
32 }
33
34 /// unary -
35 inline U1 operator-() const {
36 U1 res;
37 res.phase = phase + M_PI;
38 return res;
39 }
40
41 /// unary +
42 inline U1 operator+() const {
43 return *this;
44 }
45
46 /// multiply assign
47 template <
48 typename S,
49 std::enable_if_t<std::is_convertible<hila::type_plus<T, S>, T>::value, int> = 0>
50 U1<T> &operator*=(const U1<S> &rhs) {
51 phase += rhs.phase;
52 return *this;
53 }
54
55 /// U1 -> complex number
56 inline Complex<T> complex() const {
57 return Complex<T>(cos(phase), sin(phase));
58 }
59
60 template <typename S, std::enable_if_t<hila::is_arithmetic<S>::value, int> = 0>
61 U1 &set_phase(const S val) out_only {
62 phase = val;
63 return *this;
64 }
65
66 template <typename S, std::enable_if_t<hila::is_arithmetic<S>::value, int> = 0>
67 U1 &set_phase(const Complex<S> val) out_only {
68 phase = val.arg();
69 return *this;
70 }
71
72 inline U1 conj() const {
73 U1 res;
74 res.phase = -phase;
75 return res;
76 }
77
78 inline U1 dagger() const {
79 return conj();
80 }
81
82 inline T real() const {
83 return cos(phase);
84 }
85
86 inline T imag() const {
87 return sin(phase);
88 }
89
90
91 /// Generate random elements
92 U1 &random() out_only {
93 phase = M_PI * (2.0 * hila::random() - 1.0);
94 return *this;
95 }
96
97 U1 &gaussian_random(double width=1.0) out_only {
98 phase = hila::gaussrand() * width;
99 return *this;
100 }
101};
102
103/// conjugate
104template <typename T>
105inline U1<T> conj(const U1<T> arg) {
106 return arg.conj();
107}
108/// real part
109template <typename T>
110inline T real(const U1<T> arg) {
111 return arg.real();
112}
113/// imaginary part
114template <typename T>
115inline T imag(const U1<T> arg) {
116 return arg.imag();
117}
118
119/// and U1*U1
120template <typename T>
121inline U1<T> operator*(U1<T> a, const U1<T> b) {
122 a += b;
123 return a;
124}
125
126
127/// Multiply complex number
128template <typename T, typename S>
129inline Complex<hila::type_mul<T, S>> operator*(const U1<T> a, const Complex<S> &b) {
131 r = a.complex() * b;
132 return r;
133}
134
135/// Multiply complex number
136template <typename T, typename S>
137inline Complex<hila::type_mul<T, S>> operator*(const Complex<S> &b, const U1<T> a) {
139 r = a.complex() * b;
140 return r;
141}
142
143
144/// Stream operator
145template <typename T>
146std::ostream &operator<<(std::ostream &strm, const U1<T> A) {
147 return operator<<(strm, A.phase);
148}
149
150
151// Cast operators to different number type
152// cast_to<double>(a);
153
154template <typename Ntype, typename T,
155 std::enable_if_t<hila::is_arithmetic<T>::value, int> = 0>
156U1<Ntype> cast_to(const U1<T> m) {
157 U1<Ntype> res;
158 res.phase = m.phase;
159 return res;
160}
161
162
163#endif
Array< n, m, T > conj(const Array< n, m, T > &arg)
Return conjugate Array.
Definition array.h:674
std::ostream & operator<<(std::ostream &strm, const Array< n, m, T > &A)
Stream operator.
Definition array.h:977
Array< n, m, hila::arithmetic_type< T > > imag(const Array< n, m, T > &arg)
Return imaginary part of Array.
Definition array.h:702
Array< n, m, T > cos(Array< n, m, T > a)
Cosine.
Definition array.h:1089
Array< n, m, T > operator*(Array< n, m, T > a, const Array< n, m, T > &b)
Multiplication operator.
Definition array.h:861
Array< n, m, Ntype > cast_to(const Array< n, m, T > &mat)
Array casting operation.
Definition array.h:1289
Array< n, m, T > sin(Array< n, m, T > a)
Sine.
Definition array.h:1079
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
Definition array.h:688
Complex definition.
Definition cmplx.h:56
Definition u1.h:14
U1 & random()
Generate random elements.
Definition u1.h:92
U1< T > & operator*=(const U1< S > &rhs)
multiply assign
Definition u1.h:50
U1()=default
define default constructors to ensure std::is_trivial
U1 operator-() const
unary -
Definition u1.h:35
hila::arithmetic_type< T > base_type
std incantation for field types
Definition u1.h:21
Complex< T > complex() const
U1 -> complex number.
Definition u1.h:56
U1 operator+() const
unary +
Definition u1.h:42
Definition of Complex types.
T arg(const Complex< T > &a)
Return argument of Complex number.
Definition cmplx.h:1199
This file defines all includes for HILA.
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:118
double gaussrand()
Gaussian random generation routine.
Definition random.cpp:216