Bug#327027: [Pkg-octave-devel] Bug#327027: octave2.1: not installable in sid

John W. Eaton jwe at bevo.che.wisc.edu
Fri Sep 9 21:44:55 UTC 2005


On  9-Sep-2005, Laurent Bonnaud wrote:

| Here is the build with g++-3.4.  It is worse than with g++-4.0 (6
| failures instead of 2).

Odd.  My results were:

  3.3: all tests pass

  3.4: all tests pass

  4.0: 1 failed  (FAIL: octave.test/arith/coth-1.m)

My system is Debian testing, updated to the latest packages just
before running my tests.  I built Octave 2.1.71 (downloaded from the
Octave ftp site) using 3.3, 3.4, and 4.0, with the following commands:

  tar zxf octave-2.1.71.tar.gz
  top=`pwd`
  for v in 3.3 3.4
  do
    mkdir $top/$v
    cd $top/$v
    ## since there is no g77-4.0, I used the default g77 (3.4) when
    ## building with gcc/g++ 4.0
    if [ "$v" = "4.0" ]; then G77=g77; else G77=g77-$v; fi
    ../octave-2.1.71/configure --enable-shared --disable-static CC=gcc-$v CXX=g++-$v F77=$G77
    make all check
  done

The failed test is:

  x = [pi/2*i, 3*pi/2*i];
  v = [0, 0];
  all (abs (coth (x) - v) < sqrt (eps))

Running this by hand (and looking at what is actually produced by coth
instead of just the final result) shows

  octave:4> coth(x)
  ans =

	     NaN -         NaNi           NaN -         NaNi

At least it is NaN, which will show up in obvious ways later on in a
calculation, instead of just some incorrect numerical result.  But
still, I would prefer that this bug be fixed before Octave packages
built with gcc 4.0 are distributed.

Octave's coth function is just a simple

  function w = coth (z)

    if (nargin != 1)
      usage ("coth (z)");
    endif

    w = 1 ./ tanh (z);

  endfunction

but tanh is a built-in function, and it is returning

  octave:7> tanh (x)
  ans =

	     NaN +         Infi           NaN +         Infi

for the same X as above.

The 4.0 <complex> header has

  // 26.2.8/15 tanh(__z):  Returns the hyperbolic tangent of __z.
  
  template<typename _Tp>
    inline complex<_Tp>
    __complex_tanh(const complex<_Tp>& __z)
    { return std::sinh(__z) / std::cosh(__z); }

#if _GLIBCXX_USE_C99_COMPLEX
  inline __complex__ float
  __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); }

  inline __complex__ double
  __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); }

  inline __complex__ long double
  __complex_tanh(const __complex__ long double& __z)
  { return __builtin_ctanhl(__z); }

  template<typename _Tp>
    inline complex<_Tp>
    tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); }
#else
  template<typename _Tp>
    inline complex<_Tp>
    tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); }
#endif

while the 3.3 <complex> header has

  template<typename _Tp>
    inline complex<_Tp>
    tanh(const complex<_Tp>& __z)
    {
      return sinh(__z) / cosh(__z);
    }

so my guess is the bug is in the __builtin_ctanh code.

Here is a simpler test case:

  #include <cmath>
  #include <iostream>
  #include <complex>

  int
  main (void)
  {
    std::cout << std::tanh (std::complex<double> (0, M_PI/2)) << std::endl;
    std::cout << std::tanh (std::complex<double> (0, 3*M_PI/2)) << std::endl;

    return 0;
  }

I think this should produce (0, inf) in both cases.  With 3.3, it is
still not right, as it produces

  (0,1.63318e+16)
  (0,5.44393e+15)

but at least it does not give NaN.

Or, is the C math library standard written so that tanh is required to
give (nan, inf) here?

Thanks,

jwe




More information about the Pkg-octave-devel mailing list