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 
20 template<typename T> class Jones {
21 
22 public:
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 
96  Jones& operator *= (T a)
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  const 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 
177 template<typename T, typename U>
179 operator + (const Jones<T>& a, const Jones<U>& b)
180 { Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret+=b; return ret; }
181 
183 template<typename T, typename U>
185 operator - (const Jones<T>& a, const Jones<U>& b)
186 { Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret-=b; return ret; }
187 
189 template<typename T, typename U>
191 operator * (const Jones<T>& a, const Jones<U>& b)
192 { Jones<typename PromoteTraits<T,U>::promote_type> ret(a); ret*=b; return ret; }
193 
194 
196 template<typename T>
198 {
199  static Jones<T> I (1,0,
200  0,1);
201  return I;
202 }
203 
205 template<typename T> struct DatumTraits< Jones<T> >
206 {
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 
218 template<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 
229 template<typename T>
230 Jones<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 
238 template<typename T>
239 Jones<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 
246 template<typename T>
247 Jones<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 
254 template<typename T>
255 std::complex<T> det (const Jones<T>& j) { return j.j00*j.j11 - j.j01*j.j10; }
256 
258 template<typename T>
259 std::complex<T> trace (const Jones<T>& j) { return j.j00 + j.j11; }
260 
262 template<typename T>
263 T norm (const Jones<T>& j)
264 { return
265  norm(j.j00) + norm(j.j01) +
266  norm(j.j10) + norm(j.j11);
267 }
268 
269 template<typename T>
270 bool myfinite (const Jones<T>& j)
271 { return myfinite(j.j00) && myfinite(j.j01) && myfinite(j.j10) && myfinite(j.j11); }
272 
273 template<typename T>
274 T fabs (const Jones<T>& j)
275 {
276  return sqrt (norm(j));
277 }
278 
280 template<typename T>
281 std::ostream& operator<< (std::ostream& ostr, const Jones<T>& j)
282 {
283  return ostr << "[" << j.j00 << j.j01 << j.j10 << j.j11 << "]";
284 }
285 
286 #endif /* not __Jones_H defined */
287 
friend const friend Jones operator/(Jones a, U c)
bool operator==(const Jones &b) const
bool operator!=(const Jones &b) const
Jones & operator+=(const Jones &s)
Jones & operator-=(const Jones &s)
friend const friend Jones operator*(Jones a, std::complex< U > c)
Jones matrices are 2x2 matrices with complex elements.
Definition: Jones.h:20
Traits of an element type.
Definition: Traits.h:31
Jones & operator=(const Jones &s)
std::complex< T > & operator[](unsigned n)
unsigned size() const
Matrix is a column vector of row vectors.
Definition: Matrix.h:20
std::complex< T > & operator()(unsigned ir, unsigned ic)
friend const friend Jones operator-(Jones s)
E element_traits
Traits of the elements of the data type.
Definition: Traits.h:73
const bool is_diagonal() const
T p() const
Jones & operator/=(const std::complex< U > &au)
Jones & operator*=(const Jones &j)
Jones(T scalar=0.0)
Traits of the data type.
Definition: Traits.h:70
static const Jones & identity()
The identity matrix.
Definition: Jones.h:197

Generated using doxygen 1.8.17