
    \hQ                     z   S r / SQrSSKJr  SSKJrJr  SSKJr  SSK	J
r
Jr  SSKJr  SSKJr  SS	KJrJr  SS
KJr  SSKJr   " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rS%S jr S r!S  r"S! r#\#r$S" r%S# r&g$)&a  
Gaussian optics.

The module implements:

- Ray transfer matrices for geometrical and gaussian optics.

  See RayTransferMatrix, GeometricRay and BeamParameter

- Conjugation relations for geometrical and gaussian optics.

  See geometric_conj*, gauss_conj and conjugate_gauss_beams

The conventions for the distances are as follows:

focal distance
    positive for convergent lenses
object distance
    positive for real objects
image distance
    positive for real images
)RayTransferMatrix	FreeSpaceFlatRefractionCurvedRefraction
FlatMirrorCurvedMirrorThinLensGeometricRayBeamParameterwaist2rayleighrayleigh2waistgeometric_conj_abgeometric_conj_afgeometric_conj_bfgaussian_conjconjugate_gauss_beams    )Expr)Ipi)sympify)imre)sqrt)atan2)MatrixMutableDenseMatrix)together)
filldedentc                   d    \ rS rSrSrS rS r\S 5       r\S 5       r	\S 5       r
\S 5       rS	rg
)r   ;   aB  
Base class for a Ray Transfer Matrix.

It should be used if there is not already a more specific subclass mentioned
in See Also.

Parameters
==========

parameters :
    A, B, C and D or 2x2 matrix (Matrix(2, 2, [A, B, C, D]))

Examples
========

>>> from sympy.physics.optics import RayTransferMatrix, ThinLens
>>> from sympy import Symbol, Matrix

>>> mat = RayTransferMatrix(1, 2, 3, 4)
>>> mat
Matrix([
[1, 2],
[3, 4]])

>>> RayTransferMatrix(Matrix([[1, 2], [3, 4]]))
Matrix([
[1, 2],
[3, 4]])

>>> mat.A
1

>>> f = Symbol('f')
>>> lens = ThinLens(f)
>>> lens
Matrix([
[   1, 0],
[-1/f, 1]])

>>> lens.C
-1/f

See Also
========

GeometricRay, BeamParameter,
FreeSpace, FlatRefraction, CurvedRefraction,
FlatMirror, CurvedMirror, ThinLens

References
==========

.. [1] https://en.wikipedia.org/wiki/Ray_transfer_matrix_analysis
c                 6   [        U5      S:X  a  US   US   4US   US   44nO`[        U5      S:X  a1  [        US   [        5      (       a  US   R                  S:X  a  US   nO [	        [        S[        U5      -  5      5      e[        R                  " X5      $ )N   r            )r$   r$   z`
                Expecting 2x2 Matrix or the 4 elements of
                the Matrix but got %slen
isinstancer   shape
ValueErrorr   str__new__clsargstemps      U/var/www/auris/envauris/lib/python3.13/site-packages/sympy/physics/optics/gaussopt.pyr,   RayTransferMatrix.__new__s   s    t9>!Wd1g&a$q'(:;DY!^47F++GMMV+7DZ ))+.t9)5 6 7 7 ~~c((    c           	         [        U[        5      (       a   [        [        U 5      [        U5      -  5      $ [        U[        5      (       a   [        [        U 5      [        U5      -  5      $ [        U[        5      (       au  [        U 5      [        UR
                  4S45      -  nUS   US   -  R                  SS9n[	        UR                  [        [        U5      5      [        [        U5      5      S9$ [        R                  " X5      $ )Nr#   r   r#   T)complex)z_r)r(   r   r   r	   r
   qexpandwavelenr   r   r   __mul__)selfotherr0   r8   s       r1   r;   RayTransferMatrix.__mul__   s    e.//$VD\&-%?@@|,,tVE] :;;}--$<
D'9 ::Daa(((6A !)"Q%%-be_6 6 >>$..r3   c                     U S   $ )z
The A parameter of the Matrix.

Examples
========

>>> from sympy.physics.optics import RayTransferMatrix
>>> mat = RayTransferMatrix(1, 2, 3, 4)
>>> mat.A
1
)r   r    r<   s    r1   ARayTransferMatrix.A        Dzr3   c                     U S   $ )z
The B parameter of the Matrix.

Examples
========

>>> from sympy.physics.optics import RayTransferMatrix
>>> mat = RayTransferMatrix(1, 2, 3, 4)
>>> mat.B
2
)r   r#   r@   rA   s    r1   BRayTransferMatrix.B   rD   r3   c                     U S   $ )z
The C parameter of the Matrix.

Examples
========

>>> from sympy.physics.optics import RayTransferMatrix
>>> mat = RayTransferMatrix(1, 2, 3, 4)
>>> mat.C
3
)r#   r   r@   rA   s    r1   CRayTransferMatrix.C   rD   r3   c                     U S   $ )z
The D parameter of the Matrix.

Examples
========

>>> from sympy.physics.optics import RayTransferMatrix
>>> mat = RayTransferMatrix(1, 2, 3, 4)
>>> mat.D
4
)r#   r#   r@   rA   s    r1   DRayTransferMatrix.D   rD   r3   r@   N)__name__
__module____qualname____firstlineno____doc__r,   r;   propertyrB   rF   rI   rL   __static_attributes__r@   r3   r1   r   r   ;   sb    5n)/        r3   r   c                       \ rS rSrSrS rSrg)r      a  
Ray Transfer Matrix for free space.

Parameters
==========

distance

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import FreeSpace
>>> from sympy import symbols
>>> d = symbols('d')
>>> FreeSpace(d)
Matrix([
[1, d],
[0, 1]])
c                 4    [         R                  U SUSS5      $ Nr#   r   r   r,   )r.   ds     r1   r,   FreeSpace.__new__        ((aAq99r3   r@   NrN   rO   rP   rQ   rR   r,   rT   r@   r3   r1   r   r      s    0:r3   r   c                       \ rS rSrSrS rSrg)r      ax  
Ray Transfer Matrix for refraction.

Parameters
==========

n1 :
    Refractive index of one medium.
n2 :
    Refractive index of other medium.

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import FlatRefraction
>>> from sympy import symbols
>>> n1, n2 = symbols('n1 n2')
>>> FlatRefraction(n1, n2)
Matrix([
[1,     0],
[0, n1/n2]])
c                 ^    [        [        X45      u  p[        R                  U SSSX-  5      $ rX   mapr   r   r,   )r.   n1n2s      r1   r,   FlatRefraction.__new__  s-    Wrh' ((aAru==r3   r@   Nr]   r@   r3   r1   r   r      s    6>r3   r   c                       \ rS rSrSrS rSrg)r   i
  a  
Ray Transfer Matrix for refraction on curved interface.

Parameters
==========

R :
    Radius of curvature (positive for concave).
n1 :
    Refractive index of one medium.
n2 :
    Refractive index of other medium.

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import CurvedRefraction
>>> from sympy import symbols
>>> R, n1, n2 = symbols('R n1 n2')
>>> CurvedRefraction(R, n1, n2)
Matrix([
[               1,     0],
[(n1 - n2)/(R*n2), n1/n2]])
c                 r    [        [        XU45      u  pn[        R                  U SSX#-
  U-  U-  X#-  5      $ rX   ra   )r.   Rrc   rd   s       r1   r,   CurvedRefraction.__new__(  s;    !-	r ((aRWaKNBEJJr3   r@   Nr]   r@   r3   r1   r   r   
  s    :Kr3   r   c                       \ rS rSrSrS rSrg)r   i-  z
Ray Transfer Matrix for reflection.

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import FlatMirror
>>> FlatMirror()
Matrix([
[1, 0],
[0, 1]])
c                 4    [         R                  U SSSS5      $ rX   rY   )r.   s    r1   r,   FlatMirror.__new__?  r\   r3   r@   Nr]   r@   r3   r1   r   r   -  s    ":r3   r   c                       \ rS rSrSrS rSrg)r   iC  aS  
Ray Transfer Matrix for reflection from curved surface.

Parameters
==========

R : radius of curvature (positive for concave)

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import CurvedMirror
>>> from sympy import symbols
>>> R = symbols('R')
>>> CurvedMirror(R)
Matrix([
[   1, 0],
[-2/R, 1]])
c                 P    [        U5      n[        R                  U SSSU-  S5      $ )Nr#   r   r   r   r,   )r.   rh   s     r1   r,   CurvedMirror.__new__\  (    AJ ((aBqD!<<r3   r@   Nr]   r@   r3   r1   r   r   C  s    0=r3   r   c                       \ rS rSrSrS rSrg)r   ia  a%  
Ray Transfer Matrix for a thin lens.

Parameters
==========

f :
    The focal distance.

See Also
========

RayTransferMatrix

Examples
========

>>> from sympy.physics.optics import ThinLens
>>> from sympy import symbols
>>> f = symbols('f')
>>> ThinLens(f)
Matrix([
[   1, 0],
[-1/f, 1]])
c                 P    [        U5      n[        R                  U SSSU-  S5      $ )Nr#   r   rp   )r.   fs     r1   r,   ThinLens.__new__{  rr   r3   r@   Nr]   r@   r3   r1   r   r   a  s    2=r3   r   c                   >    \ rS rSrSrS r\S 5       r\S 5       rSr	g)r	   i  aV  
Representation for a geometric ray in the Ray Transfer Matrix formalism.

Parameters
==========

h : height, and
angle : angle, or
matrix : a 2x1 matrix (Matrix(2, 1, [height, angle]))

Examples
========

>>> from sympy.physics.optics import GeometricRay, FreeSpace
>>> from sympy import symbols, Matrix
>>> d, h, angle = symbols('d, h, angle')

>>> GeometricRay(h, angle)
Matrix([
[    h],
[angle]])

>>> FreeSpace(d)*GeometricRay(h, angle)
Matrix([
[angle*d + h],
[      angle]])

>>> GeometricRay( Matrix( ((h,), (angle,)) ) )
Matrix([
[    h],
[angle]])

See Also
========

RayTransferMatrix

c                 &   [        U5      S:X  a1  [        US   [        5      (       a  US   R                  S:X  a  US   nO<[        U5      S:X  a  US   4US   44nO [	        [        S[        U5      -  5      5      e[        R                  " X5      $ )Nr#   r   )r$   r#   r$   z`
                Expecting 2x1 Matrix or the 2 elements of
                the Matrix but got %sr&   r-   s      r1   r,   GeometricRay.__new__  s    t9>ja&99GMMV+7DY!^!WJa
+DZ ))+.t9)5 6 7 7 ~~c((r3   c                     U S   $ )z
The distance from the optical axis.

Examples
========

>>> from sympy.physics.optics import GeometricRay
>>> from sympy import symbols
>>> h, angle = symbols('h, angle')
>>> gRay = GeometricRay(h, angle)
>>> gRay.height
h
r   r@   rA   s    r1   heightGeometricRay.height       Awr3   c                     U S   $ )z
The angle with the optical axis.

Examples
========

>>> from sympy.physics.optics import GeometricRay
>>> from sympy import symbols
>>> h, angle = symbols('h, angle')
>>> gRay = GeometricRay(h, angle)
>>> gRay.angle
angle
r#   r@   rA   s    r1   angleGeometricRay.angle  r~   r3   r@   N)
rN   rO   rP   rQ   rR   r,   rS   r|   r   rT   r@   r3   r1   r	   r	     s5    %N
)     r3   r	   c                       \ rS rSrSrSS jr\S 5       r\S 5       r\S 5       r	\S 5       r
\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       rSrg)r
   i  a&  
Representation for a gaussian ray in the Ray Transfer Matrix formalism.

Parameters
==========

wavelen : the wavelength,
z : the distance to waist, and
w : the waist, or
z_r : the rayleigh range.
n : the refractive index of medium.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.q
1 + 1.88679245283019*I*pi

>>> p.q.n()
1.0 + 5.92753330865999*I
>>> p.w_0.n()
0.00100000000000000
>>> p.z_r.n()
5.92753330865999

>>> from sympy.physics.optics import FreeSpace
>>> fs = FreeSpace(10)
>>> p1 = fs*p
>>> p.w.n()
0.00101413072159615
>>> p1.w.n()
0.00210803120913829

See Also
========

RayTransferMatrix

References
==========

.. [1] https://en.wikipedia.org/wiki/Complex_beam_parameter
.. [2] https://en.wikipedia.org/wiki/Gaussian_beam
Nc                     [        U5      n[        U5      n[        U5      nUb  Uc  [        U5      nO-Ub  Uc  [        [        U5      X5      nOUc  Uc  [        S5      e[        R                  " XX#U5      $ )NzMust specify one of w and z_r.)r   r   r*   r   r,   )r.   r:   zr7   wns         r1   r,   BeamParameter.__new__  sq    '"AJAJ?qy#,C]s{ W8C[QY=>>||C!!44r3   c                      U R                   S   $ )Nr   r/   rA   s    r1   r:   BeamParameter.wavelen       yy|r3   c                      U R                   S   $ )Nr#   r   rA   s    r1   r   BeamParameter.z$  r   r3   c                      U R                   S   $ )Nr$   r   rA   s    r1   r7   BeamParameter.z_r(  r   r3   c                      U R                   S   $ )Nr%   r   rA   s    r1   r   BeamParameter.n,  r   r3   c                 B    U R                   [        U R                  -  -   $ )z
The complex parameter representing the beam.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.q
1 + 1.88679245283019*I*pi
)r   r   r7   rA   s    r1   r8   BeamParameter.q0  s     vv$((
""r3   c                 Z    U R                   SU R                  U R                   -  S-  -   -  $ )z
The radius of curvature of the phase front.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.radius
1 + 3.55998576005696*pi**2
r#   r$   )r   r7   rA   s    r1   radiusBeamParameter.radius?  s)     vvqDHHTVVOa//00r3   c                 l    U R                   [        SU R                  U R                  -  S-  -   5      -  $ )aC  
The radius of the beam w(z), at any position z along the beam.
The beam radius at `1/e^2` intensity (axial value).

See Also
========

w_0 :
    The minimal radius of beam.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.w
0.001*sqrt(0.2809/pi**2 + 1)
r#   r$   )w_0r   r   r7   rA   s    r1   r   BeamParameter.wN  s.    ( xxQ$&&/A!55666r3   c                 n    [        U R                  [        U R                  -  -  U R                  -  5      $ )a  
 The minimal radius of beam at `1/e^2` intensity (peak value).

See Also
========

w : the beam radius at `1/e^2` intensity (axial value).

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.w_0
0.00100000000000000
)r   r7   r   r   r:   rA   s    r1   r   BeamParameter.w_0d  s)    $ DHHbi(566r3   c                 B    U R                   [        -  U R                  -  $ )z
Half of the total angular spread.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.divergence
0.00053/pi
)r:   r   r   rA   s    r1   
divergenceBeamParameter.divergencex  s     ||Btxx''r3   c                 B    [        U R                  U R                  5      $ )z
The Gouy phase.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.gouy
atan(0.53/pi)
)r   r   r7   rA   s    r1   gouyBeamParameter.gouy  s     TVVTXX&&r3   c                 .    SU R                   -  [        -  $ )as  
The minimal waist for which the gauss beam approximation is valid.

Explanation
===========

The gauss beam is a solution to the paraxial equation. For curvatures
that are too great it is not a valid approximation.

Examples
========

>>> from sympy.physics.optics import BeamParameter
>>> p = BeamParameter(530e-9, 1, w=1e-3)
>>> p.waist_approximation_limit
1.06e-6/pi
r$   )r:   r   rA   s    r1   waist_approximation_limit'BeamParameter.waist_approximation_limit  s    & ~b  r3   r@   )NNr#   )rN   rO   rP   rQ   rR   r,   rS   r:   r   r7   r   r8   r   r   r   r   r   r   rT   r@   r3   r1   r
   r
     s    -d5         # # 1 1 7 7* 7 7& ( ( ' ' ! !r3   r
   c                 L    [        [        X45      u  pU S-  U-  [        -  U-  $ )a.  
Calculate the rayleigh range from the waist of a gaussian beam.

See Also
========

rayleigh2waist, BeamParameter

Examples
========

>>> from sympy.physics.optics import waist2rayleigh
>>> from sympy import symbols
>>> w, wavelen = symbols('w wavelen')
>>> waist2rayleigh(w, wavelen)
pi*w**2/wavelen
r$   )rb   r   r   )r   r:   r   s      r1   r   r     s+    $ Wql+JAa46"9Wr3   c                 R    [        [        X45      u  p[        U [        -  U-  5      $ )a>  Calculate the waist from the rayleigh range of a gaussian beam.

See Also
========

waist2rayleigh, BeamParameter

Examples
========

>>> from sympy.physics.optics import rayleigh2waist
>>> from sympy import symbols
>>> z_r, wavelen = symbols('z_r wavelen')
>>> rayleigh2waist(z_r, wavelen)
sqrt(wavelen*z_r)/sqrt(pi)
)rb   r   r   r   )r7   r:   s     r1   r   r     s'    " w/LCBwr3   c                     [        [        X45      u  pU R                  (       d  UR                  (       a  UR                  (       a  U $ U$ X-  X-   -  $ )a  
Conjugation relation for geometrical beams under paraxial conditions.

Explanation
===========

Takes the distances to the optical element and returns the needed
focal distance.

See Also
========

geometric_conj_af, geometric_conj_bf

Examples
========

>>> from sympy.physics.optics import geometric_conj_ab
>>> from sympy import symbols
>>> a, b = symbols('a b')
>>> geometric_conj_ab(a, b)
a*b/(a + b)
)rb   r   is_infinite)abs     r1   r   r     s@    0 wDA}}MMq(q(sAE{r3   c                 B    [        [        X45      u  p[        X* 5      * $ )aE  
Conjugation relation for geometrical beams under paraxial conditions.

Explanation
===========

Takes the object distance (for geometric_conj_af) or the image distance
(for geometric_conj_bf) to the optical element and the focal distance.
Then it returns the other distance needed for conjugation.

See Also
========

geometric_conj_ab

Examples
========

>>> from sympy.physics.optics.gaussopt import geometric_conj_af, geometric_conj_bf
>>> from sympy import symbols
>>> a, b, f = symbols('a b f')
>>> geometric_conj_af(a, f)
a*f/(a - f)
>>> geometric_conj_bf(b, f)
b*f/(b - f)
)rb   r   r   )r   rv   s     r1   r   r     s$    6 wDAa$$$r3   c                     [        [        XU45      u  pnSSXS-  X-
  -  -   -  SU-  -   -  nS[        SX-  S-  -
  X-  S-  -   5      -  nUSX-  S-  -
  X-  S-  -   -  nX5U4$ )a]  
Conjugation relation for gaussian beams.

Parameters
==========

s_in :
    The distance to optical element from the waist.
z_r_in :
    The rayleigh range of the incident beam.
f :
    The focal length of the optical element.

Returns
=======

a tuple containing (s_out, z_r_out, m)
s_out :
    The distance between the new waist and the optical element.
z_r_out :
    The rayleigh range of the emergent beam.
m :
    The ration between the new and the old waists.

Examples
========

>>> from sympy.physics.optics import gaussian_conj
>>> from sympy import symbols
>>> s_in, z_r_in, f = symbols('s_in z_r_in f')

>>> gaussian_conj(s_in, z_r_in, f)[0]
1/(-1/(s_in + z_r_in**2/(-f + s_in)) + 1/f)

>>> gaussian_conj(s_in, z_r_in, f)[1]
z_r_in/(1 - s_in**2/f**2 + z_r_in**2/f**2)

>>> gaussian_conj(s_in, z_r_in, f)[2]
1/sqrt(1 - s_in**2/f**2 + z_r_in**2/f**2)
r#   ru   r$   )rb   r   r   )s_inz_r_inrv   s_outmz_r_outs         r1   r   r     s    R 'D!#45OD!"dQY112QqS8:E	$TVaKFHq=0
11Adfq[VXM9:GAr3   c                    [        [        XU45      u  pnX!-  n[        X5      n[        U5      S:w  a  [	        S5      eSU;   a  [        [        S5      5      eSU;   aA  [        US   5      nUS[        SUS-  -  US-  US-  -  -
  5      -
  -  n[        XuU5      S   nO.SU;   a  [        [        S5      5      e[	        [        S	5      5      eXxU4$ )
a  
Find the optical setup conjugating the object/image waists.

Parameters
==========

wavelen :
    The wavelength of the beam.
waist_in and waist_out :
    The waists to be conjugated.
f :
    The focal distance of the element used in the conjugation.

Returns
=======

a tuple containing (s_in, s_out, f)
s_in :
    The distance before the optical element.
s_out :
    The distance after the optical element.
f :
    The focal distance of the optical element.

Examples
========

>>> from sympy.physics.optics import conjugate_gauss_beams
>>> from sympy import symbols, factor
>>> l, w_i, w_o, f = symbols('l w_i w_o f')

>>> conjugate_gauss_beams(l, w_i, w_o, f=f)[0]
f*(1 - sqrt(w_i**2/w_o**2 - pi**2*w_i**4/(f**2*l**2)))

>>> factor(conjugate_gauss_beams(l, w_i, w_o, f=f)[1])
f*w_o**2*(w_i**2/w_o**2 - sqrt(w_i**2/w_o**2 -
          pi**2*w_i**4/(f**2*l**2)))/w_i**2

>>> conjugate_gauss_beams(l, w_i, w_o, f=f)[2]
f
r#   z,The function expects only one named argumentdistzD
            Currently only focal length is supported as a parameterrv   r$   r   r   zG
            The functions expects the focal length as a named argument)	rb   r   r   r'   r*   NotImplementedErrorr   r   r   )	r:   waist_in	waist_outkwargsr   r   rv   r   r   s	            r1   r   r   K  s   V $'wI0N#O GyAx)A
6{aGHH	6	!* .G #H I 	I	F3K AQq!tVad1a4i/001dq)!,	6	!* .G #H I 	I  %J K L 	Lr3   Nr5   )'rR   __all__sympy.core.exprr   sympy.core.numbersr   r   sympy.core.sympifyr   $sympy.functions.elementary.complexesr   r   (sympy.functions.elementary.miscellaneousr   (sympy.functions.elementary.trigonometricr   sympy.matrices.denser   r   sympy.polys.rationaltoolsr   sympy.utilities.miscr   r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r@   r3   r1   <module>r      s   .( ! & & 9 9 : ; . +N* Nb:! ::>& >B K(  KF:" :,=$ =<=  =FT% TvJ!D J!b, *>%< & -`=r3   