Pauli.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/Pauli.h
10
11#ifndef __Pauli_H
12#define __Pauli_H
13
14#include "Jones.h"
15#include "Quaternion.h"
16#include "Stokes.h"
17#include "Basis.h"
18
19#include <vector>
20#include <limits>
21
22namespace Pauli {
23
25 Basis<double>& basis();
26
28 Jones<double> matrix (unsigned i);
29}
30
31
32// convert Hermitian Quaternion to Jones matrix
33template<typename T>
34const Jones<T> convert (const Quaternion<std::complex<T>,Hermitian>& q)
35{
36 return Jones<T> (q.s0+q.s1, q.s2-ci(q.s3),
37 q.s2+ci(q.s3), q.s0-q.s1);
38}
39
40// convert Unitary Quaternion to Jones matrix
41template<typename T>
42const Jones<T> convert (const Quaternion<std::complex<T>,Unitary>& q)
43{
44 return Jones<T> (q.s0+ci(q.s1), q.s3+ci(q.s2),
45 -q.s3+ci(q.s2), q.s0-ci(q.s1));
46}
47
48// convert Hermitian Quaternion to Jones matrix
49template<typename T>
50const Jones<T> convert (const Quaternion<T,Hermitian>& q)
51{
52 return Jones<T> (std::complex<T>(q.s0+q.s1,0.0), std::complex<T>(q.s2,-q.s3),
53 std::complex<T>(q.s2,q.s3), std::complex<T>(q.s0-q.s1,0.0));
54}
55
56// convert Unitary Quaternion to Jones matrix
57template<typename T>
58const Jones<T> convert (const Quaternion<T,Unitary>& q)
59{
60 return Jones<T> (q.s0+ci(q.s1), q.s3+ci(q.s2),
61 -q.s3+ci(q.s2), q.s0-ci(q.s1));
62}
63
64// convert complex Stokes parameters to Jones matrix
65template<typename T>
66const Jones<T> convert (const Stokes< std::complex<T> >& stokes)
67{
68 Quaternion<std::complex<T>,Hermitian> q;
69
70 q.set_scalar (stokes.get_scalar());
71 q.set_vector (Pauli::basis().get_out(stokes.get_vector()));
72
73 std::complex<T> half (0.5, 0.0);
74 return convert (half*q);
75}
76
77// convert Stokes parameters to Jones matrix
78template<typename T>
79const Jones<T> convert (const Stokes<T>& stokes)
80{
81 Quaternion<T,Hermitian> q (stokes.get_scalar(),
82 Pauli::basis().get_out(stokes.get_vector()));
83 return convert (T(0.5)*q);
84}
85
86// convert coherency vector to Jones matrix
87template<typename T>
88const Jones<T> convert (const std::vector<T>& c)
89{
90 if (c.size() != 4)
91 throw std::runtime_error ("Jones<T> convert (std::vector<T>) vector.size() != 4");
92
93 return Jones<T> (c[0], std::complex<T> (c[2], -c[3]),
94 std::complex<T> (c[2], c[3]), c[1]);
95}
96
97// convert Stokes parameters to natural basis
98template<typename T>
99const Quaternion<T,Hermitian> natural (const Stokes<T>& stokes)
100{
102 (stokes.get_scalar(), Pauli::basis().get_out(stokes.get_vector()));
103}
104
105template<typename T>
106const Stokes<T> standard (const Quaternion<T,Hermitian>& q)
107{
108 return Stokes<T>( q.get_scalar(), Pauli::basis().get_in(q.get_vector()) );
109}
110
111
112// convert Jones matrix to Hermitian Biquaternion
113template<typename T>
114const Quaternion<std::complex<T>, Hermitian> convert (const Jones<T>& j)
115{
116 return Quaternion<std::complex<T>, Hermitian>
117 ( T(0.5) * (j.j00 + j.j11),
118 T(0.5) * (j.j00 - j.j11),
119 T(0.5) * (j.j01 + j.j10),
120 T(0.5) * ci (j.j01 - j.j10) );
121}
122
123// convert Jones matrix to Unitary Biquaternion
124template<typename T>
125const Quaternion<std::complex<T>, Unitary> unitary (const Jones<T>& j)
126{
127 return Quaternion<std::complex<T>, Unitary>
128 ( T(0.5) * (j.j00 + j.j11),
129 T(-0.5) * ci (j.j00 - j.j11),
130 T(-0.5) * ci (j.j01 + j.j10),
131 T(0.5) * (j.j01 - j.j10) );
132}
133
134// convert a Hermitian Jones matrix to Stokes parameters
135template<typename T>
136const Stokes<T> coherency (const Jones<T>& j)
137{
138 Quaternion<std::complex<T>,Hermitian> h = convert (j);
139 return real_coherency (h);
140}
141
142// convert a Hermitian Jones matrix to Stokes parameters
143template<typename T>
144const Stokes< std::complex<T> > complex_coherency (const Jones<T>& j)
145{
146 Quaternion<std::complex<T>,Hermitian> h = convert (j);
147 return coherency (h);
148}
149
150// convert a complex Hermitian Quaternion to Stokes parameters
151template<typename T>
152const Stokes<T> real_coherency (const Quaternion<std::complex<T>,Hermitian>& q)
153{
154 Quaternion<T,Hermitian> realpart (real(q));
155 Quaternion<T,Hermitian> imaginary (imag(q));
156 T nr = norm(realpart);
157 T ni = norm(imaginary);
158 if (ni > 1e8*std::numeric_limits<T>::epsilon() && ni*1e5 > nr)
159 {
160 const char* msg = "Stokes<T> coherency (Quaternion<complex<T>,Hermitian>) "
161 "non-zero imaginary component";
162
163 std::cerr << msg <<
164 "\n norm(imag(q))=" << ni << " norm=" << nr << std::endl;
165
166 throw std::runtime_error (msg);
167 }
168
169 return coherency (realpart);
170}
171
172// convert a Hermitian Quaternion to Stokes parameters
173template<typename T>
174const Stokes<T> coherency (const Quaternion<T,Hermitian>& q)
175{
176 return Stokes<T>( T(2.0) * q.get_scalar(),
177 T(2.0) * Pauli::basis().get_in(q.get_vector()) );
178}
179
180// transform the Stokes parameters by the given Jones matrix
181template<typename T, typename U>
182const Stokes<T> transform (const Stokes<T>& input, const Jones<U>& jones)
183{
184 return coherency (jones * convert(input) * herm(jones));
185}
186
187// transform the Stokes parameters by the given Jones matrix
188template<typename T, typename U>
189const Stokes< std::complex<T> >
190transform (const Stokes< std::complex<T> >& input, const Jones<U>& jones)
191{
192 return complex_coherency (jones * convert(input) * herm(jones));
193}
194
195// transform the coherency matrix by the given Mueller matrix
196template<typename T, typename U>
197Jones<T> transform (const Matrix<4,4,U>& M, const Jones<T>& rho)
198{
199 Stokes< std::complex<T> > s = M * complex_coherency(rho);
200 return convert(s);
201}
202
203// convert Jones matrix to Hermitian and Unitary Quaternion
204template<typename T>
205void polar (std::complex<T>& d, Quaternion<T, Hermitian>& h,
207{
208 // make j unimodular
209 d = sqrt (det(j));
210 j /= d;
211
212 // calculate the hermitian
213 h = sqrt( real( convert( j*herm(j) ) ) );
214
215 // remove the hermitian component from j
216 j = inv(convert(h)) * j;
217
218 // take the unitary component out of j
219 u = real ( unitary (j) );
220}
221
222
223// multiply a Jones matrix by a Quaternion
224template<typename T, typename U, QBasis B>
225const Jones<T> operator * (const Jones<T>& j, const Quaternion<U,B>& q)
226{
227 return j * convert(q);
228}
229
230// multiply a Jones matrix by a Quaternion
231template<typename T, typename U, QBasis B>
232const Jones<T> operator * (const Quaternion<T,B>& q, const Jones<U>& j)
233{
234 return convert(q) * j;
235}
236
237// multiply Quaternions from different QBasis
238template<typename T, typename U, QBasis A, QBasis B>
239const Jones<T> operator * (const Quaternion<T,A>& q, const Quaternion<U,B>& u)
240{
241 return convert(q) * convert(u);
242}
243
244// return the Mueller matrix corresponding to the given Jones matrix
245template<typename T>
246Matrix<4,4,T> Mueller (const Jones<T>& J)
247{
248 Matrix<4,4,T> result;
249
250 for (unsigned row=0; row < 4; row++) {
251 Stokes<T> basis;
252 basis[row] = 1.0;
253 result[row] = coherency(herm(J) * convert(basis) * J);
254 }
255
256 return result;
257}
258
259// return the Mueller matrix derivative Jones matrix
260template<typename T>
261Matrix<4,4,T> Mueller (const Jones<T>& J, const Jones<T>& Jgrad)
262{
263 Matrix<4,4,T> result;
264
265 for (unsigned row=0; row < 4; row++) {
266 Stokes<T> basis;
267 basis[row] = 1.0;
268 Jones<T> rho = convert(basis);
269 result[row] = coherency(herm(Jgrad) * rho * J + herm(J) * rho * Jgrad);
270 }
271
272 return result;
273}
274
275#endif
Vector< 3, T > get_vector() const
void set_scalar(T s)
T get_scalar() const
void set_vector(const Vector< 3, U > &v)

Generated using doxygen 1.14.0