* Bug #14093 fixed - atanh returns NaN for values with an absolute value greater... 72/17072/3
Cedric Delamarre [Thu, 20 Aug 2015 08:18:41 +0000 (10:18 +0200)]
test_run elementary_functions bug_14093

Change-Id: I8d78ffdf02b65be0a7ff0104371abd4ab555e67a

scilab/CHANGES_6.0.X
scilab/modules/elementary_functions/sci_gateway/cpp/sci_atanh.cpp
scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.dia.ref [new file with mode: 0644]
scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.tst [new file with mode: 0644]

index 52da336..a16be2d 100644 (file)
@@ -41,6 +41,8 @@ Scilab Bug Fixes
 
 * Bug #14058 fixed - Scilab crashed with 'file("close", file())' instruction
 
+* Bug #14093 fixed - atanh returns NaN for values with an absolute value greater than 1
+
 * Bug #14095 fixed - Scilab crashed when a .fig file was loaded with loadmatfile function.
 
 
index ab6e171..77b9eef 100644 (file)
 #include "double.hxx"
 #include "overload.hxx"
 #include "execvisitor.hxx"
+#include "configvariable.hxx"
 
 extern "C"
 {
 #include "Scierror.h"
 #include "localization.h"
 #include "elem_common.h"
+#include "sciprint.h"
 }
 
 /*
@@ -48,33 +50,72 @@ types::Function::ReturnValue sci_atanh(types::typed_list &in, int _iRetCount, ty
     if (in[0]->isDouble())
     {
         pDblIn = in[0]->getAs<types::Double>();
-        pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray(), pDblIn->isComplex());
-
         double* pInR = pDblIn->get();
-        double* pOutR = pDblOut->get();
-        int size = pDblIn->getSize();
-        if (pDblIn->isComplex())
+        double* pInI = pDblIn->getImg();
+
+        int iSize = pDblIn->getSize();
+        bool bComplex = pDblIn->isComplex();
+        bool bAlreadyDisp = false;
+
+        if (bComplex == false)
         {
-            double* pInI = pDblIn->getImg();
-            double* pOutI = pDblOut->getImg();
+            // check values
+            for (int i = 0; i < iSize; i++)
+            {
+                double dAbsIn = abs(pInR[i]);
+                if (dAbsIn == 1)
+                {
+                    if (pInI && pDblIn->isComplex() == false)
+                    {
+                        delete[] pInI;
+                    }
+
+                    if (ConfigVariable::getIeee() == 0)
+                    {
+                        Scierror(78, _("%s: Warning: Wrong value for input argument #%d : Singularity of the function.\n"), "atanh", 1);
+                        return types::Function::Error;
+                    }
+
+                    if (ConfigVariable::getIeee() == 1 && ConfigVariable::getWarningMode() && bAlreadyDisp == false)
+                    {
+                        bAlreadyDisp = true;
+                        sciprint(_("%s: Warning: Wrong value for input argument #%d : Singularity of the function.\n"), "atanh", 1);
+                    }
+                }
+                else if (dAbsIn > 1 && bComplex == false)
+                {
+                    bComplex = true;
+                    pInI = new double[iSize];
+                    memset(pInI, 0x00, iSize * sizeof(double));
+                }
+            }
+        }
+
+        pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray(), bComplex);
+        double* pOutR = pDblOut->get();
+        double* pOutI = pDblOut->getImg();
 
-            for (int i = 0; i < size; i++)
+        if (bComplex)
+        {
+            // using scilab 5 macro atanh is faster than std::atanh (08/2015)
+            // see comment a the begins of this gateway
+            for (int i = 0; i < iSize; i++)
             {
                 //zcoss(-pInI[i], pInR[i], &pOutR[i], &pOutI[i]);
                 std::complex<double> c(pInR[i], pInI[i]);
                 std::complex<double> d = std::atanh(c);
+
                 pOutR[i] = d.real();
                 pOutI[i] = d.imag();
             }
         }
         else
         {
-            for (int i = 0; i < size; i++)
+            for (int i = 0; i < iSize; i++)
             {
                 pOutR[i] = atanh(pInR[i]);
             }
         }
-
         out.push_back(pDblOut);
     }
     else
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.dia.ref b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.dia.ref
new file mode 100644 (file)
index 0000000..654e729
--- /dev/null
@@ -0,0 +1,15 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 14093 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=14093
+//
+// <-- Short Description -->
+//    atanh returns NaN for values with an absolute value greater than 1
+assert_checktrue(atanh(3) <> %nan);
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_14093.tst
new file mode 100644 (file)
index 0000000..8fed7c4
--- /dev/null
@@ -0,0 +1,18 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2015 - Scilab Enterprises - Cedric Delamarre
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+
+// <-- Non-regression test for bug 14093 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=14093
+//
+// <-- Short Description -->
+//    atanh returns NaN for values with an absolute value greater than 1
+
+assert_checktrue(atanh(3) <> %nan);