3

When estimating the hyperbolic tangent in Windows using the R base function tanh for large (real, with 0 imaginary part) values the function returns 'NaN':

tanh(356 + 0i)
> NaN + 0i

However, in Mac the same value returns 1 (coinciding with the "real" mathematical value should be close to 1):

tanh(356 + 0i)
> 1 + 0i

Question 1: Does anybody have a clue on why is this happening?

Extra info

This seems not a floating point problem because it seems that Mac's tanh returns 1 for arbitrarily large values:

tanh(999999677873648767519238192348124812341234182374817239847812738481234871823+0i)
> 1 + 0i

The problem seems to be related with the imaginary part as:

tanh(356)
> 1

in both Windows and Mac. The issue seems to be system (or processor?)-specific as we have tried it in:

  • Mac with El Capitan v 10.11.6 processor: 2.7 GHz Intel Core i5
  • Mac with Sierra v 10.12.3 processor: 3.2 GHz Intel Core i5
  • Windows 10 Home v 1607 processor: Intel Core m3-SY30 CPU@ 0.90 GHz 1.51 GHz
  • Windows 7 Home Premium Service Pack 1 processor: Intel Core i5-2410M CPU @2.30 GHz 2.30GHz.

These Windows machines throw NaN, the Mac's 1 + 0i. In all cases we are using R version 3.3.3 the "newest" (64 bit).

Rodrigo Zepeda
  • 1,935
  • 2
  • 15
  • 25
  • 1
    Interesting, on windows v 3.3.2 I get [1] "NaN+0i". – thc Mar 17 '17 at 01:30
  • I was getting also the `+ 0i` I didn't copy it correctly. I have edited now the term. – Rodrigo Zepeda Mar 17 '17 at 01:51
  • Ubuntu's seem to have same behavior as a mac – OganM Mar 17 '17 at 02:00
  • 1
    this looks like a glibc bug: fixed 2012 https://sourceware.org/bugzilla/show_bug.cgi?id=11521 . I don't know how to check glibc version on Windows. This might be a good question for `r-devel@r-project.org` ... – Ben Bolker Mar 17 '17 at 02:07
  • To follow up on this: I think the next step would be to write a short C program that calls the system-level complex-tanh function. If it fails in the same way, as expected, then that confirms that the problem is with the Windows system libraries. Don't know how to work around it though. – Ben Bolker Mar 20 '17 at 00:14

1 Answers1

4

@Ben Bolker is right on spot. Windows uses somewhat old C libraries, and here it is the "mathlib" part of glibc.

More specifically, according to the CRAN download page for R-devel for Windows https://cran.r-project.org/bin/windows/base/rdevel.html , the R 3.3.z series uses the gcc 4.6.3 (March 2012) toolchain, whereas "R-devel", the upcoming (not yet released!) R 3.4.z series uses the gcc 4.9.3 (June 2015) toolchain.

**However* I've just checked (installed the R-devel binary from CRAN on our Windows server virtual machine) and I see that the problem is still present there: In yesterday's version of R-devel, tanh(500+0i) still returns NaN+0i.

I now think a better solution would be to use R's internal substitute (in R's src/main/complex.c): We have

#ifndef HAVE_CTANH
#define ctanh R_ctanh
static double complex ctanh(double complex z)
{
    return -I * ctan(z * I); /* A&S 4.5.9 */
}
#endif

and we should use it, as I see that indeed, also on Windows,

R> -1i * tan((500+0i)*1i)

gives

[1] 1+0i

as it should for tanh(500+0i) --- but does not on Windows.

Martin Mächler
  • 4,619
  • 27
  • 27