12 #include <type_traits> 19 namespace alps {
namespace alea {
29 namespace alps {
namespace alea {
52 static_assert(std::is_floating_point<T>::value,
53 "T argument of complex_op<T> must be real scalar type");
57 return complex_op(a.real() * b.real(), a.real() * b.imag(),
58 a.imag() * b.real(), a.imag() * b.imag());
84 T &
rere() {
return vals_[0][0]; }
85 T &
reim() {
return vals_[0][1]; }
86 T &
imre() {
return vals_[1][0]; }
87 T &
imim() {
return vals_[1][1]; }
89 const T &
rere()
const {
return vals_[0][0]; }
90 const T &
reim()
const {
return vals_[0][1]; }
91 const T &
imre()
const {
return vals_[1][0]; }
92 const T &
imim()
const {
return vals_[1][1]; }
97 &vals_[0][0], std::plus<T>());
104 &vals_[0][0], std::minus<T>());
121 return complex_op(-x.rere(), -x.reim(), -x.imre(), -x.imim());
149 return complex_op(l.rere() * r.rere() + l.reim() * r.imre(),
150 l.rere() * r.reim() + l.reim() * r.imim(),
151 l.imre() * r.rere() + l.imim() * r.imre(),
152 l.imre() * r.reim() + l.imim() * r.imim());
157 return dot(l, inv(r));
162 return std::equal(&l.vals_[0][0], &l.vals_[2][0], &r.vals_[0][0]);
167 return !std::equal(&l.vals_[0][0], &l.vals_[2][0], &r.vals_[0][0]);
173 T inv_det = 1/(x.rere() * x.imim() - x.reim() * x.imre());
174 return complex_op(inv_det * x.imim(), inv_det * -x.reim(),
175 inv_det * -x.imre(), inv_det * x.rere());
181 T off_diag = x.rere() * x.reim() + x.imre() * x.imim();
182 return complex_op(x.rere() * x.rere() + x.imre() * x.imre(),
184 x.reim() * x.reim() + x.imim() * x.imim());
190 T det = x.rere() * x.imim() - x.reim() * x.imre();
191 T tr = x.rere() + x.imim();
194 if (det < 0 || tr < 0)
200 return complex_op(inv_t * (x.rere() + s), inv_t * x.reim(),
201 inv_t * x.imre(), inv_t * (x.imim() + s));
206 return std::any_of(&x.vals_[0][0], &x.vals_[2][0], [](T y) {return std::isnan(y); });
211 return std::all_of(&x.vals_[0][0], &x.vals_[2][0], [](T y) {return std::isfinite(y); });
221 return std::any_of(&x.vals_[0][0], &x.vals_[2][0], [](T y) {return std::isinf(y); });
228 out <<
'(' << x.rere() <<
',' << x.reim()
229 <<
';' << x.imre() <<
',' << x.imim() <<
')';
245 template <
typename T>
257 RequireInitialization = 1,
264 template <
typename T,
typename BinaryOp>
270 template <
typename T,
typename BinaryOp>
friend complex_op abs(complex_op x)
friend complex_op operator-(complex_op x)
friend complex_op abs2(complex_op x)
friend bool operator==(complex_op l, complex_op r)
friend complex_op operator/(complex_op x, double f)
boost::array< T, N > sqrt(boost::array< T, N > arg)
friend complex_op operator*(complex_op x, double f)
friend bool isfinite(complex_op x)
friend complex_op operator-(complex_op l, complex_op r)
friend complex_op operator*(double f, complex_op x)
static complex_op diag(std::complex< T > a)
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
complex_op & operator/=(double x)
friend bool isnan(complex_op x)
alps::alea::complex_op< T > NonInteger
complex_op(T rere, T reim, T imre, T imim)
friend complex_op operator+(complex_op l, complex_op r)
friend std::ostream & operator<<(std::ostream &out, complex_op x)
static complex_op diag(T a)
complex_op & operator*=(double x)
friend bool operator!=(complex_op l, complex_op r)
friend complex_op inv(complex_op x)
static complex_op outer(std::complex< T > a, std::complex< T > b)
friend complex_op dot(complex_op l, complex_op r)
alps::alea::complex_op< T > ReturnType
friend complex_op sqrt(complex_op x)
alps::alea::complex_op< T > Real
alps::alea::complex_op< T > Nested
friend complex_op solve(complex_op l, complex_op r)
T r(T x, T y=T(), T z=T())
complex_op & operator-=(complex_op x)
alps::alea::complex_op< T > ReturnType
friend bool isinf(complex_op x)
complex_op & operator+=(complex_op x)