5.2.1. Example 3: Analysis

In Optics, polarimetry is the discipline that studies the measurement and interpretation of the polarization of light waves, and the behavior of optical elements upon the polarization of light waves. In other words, it studies the measurement and analysis of Jones/Stokes vectors (light waves) and Jones/Mueller matrices (optical objects). This example is devoted to show the different analysis possibilities offered by py_pol.

[9]:
import numpy as np

from py_pol import degrees
from py_pol.jones_vector import Jones_vector
from py_pol.jones_matrix import Jones_matrix
from py_pol.stokes import Stokes, create_Stokes
from py_pol.mueller import Mueller
The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload

5.2.1.1. Analysis of light waves

5.2.1.1.1. Theory of Jones vectors

A transversal light wave can be described as:

\(\overrightarrow{E}=\left[\begin{array}{c} E_{x}\\ E_{y}\\ 0 \end{array}\right]e^{i\left(kz-\omega t\right)}e^{i\varphi}=\overrightarrow{E}_{pol}e^{i\left(kz-\omega t\right)}\)

Being \(\varphi\) the global phase, \(z\) the propagation direction of light, $k=:nbsphinx-math:left\Vert `:nbsphinx-math:overrightarrow{k}`:nbsphinx-math:right\Vert `$ the wavevector modulus, :math:omega` the angular frequency and \(\overrightarrow{E}_{pol}\) the polarization Jones vector composed of two complex components \(E_x\) and \(E_y\). Any complex 2x1 vector can describe a physically realizable light wave polarization state.

The Jones vector is completely described by four parameters. There are several sets of parameters that can be used. Some of the most used ones are the following:

  1. The real and imaginary parts of \(E_x\) and \(E_y\).
  2. Global phase (phase of \(E_x\), \(\varphi\)), electric field amplitudes (\(\left|E_{x}\right|\) and \(\left|E_{y}\right|\)) and the phase difference between components (\(\delta\)).
  3. Global phase, semimajor and semiminor ellipse axes (\(a\) and \(b\) respectively) and the semimajor axis azimuth (\(\phi\)).
  4. Global phase, wave intensity (\(I=\left|E_{x}\right|^{2}+\left|E_{y}\right|^{2}\)) and the characteristic angles \(\alpha\) (ratio angle: \(\tan\alpha=\frac{\left|E_{y}\right|}{\left|E_{x}\right|}\)) and \(\delta\).
  5. Global phase, wave intensity, azimuth (\(\phi\)) and ellipticity angle (\(\tan\chi=\frac{b}{a}\)).

Most of these parameters can be easily visualized in the ellipse produced by the real part of \(\overrightarrow{E}\):

2e666d101c934dcfb5269ce6fa73e1ac

It is worth noting that not all the values for the four angles should be used. Specifically:

  1. \(\;\alpha\;\in\;[0º, 90º]\)
  2. \(\;\delta\;\in\;[0º, 360º)\)
  3. \(\;\phi\;\in\;[0º, 180º)\)
  4. \(\;\chi\;\in\;[-45º, 45º]\)

Also, there are some cases where two or more different values correspond to the same polarization state. For example, right-handed circular polarization corresponds to \(\chi=45º\) and any azimuth value.

Analyze a Jones vector means calculating one set of 4 parameters. We chose to use mainly the two last sets of parameters, as their physical meaning is easily understood and highly compatible with polarimetry experiments.

In some special cases, one one of the parameters used to describe the light wave may be undetermined. For example, circular polarization states does not have a determined azimuth.

5.2.1.1.2. Example of analysis of Jones vectors

All the parameters described above can be easily calculated from a Jones_vector object through the parameters subclass. This subclass also provides some other parameters that can be useful.

[2]:
# Create a random Jones vector
E = Jones_vector('Random polarization')
E_real = np.random.rand(2, 10)
E_imag = np.random.rand(2, 10)
E.from_matrix(M=E_real+1j*E_imag)
print(E)
Random polarization =
[+1.000+0.373j]   [+0.745+0.982j]   [+0.421+0.062j]   [+0.328+0.216j]   [+0.520+0.298j]   [+0.350+0.941j]   [+0.089+0.464j]   [+0.845+0.579j]   [+0.675+0.215j]   [+0.468+0.175j]
[+0.797+0.388j]   [+0.578+0.631j]   [+0.915+0.942j]   [+0.177+0.308j]   [+0.686+0.451j]   [+0.179+0.659j]   [+0.181+0.677j]   [+0.443+0.927j]   [+0.024+0.792j]   [+0.952+0.084j]

[3]:
# Calculate a set of parameters
gp = E.parameters.global_phase(verbose=True)
I = E.parameters.intensity(verbose=True)
azimuth = E.parameters.azimuth(verbose=True)
ellipticity = E.parameters.ellipticity_angle(verbose=True)
The global phase of Random polarization is (deg.):
[20.47881277 52.82310549  8.37669939 33.4224342  29.80730163 69.62319614
 79.10493956 34.41232349 17.71335467 20.46600872]
The mean value is 36.62281760625346 +- 22.124347087961016

The intensity of Random polarization is (a.u.):
[1.92452675 2.25289393 1.90468351 0.28056211 1.0330991  1.47356069
 0.71500272 2.10269023 1.13019968 1.16393945]
The mean value is 1.3981158181111537 +- 0.6117112533271021

The azimuth of Random polarization is (deg.):
[39.67195812 34.73076642 75.06633859 41.80155297 53.92044418 34.17850188
 56.03811077 45.103272   54.3856788  62.89374159]
The mean value is 49.77903653215532 +- 12.435733679626598

The ellipticity angle of Random polarization is (deg.):
[ 2.69254418 -2.492722   10.44696024 13.32323771  1.67171187  2.38605174
 -1.88274892 15.02903114 34.78040804 -6.29793778]
The mean value is 6.9656536217808736 +- 11.411191797005818

[4]:
# Calculate some other parameters
dlp = E.parameters.degree_linear_polarization(verbose=True)
dcp = E.parameters.degree_circular_polarization(verbose=True)
The degree of linear polarization of Random polarization is:
[0.99558642 0.99621681 0.93424232 0.89379074 0.9982979  0.99653348
 0.9978412  0.86551827 0.34921296 0.97593246]
The mean value is 0.9003172572480562 +- 0.18933560250702827

The degree of circular polarization of Random polarization is:
[ 0.09384921 -0.08690266  0.35663887  0.44848423  0.05832064  0.08319265
 -0.06567304  0.50087735  0.93704339 -0.21807299]
The mean value is 0.2107757665675825 +- 0.3303852934869926

The checks subclass has some methods that allow analyzing the Jones vectors to see if some conditions are met.

[15]:
cond = E.checks.is_linear(verbose=True)
Random polarization is linearly polarized:
[False False False False False False False False False False]
The mean value is 0.0 +- 0.0

5.2.1.1.3. Theory of Stokes vectors

Stokes vectors can also be used to represent the polarization state of light waves. They are composed of four real elements:

\(S=\left[\begin{array}{c} I\\ Q\\ U\\ V \end{array}\right]=\left[\begin{array}{c} S_{0}\\ S_{1}\\ S_{2}\\ S_{3} \end{array}\right]=\left[\begin{array}{c} I_{total}\\ I_{0\text{º}}-I_{90\text{º}}\\ I_{45\text{º}}-I_{135\text{º}}\\ I_{right}-I_{left} \end{array}\right]\)

The four elements of the Stokes vector represent some intensities: \(I_{total}\) is the total intensity, \(I_x\) is the partial intensity of linear polarization of angle \(x\), and \(I_{right}\) and \(I_{left}\) are the partial right-handed and left-handed circular polarizations. Not every 4x1 real vector is a physically realizable Stokes vector, as it must fulfill the conservation of energy:

\(S_{0}^{2}\geq S_{1}^{2}+S_{2}^{2}+S_{3}^{2}\).

There are some differences between Stokes and Jones vectors. Stokes vectors use intensity, while Jones vectors use electric field. This means that Jones vectors have the information of the wave global phase, while Stokes vectors can be used to describe partially depolarized light. Totally polarized states (pure states) have their electric field totally described by the equation above. Totally depolarized light (or natural light) electric field is random (with the module of the electric field limited by the wave intensity). Partially polarized light can be divided into the sum of a totally polarized state plus a totally unpolarized state:

\(S=\wp S_{pol}+(1-\wp)S_{depol}\).

Being \(\wp\) the polarization degree, \(S_{pol}\) the pure Stokes vector. The totally polarized Stokes vector fulfills the equation:

\(S_{0}^{2} = S_{1}^{2}+S_{2}^{2}+S_{3}^{2}\).

While a totally unpolarized Stokes vectors have \(S_1=S_2=S_3=0\).

NOTE: Even if Stokes vectors do not contain neither use the global phase of the light wave, Stokes objects do. So it is possible to calculate the result of interference experiments using Stokes objects.

A Stokes vector can be analyzed by describing some of their parameters. Like Jones vectors, there are several sets of 4 parameters that completely describe a Stokes vector. The most usual are:

  1. The four components of the vector.
  2. Polarization degree, wave total intensity and the characteristic angles \(\alpha\) and \(\delta\).
  3. Polarization degree, wave total intensity, azimuth (\(\phi\)) and ellipticity angle (\(\chi\)).

It is important noting that the four angles are defined only for pure states. In the case of partially depolarized states, those angles are referred to the totally polarized part of the Stokes vector.

5.2.1.1.4. Example of analysis of Stokes vectors

All the parameters described above can be easily calculated from a Stokes object through the parameters subclass. This subclass also provides some other parameters that can be useful.

[7]:
# Create a random Stokes vector
S = Stokes('Random polarization')
S_matrix = np.random.rand(4, 10)
S_matrix[0,:] = np.sqrt(3)   # This assures that the Stokes vectors are physically realizable.
S.from_matrix(M=S_matrix)
print(S)
Random polarization =
[+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]   [+1.732]
[+0.561]   [+0.186]   [+0.951]   [+0.158]   [+0.086]   [+0.228]   [+0.989]   [+0.619]   [+0.674]   [+0.598]
[+0.067]   [+0.690]   [+0.973]   [+0.774]   [+0.379]   [+0.225]   [+0.109]   [+0.932]   [+0.902]   [+0.629]
[+0.949]   [+0.652]   [+0.550]   [+0.132]   [+0.178]   [+0.846]   [+0.966]   [+0.973]   [+0.817]   [+0.579]

[11]:
# Calculate a set of parameters# Calculate a set of parameters
P = S.parameters.degree_polarization(verbose=True)
I = S.parameters.intensity(verbose=True)
azimuth = S.parameters.azimuth(verbose=True)
ellipticity = S.parameters.ellipticity_angle(verbose=True)
The degree of polarization of Random polarization is:
[0.63762812 0.55837176 0.84697073 0.4626651  0.24694762 0.5224137
 0.80099099 0.85597778 0.80317173 0.60228119]
The mean value is 0.6337418716831728 +- 0.18694668753460006

The intensity of Random polarization is (a.u.):
[1.73205081 1.73205081 1.73205081 1.73205081 1.73205081 1.73205081
 1.73205081 1.73205081 1.73205081 1.73205081]
The mean value is 1.7320508075688772 +- 0.0

The azimuth of Random polarization is (deg):
[ 3.40989654 37.46278842 22.82597776 39.23257653 38.59205754 22.29215954
  3.14242587 28.19732688 26.62926903 23.23188297]
The mean value is 24.501636108744115 +- 12.296732222924637

The ellipticity angle of Random polarization is (deg):
[29.61105375 21.18829465 11.00851636  4.73496352 12.30511127 34.61733771
 22.07461622 20.50166121 17.97886053 16.86008132]
The mean value is 19.088049654937674 +- 8.310918395121357

[12]:
# Calculate some other parameters
dlp = S.parameters.degree_linear_polarization(verbose=True)
dcp = S.parameters.degree_circular_polarization(verbose=True)
The degree of linear polarization of Random polarization is:
[0.32628158 0.41248641 0.78520323 0.45635994 0.22451534 0.18521715
 0.57473351 0.64598207 0.65012776 0.50095269]
The mean value is 0.47618596856749357 +- 0.1843437348289973

The degree of circular polarization of Random polarization is:
[0.54782292 0.3763429  0.31751426 0.07612225 0.10283961 0.48847793
 0.55791393 0.56160941 0.47161289 0.33434867]
The mean value is 0.3834604771096698 +- 0.16970620839618467

The checks subclass has some methods that allow analyzing the Stokes vectors to see if some conditions are met.

[15]:
cond = E.checks.is_linear(verbose=True)
Random polarization is linearly polarized:
[False False False False False False False False False False]
The mean value is 0.0 +- 0.0

[17]:
S.M[0,0] = 0  # This forces the first Stokes vector to not be physically realizable
cond = S.checks.is_physical(verbose=True)
Random polarization is physically realizable:
[False  True  True  True  True  True  True  True  True  True]
The mean value is 0.9 +- 0.30000000000000004

d:\codigo_ucm\py_pol\py_pol\stokes.py:3062: RuntimeWarning: invalid value encountered in less_equal
  DOP = self.parent.parameters.degree_polarization(out_number=False)

5.2.1.2. Analysis of optical elements

5.2.1.2.1. Theory of Jones matrix objects

Pure optical elements (elements that do not depolarize totally polarized light states) can be described by a Jones matrix, a 2x2 matrix of complex numbers:

\(J=\left[\begin{array}{cc} J_{00} & J_{01}\\ J_{10} & J_{11} \end{array}\right]\).

The effect of an optical element upon an incident light wave is calculated by multiplying the Jones matrix of the optical object by the Jones vector of the light wave:

\(E_{out}=J\,E_{in}\).

There are three things that an optical object can do to a light wave in Jones formalism:

  1. Diattenuate (vary the electric field amplitude).
  2. Retard (vary the delay between electric field components).
  3. Increase the global phase.

The first two phenomena define two types of optical elements: diattenuator and retarders. Both diattenuators and retarders may increase the global phase of light waves.

Diattenuators are element that vary the electric field amplitude of the incident wave. Usually, this variation is different on both electric field components. These variations are described by the maximum and minimum field transmissions (\(p_1\) and \(p_2\) respectively). Alternatively, intensity transmissions can be used: \(T_{max}=p_1^2\) and \(T_{min}=p2^2\). Passive diattenuators have both \(T_{i}\leq1\), while active diattenuators have one or both \(T_{i}>1\). The last ones are usually called amplifiers. Diattenuators are often called polarizers (it will be explained for Mueller formalism) and usually have \(p_{1}\simeq1\) and \(p_{2}\simeq0\).

Retarders introduce a phase delay between electric field components called retardance (\(\Delta\)). This allows changing from linear to elliptical polarization. Retardance is between 0º and 180º, as different values are equivalent to a retardance between those values and/or a rotation. Special cases of retarders are quarter and half-waveplates, which present a retardance of 90º and 180º respectively.

Every Jones matrix due to being a 2x2 matrix, has at least two eigenvectors, often referred as eigenstates. If those eigenstates are orthogonal, the optical element is referred as homogeneous. The eigenvalues of a diattenuator are \(p_1e^{i\varphi}\) and \(p_2e^{i\varphi}\). The eigenstate associated to \(p_1\) is called the transmission axis and the eigenstate associated to \(p_2\) the extinction axis (due to the usual values for polarizers). In the case of retarders, the two eigenvalues are \(e^{i\varphi}\) and \(e^{i(\varphi + \Delta}\). The eigenstate associated with those eigenvalues are called the fast and slow axes respectively, due to the difference in phase.

Independently of the optical element, its eigenstates are usually characterized using two angles: the characteristic angles or azimuth and ellipticity. The reason is that, if a Jones vector is an eigenvector of \(J\), it remains an eigenvector even if its intensity or global phase is varied. If the optical element is homogeneous, then only one eigenstate is characterized, as the other is orthogonal to the given one. In the case of diattenuators and retarders, the given eigenstate is usually the transmission axis and the fast axis respectively.

The global phase introduced by the Jones matrix can be a difficult topic. First, this parameter is rarely measured, as most experiments only consider intensity and do not introduce interferences between light waves. Also, the global phase introduced by a Jones matrix may depend on the incident light wave. That renders difficult to define a good reference for global phase. We choose that reference to be when \(J_{00}\) is real and positive.

5.2.1.2.2. Examples of characterization of Jones matrices

Many parameters can be easily calculated from a Jones_matrix object through the parameters subclass.

[22]:
# Create a random Jones matrix
J = Jones_matrix('Random element')
M_real = np.random.rand(2, 2, 5)
M_imag = np.random.rand(2, 2, 5)
J.from_matrix(M=M_real+1j*M_imag)
print(J)
Random element =
[+0.210+0.431j +0.205+0.113j]   [+0.556+0.783j +0.282+0.635j]   [+0.702+0.701j +0.101+0.490j]   [+0.854+0.932j +0.235+0.163j]   [+0.643+0.736j +0.098+0.389j]
[+0.523+0.399j +0.995+0.051j]   [+0.855+0.501j +0.146+0.668j]   [+0.164+0.184j +0.214+0.386j]   [+0.967+0.451j +0.548+0.450j]   [+0.922+0.079j +0.328+0.732j]

[24]:
# Calculate the transmission and retardance of the random eleemnt
trans = J.parameters.transmissions(kind='all', verbose=True)
ret = J.parameters.retardance(verbose=True)
The intensity transmissions of Random element are:
  Maximum (int.)
[1.64695644 2.79459313 1.41513167 3.1924615  2.50762893]
  Minimum (int.)
[0.06341533 0.06179514 0.07474705 0.12867671 0.1077289 ]
The mean value of param Maximum (int.) is 2.311354334237151 +- 0.6772049792862028
The mean value of param Minimum (int.) is 0.0872726272050373 +- 0.026487434381375564

The field transmissions of Random element are:
  Maximum (int.)
[1.28333801 1.67170366 1.18959307 1.78674606 1.58354947]
  Minimum (int.)
[0.251824   0.24858629 0.27339907 0.35871537 0.32822082]
The mean value of param Maximum (int.) is 1.502986054752848 +- 0.2288826193829923
The mean value of param Minimum (int.) is 0.2921491068198357 +- 0.04383522087784595

The retardance of Random element is (deg.):
[48.97269025 98.29319062 12.22748499 30.01450328 42.63314305]
The mean value is 46.42820243893986 +- 28.809555663155344

d:\codigo_ucm\py_pol\py_pol\jones_matrix.py:2446: ComplexWarning: Casting complex values to real discards the imaginary part
  R[cond1] = 2 * np.arccos(np.sqrt(num / den) * co)

The checks subclass also includes some interesting methods to calculate if an optical element fulfills some conditions. For example, we can calculate if an element is an homogeneous diattenuator:

[25]:
cond = J.checks.is_diattenuator(verbose=True)
Random element is an homogeneous diattenuator:
[False False False False False]
The mean value is 0.0 +- 0.0

Homogeneous diattenuators and retarders are well understood. They are characterized by the transmissions (diattenuators) and retardance (retarders), plus the transmission/fast eigenstate (as the other one is perpendicular). The analysis subclass have two methods to extract those parameters from an homogeneous diattenuator or retarder.

For example, we can create the most general diattenuator and compare the calculations with the original values:

[47]:
# Create random values
N = 1000
p1 = np.random.rand(N) * 0.5 + 0.5
p2 = np.random.rand(N) * 0.5
alpha = np.random.rand(N) * 90 * degrees
delay = np.random.rand(N) * 360 * degrees

# Create the py_pol object
J = Jones_matrix('General random diattenuator')
J.diattenuator_charac_angles(p1=p1, p2=p2, alpha=alpha, delay=delay)

# Analyze it
trans, angles = J.analysis.diattenuator(angles='charac', transmissions='field')

# Compare the results
print('Error in p1:')
error = np.linalg.norm(p1 - trans[0])
print(error)
print('Error in p2:')
error = np.linalg.norm(p2 - trans[1])
print(error)
print('Error in alpha:')
error = np.linalg.norm(alpha - angles[0])/degrees
print(error)
print('Error in delay')
error = np.linalg.norm(delay - angles[1])/degrees
print(error)
Error in p1:
3.575193960459936e-15
Error in p2:
1.2557344989130534e-14
Error in alpha:
4.377375969826691e-13
Error in delay
4.985750427120611e-13

Same for the most general homogeneous retarder with randomized values.

[11]:
# Create random values
N = 1000
R = np.random.rand(N) * 180 * degrees
alpha = np.random.rand(N) * 90 * degrees
delay = np.random.rand(N) * 360 * degrees

# Create the py_pol object
J = Jones_matrix('General random diattenuator')
J.retarder_charac_angles(R=R, alpha=alpha, delay=delay)

# Analyze it
R_calc, angles = J.analysis.retarder(angles='charac')

# Compare the results
print('Error in retardance:')
error = np.linalg.norm(R - R_calc)/degrees
print(error)
print('Error in alpha:')
error = np.linalg.norm(alpha - angles[0])/degrees
print(error)
print('Error in delay')
error = np.linalg.norm(delay - angles[1])/degrees
print(error)
Error in retardance:
8.913732066593084e-12
Error in alpha:
1.739757186343351e-09
Error in delay
2.711462214533282e-13
d:\codigo_ucm\py_pol\py_pol\jones_matrix.py:2446: ComplexWarning: Casting complex values to real discards the imaginary part
  R[cond1] = 2 * np.arccos(np.sqrt(num / den) * co)

The analysis of homogeneous diattenuators and retarders is very useful and easy to understand. However, not every optical element is an homogeneous diattenuator or retarder. Some of them may be inhomogeneous diattenuators or retarders, easy to understand but not so much to identify. Even more common are optical elements that show both diattenuation and retardance. We provide an easy method to analyze these matrices taking advantage from the polar decomposition theorem. This theorem states that every Jones matrix can be decomposed in the product of an homogeneous diattenuator \(J_D\) and an homogeneous retarder \(J_R\). There are two possible combinations:

  1. \(J=J_D*J_R\)
  2. \(J=J_R*J_D\)

Then, each element can be easily analyzed separately. This means that Jones matrix is decomposed in seven parameters: \(p_1\) and \(p_2\) from \(J_D\), \(\phi_D\) and \(\chi_D\) (or \(\alpha_D\) and \(\delta_D\)) of the transmission axis of the diattenuator, and \(\Delta\), \(\phi_R\) and \(\chi_R\) (or \(\alpha_R\) and \(\delta_R\)) of the fast axis of the retarder, plus a global phase phase factor.

Here we present an example of the decomposition and analysis of random matrices.

[13]:
# Create random Jones matrices
M_real = np.random.rand(2,2,5)
M_imag = np.random.rand(2,2,5)

# Create the pypol object
J = Jones_matrix('Random element')
J.from_matrix(M=M_real + 1j*M_imag)

# Decompose the matrix and measure all the relevant aprameters
Jr, Jd, parameters = J.analysis.decompose_pure(verbose=True, all_info=True)

------------------------------------------------------
Polar decomposition of Random element as M = RP.

Analysis of Random element Diattenuator as polarizer:

- Transmissions of Random element Diattenuator are:
  Max. transmission
[2.31222555 2.17868416 2.93798912 3.40565529 2.94364259]
  Min. transmission
[0.03689747 0.02998905 0.09149645 0.23282748 0.0017845 ]
  p1
[1.52060039 1.47603664 1.71405633 1.84544176 1.71570469]
  p2
[0.19208714 0.17317347 0.3024838  0.482522   0.04224337]
The mean value of param Max. transmission is 2.755639340420053 +- 0.451798732850638
The mean value of param Min. transmission is 0.07859899000810314 +- 0.08240774087740922
The mean value of param p1 is 1.654367963003518 +- 0.13676981906708907
The mean value of param p2 is 0.23850195639484006 +- 0.14736284064830235

- Angles of Random element Diattenuator are:
  Alpha
[64.27653861 43.52943726 49.92039375 53.09474915 51.18469335]
  Delay
[ 12.23299094 356.7133992    0.59222081  42.93019956  13.20098798]
  Azimuth
[64.59802752 43.52701883 49.92065146 55.81474284 51.3471884 ]
  Ellipticity angle
[ 4.76902817 -1.64113345  0.29175343 20.42562493  6.4446046 ]
The mean value of param Alpha is 52.40116242268018 +- 6.7505131613387785
The mean value of param Delay is 85.13395969893591 +- 136.50843095527404
The mean value of param Azimuth is 53.041525811294676 +- 6.991136437843724
The mean value of param Ellipticity angle is 6.0579755366576915 +- 7.7558469944698105


Analysis of Random element Retarder as retarder:

- Retardance of Random element Retarder is:
[179.98294741 172.84269897 118.1761176   83.63765305 116.12427906]
The mean value is 134.1527392185979 +- 36.68616282010433

- Angles of Random element Retarder are:
  Alpha
[35.71619068 36.88159097 39.46679517 28.68533112 42.5317236 ]
  Delay
[338.11561768  16.39980999 337.94641839 176.09702366 358.96207944]
  Azimuth
[ 35.05001898  36.55651628  39.04203736 151.34489001  42.53132055]
  Ellipticity
[-10.34567023   7.86418204 -10.81131376   1.6431273   -0.51703504]
The mean value of param Alpha is 36.65632630836703 +- 4.623643411436292
The mean value of param Delay is 245.50418983253775 +- 132.13728200506344
The mean value of param Azimuth is 60.90495663588829 +- 45.29080180391635
The mean value of param Ellipticity is -2.433341937983976 +- 7.198946928846067

Random element decomposition mean square error:
[1.07854610e-15 1.08424519e-15 8.33129733e-16 8.17730320e-16
 9.30138993e-15]
The mean value is 2.62300825445496e-15 +- 3.341156399458237e-15

5.2.1.2.3. Theory of Mueller objects

All the theory of Jones matrices can be directly extrapolated to pure Mueller matrices. However, Mueller-Stokes formalism allows working with partially polarized light and optical elements which depolarize light. This allows defining a third basic optical element: the depolarizer. A depolarizer is an optical element that increases the depolarization degree of incoming light waves.

A Mueller matrix is a 4x4 matrix of real elements. Its 16 components are usually divided in blocks that allow describing its properties easily:

\(M=\left[\begin{array}{cccc} M_{00} & M_{01} & M_{02} & M_{03}\\ M_{10} & M_{11} & M_{12} & M_{13}\\ M_{20} & M_{21} & M_{22} & M_{23}\\ M_{30} & M_{31} & M_{32} & M_{33} \end{array}\right]=M\left[\begin{array}{cc} 1 & \overrightarrow{D}\\ \overrightarrow{P} & m \end{array}\right]=M_{00}\left[\begin{array}{cccc} 1 & D_{1} & D_{2} & D_{3}\\ P_{1} & m_{11} & m_{12} & m_{13}\\ P_{2} & m_{21} & m_{22} & m_{23}\\ P_{3} & m_{31} & m_{32} & m_{33} \end{array}\right]\).

This divides the Mueller matrix in four blocks:

  1. :math:`M_{00}`: Mean transmission coefficient. This number describes the mean transmission of the object.
  2. :math:`overrightarrow{D}`: Diattenuation vector. This 1x3 vector describes the properties of the object to reduce the intensity of the light that gets through it.
  3. :math:`overrightarrow{P}`: Polarizance vector. This 3x1 vector describes the properties of the object to transform depolarized light into polarized light.
  4. :math:`m`: Small matrix m. This 3x3 matrix describes the depolarization and retardance properties of the optical object.

These four blocks allow start to analyze de behavior of a Mueller matrix, as the three basic optical elements fulfill some conditions:

  1. Diattenuator:
    • \(M_{00}=\frac{p_{1}^{2}+p_{2}^{2}}{2}\).
    • \(\overrightarrow{D}=\overrightarrow{P}^{T}\).
    • \(m=m^T\) with \(det(m)=0\).
  2. Retarder:
    • \(M_{00}=1\).
    • \(P_{i}=D_{i}=0\).
    • \(det(m)=\pm1\).
  3. Depolarizer:
    • \(m=m^T\).

This also explains the reason why diattenuators are commonly referred as polarizers: due to the condition \(\overrightarrow{D}=\overrightarrow{P}^{T}\). This means that a diatenuator reduces the depolarization degree of light waves, behaving also as a polarizer.

5.2.1.2.4. Examples of characterization of Mueller matrices

Again, the parameters class includes many methods to characterize Mueller matrices.

[3]:
# Create optical elements. We start from Jones matrices because it is  easier to create physically realizable random matrices.
M_real = np.random.rand(2,2,5)
M_imag = np.random.rand(2,2,5)

# Create the pypol object
J = Jones_matrix('Random element')
J.from_matrix(M=M_real + 1j*M_imag)
M = Mueller('Random element')
M.from_Jones(J)
print(M)
Random element =
[+1.041 +0.976 +0.309 +0.177]   [+1.448 +0.362 +1.302 +0.391]   [+1.478 -0.439 +1.074 +0.860]   [+0.939 -0.242 +0.590 -0.136]   [+1.508 +0.756 +0.654 +0.378]
[-0.011 -0.017 -0.012 +0.050]   [-0.197 +0.146 -0.160 -0.334]   [+0.184 +0.104 +0.345 -0.061]   [-0.010 +0.507 +0.091 -0.438]   [+0.082 -0.242 -0.128 +1.031]
[+0.947 +0.884 +0.303 +0.164]   [+1.158 +0.182 +1.178 +0.200]   [+1.228 -0.269 +0.890 +0.862]   [+0.567 -0.110 +0.873 +0.067]   [+1.052 +0.967 +1.053 +0.441]
[-0.428 -0.418 -0.082 -0.068]   [+0.773 +0.443 +0.633 +0.348]   [-0.738 +0.457 -0.586 -0.303]   [-0.322 +0.496 -0.187 +0.528]   [-0.168 -0.842 +0.659 -0.129]

[4]:
# Calculate the transmissions and retardance of the random matrices
trans = M.parameters.transmissions(verbose=True)
The intensity transmissions of Random element are:
  Maximum (int.)
[2.0802189  2.85510391 2.92226298 1.59204482 2.57686893]
  Minimum (int.)
[0.00134622 0.04183691 0.03409886 0.28694948 0.43893157]
The mean value of param Maximum (int.) is 2.4052999100062467 +- 0.5032041110108076
The mean value of param Minimum (int.) is 0.16063260711030697 +- 0.1725697670100231

The checks subclass also includes some interesting methods to calculate if an optical element fulfills some conditions. For example, we can calculate if an element is pure (it must be, as it comes from a Jones matrix):

[6]:
cond = M.checks.is_pure(verbose=True)
Random element is pure (non-depolarizing):
[ True  True  True  True  True]
The mean value is 1.0 +- 0.0

Homogeneous diattenuators and retarders are well understood. They are characterized by the transmissions (diattenuators) and retardance (retarders), plus the transmission/fast eigenstate (as the other one is perpendicular). The analysis subclass have two methods to extract those parameters from an homogeneous diattenuator or retarder.

For example, we can create the most general diattenuator and compare the calculations with the original values:

[7]:
# Create random values
N = 1000
p1 = np.random.rand(N) * 0.5 + 0.5
p2 = np.random.rand(N) * 0.5
alpha = np.random.rand(N) * 90 * degrees
delay = np.random.rand(N) * 360 * degrees

# Create the py_pol object
M = Mueller('General random diattenuator')
M.diattenuator_charac_angles(p1=p1, p2=p2, alpha=alpha, delay=delay)

# Analyze it
trans, angles = M.analysis.diattenuator(angles='charac', transmissions='field')

# Compare the results
print('Error in p1:')
error = np.linalg.norm(p1 - trans[0])
print(error)
print('Error in p2:')
error = np.linalg.norm(p2 - trans[1])
print(error)
print('Error in alpha:')
error = np.linalg.norm(alpha - angles[0])/degrees
print(error)
print('Error in delay')
error = np.linalg.norm(delay - angles[1])/degrees
print(error)
Error in p1:
1.2008898127460164e-15
Error in p2:
8.076479830048999e-14
Error in alpha:
1.0848826826569258e-12
Error in delay
1.53233195374529e-08

Depolarizers are slightly harder to characterize. The most general depolarizer is easily understood using its division in blocks. First, a depolarizer may present diattenuation ($D=:nbsphinx-math:left\Vert `:nbsphinx-math:overrightarrow{D}`:nbsphinx-math:right\Vert `\ :math:) or polarizance (P=:nbsphinx-math:left`:nbsphinx-math:Vert `:nbsphinx-math:overrightarrow{P}`:nbsphinx-math:right\Vert `$). That may seem strange, but in some cases a depolarized can increase the polarization degree light (also, in some cases a non-depolarizing element may decrease the polarization degree of light). Second, the small m matrix has three 3x1 orthonormal eigenvectors :math:overrightarrow{v_{i}}`. Those eigenvectors can be transformed into six Stokes vectors in order to describe the principal states as:

\(S_{i}=\left[\begin{array}{c} 1\\ \overrightarrow{v_{i}} \end{array}\right]\).

\(S_{i+3}=\left[\begin{array}{c} 1\\ -\overrightarrow{v_{i}} \end{array}\right]\).

Its associated eigenvalues (which are lower than 1) are called its depolarization factors.

The principal states are not orthogonal in a polarization sense. Also, in general those states will not be eigenstates of the Mueller matrix of the depolarizer. As the last three states are easily calculated from the first three, only the first ones are usually calculated.

We can check this using a random depolarizer.

[136]:
# Create the random variables
N = 5
D = np.random.rand(N)
alphaD = np.random.rand(N) * 90 * degrees
delayD = np.random.rand(N) * 360 * degrees
Dv = np.array([D*np.cos(2*alphaD), D*np.sin(2*alphaD)*np.cos(delayD), D*np.sin(2*alphaD)*np.sin(delayD)])

P = np.random.rand(N)
alphaP = np.random.rand(N) * 90 * degrees
delayP = np.random.rand(N) * 360 * degrees
Pv = np.array([P*np.cos(2*alphaP), P*np.sin(2*alphaP)*np.cos(delayP), P*np.sin(2*alphaP)*np.sin(delayP)])

d1 = np.random.rand(N)
d2 = np.random.rand(N)
d3 = np.random.rand(N)
alpha1 = np.random.rand(N) * 45 * degrees # Alpha can go up to 90º, but then we could have a problem calculating the orthogonal principal states
alpha2 = 45*degrees  # If we can compare the results, S1, S2 and S3 3x1 vectors must be orthogonal
alpha3 = 45*degrees - alpha1
delay1 = np.random.rand(N) * 360 * degrees
delay2 = delay1 - 90*degrees
delay3 = delay1 + 180*degrees

# Create the pypol objects
S1, S2, S3 = create_Stokes(N=3)
S1.general_charac_angles(alpha=alpha1, delay=delay1)
S2.general_charac_angles(alpha=alpha2, delay=delay2)
S3.general_charac_angles(alpha=alpha3, delay=delay3)

M = Mueller('Rangom general depolarizer')
M.depolarizer_states(d=[d1, d2, d3], S=[S1, S2, S3], Pv=Pv, Dv=Dv)
print(M)

# Analyze the depolarizer
trans_D, trans_P, ang_D, ang_P, depolar, principal_states = M.analysis.depolarizer(angles='Charac', transmissions='Intensity', depolarization='Factors')
Rangom general depolarizer =
[+1.000 +0.671 +0.005 -0.060]   [+1.000 -0.000 +0.683 +0.174]   [+1.000 -0.243 -0.042 +0.653]   [+1.000 +0.305 -0.468 -0.575]   [+1.000 -0.040 -0.150 +0.019]
[+0.955 +0.579 -0.079 -0.063]   [-0.050 +0.507 -0.154 +0.091]   [-0.101 +0.713 +0.001 -0.019]   [-0.038 +0.184 +0.112 -0.049]   [-0.002 +0.522 -0.059 -0.034]
[+0.157 -0.079 +0.674 +0.312]   [+0.076 -0.154 +0.698 -0.229]   [+0.051 +0.001 +0.687 -0.000]   [-0.706 +0.112 +0.166 +0.007]   [+0.019 -0.059 +0.205 +0.016]
[+0.175 -0.063 +0.312 +0.529]   [+0.026 +0.091 -0.229 +0.445]   [+0.041 -0.019 -0.000 +0.689]   [-0.617 -0.049 +0.007 +0.179]   [+0.027 -0.034 +0.016 +0.187]

[137]:
print(d1, d2, d3, '\n', sep='\n')
print(depolar[0], depolar[1], depolar[2], '\n', sep='\n')
[0.94973259 0.91255888 0.67802625 0.29693391 0.20030754]
[0.28090059 0.30965405 0.68669381 0.18172246 0.17803357]
[0.55135005 0.4280079  0.7239018  0.0507721  0.53658826]


[0.94973259 0.4280079  0.7239018  0.29693391 0.53658826]
[0.55135005 0.91255888 0.67802625 0.0507721  0.20030754]
[0.28090059 0.30965405 0.68669381 0.18172246 0.17803357]


[138]:
# Diattenuation vector errors
Dcalc = (trans_D[0]-trans_D[1])/2
error = D-Dcalc
print('The error in the diattenuation is:')
print(np.linalg.norm(error))
error = alphaD-ang_D[0]
print('The error in the diattenuation alpha is:')
print(np.linalg.norm(error))
error = delayD-ang_D[1]
print('The error in the diattenuation delay is:')
print(np.linalg.norm(error), '\n')
The error in the diattenuation is:
1.6653345369377348e-16
The error in the diattenuation alpha is:
2.420669712248692e-16
The error in the diattenuation delay is:
3.198140942662673e-14

[139]:
# Polarizance vector errors
Pcalc = (trans_P[0]-trans_P[1])/2
error = P-Pcalc
print('The error in the polarizance is:')
print(np.linalg.norm(error))
error = alphaP-ang_P[0]
print('The error in the polarizance alpha is:')
print(np.linalg.norm(error))
error = delayP-ang_P[1]
print('The error in the polarizance delay is:')
print(np.linalg.norm(error), '\n')
The error in the polarizance is:
7.850462293418876e-17
The error in the polarizance alpha is:
2.5476231888929306e-16
The error in the polarizance delay is:
4.1910000110727263e-16

[140]:
# First depolarization factor / principal state errorserror1 = d1-depolar[0]
error1 = d1-depolar[0]
error2 = d1-depolar[1]
error3 = d1-depolar[2]
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3)]) # Eig algorithms dont give the same order we used, so we have to compare to all
print('The error in the first depolarization factor is:')
print(np.linalg.norm(error))
error1 = np.linalg.norm(S1.M - principal_states[0].M, axis=0)
error2 = np.linalg.norm(S1.M - principal_states[1].M, axis=0)
error3 = np.linalg.norm(S1.M - principal_states[2].M, axis=0)
S1.M[1:,:] = -S1.M[1:,:]
error4 = np.linalg.norm(S1.M - principal_states[0].M, axis=0)
error5 = np.linalg.norm(S1.M - principal_states[1].M, axis=0)
error6 = np.linalg.norm(S1.M - principal_states[2].M, axis=0)
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3), np.abs(error4), np.abs(error5), np.abs(error6)])
print('The error in the first principal state is:')
print(np.linalg.norm(error), '\n')
The error in the first depolarization factor is:
3.433175098891678e-16
The error in the first principal state is:
6.847141445191268e-15

[141]:
# Second depolarization factor / principal state errors
error1 = d2-depolar[0]
error2 = d2-depolar[1]
error3 = d2-depolar[2]
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3)])
print('The error in the second depolarization factor is:')
print(np.linalg.norm(error))
error1 = np.linalg.norm(S2.M - principal_states[0].M, axis=0)
error2 = np.linalg.norm(S2.M - principal_states[1].M, axis=0)
error3 = np.linalg.norm(S2.M - principal_states[2].M, axis=0)
S2.M[1:,:] = -S2.M[1:,:]
error4 = np.linalg.norm(S2.M - principal_states[0].M, axis=0)
error5 = np.linalg.norm(S2.M - principal_states[1].M, axis=0)
error6 = np.linalg.norm(S2.M - principal_states[2].M, axis=0)
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3), np.abs(error4), np.abs(error5), np.abs(error6)])
print('The error in the second principal state is:')
print(np.linalg.norm(error), '\n')
The error in the second depolarization factor is:
2.3714374201337736e-16
The error in the second principal state is:
1.743906609776931e-14

[142]:
# Third depolarization factor / principal state errors
error1 = d3-depolar[0]
error2 = d3-depolar[1]
error3 = d3-depolar[2]
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3)])
print('The error in the third depolarization factor is:')
print(np.linalg.norm(error))
error1 = np.linalg.norm(S3.M - principal_states[0].M, axis=0)
error2 = np.linalg.norm(S3.M - principal_states[1].M, axis=0)
error3 = np.linalg.norm(S3.M - principal_states[2].M, axis=0)
S3.M[1:,:] = -S3.M[1:,:]
error4 = np.linalg.norm(S3.M - principal_states[0].M, axis=0)
error5 = np.linalg.norm(S3.M - principal_states[1].M, axis=0)
error6 = np.linalg.norm(S3.M - principal_states[2].M, axis=0)
error = np.minimum.reduce([np.abs(error1), np.abs(error2), np.abs(error3), np.abs(error4), np.abs(error5), np.abs(error6)])
print('The error in the third principal state is:')
print(np.linalg.norm(error))
The error in the third depolarization factor is:
3.3306690738754696e-16
The error in the third principal state is:
4.443083001703408e-15

Again, most optical elements do not belong to one of the three basic groups of basic elements, but are a mix of them. In the case of non-pure optical elements, the polar decomposition theorem states that every Mueller matrix can be decomposed in the product of a pure homogeneous diattenuator \(M_D\), a pure homogeneous retarder \(M_R\) and a depolarizer \(M_P\):

\(M = M_R*M_P*M_D\).

There are six possible combinations, altering the order of the elements.

This decomposition allows analyzing the three elements separately. The method decompose_polar of analysis class calculates the polar decomposition of Mueller matrices. If only pure matrices are analyzed, use decompose_pure instead. For example, if we build the most general element:

[51]:
# Create the diattenuator
N = 5
p1 = np.random.rand(N)
p2 = np.random.rand(N)
alpha = np.random.rand(N) * 90*degrees
delay = np.random.rand(N) * 360*degrees
Md = Mueller('Diattenuator')
Md.diattenuator_charac_angles(p1=p1, p2=p2, alpha=alpha, delay=delay)

# Create the retarder
R = np.random.rand(N) * 180*degrees
alpha = np.random.rand(N) * 90*degrees
delay = np.random.rand(N) * 360*degrees
Mr = Mueller('Retarder')
Mr.retarder_charac_angles(R=R, alpha=alpha, delay=delay)

# Create the depolarizer
P = np.random.rand(N)
alphaP = np.random.rand(N) * 90 * degrees
delayP = np.random.rand(N) * 360 * degrees
Pv = np.array([P*np.cos(2*alphaP), P*np.sin(2*alphaP)*np.cos(delayP), P*np.sin(2*alphaP)*np.sin(delayP)])
d1 = np.random.rand(N)
d2 = np.random.rand(N)
d3 = np.random.rand(N)
alpha1 = np.random.rand(N) * 90 * degrees
alpha2 = np.random.rand(N) * 90 * degrees
alpha3 = np.random.rand(N) * 90 * degrees
delay1 = np.random.rand(N) * 360 * degrees
delay2 = np.random.rand(N) * 90 * degrees
delay3 = np.random.rand(N) * 90 * degrees
S1, S2, S3 = create_Stokes(N=3)
S1.general_charac_angles(alpha=alpha1, delay=delay1)
S2.general_charac_angles(alpha=alpha2, delay=delay2)
S3.general_charac_angles(alpha=alpha3, delay=delay3)
Mp = Mueller('Depolarizer')
Mp.depolarizer_states(d=[d1, d2, d3], S=[S1, S2, S3], Pv=Pv)

# Calculate the product
M = Mp * Mr * Md
M.name = 'General matrix'
print(M)
General matrix =
[+0.698 +0.104 +0.013 +0.152]   [+0.263 -0.016 +0.026 -0.021]   [+0.119 +0.042 -0.005 +0.021]   [+0.060 -0.013 -0.027 -0.001]   [+0.146 +0.078 -0.068 -0.103]
[-0.650 -0.676 -0.875 +0.433]   [+0.113 +0.203 -0.055 -0.090]   [-0.029 -0.057 +0.045 -0.044]   [-0.008 +0.022 -0.017 -0.012]   [-0.073 -0.034 +0.026 +0.061]
[+0.021 -0.047 +0.406 -0.358]   [+0.055 +0.009 +0.097 -0.019]   [+0.031 +0.056 +0.047 +0.083]   [-0.009 -0.019 +0.015 +0.003]   [-0.063 -0.030 +0.028 +0.047]
[-0.161 +0.160 +0.321 -0.270]   [+0.034 -0.117 +0.153 +0.048]   [+0.037 +0.097 -0.017 +0.062]   [+0.019 -0.032 -0.011 -0.023]   [+0.009 +0.006 -0.005 -0.005]

[56]:
Mr, Md, Mp = M.analysis.decompose_polar(verbose=True)

------------------------------------------------------
Polar decomposition of General matrix as M = .

Analysis of Diattenuator of General matrix as diattenuator:

- Transmissions of Diattenuator of General matrix are:
  Max. transmission
[0.88198152 0.30022504 0.16590048 0.08914879 0.29243019]
  Min. transmission
[5.13179191e-01 2.25205746e-01 7.11392932e-02 2.99717743e-02
 4.59311831e-04]
  p1
[0.93913871 0.54792795 0.40730882 0.29857794 0.54076814]
  p2
[0.71636526 0.47455847 0.2667195  0.17312358 0.02143156]
The mean value of param Max. transmission is 0.34593720239581227 +- 0.27951730727596963
The mean value of param Min. transmission is 0.1679910631739822 +- 0.18916915204292745
The mean value of param p1 is 0.5467443149886063 +- 0.21681295261919178
The mean value of param p2 is 0.3304396766952467 +- 0.24248852187170236

- Angles of Diattenuator of General matrix are:
  Alpha
[27.84607161 58.04488939 13.84981514 57.53645919 28.88866877]
  Delay
[ 85.0078597  321.07323849 104.32877719 182.56334098 236.40447466]
  Azimuth
[  3.63378343  61.09400437 176.2984921  122.45252888 159.3600951 ]
  Ellipticity angle
[ 27.68745459 -17.17698052  13.383905    -1.16082806 -22.40157465]
The mean value of param Alpha is 37.23318082239673 +- 17.606139936486752
The mean value of param Delay is 185.87553820419188 +- 86.79484435277902
The mean value of param Azimuth is 104.56778077503436 +- 64.10147880568259
The mean value of param Ellipticity angle is 0.06639527144997573 +- 18.675806499471012


Analysis of Retarder of General matrix as retarder:

- Retardance of Retarder of General matrix is:
[170.92392209  49.99121033 104.18931098 154.67147499  76.74592979]
The mean value is 111.30436963607733 +- 45.69334785299364

- Angles of Retarder of General matrix are:
  Alpha
[57.84385169 88.76445186 32.42385232 19.59367553 40.47534568]
  Delay
[343.73653633 127.82768821  24.72208126 202.23867174 224.86760839]
  Azimuth
[ 58.3066556   90.75804107  31.33220352 161.4813861  141.3325167 ]
  Ellipticity angle
[ -7.30910264   0.97579464  11.12232958  -6.91779386 -22.08103099]
The mean value of param Alpha is 47.820235416254064 +- 23.935899584207476
The mean value of param Delay is 184.67851718720647 +- 105.86883741774207
The mean value of param Azimuth is 96.64216059779035 +- 48.930516839740804
The mean value of param Ellipticity angle is -4.841960654879352 +- 10.920496863130417


Analysis of Depolarizer of General matrix as depolarizer:
- Depolarization index of Depolarizer of General matrix is:
[       nan 0.63779108 0.38840727 0.77017126 0.63303606]
The mean value is nan +- nan

- First depolarization factor of Depolarizer of General matrix is:
[2.00466434 1.13485499 1.43749032 0.03901074 1.23742444]
The mean value is 1.1706889647488454 +- 0.6408012474870327

The alpha of First principal state is (deg):
[75.60609681 70.0309573  57.81949517 29.11226629  9.88341614]
The mean value is 48.49044634139649 +- 25.10896217603074

The delay of First principal state is (deg):
[ 42.82915408  79.4028255   49.97008913 344.53020389  20.72726024]
The mean value is 107.49190656698616 +- 119.99523804284395

The azimuth of First principal state is (deg):
[79.0258232  85.62332729 63.36544348 28.63519594  9.2889677 ]
The mean value is 53.18775152168685 +- 29.50657263363871

The ellipticity angle of First principal state is (deg):
[ 9.55480462 19.56235539 21.82755508 -6.55297175  3.43720101]
The mean value is 9.56578887119095 +- 10.4657193387497

- Second depolarization factor of Depolarizer of General matrix is:
[0.44871276 0.47482309 0.15969467 0.62848492 0.24025284]
The mean value is 0.39039365727810144 +- 0.16910422117889026

The alpha of Second principal state is (deg):
[34.13047619 60.35743778 23.17816768 24.71585255 35.16369238]
The mean value is 35.509125315776934 +- 13.326709141628355

The delay of Second principal state is (deg):
[359.35355611 214.60405719 112.72777955 106.5575901  194.90213788]
The mean value is 197.62902416633068 +- 91.59982459282895

The azimuth of Second principal state is (deg):
[ 34.12984885 117.08919412 168.97375487 170.7946478  145.15111827]
The mean value is 127.22771278268712 +- 50.46198599171677

The ellipticity angle of Second principal state is (deg):
[ -0.30023365 -14.61237074  20.9354951   23.36502129  -7.00698018]
The mean value is 4.476186365617659 +- 15.144287657272631

- Third depolarization factor of Depolarizer of General matrix is:
[0.01020537 0.03828233 0.66805179 0.84294551 0.00173165]
The mean value is 0.31224332974003594 +- 0.3663177663524229

The alpha of Third principal state is (deg):
[36.03739245 56.44250227 62.72633067 61.59735072 45.92607924]
The mean value is 52.54593107031307 +- 10.169624245433413

The delay of Third principal state is (deg):
[ 96.76436491 319.12759616 159.95373118  50.62251875 105.56455357]
The mean value is 146.40655291529325 +- 93.08392101591284

The azimuth of Third principal state is (deg):
[169.9960686   59.5855539  116.41952122  67.94063631 131.56402011]
The mean value is 109.1011600280975 +- 41.01783111508235

The ellipticity angle of Third principal state is (deg):
[ 35.44011083 -18.53782158   8.10700669  20.15202588  37.16416867]
The mean value is 16.465098099476872 +- 20.480030006449336

- Depolarizer of General matrix has no diattenuation.
- Transmissions of Depolarizer of General matrix from polarizance are:
  Max. transmission
[1.9983297  1.51463509 1.09615282 1.33680321 1.45700371]
  Min. transmission
[0.0016703  0.48536491 0.90384718 0.66319679 0.54299629]
  p1
[1.4136229  1.23070512 1.04697317 1.15620206 1.20706409]
  p2
[0.04086927 0.69668136 0.95070878 0.81436895 0.73688282]
The mean value of param Max. transmission is 1.4805849044509007 +- 0.2960528227690688
The mean value of param Min. transmission is 0.5194150955490994 +- 0.29605282276906886
The mean value of param p1 is 1.2109134669351374 +- 0.119471670474747
The mean value of param p2 is 0.6479022362064927 +- 0.31565453880425265

- Angles of Depolarizer of General matrix from diattenuation are:
  Alpha
[45. 45. 45. 45. 45.]
  Delay
[0. 0. 0. 0. 0.]
  Azimuth
[45. 45. 45. 45. 45.]
  Ellipticity angle
[0. 0. 0. 0. 0.]
The mean value of param Alpha is 45.0 +- 0.0
The mean value of param Delay is 0.0 +- 0.0
The mean value of param Azimuth is 45.0 +- 0.0
The mean value of param Ellipticity angle is 0.0 +- 0.0

General matrix decomposition mean square error:
[0.16008588 0.1076687  0.12040788 0.12280425 0.1216883 ]
The mean value is 0.12653099945189955 +- 0.017643974691655174

------------------------------------------------------

d:\codigo_ucm\py_pol\py_pol\mueller.py:3757: RuntimeWarning: invalid value encountered in sqrt
  DI = sqrt(1. - PP**2)