| """ |
| 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 |
|
|
| |
| |
| |
|
|
|
|
| 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) |
|
|
|
|
| |
| |
| |
|
|
| 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] |
|
|
|
|
| |
| |
| |
|
|
| 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 |
| """ |
| |
| |
| |
|
|
| 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 |
|
|
|
|
| |
| |
| |
|
|
| 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 |
| """ |
| |
| 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) |
|
|
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|