浏览代码

Simplify sinh() and tanh() code now that we have expm1()

wip/image-kernel
Sam Hocevar 2 年前
父节点
当前提交
f1b95ac648
共有 1 个文件被更改,包括 9 次插入15 次删除
  1. +9
    -15
      include/lol/private/types/real.ipp

+ 9
- 15
include/lol/private/types/real.ipp 查看文件

@@ -1228,29 +1228,23 @@ template<typename T> real_t<T> erfc(real_t<T> const &x)

template<typename T> real_t<T> sinh(real_t<T> const &x)
{
/* We cannot always use (exp(x)-exp(-x))/2 because we'll lose
* accuracy near zero. We only use this identity for |x|>0.5. If
* |x|<=0.5, we compute exp(x)-1 and exp(-x)-1 instead. */
bool near_zero = (fabs(x) < real_t<T>::R_1() / 2);
auto x1 = near_zero ? fast_exp_sub(x, real_t<T>::R_1()) : exp(x);
auto x2 = near_zero ? fast_exp_sub(-x, real_t<T>::R_1()) : exp(-x);
return (x1 - x2) / 2;
// Use expm1() to ensure high accuracy around 0. No need to worry about
// accuracy in other ranges because either exp(x) or exp(-x) will be
// very large and cancel the other term.
return (expm1(x) - expm1(-x)) / 2;
}

template<typename T> real_t<T> tanh(real_t<T> const &x)
{
/* See sinh() for the strategy here */
bool near_zero = (fabs(x) < real_t<T>::R_1() / 2);
auto x1 = near_zero ? fast_exp_sub(x, real_t<T>::R_1()) : exp(x);
auto x2 = near_zero ? fast_exp_sub(-x, real_t<T>::R_1()) : exp(-x);
auto x3 = near_zero ? x1 + x2 + real_t<T>::R_2() : x1 + x2;
return (x1 - x2) / x3;
// See sinh() for the strategy here.
auto x1 = expm1(x), x2 = expm1(-x);
return (x1 - x2) / (x1 + x2 + real_t<T>::R_2());
}

template<typename T> real_t<T> cosh(real_t<T> const &x)
{
/* No need to worry about accuracy here; maybe the last bit is slightly
* off, but that's about it. */
// No need to worry about accuracy here; maybe the last bit is slightly
// off, but that's about it.
return (exp(x) + exp(-x)) / 2;
}



正在加载...
取消
保存