예제 #1
0
 def _log_cdf(self, x):
   loc, scale, low, high = self._loc_scale_low_high()
   std_low, std_high = self._standardized_low_and_high(
       low=low, high=high, loc=loc, scale=scale)
   return (_log_sub_exp(
       special_math.log_ndtr(
           (x - loc) / scale), special_math.log_ndtr(std_low)) -
           self._log_normalizer(std_low=std_low, std_high=std_high))
예제 #2
0
 def _mean(self):
   loc, scale, low, high = self._loc_scale_low_high()
   std_low, std_high = self._standardized_low_and_high(
       loc=loc, scale=scale, low=low, high=high)
   lse, sign = _log_sub_exp(_normal_log_pdf(std_low),
                            _normal_log_pdf(std_high),
                            return_sign=True)
   return loc + scale * sign * tf.math.exp(
       lse - self._log_normalizer(std_low=std_low, std_high=std_high))
예제 #3
0
def _normal_cdf_log_difference(x, y):
    """Computes log(ndtr(x) - ndtr(y)) assuming that x >= y."""
    # When x >= y >= 0, we will return log(ndtr(-y) - ndtr(-x))
    # because ndtr does not have a good precision for large positive x, y.
    is_y_positive = y >= 0
    x_hat = tf.where(is_y_positive, -y, x)
    y_hat = tf.where(is_y_positive, -x, y)
    return _log_sub_exp(special_math.log_ndtr(x_hat),
                        special_math.log_ndtr(y_hat))
예제 #4
0
 def _log_normalizer(self,
                     loc=None,
                     scale=None,
                     low=None,
                     high=None,
                     std_low=None,
                     std_high=None):
   if std_low is None or std_high is None:
     std_low, std_high = self._standardized_low_and_high(
         loc=loc, scale=scale, low=low, high=high)
   return _log_sub_exp(
       special_math.log_ndtr(std_high), special_math.log_ndtr(std_low))
예제 #5
0
 def _log_normalizer(self,
                     loc=None,
                     scale=None,
                     low=None,
                     high=None,
                     std_low=None,
                     std_high=None):
     if std_low is None or std_high is None:
         std_low, std_high = self._standardized_low_and_high(loc=loc,
                                                             scale=scale,
                                                             low=low,
                                                             high=high)
     return _log_sub_exp(_log_cauchy_cdf(std_high),
                         _log_cauchy_cdf(std_low))
예제 #6
0
 def _variance(self):
   loc, scale, low, high = self._loc_scale_low_high()
   std_low, std_high = self._standardized_low_and_high(
       loc=loc, scale=scale, low=low, high=high)
   log_normalizer = self._log_normalizer(std_low=std_low, std_high=std_high)
   var = (
       tf.square(scale) *
       (1. +
        (std_low * _normal_pdf(std_low) - std_high * _normal_pdf(std_high)) /
        tf.exp(log_normalizer) -
        tf.exp(2. * (
            _log_sub_exp(  # ignore sign because result gets squared
                _normal_log_pdf(std_low), _normal_log_pdf(std_high))
            - log_normalizer))))
   return var