Intro to Polarization#

This tutorial will guide you through the basics of Jones calculus. Any polarization state can be represented by a simple 2-vector called a Jones vector \(\mathbf{v}\)

\[\begin{split}\mathbf{v} = \begin{pmatrix} E_{x} \\ E_{y} \\ \end{pmatrix}\end{split}\]

The components of \(\mathbf{v}\) are the complex amplitudes that correspond to light oriented (polarized) in the local horizontal and vertical directions. Horizontally polarized light looks like:

\[\begin{split}\mathbf{v}_{H} = \begin{pmatrix} 1 \\ 0 \\ \end{pmatrix}.\end{split}\]

Whereas vertically polarized light looks like:

\[\begin{split}\mathbf{v}_{V} = \begin{pmatrix} 0 \\ 1 \\ \end{pmatrix}.\end{split}\]

In prysm.x.polarization, you can create these vectors using linear_pol_vector

[1]:
from prysm.x.polarization import linear_pol_vector
import numpy as np

hpol = linear_pol_vector(0)
vpol = linear_pol_vector(90)

print('Horizontal Polarization = ',hpol)
print('Vertical Polarization   = ',vpol)
Horizontal Polarization =  [1.+0.j 0.+0.j]
Vertical Polarization   =  [6.123234e-17+0.j 1.000000e+00+0.j]

We can also describe a polarization state with a phase delay between the horizontal and linear polarization states. A quarter-wave phase delay is $:nbsphinx-math:delta\phi `= 2:nbsphinx-math:pi`/4 $ or \(\pi/2\). If we add this phase delay to the \(E_{y}\) component, the resultant Jones vector looks like this:

\[\begin{split}\mathbf{v}_{L} = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 \\ e^{i\pi/2} \\ \end{pmatrix}.\end{split}\]

Where the factor of \(1/\sqrt{2}\) is there to normalize the Jones vector. This kind of polarization is called “Circular” polarization. Light can be circularly polarized in the left- or right-handed direction. Both are available via the circular_pol_vector method. The only difference is the sign of the imaginary part of the polarization state.

[2]:
from prysm.x.polarization import circular_pol_vector

lpol = circular_pol_vector(handedness='left')
rpol = circular_pol_vector(handedness='right')

print('Left-hand Circular Polarization = ',lpol)
print('Right-hand Circular Polarization = ',rpol)
Left-hand Circular Polarization =  [0.70710678+0.j         0.        +0.70710678j]
Right-hand Circular Polarization =  [ 0.70710678+0.j         -0.        -0.70710678j]

Now that we are equipped with the calculus to understand the polarization state of a given beam of light, we need to know how to operate on it. It follows from our use of 2-vectors that the corresponding operator is a 2x2 matrix. We refer to these as Jones matrices, and they take the form of \(\mathbf{J}\)

\[\begin{split}\mathbf{J} = \begin{pmatrix} J_{xx} & J_{xy} \\ J_{yx} & J_{yy} \\ \end{pmatrix}\end{split}\]

The on-diagonals of this matrix tell us how our polarization states propagate through our system. The off-diagonals of this matrix tell us how the polarization states rotate into eachother. We can model a horizontal polarizer with linear_polarizer.

[3]:
from prysm.x.polarization import linear_polarizer

# polarizers accept radians as input angle
h_polarizer = linear_polarizer(theta=np.radians(0))
print(h_polarizer)
[[1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j]]

This device only allows horizontally-polarized light through the system. We can understand the throughput of the above polarizations by mutiplying the vectors by the matrix.

[4]:
import numpy as np
polarizations = [hpol,vpol,lpol,rpol]
prefix = ['H','V','L','R']

compute_power = lambda pol: np.abs(np.dot(pol,pol.conj()))

for pol,pre in zip(polarizations,prefix):
    pol_out = h_polarizer @ pol
    print(f'Total Power of {pre}-pol after polarizer = ',compute_power(pol_out))
Total Power of H-pol after polarizer =  1.0
Total Power of V-pol after polarizer =  3.749399456654644e-33
Total Power of L-pol after polarizer =  0.4999999999999999
Total Power of R-pol after polarizer =  0.4999999999999999

This is about what we would expect from a linear polarizer subject to these polarization states. We can perform a simmilar experiment for a half wave plate to show how it rotates the polarization state. Let us just consider the linear polarization states.

[5]:
from prysm.x.polarization import half_wave_plate

hwp = half_wave_plate(np.radians(45)) # rotated HWP at 22.5 deg
linear_pols = polarizations[:2]

for pol,pre in zip(linear_pols,prefix[:2]):
    pol_out = hwp @ pol
    print(f'polarization in = {pol}')
    print(f'polarization out = {pol_out}')
polarization in = [1.+0.j 0.+0.j]
polarization out = [1.99673462e-16+6.123234e-17j 1.00000000e+00-6.123234e-17j]
polarization in = [6.123234e-17+0.j 1.000000e+00+0.j]
polarization out = [ 1.00000000e+00-6.123234e-17j -1.18148049e-16+6.123234e-17j]

These data tell us that a HWP oriented at 45 degrees w.r.t. the horizontal will cause x-polarization to flip into y-polarization, which is exactly what we expect from these polarization states. This concludes the brief introduction on using jones calculus in prysm. For more general use, x.polarization supports arbitrary linear diattenuators and retarders through the following methods:

  • linear_retarder

  • linear_diattenuator

Future demos will illustrate how to use these elements to operate on wavefronts for integrated modeling of physical optics and polarization, as well as an introduction to Mueller calculus.