Пример #1
0
def geodetic2isometric(geodetic_lat: ndarray,
                       ell: Ellipsoid = None,
                       deg: bool = True) -> float:
    """
    computes isometric latitude on an ellipsoid


    like Matlab map.geodesy.IsometricLatitudeConverter.forward()

    Parameters
    ----------
    lat : float
         geodetic latitude
    ell : Ellipsoid, optional
         reference ellipsoid (default WGS84)
    deg : bool, optional
         degrees input/output  (False: radians in/out)

    Returns
    -------
    isolat : float
         isometric latiude

    Notes
    -----
    Isometric latitude is an auxiliary latitude proportional to the spacing
    of parallels of latitude on an ellipsoidal mercator projection.
    Based on Deakin, R.E., 2010, 'The Loxodrome on an Ellipsoid', Lecture Notes,
    School of Mathematical and Geospatial Sciences, RMIT University,
    January 2010
    """

    geodetic_lat, ell = sanitize(geodetic_lat, ell, deg)

    e = ell.eccentricity

    isometric_lat = asinh(tan(geodetic_lat)) - e * atanh(e * sin(geodetic_lat))
    # same results
    # a1 = e * sin(geodetic_lat)
    # y = (1 - a1) / (1 + a1)
    # a2 = pi / 4 + geodetic_lat / 2
    # isometric_lat = log(tan(a2) * (y ** (e / 2)))
    # isometric_lat = log(tan(a2)) + e/2 * log((1-e*sin(geodetic_lat)) / (1+e*sin(geodetic_lat)))

    try:
        isometric_lat[abs(geodetic_lat - pi / 2) <= 1e-9] = inf
        isometric_lat[abs(-geodetic_lat - pi / 2) <= 1e-9] = -inf
    except TypeError:
        if abs(geodetic_lat - pi / 2) <= 1e-9:
            isometric_lat = inf
        elif abs(-geodetic_lat - pi / 2) <= 1e-9:
            isometric_lat = -inf

    return degrees(isometric_lat) if deg else isometric_lat
Пример #2
0
def geodetic2isometric_point(geodetic_lat: float,
                             ell: Ellipsoid = None,
                             deg: bool = True) -> float:
    geodetic_lat, ell = sanitize(geodetic_lat, ell, deg)

    e = ell.eccentricity

    if abs(geodetic_lat - pi / 2) <= 1e-9:
        isometric_lat = inf
    elif abs(-geodetic_lat - pi / 2) <= 1e-9:
        isometric_lat = -inf
    else:
        isometric_lat = asinh(
            tan(geodetic_lat)) - e * atanh(e * sin(geodetic_lat))
        # same results
        # a1 = e * sin(geodetic_lat)
        # y = (1 - a1) / (1 + a1)
        # a2 = pi / 4 + geodetic_lat / 2
        # isometric_lat = log(tan(a2) * (y ** (e / 2)))
        # isometric_lat = log(tan(a2)) + e/2 * log((1-e*sin(geodetic_lat)) / (1+e*sin(geodetic_lat)))

    return degrees(isometric_lat) if deg else isometric_lat
Пример #3
0
    def test_unary_fun(self):

        import math

        data = [1., 2., 3.]
        c = np.array(data)

        d = np.acos(c / 3)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.acos(data[i] / 3))

        d = np.asin(c / 3)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.asin(data[i] / 3))

        d = np.atan(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.atan(data[i]))

        d = np.sin(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.sin(data[i]))

        d = np.cos(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.cos(data[i]))

        d = np.tan(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.tan(data[i]))

        d = np.acosh(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.acosh(data[i]))

        d = np.asinh(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.asinh(data[i]))

        d = np.atanh(c / 3.1)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.atanh(data[i] / 3.1))

        d = np.sinh(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.sinh(data[i]))

        d = np.cosh(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.cosh(data[i]))

        d = np.tanh(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.tanh(data[i]))

        d = np.ceil(c * 2.7)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.ceil(data[i] * 2.7))

        d = np.floor(c * 2.7)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.floor(data[i] * 2.7))

        d = np.erf(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.erf(data[i]))

        d = np.erfc(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.erfc(data[i]))

        d = np.exp(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.exp(data[i]))

        d = np.expm1(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.expm1(data[i]))

        d = np.gamma(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.gamma(data[i]))

        d = np.lgamma(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.lgamma(data[i]))

        d = np.log(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.log(data[i]))

        d = np.log10(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.log10(data[i]))

        d = np.log2(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.log2(data[i]))

        d = np.sqrt(c)
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.sqrt(data[i]))

        # slices
        data = [1., 2., 3.]
        c = np.array(data + data)

        d = np.cos(c[::2])
        mm = data + data
        for i, ei in enumerate(d):
            self.assertEqual(ei, math.cos(mm[2 * i]))

        # 2d array
        data = [1., 2., 3.]
        c = np.array([data, data])

        d = np.cos(c)
        mm = [data, data]
        for i, ei in enumerate(d):
            for j, eij in enumerate(ei):
                self.assertEqual(eij, math.cos(mm[i][j]))

        # 2d array slices
        data = [1., 2., 3.]
        c = np.array([data + data, data + data])

        d = np.cos(c[:, ::2])
        mm = [data + data, data + data]
        for i, ei in enumerate(d):
            for j, eij in enumerate(ei):
                self.assertEqual(eij, math.cos(mm[i][2 * j]))
def spheroidalCF2(r, psize, axrat):
    """Spheroidal nanoparticle characteristic function.

    Form factor for ellipsoid with radii (psize/2, psize/2, axrat*psize/2)
    
    r      --  distance of interaction
    psize  --  The equatorial diameter
    axrat  --  The ratio of axis lengths

    From Lei et al., Phys. Rev. B, 80, 024118 (2009)
    
    """
    pelpt = 1.0 * axrat

    if psize <= 0 or pelpt <= 0: 
        return numpy.zeros_like(r)

    # to simplify the equations
    v = pelpt
    d = 1.0 * psize
    d2 = d*d
    v2 = v*v

    if v == 1: 
        return sphericalCF(r, psize)

    rx = r
    if v < 1:

        r = rx[rx <= v*psize]
        r2 = r*r
        f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
                - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(1-v2)*atanh(sqrt(1-v2))

        r = rx[numpy.logical_and(rx > v*psize, rx <= psize)]
        r2 = r*r
        f2 = (3*d/(8*r)*(1+r2/(2*d2))*sqrt(1-r2/d2) \
                - 3*r/(4*d)*(1-r2/(4*d2))*atanh(sqrt(1-r2/d2)) \
                ) * v/sqrt(1-v2)

        r = rx[rx > psize]
        f3 = numpy.zeros_like(r)

        f = numpy.concatenate((f1,f2,f3))

    elif v > 1:

        r = rx[rx <= psize]
        r2 = r*r
        f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
                - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1)*atan(sqrt(v2-1))

        r = rx[numpy.logical_and(rx > psize, rx <= v*psize)]
        r2 = r*r
        f2 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
            - 3.0/8*(1+r2/(2*d2))*sqrt(1-d2/r2)*v/sqrt(v2-1) \
            - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1) \
            * (atan(sqrt(v2-1)) - atan(sqrt(r2/d2-1)))

        r = rx[rx > v*psize]
        f3 = numpy.zeros_like(r)

        f = numpy.concatenate((f1,f2,f3))

    return f
Пример #5
0
def _spheroidalCF2(r, psize, axrat):
    """Spheroidal nanoparticle characteristic function.

    Form factor for ellipsoid with radii (psize/2, psize/2, axrat*psize/2)
    
    r      --  distance of interaction
    psize  --  The equatorial diameter
    axrat  --  The ratio of axis lengths

    From Lei et al., Phys. Rev. B, 80, 024118 (2009)
    
    """
    pelpt = axrat

    if psize <= 0 or pelpt <= 0:
        return numpy.zeros_like(r)

    # to simplify the equations
    v = pelpt
    d = psize
    d2 = d * d
    v2 = v * v

    if v == 1:
        return _sphericalCF(r, psize)

    rx = r
    if v < 1:

        r = rx[rx <= v * psize]
        r2 = r * r
        f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
                - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(1-v2)*atanh(sqrt(1-v2))

        r = rx[numpy.logical_and(rx > v * psize, rx <= psize)]
        r2 = r * r
        f2 = (3*d/(8*r)*(1+r2/(2*d2))*sqrt(1-r2/d2) \
                - 3*r/(4*d)*(1-r2/(4*d2))*atanh(sqrt(1-r2/d2)) \
                ) * v/sqrt(1-v2)

        r = rx[rx > psize]
        f3 = numpy.zeros_like(r)

        f = numpy.concatenate((f1, f2, f3))

    elif v > 1:

        r = rx[rx <= psize]
        r2 = r * r
        f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
                - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1)*atan(sqrt(v2-1))

        r = rx[numpy.logical_and(rx > psize, rx <= v * psize)]
        r2 = r * r
        f2 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \
            - 3.0/8*(1+r2/(2*d2))*sqrt(1-d2/r2)*v/sqrt(v2-1) \
            - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1) \
            * (atan(sqrt(v2-1)) - atan(sqrt(r2/d2-1)))

        r = rx[rx > v * psize]
        f3 = numpy.zeros_like(r)

        f = numpy.concatenate((f1, f2, f3))

    return f
Пример #6
0
    def ejecutar_trigo(self, funcion):
        if funcion.funcion == 'acos':
            try:

                return np.acos(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en acos ')
                return 0
        elif funcion.funcion == 'acosd':
            try:
                return np.acosd(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en acosd ')
                return 0
        elif funcion.funcion == 'asin':
            try:
                return np.asin(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en asin ')
                return 0
        elif funcion.funcion == 'asind':
            try:
                return np.asind(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en asind ')
                return 0
        elif funcion.funcion == 'atan':
            try:
                return np.atan(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores ')
                return 0
        elif funcion.funcion == 'atand':
            try:
                return np.atand(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores atand ')
                return 0
        elif funcion.funcion == 'atan2':
            try:
                return np.atan2(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en atan2 ')
                return 0
        elif funcion.funcion == 'cos':
            try:
                return np.cos(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en cos ')
                return 0
        elif funcion.funcion == 'cosd':
            try:
                return np.cosd(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores cosd cosd')
                return 0
        elif funcion.funcion == 'cot':
            try:
                return np.cot(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores cot')
                return 0
        elif funcion.funcion == 'cotd':
            try:
                return np.cotd(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en cotd ')
                return 0
        elif funcion.funcion == 'sin':
            try:
                return np.sin(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en sin ')
                return 0
        elif funcion.funcion == 'sind':
            try:
                return np.sind(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en sind ')
                return 0
        elif funcion.funcion == 'tan':
            try:
                return np.tan(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en tan ')
                return 0
        elif funcion.funcion == 'tand':
            try:
                return np.tand(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en tand')
                return 0
        elif funcion.funcion == 'sinh':
            try:
                return np.sinh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en sinh')
                return 0
        elif funcion.funcion == 'cosh':
            try:
                return np.cosh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en cosh ')
                return 0
        elif funcion.funcion == 'tanh':
            try:
                return np.tanh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en tanh ')
                return 0
        elif funcion.funcion == 'asinh':
            try:
                return np.asinh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en asinh')
                return 0
        elif funcion.funcion == 'acosh':
            try:
                return np.acosh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en acosh ')
                return 0
        elif funcion.funcion == 'atanh':
            try:
                return np.atanh(self.aritexc.ejecutar_operacion(funcion.op1))
            except:
                errorsem.append('error al convertir valores en atanh ')
                return 0
Пример #7
0
 def ppf(self, z):
     w = self.width.value * self._scale
     if w <= 0.0:
         return 0*z
     else:
         return (w/Tanh.C)*atanh(2*z-1)
Пример #8
0
 def ppf(self, z):
     w = self.width.value * self._scale
     if w <= 0.0:
         return 0 * z
     else:
         return (w / Tanh.C) * atanh(2 * z - 1)
Пример #9
0
class Tanh(Interface):
    r"""
    Hyperbolic tangent profile

    *width* (Parameter: 0 Angstroms)

        1-\ $\sigma$ equivalent roughness.  For roughness $w$ measured by the
        full width at half maximum (FWHM), use Tanh.as_fwhm(w).

    *name* (string: "tanh")

    The tanh profile has the form:

    .. math:

        \text{CDF}(z) = (1 + \tanh(C/wz))/2
        \text{PDF}(z) = C/(2w) \sech((C/w)z)^2
        \text{PPF}(z) = (w/C) \tanh^{-1}(2z-1)

    where $w$ is the interface roughness and $C$ is a scaling constant.
    $C$ is $\tanh^{-1}(\text{erf}(1/\sqrt{2}))$ for width defined
    by 1-\ $\sigma$, or $C$ is $2\cosh^{-1}(\sqrt{2})$ for width
    defined by FWHM.

    .. Note::
       This profile was derived from the free energy of a nonuniform system:

        * J.W. Cahn and J. E. Hilliard, J. Chem. Phys. 28, 258 (1958)

    .. seealso::
       This profile has an analytic solution. E.S. Wu, and W. W. Webb,
       Phys Rev A 8(4) 2065-2076 (1973)
    """

    # Derivation
    # ==========
    #
    # To find C where w is defined as 1-sigma equivalent, use the
    # identity Erf.CDF(z=sigma;w=sigma) = tanh.CDF(z=sigma;w=sigma).
    # This simplifies to::
    #
    #    erf.CDF  = (1+erf(z/(w*sqrt(2)))/2 = (1+erf(1/sqrt(2)))/2
    #    tanh.CDF = (1+tanh(C/w*z))/2       = (1+tanh(C))/2
    #
    #    erf.CDF = tanh.CDF => C = atanh(erf(1/sqrt(2)))
    #
    # To find C where w is defined as FWHM, use the equivalent probability
    # density function::
    #
    #    PDF(z) = C/2w * sech(C/w*z)**2
    #
    # Solving PDF(w/2) = PDF(0)/2 yields::
    #
    #    Pw = PDF(w/2) = C/2w * sech(C/2)**2
    #    Po = PDF(0) = C/2w * sech(0)**2/2 = C/2w
    #
    #    Pw = Po/2 => sech(C/2)**2 = 1/2
    #              => C = 2 acosh(sqrt(2))
    #
    # To find ws 1-sigma given tanh fwhm of w, use the scale factor
    # s = C_1_sigma/C_fwhm = 1/2 atanh(erf(1/sqrt(2)))/acosh(sqrt(2))
    # to form ws = w*s
    C = atanh(erf(1 / sqrt(2)))
    Cfwhm = 2 * acosh(sqrt(2))

    @classmethod
    def as_fwhm(cls, *args, **kw):
        """
        Defines interface using FWHM rather than 1-\ $\sigma$.
        """
        self = cls(*args, **kw)
        self._scale = Tanh.C / Tanh.Cfwhm
        return self

    def __init__(self, width=0, name="tanh"):
        self._scale = 1
        self.width = Parameter.default(width, limits=(0, inf), name=name)

    def parameters(self):
        return {'width': self.width}

    def cdf(self, z):
        w = self.width.value * self._scale
        if w <= 0.0:
            return 1. * (z > 0)
        else:
            return 0.5 * (1 + tanh((Tanh.C / w) * z))

    def pdf(self, z):
        w = self.width.value * self._scale
        if w <= 0.0:
            return inf * (z == 0)
        else:
            return sech((Tanh.C / w) * z)**2 * (Tanh.C / (2 * w))

    def ppf(self, z):
        w = self.width.value * self._scale
        if w <= 0.0:
            return 0 * z
        else:
            return (w / Tanh.C) * atanh(2 * z - 1)
Пример #10
0
 def atanh(self):
     rst = self.ensureVector(np.atanh(self))
     rst = self.setGradFn(rst, "atanh")
     return rst
Пример #11
0
def atanh(x: Number = 0.0) -> Number:
    return np.atanh(x)