Jones.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2003 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// epsic/src/util/Jones.h
10
11#ifndef __Jones_H
12#define __Jones_H
13
14#include "Matrix.h"
15#include "Traits.h"
16#include "complex_promote.h"
17#include "complex_math.h"
18
20template<typename T> class Jones {
21
22public:
23 std::complex<T> j00,j01,j10,j11;
24
26 Jones (T scalar = 0.0)
27 : j00(scalar), j01(0.0), j10(0.0), j11(scalar) { }
28
30 template<typename U> explicit Jones (const U& scalar)
31 : j00(scalar), j01(0.0), j10(0.0), j11(scalar) { }
32
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_) { }
37
39 Jones (const Jones& s)
40 : j00(s.j00), j01(s.j01), j10(s.j10), j11(s.j11) { }
41
43 template<typename U> Jones (const Jones<U>& s)
44 { operator=(s); }
45
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]) { }
49
51 Jones& operator = (const Jones& s)
52 { j00=s.j00; j01=s.j01; j10=s.j10; j11=s.j11; return *this; }
53
55 Jones& operator = (T scalar)
56 { j00=scalar; j01=0; j10=0; j11=scalar; return *this; }
57
59 Jones& operator = (std::complex<T> scalar)
60 { j00=scalar; j01=0; j10=0; j11=scalar; return *this; }
61
63 template<typename U> Jones& operator = (const Jones<U>& s)
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; }
68
69 typedef Matrix< 2, 2, std::complex<T> > equiv;
70
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; }
74
76 Jones& operator += (const Jones& s)
77 { j00+=s.j00; j01+=s.j01; j10+=s.j10; j11+=s.j11; return *this; }
78
80 Jones& operator -= (const Jones& s)
81 { j00-=s.j00; j01-=s.j01; j10-=s.j10; j11-=s.j11; return *this; }
82
84 Jones& operator *= (const Jones& j);
85
87 template<typename U> Jones& operator *= (const std::complex<U>& au)
88 { std::complex<T>a(au); j00*=a; j01*=a; j10*=a; j11*=a; return *this; }
89
91 template<typename U> Jones& operator /= (const std::complex<U>& au)
92 { std::complex<T>a(T(1.0),T(0.0));
93 a/=au; j00*=a; j01*=a; j10*=a; j11*=a; return *this; }
94
97 { j00*=a; j01*=a; j10*=a; j11*=a; return *this; }
98
100 Jones& operator /= (T a)
101 { T d=1.0/a; j00*=d; j01*=d; j10*=d; j11*=d; return *this; }
102
104 bool operator == (const Jones& b) const
105 { return
106 j00 == b.j00 && j01 == b.j01 &&
107 j10 == b.j10 && j11 == b.j11;
108 }
109
111 bool operator != (const Jones& b) const
112 { return ! Jones::operator==(b); }
113
115 template<typename U>
116 const friend Jones operator * (Jones a, std::complex<U> c)
117 { a*=c; return a; }
118
120 template<typename U>
121 const friend Jones operator * (std::complex<U> c, Jones a)
122 { a*=c; return a; }
123
125 const friend Jones operator * (Jones a, T c)
126 { a*=c; return a; }
127
129 const friend Jones operator * (T c, Jones a)
130 { a*=c; return a; }
131
133 template<typename U> const friend Jones operator / (Jones a, U c)
134 { a/=c; return a; }
135
137 const friend Jones operator - (Jones s)
138 { s.j00=-s.j00; s.j01=-s.j01; s.j10=-s.j10; s.j11=-s.j11; return s; }
139
141 std::complex<T>& operator () (unsigned ir, unsigned ic)
142 { std::complex<T>* val = &j00; return val[ir*2+ic]; }
143
145 const std::complex<T>& operator () (unsigned ir, unsigned ic) const
146 { const std::complex<T>* val = &j00; return val[ir*2+ic]; }
147
149 std::complex<T>& operator [] (unsigned n)
150 { std::complex<T>* val = &j00; return val[n]; }
151
153 const std::complex<T>& operator [] (unsigned n) const
154 { const std::complex<T>* val = &j00; return val[n]; }
155
157 bool is_diagonal () const { return (j01==std::complex<T>(0.0))
158 && (j10==std::complex<T>(0.0)); }
159
161 static const Jones& identity();
162
164 unsigned size () const { return 4; }
165
167 T p () const
168 {
169 T tr = trace(*this).real();
170 T d = det(*this).real();
171 return sqrt( 1 - 4*d/(tr*tr) );
172 }
173
174};
175
177template<typename T, typename U>
179operator + (const Jones<T>& a, const Jones<U>& b)
180{ Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret+=b; return ret; }
181
183template<typename T, typename U>
185operator - (const Jones<T>& a, const Jones<U>& b)
186{ Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret-=b; return ret; }
187
189template<typename T, typename U>
191operator * (const Jones<T>& a, const Jones<U>& b)
192{ Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret*=b; return ret; }
193
194
196template<typename T>
198{
199 static Jones<T> I (1,0,
200 0,1);
201 return I;
202}
203
205template<typename T> struct DatumTraits< Jones<T> >
206{
207 ElementTraits< std::complex<T> > element_traits;
208 typedef std::complex<T> element_type;
209
210 static inline unsigned ndim () { return 4; }
211 static inline std::complex<T>& element (Jones<T>& t, unsigned i)
212 { return t[i]; }
213 static inline const std::complex<T>& element (const Jones<T>& t, unsigned i)
214 { return t[i]; }
215};
216
218template<typename T>
220{
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;
225 return *this;
226}
227
229template<typename T>
230Jones<T> inv (const Jones<T>& j)
231{
232 std::complex<T> d(1.0,0.0); d/=det(j);
233 return Jones<T>(d*j.j11, -d*j.j01,
234 -d*j.j10, d*j.j00);
235}
236
238template<typename T>
239Jones<T> conj (const Jones<T>& j)
240{
241 return Jones<T>(std::conj(j.j00), std::conj(j.j01),
242 std::conj(j.j10), std::conj(j.j11));
243}
244
246template<typename T>
247Jones<T> herm (const Jones<T>& j)
248{
249 return Jones<T>(std::conj(j.j00), std::conj(j.j10),
250 std::conj(j.j01), std::conj(j.j11));
251}
252
254template<typename T>
255std::complex<T> det (const Jones<T>& j) { return j.j00*j.j11 - j.j01*j.j10; }
256
258template<typename T>
259std::complex<T> trace (const Jones<T>& j) { return j.j00 + j.j11; }
260
262template<typename T>
263T norm (const Jones<T>& j)
264{ return
265 norm(j.j00) + norm(j.j01) +
266 norm(j.j10) + norm(j.j11);
267}
268
269namespace true_math
270{
271 template<typename T>
272 bool finite (const Jones<T>& j)
273 { return finite(j.j00) && finite(j.j01) && finite(j.j10) && finite(j.j11); }
274}
275
276template<typename T>
277T fabs (const Jones<T>& j)
278{
279 return sqrt (norm(j));
280}
281
283template<typename T>
284std::ostream& operator<< (std::ostream& ostr, const Jones<T>& j)
285{
286 return ostr << "[" << j.j00 << j.j01 << j.j10 << j.j11 << "]";
287}
288
289#endif /* not __Jones_H defined */
290
Jones & operator-=(const Jones &s)
Jones & operator=(const Jones &s)
bool is_diagonal() const
Jones & operator*=(const Jones &j)
std::complex< T > & operator()(unsigned ir, unsigned ic)
friend const friend Jones operator/(Jones a, U c)
unsigned size() const
friend const friend Jones operator-(Jones s)
T p() const
Jones & operator/=(const std::complex< U > &au)
Jones(T scalar=0.0)
Jones & operator+=(const Jones &s)
bool operator!=(const Jones &b) const
bool operator==(const Jones &b) const
static const Jones & identity()
Definition Jones.h:197
friend const friend Jones operator*(Jones a, std::complex< U > c)
std::complex< T > & operator[](unsigned n)
E element_traits
Definition Traits.h:73

Generated using doxygen 1.14.0