tensorflow_probability/python/distributions/von_mises_fisher.py
def _bessel_ive(v, z, cache=None):
  """Computes I_v(z)*exp(-abs(z)) using a recurrence relation, where z > 0."""
  # TODO(b/67497980): Switch to a more numerically faithful implementation.
  z = tf.convert_to_tensor(value=z)

  wrap = lambda result: tf.debugging.check_numerics(result, 'besseli{}'.format(v
                                                                              ))

  if float(v) >= 2:
    raise ValueError(
        'Evaluating bessel_i by recurrence becomes imprecise for large v')

  cache = cache or {}
  safe_z = tf.where(z > 0, z, tf.ones_like(z))
  if v in cache:
    return wrap(cache[v])
  if v == 0:
    cache[v] = tf.math.bessel_i0e(z)
  elif v == 1:
    cache[v] = tf.math.bessel_i1e(z)
  elif v == 0.5:
    # sinh(x)*exp(-abs(x)), sinh(x) = (e^x - e^{-x}) / 2
    sinhe = lambda x: (tf.exp(x - tf.abs(x)) - tf.exp(-x - tf.abs(x))) / 2
    cache[v] = (
        np.sqrt(2 / np.pi) * sinhe(z) *
        tf.where(z > 0, tf.math.rsqrt(safe_z), tf.ones_like(safe_z)))
  elif v == -0.5:
    # cosh(x)*exp(-abs(x)), cosh(x) = (e^x + e^{-x}) / 2
    coshe = lambda x: (tf.exp(x - tf.abs(x)) + tf.exp(-x - tf.abs(x))) / 2
    cache[v] = (
        np.sqrt(2 / np.pi) * coshe(z) *
        tf.where(z > 0, tf.math.rsqrt(safe_z), tf.ones_like(safe_z)))
  if v <= 1:
    return wrap(cache[v])
  # Recurrence relation:
  cache[v] = (_bessel_ive(v - 2, z, cache) -
              (2 * (v - 1)) * _bessel_ive(v - 1, z, cache) / z)
  return wrap(cache[v])
def _bessel_ive(v, z, cache=None):
  """Computes I_v(z)*exp(-abs(z)) using a recurrence relation, where z > 0."""
  # TODO(b/67497980): Switch to a more numerically faithful implementation.
  z = tf.convert_to_tensor(value=z)

  wrap = lambda result: tf.debugging.check_numerics(result, 'besseli{}'.format(v
                                                                              ))

  if float(v) >= 2:
    raise ValueError(
        'Evaluating bessel_i by recurrence becomes imprecise for large v')

  cache = cache or {}
  safe_z = tf.where(z > 0, z, tf.ones_like(z))
  if v in cache:
    return wrap(cache[v])
  if v == 0:
    cache[v] = tf.math.bessel_i0e(z)
  elif v == 1:
    cache[v] = tf.math.bessel_i1e(z)
  elif v == 0.5:
    # sinh(x)*exp(-abs(x)), sinh(x) = (e^x - e^{-x}) / 2
    sinhe = lambda x: (tf.exp(x - tf.abs(x)) - tf.exp(-x - tf.abs(x))) / 2
    cache[v] = (
        np.sqrt(2 / np.pi) * sinhe(z) *
        tf.where(z > 0, tf.math.rsqrt(safe_z), tf.ones_like(safe_z)))
  elif v == -0.5:
    # cosh(x)*exp(-abs(x)), cosh(x) = (e^x + e^{-x}) / 2
    coshe = lambda x: (tf.exp(x - tf.abs(x)) + tf.exp(-x - tf.abs(x))) / 2
    cache[v] = (
        np.sqrt(2 / np.pi) * coshe(z) *
        tf.where(z > 0, tf.math.rsqrt(safe_z), tf.ones_like(safe_z)))
  if v <= 1:
    return wrap(cache[v])
  # Recurrence relation:
  cache[v] = (_bessel_ive(v - 2, z, cache) -
              (2 * (v - 1)) * _bessel_ive(v - 1, z, cache) / z)
  return wrap(cache[v])
def _bessel_ive ( v , z , cache = None ) : # TODO(b/67497980): Switch to a more numerically faithful implementation. z = tf . convert_to_tensor ( value = z ) wrap = lambda result : tf . debugging . check_numerics ( result , 'besseli{}' . format ( v ) ) if float ( v ) >= 2 : raise ValueError ( 'Evaluating bessel_i by recurrence becomes imprecise for large v' ) cache = cache or { } safe_z = tf . where ( z > 0 , z , tf . ones_like ( z ) ) if v in cache : return wrap ( cache [ v ] ) if v == 0 : cache [ v ] = tf . math . bessel_i0e ( z ) elif v == 1 : cache [ v ] = tf . math . bessel_i1e ( z ) elif v == 0.5 : # sinh(x)*exp(-abs(x)), sinh(x) = (e^x - e^{-x}) / 2 sinhe = lambda x : ( tf . exp ( x - tf . abs ( x ) ) - tf . exp ( - x - tf . abs ( x ) ) ) / 2 cache [ v ] = ( np . sqrt ( 2 / np . pi ) * sinhe ( z ) * tf . where ( z > 0 , tf . math . rsqrt ( safe_z ) , tf . ones_like ( safe_z ) ) ) elif v == - 0.5 : # cosh(x)*exp(-abs(x)), cosh(x) = (e^x + e^{-x}) / 2 coshe = lambda x : ( tf . exp ( x - tf . abs ( x ) ) + tf . exp ( - x - tf . abs ( x ) ) ) / 2 cache [ v ] = ( np . sqrt ( 2 / np . pi ) * coshe ( z ) * tf . where ( z > 0 , tf . math . rsqrt ( safe_z ) , tf . ones_like ( safe_z ) ) ) if v <= 1 : return wrap ( cache [ v ] ) # Recurrence relation: cache [ v ] = ( _bessel_ive ( v - 2 , z , cache ) - ( 2 * ( v - 1 ) ) * _bessel_ive ( v - 1 , z , cache ) / z ) return wrap ( cache [ v ] )
Computes I_v(z)*exp(-abs(z)) using a recurrence relation, where z > 0.
Computes I_v ( z ) * exp ( - abs ( z )) using a recurrence relation where z > 0 .