16 #include "complex_promote.h"
17 #include "complex_math.h"
20 template<
typename T>
class Jones {
23 std::complex<T> j00,j01,j10,j11;
26 Jones (T scalar = 0.0)
27 : j00(scalar), j01(0.0), j10(0.0), j11(scalar) { }
30 template<
typename U>
explicit Jones (
const U& scalar)
31 : j00(scalar), j01(0.0), j10(0.0), j11(scalar) { }
34 Jones (std::complex<T> j00_, std::complex<T> j01_,
35 std::complex<T> j10_, std::complex<T> j11_)
36 : j00(j00_), j01(j01_), j10(j10_), j11(j11_) { }
40 : j00(s.j00), j01(s.j01), j10(s.j10), j11(s.j11) { }
47 template<
typename U>
Jones (
const Matrix< 2, 2, std::complex<U> >& M)
48 : j00(M[0][0]), j01(M[0][1]), j10(M[1][0]),j11(M[1][1]) { }
52 { j00=s.j00; j01=s.j01; j10=s.j10; j11=s.j11;
return *
this; }
56 { j00=scalar; j01=0; j10=0; j11=scalar;
return *
this; }
60 { j00=scalar; j01=0; j10=0; j11=scalar;
return *
this; }
64 { j00=std::complex<T>(s.j00.real(), s.j00.imag());
65 j01=std::complex<T>(s.j01.real(), s.j01.imag());
66 j10=std::complex<T>(s.j10.real(), s.j10.imag());
67 j11=std::complex<T>(s.j11.real(), s.j11.imag());
return *
this; }
72 operator equiv ()
const
73 { equiv M; M[0][0]=j00; M[0][1]=j01; M[1][0]=j10; M[1][1]=j11;
return M; }
77 { j00+=s.j00; j01+=s.j01; j10+=s.j10; j11+=s.j11;
return *
this; }
81 { j00-=s.j00; j01-=s.j01; j10-=s.j10; j11-=s.j11;
return *
this; }
88 { std::complex<T>a(au); j00*=a; j01*=a; j10*=a; j11*=a;
return *
this; }
92 { std::complex<T>a(T(1.0),T(0.0));
93 a/=au; j00*=a; j01*=a; j10*=a; j11*=a;
return *
this; }
97 { j00*=a; j01*=a; j10*=a; j11*=a;
return *
this; }
101 { T d=1.0/a; j00*=d; j01*=d; j10*=d; j11*=d;
return *
this; }
106 j00 == b.j00 && j01 == b.j01 &&
107 j10 == b.j10 && j11 == b.j11;
138 { s.j00=-s.j00; s.j01=-s.j01; s.j10=-s.j10; s.j11=-s.j11;
return s; }
141 std::complex<T>&
operator () (
unsigned ir,
unsigned ic)
142 { std::complex<T>* val = &j00;
return val[ir*2+ic]; }
145 const std::complex<T>&
operator () (
unsigned ir,
unsigned ic)
const
146 {
const std::complex<T>* val = &j00;
return val[ir*2+ic]; }
150 { std::complex<T>* val = &j00;
return val[n]; }
153 const std::complex<T>&
operator [] (
unsigned n)
const
154 {
const std::complex<T>* val = &j00;
return val[n]; }
157 const bool is_diagonal ()
const {
return (j01==std::complex<T>(0.0))
158 && (j10==std::complex<T>(0.0)); }
164 unsigned size ()
const {
return 4; }
169 T tr = trace(*this).real();
170 T d = det(*this).real();
171 return sqrt( 1 - 4*d/(tr*tr) );
177 template<
typename T,
typename U>
183 template<
typename T,
typename U>
189 template<
typename T,
typename U>
210 static inline unsigned ndim () {
return 4; }
211 static inline std::complex<T>& element (
Jones<T>& t,
unsigned i)
213 static inline const std::complex<T>& element (
const Jones<T>& t,
unsigned i)
221 std::complex<T> temp (j00 * j.j00 + j01 * j.j10);
222 j01 = j00 * j.j01 + j01 * j.j11; j00=temp;
223 temp = j10 * j.j00 + j11 * j.j10;
224 j11 = j10 * j.j01 + j11 * j.j11; j10=temp;
232 std::complex<T> d(1.0,0.0); d/=det(j);
241 return Jones<T>(std::conj(j.j00), std::conj(j.j01),
242 std::conj(j.j10), std::conj(j.j11));
249 return Jones<T>(std::conj(j.j00), std::conj(j.j10),
250 std::conj(j.j01), std::conj(j.j11));
255 std::complex<T> det (
const Jones<T>& j) {
return j.j00*j.j11 - j.j01*j.j10; }
259 std::complex<T> trace (
const Jones<T>& j) {
return j.j00 + j.j11; }
265 norm(j.j00) + norm(j.j01) +
266 norm(j.j10) + norm(j.j11);
271 {
return myfinite(j.j00) && myfinite(j.j01) && myfinite(j.j10) && myfinite(j.j11); }
276 return sqrt (norm(j));
281 std::ostream& operator<< (std::ostream& ostr,
const Jones<T>& j)
283 return ostr <<
"[" << j.j00 << j.j01 << j.j10 << j.j11 <<
"]";