switching to high quality piper tts and added label translations
This commit is contained in:
@@ -0,0 +1,923 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
__all__ = [
|
||||
'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',
|
||||
]
|
||||
|
||||
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core.numbers import (I, pi)
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.functions.elementary.complexes import (im, re)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import atan2
|
||||
from sympy.matrices.dense import Matrix, MutableDenseMatrix
|
||||
from sympy.polys.rationaltools import together
|
||||
from sympy.utilities.misc import filldedent
|
||||
|
||||
###
|
||||
# A, B, C, D matrices
|
||||
###
|
||||
|
||||
|
||||
class RayTransferMatrix(MutableDenseMatrix):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
|
||||
if len(args) == 4:
|
||||
temp = ((args[0], args[1]), (args[2], args[3]))
|
||||
elif len(args) == 1 \
|
||||
and isinstance(args[0], Matrix) \
|
||||
and args[0].shape == (2, 2):
|
||||
temp = args[0]
|
||||
else:
|
||||
raise ValueError(filldedent('''
|
||||
Expecting 2x2 Matrix or the 4 elements of
|
||||
the Matrix but got %s''' % str(args)))
|
||||
return Matrix.__new__(cls, temp)
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, RayTransferMatrix):
|
||||
return RayTransferMatrix(Matrix(self)*Matrix(other))
|
||||
elif isinstance(other, GeometricRay):
|
||||
return GeometricRay(Matrix(self)*Matrix(other))
|
||||
elif isinstance(other, BeamParameter):
|
||||
temp = Matrix(self)*Matrix(((other.q,), (1,)))
|
||||
q = (temp[0]/temp[1]).expand(complex=True)
|
||||
return BeamParameter(other.wavelen,
|
||||
together(re(q)),
|
||||
z_r=together(im(q)))
|
||||
else:
|
||||
return Matrix.__mul__(self, other)
|
||||
|
||||
@property
|
||||
def A(self):
|
||||
"""
|
||||
The A parameter of the Matrix.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import RayTransferMatrix
|
||||
>>> mat = RayTransferMatrix(1, 2, 3, 4)
|
||||
>>> mat.A
|
||||
1
|
||||
"""
|
||||
return self[0, 0]
|
||||
|
||||
@property
|
||||
def B(self):
|
||||
"""
|
||||
The B parameter of the Matrix.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import RayTransferMatrix
|
||||
>>> mat = RayTransferMatrix(1, 2, 3, 4)
|
||||
>>> mat.B
|
||||
2
|
||||
"""
|
||||
return self[0, 1]
|
||||
|
||||
@property
|
||||
def C(self):
|
||||
"""
|
||||
The C parameter of the Matrix.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import RayTransferMatrix
|
||||
>>> mat = RayTransferMatrix(1, 2, 3, 4)
|
||||
>>> mat.C
|
||||
3
|
||||
"""
|
||||
return self[1, 0]
|
||||
|
||||
@property
|
||||
def D(self):
|
||||
"""
|
||||
The D parameter of the Matrix.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import RayTransferMatrix
|
||||
>>> mat = RayTransferMatrix(1, 2, 3, 4)
|
||||
>>> mat.D
|
||||
4
|
||||
"""
|
||||
return self[1, 1]
|
||||
|
||||
|
||||
class FreeSpace(RayTransferMatrix):
|
||||
"""
|
||||
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]])
|
||||
"""
|
||||
def __new__(cls, d):
|
||||
return RayTransferMatrix.__new__(cls, 1, d, 0, 1)
|
||||
|
||||
|
||||
class FlatRefraction(RayTransferMatrix):
|
||||
"""
|
||||
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]])
|
||||
"""
|
||||
def __new__(cls, n1, n2):
|
||||
n1, n2 = map(sympify, (n1, n2))
|
||||
return RayTransferMatrix.__new__(cls, 1, 0, 0, n1/n2)
|
||||
|
||||
|
||||
class CurvedRefraction(RayTransferMatrix):
|
||||
"""
|
||||
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]])
|
||||
"""
|
||||
def __new__(cls, R, n1, n2):
|
||||
R, n1, n2 = map(sympify, (R, n1, n2))
|
||||
return RayTransferMatrix.__new__(cls, 1, 0, (n1 - n2)/R/n2, n1/n2)
|
||||
|
||||
|
||||
class FlatMirror(RayTransferMatrix):
|
||||
"""
|
||||
Ray Transfer Matrix for reflection.
|
||||
|
||||
See Also
|
||||
========
|
||||
|
||||
RayTransferMatrix
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import FlatMirror
|
||||
>>> FlatMirror()
|
||||
Matrix([
|
||||
[1, 0],
|
||||
[0, 1]])
|
||||
"""
|
||||
def __new__(cls):
|
||||
return RayTransferMatrix.__new__(cls, 1, 0, 0, 1)
|
||||
|
||||
|
||||
class CurvedMirror(RayTransferMatrix):
|
||||
"""
|
||||
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]])
|
||||
"""
|
||||
def __new__(cls, R):
|
||||
R = sympify(R)
|
||||
return RayTransferMatrix.__new__(cls, 1, 0, -2/R, 1)
|
||||
|
||||
|
||||
class ThinLens(RayTransferMatrix):
|
||||
"""
|
||||
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]])
|
||||
"""
|
||||
def __new__(cls, f):
|
||||
f = sympify(f)
|
||||
return RayTransferMatrix.__new__(cls, 1, 0, -1/f, 1)
|
||||
|
||||
|
||||
###
|
||||
# Representation for geometric ray
|
||||
###
|
||||
|
||||
class GeometricRay(MutableDenseMatrix):
|
||||
"""
|
||||
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
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
if len(args) == 1 and isinstance(args[0], Matrix) \
|
||||
and args[0].shape == (2, 1):
|
||||
temp = args[0]
|
||||
elif len(args) == 2:
|
||||
temp = ((args[0],), (args[1],))
|
||||
else:
|
||||
raise ValueError(filldedent('''
|
||||
Expecting 2x1 Matrix or the 2 elements of
|
||||
the Matrix but got %s''' % str(args)))
|
||||
return Matrix.__new__(cls, temp)
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return self[0]
|
||||
|
||||
@property
|
||||
def angle(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return self[1]
|
||||
|
||||
|
||||
###
|
||||
# Representation for gauss beam
|
||||
###
|
||||
|
||||
class BeamParameter(Expr):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
#TODO A class Complex may be implemented. The BeamParameter may
|
||||
# subclass it. See:
|
||||
# https://groups.google.com/d/topic/sympy/7XkU07NRBEs/discussion
|
||||
|
||||
def __new__(cls, wavelen, z, z_r=None, w=None, n=1):
|
||||
wavelen = sympify(wavelen)
|
||||
z = sympify(z)
|
||||
n = sympify(n)
|
||||
|
||||
if z_r is not None and w is None:
|
||||
z_r = sympify(z_r)
|
||||
elif w is not None and z_r is None:
|
||||
z_r = waist2rayleigh(sympify(w), wavelen, n)
|
||||
elif z_r is None and w is None:
|
||||
raise ValueError('Must specify one of w and z_r.')
|
||||
|
||||
return Expr.__new__(cls, wavelen, z, z_r, n)
|
||||
|
||||
@property
|
||||
def wavelen(self):
|
||||
return self.args[0]
|
||||
|
||||
@property
|
||||
def z(self):
|
||||
return self.args[1]
|
||||
|
||||
@property
|
||||
def z_r(self):
|
||||
return self.args[2]
|
||||
|
||||
@property
|
||||
def n(self):
|
||||
return self.args[3]
|
||||
|
||||
@property
|
||||
def q(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return self.z + I*self.z_r
|
||||
|
||||
@property
|
||||
def radius(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return self.z*(1 + (self.z_r/self.z)**2)
|
||||
|
||||
@property
|
||||
def w(self):
|
||||
"""
|
||||
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)
|
||||
"""
|
||||
return self.w_0*sqrt(1 + (self.z/self.z_r)**2)
|
||||
|
||||
@property
|
||||
def w_0(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return sqrt(self.z_r/(pi*self.n)*self.wavelen)
|
||||
|
||||
@property
|
||||
def divergence(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return self.wavelen/pi/self.w_0
|
||||
|
||||
@property
|
||||
def gouy(self):
|
||||
"""
|
||||
The Gouy phase.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.optics import BeamParameter
|
||||
>>> p = BeamParameter(530e-9, 1, w=1e-3)
|
||||
>>> p.gouy
|
||||
atan(0.53/pi)
|
||||
"""
|
||||
return atan2(self.z, self.z_r)
|
||||
|
||||
@property
|
||||
def waist_approximation_limit(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
return 2*self.wavelen/pi
|
||||
|
||||
|
||||
###
|
||||
# Utilities
|
||||
###
|
||||
|
||||
def waist2rayleigh(w, wavelen, n=1):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
w, wavelen = map(sympify, (w, wavelen))
|
||||
return w**2*n*pi/wavelen
|
||||
|
||||
|
||||
def rayleigh2waist(z_r, wavelen):
|
||||
"""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)
|
||||
"""
|
||||
z_r, wavelen = map(sympify, (z_r, wavelen))
|
||||
return sqrt(z_r/pi*wavelen)
|
||||
|
||||
|
||||
def geometric_conj_ab(a, b):
|
||||
"""
|
||||
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)
|
||||
"""
|
||||
a, b = map(sympify, (a, b))
|
||||
if a.is_infinite or b.is_infinite:
|
||||
return a if b.is_infinite else b
|
||||
else:
|
||||
return a*b/(a + b)
|
||||
|
||||
|
||||
def geometric_conj_af(a, f):
|
||||
"""
|
||||
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)
|
||||
"""
|
||||
a, f = map(sympify, (a, f))
|
||||
return -geometric_conj_ab(a, -f)
|
||||
|
||||
geometric_conj_bf = geometric_conj_af
|
||||
|
||||
|
||||
def gaussian_conj(s_in, z_r_in, f):
|
||||
"""
|
||||
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)
|
||||
"""
|
||||
s_in, z_r_in, f = map(sympify, (s_in, z_r_in, f))
|
||||
s_out = 1 / ( -1/(s_in + z_r_in**2/(s_in - f)) + 1/f )
|
||||
m = 1/sqrt((1 - (s_in/f)**2) + (z_r_in/f)**2)
|
||||
z_r_out = z_r_in / ((1 - (s_in/f)**2) + (z_r_in/f)**2)
|
||||
return (s_out, z_r_out, m)
|
||||
|
||||
|
||||
def conjugate_gauss_beams(wavelen, waist_in, waist_out, **kwargs):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
#TODO add the other possible arguments
|
||||
wavelen, waist_in, waist_out = map(sympify, (wavelen, waist_in, waist_out))
|
||||
m = waist_out / waist_in
|
||||
z = waist2rayleigh(waist_in, wavelen)
|
||||
if len(kwargs) != 1:
|
||||
raise ValueError("The function expects only one named argument")
|
||||
elif 'dist' in kwargs:
|
||||
raise NotImplementedError(filldedent('''
|
||||
Currently only focal length is supported as a parameter'''))
|
||||
elif 'f' in kwargs:
|
||||
f = sympify(kwargs['f'])
|
||||
s_in = f * (1 - sqrt(1/m**2 - z**2/f**2))
|
||||
s_out = gaussian_conj(s_in, z, f)[0]
|
||||
elif 's_in' in kwargs:
|
||||
raise NotImplementedError(filldedent('''
|
||||
Currently only focal length is supported as a parameter'''))
|
||||
else:
|
||||
raise ValueError(filldedent('''
|
||||
The functions expects the focal length as a named argument'''))
|
||||
return (s_in, s_out, f)
|
||||
|
||||
#TODO
|
||||
#def plot_beam():
|
||||
# """Plot the beam radius as it propagates in space."""
|
||||
# pass
|
||||
|
||||
#TODO
|
||||
#def plot_beam_conjugation():
|
||||
# """
|
||||
# Plot the intersection of two beams.
|
||||
#
|
||||
# Represents the conjugation relation.
|
||||
#
|
||||
# See Also
|
||||
# ========
|
||||
#
|
||||
# conjugate_gauss_beams
|
||||
# """
|
||||
# pass
|
||||
Reference in New Issue
Block a user