code: """Trigonometric and Hyperbolic Functions"""
  
  from typing import Callable
  
  import numpy
  from pipda import register_func
  
  from ..core.contexts import Context
  from ..core.types import FloatOrIter
  from .constants import pi
  
  
  def _register_trig_hb_func(name: str, np_name: str, doc: str) -> Callable:
      """Register trigonometric and hyperbolic function"""
      np_fun = getattr(numpy, np_name)
      if name.endswith("pi"):
          func = lambda x: np_fun(x * pi)
      else:
          # ufunc cannot set context
          func = lambda x: np_fun(x)
  
      func = register_func(None, context=Context.EVAL, func=func)
      func.__name__ = name
      func.__doc__ = doc
      return func
  
  
  sin = _register_trig_hb_func(
      "sin",
      "sin",
      doc="""The sine function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The sine value of `x`
  """,
  )
  
  cos = _register_trig_hb_func(
      "cos",
      "cos",
      doc="""The cosine function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The cosine value of `x`
  """,
  )
  
  tan = _register_trig_hb_func(
      "tan",
      "tan",
      doc="""The tangent function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The tangent value of `x`
  """,
  )
  
  acos = _register_trig_hb_func(
      "acos",
      "arccos",
      doc="""The arc-cosine function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The arc-cosine value of `x`
  """,
  )
  
  asin = _register_trig_hb_func(
      "acos",
      "arcsin",
      doc="""The arc-sine function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The arc-sine value of `x`
  """,
  )
  
  atan = _register_trig_hb_func(
      "acos",
      "arctan",
      doc="""The arc-sine function
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The arc-sine value of `x`
  """,
  )
  
  sinpi = _register_trig_hb_func(
      "sinpi",
      "sin",
      doc="""The sine function
  
  Args:
      x: a numeric value or iterable, which is the multiple of pi
  
  Returns:
      The sine value of `x`
  """,
  )
  
  cospi = _register_trig_hb_func(
      "cospi",
      "cos",
      doc="""The cosine function
  
  Args:
      x: a numeric value or iterable, which is the multiple of pi
  
  Returns:
      The cosine value of `x`
  """,
  )
  
  tanpi = _register_trig_hb_func(
      "tanpi",
      "tan",
      doc="""The tangent function
  
  Args:
      x: a numeric value or iterable, which is the multiple of pi
  
  Returns:
      The tangent value of `x`
  """,
  )
  
  cosh = _register_trig_hb_func(
      "cosh",
      "cosh",
      doc="""Hyperbolic cosine
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic cosine value of `x`
  """,
  )
  
  sinh = _register_trig_hb_func(
      "sinh",
      "sinh",
      doc="""Hyperbolic sine
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic sine value of `x`
  """,
  )
  
  tanh = _register_trig_hb_func(
      "tanh",
      "tanh",
      doc="""Hyperbolic tangent
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic tangent value of `x`
  """,
  )
  
  acosh = _register_trig_hb_func(
      "acosh",
      "arccosh",
      doc="""Hyperbolic arc-cosine
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic arc-cosine value of `x`
  """,
  )
  
  asinh = _register_trig_hb_func(
      "asinh",
      "arcsinh",
      doc="""Hyperbolic arc-sine
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic arc-sine value of `x`
  """,
  )
  
  atanh = _register_trig_hb_func(
      "atanh",
      "arctanh",
      doc="""Hyperbolic arc-tangent
  
  Args:
      x: a numeric value or iterable
  
  Returns:
      The hyperbolic arc-tangent value of `x`
  """,
  )
  
  
  @register_func(None, context=Context.EVAL)
  def atan2(y: FloatOrIter, x: FloatOrIter) -> FloatOrIter:
      """Calculates the angle between the x-axis and the vector (0,0) -> (x,y)
  
      Args:
          y: and
          x: The end coordinates of the vector
  
      Returns:
          The angle between x-axis and vector (0,0) -> (x,y)
      """
      return numpy.arctan2(y, x)
  
apis: numpy.arctan2