Source code for clifford.taylor_expansions

"""
.. currentmodule:: clifford.taylor_expansions

=====================================================
taylor_expansions (:mod:`clifford.taylor_expansions`)
=====================================================

.. versionadded:: 1.4.0

This file implements various Taylor expansions for useful functions of multivectors.
For some algebra signatures there may exist closed forms of these functions which would likely be faster
and more accurate. Nonetheless, having pre-written taylor expansions for the general case is useful.

.. note::
    Many of these functions are also exposed as :class:`~clifford.MultiVector` methods,
    such as :meth:`clifford.MultiVector.sin`. This means that ``mv.sin()`` or even ``np.sin(mv)`` can be used
    as a convenient interface to functions in this module, without having to import it directly.

    For example::

        >>> from clifford.g3 import *
        >>> import numpy as np
        >>> np.sin(np.pi*e12/4)
        (0.86867^e12)

Implemented functions
---------------------

.. autofunction:: exp
.. autofunction:: sin
.. autofunction:: cos
.. autofunction:: tan
.. autofunction:: sinh
.. autofunction:: cosh
.. autofunction:: tanh

"""
import math
import numpy as np

from . import _numba_utils
from . import _settings


[docs]@_numba_utils.njit def exp(x, max_order=15): r""" This implements the series expansion of :math:`\exp x` where :math:`x` is a multivector The parameter `max_order` is the maximum order of the taylor series to use """ result = 1.0 + 0.0*x if max_order == 0: return result # scale by power of 2 so that its norm is < 1 max_val = int(np.max(np.abs(x.value))) scale = 1 if max_val > 1: max_val <<= 1 while max_val: max_val >>= 1 scale <<= 1 scaled = x * (1.0 / scale) # taylor approximation tmp = 1.0 + 0.0*x for i in range(1, max_order): if np.any(np.abs(tmp.value) > _settings._eps): tmp = tmp*scaled * (1.0 / i) result = result + tmp else: break # undo scaling while scale > 1: result = result*result scale >>= 1 return result
[docs]@_numba_utils.njit def sin(X, max_order=30): """ A taylor series expansion for sin The parameter `max_order` is the maximum order of the taylor series to use """ op = +X X2 = X*X X2np1 = X for n in range(1, max_order): X2np1 = X2np1 * X2 op = op + ((-1) ** (n) / math.gamma(2 * n + 2)) * X2np1 return op
[docs]@_numba_utils.njit def cos(X, max_order=30): """ A taylor series expansion for cos The parameter `max_order` is the maximum order of the taylor series to use """ op = 1 + 0*X X2 = X * X X2n = 1 + 0*X for n in range(1, max_order): X2n = X2n*X2 op = op + ((-1) ** (n) / math.gamma(2 * n + 1)) * X2n return op
[docs]def tan(X, max_order=30): """ The tan function as the ratio of sin and cos The parameter `max_order` is the maximum order of the taylor series to use .. note:: It would probably be better to implement this as its own taylor series. This function is not JITed as currently we do not overload the truediv operator for multivectors. """ return sin(X, max_order) / cos(X, max_order)
[docs]@_numba_utils.njit def sinh(X, max_order=30): """ A taylor series expansion for sinh The parameter `max_order` is the maximum order of the taylor series to use """ op = +X X2 = X * X X2np1 = X for n in range(1, max_order): X2np1 = X2np1 * X2 op = op + (1 / math.gamma(2 * n + 2)) * X2np1 return op
[docs]@_numba_utils.njit def cosh(X, max_order=30): """ A taylor series expansion for cosh The parameter `max_order` is the maximum order of the taylor series to use """ op = 1 + 0 * X X2 = X * X X2n = 1 + 0 * X for n in range(1, max_order): X2n = X2n * X2 op = op + (1 / math.gamma(2 * n + 1)) * X2n return op
[docs]def tanh(X, max_order=30): """ The tanh function as the ratio of sinh and cosh The parameter `max_order` is the maximum order of the taylor series to use .. note:: It would probably be better to implement this as its own taylor series. This function is not JITed as currently we do not overload the truediv operator for multivectors. """ return sinh(X, max_order) / cosh(X, max_order)