[goffice] Math: add go_cotpi and go_atanpi.



commit 41b7f03720b17dc749e9762df01a9bd887928d6a
Author: Morten Welinder <terra gnome org>
Date:   Sat Apr 11 22:21:35 2015 -0400

    Math: add go_cotpi and go_atanpi.

 ChangeLog              |    5 ++++
 NEWS                   |    1 +
 goffice/math/go-math.c |   60 ++++++++++++++++++++++++++++-------------------
 goffice/math/go-math.h |    4 +++
 tests/test-math.c      |   49 ++++++++++++++++++++++++++++++++++++---
 5 files changed, 91 insertions(+), 28 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8fa7be9..2f28e5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-11  Morten Welinder  <terra gnome org>
+
+       * goffice/math/go-math.c (go_atan2pi): Simplify.
+       (go_atanpi, go_cotpi): New functions.
+
 2015-04-03  Morten Welinder  <terra gnome org>
 
        * goffice/utils/go-pattern.c (go_pattern_create_cairo_pattern):
diff --git a/NEWS b/NEWS
index 0af622a..4c8a102 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Morten:
        * Don't force bar/col axis to include 0 for log axis.
        * Don't force radial plots to include 0 for log axis.
        * Rewrite pattern-fill rendering.  [#747212]
+       * Add go_cotpi and go_atan2pi.
 
 --------------------------------------------------------------------------
 goffice 0.10.21:
diff --git a/goffice/math/go-math.c b/goffice/math/go-math.c
index 6c5dfc8..2999c1d 100644
--- a/goffice/math/go-math.c
+++ b/goffice/math/go-math.c
@@ -1025,23 +1025,29 @@ go_tanpi (double x)
 }
 
 double
-go_atan2pi (double y, double x)
+go_cotpi (double x)
 {
-       /* This ignores loads of cases with -0. */
-
-       if (y == 0)
-               return (x >= 0 ? 0 : +1);
-
-       if (x == 0)
-               return (y >= 0 ? 0.5 : -0.5);
-
-       if (fabs (x) == fabs (y))
-               return (y > 0 ? +1 : -1) * (x > 0 ? 0.25 : 0.75);
+       int k;
+       x = reduce_half (x, &k);
+       return do_sinpi (x, k + 1) / do_sinpi (x, k);
+}
 
-       /* Fallback.  */
+double
+go_atan2pi (double y, double x)
+{
+       /*
+        * This works perfectly for results that are (n/4).   We currently have
+        * nothing interesting to add.
+        */
        return atan2 (y, x) / M_PI;
 }
 
+double
+go_atanpi (double x)
+{
+       return x < 0 ? go_atan2pi (-x, -1) : go_atan2pi (x, 1);
+}
+
 #ifdef GOFFICE_WITH_LONG_DOUBLE
 
 #define M_PIgo    
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117L
@@ -1132,23 +1138,29 @@ go_tanpil (long double x)
 }
 
 long double
-go_atan2pil (long double y, long double x)
+go_cotpil (long double x)
 {
-       /* This ignores loads of cases with -0. */
-
-       if (y == 0)
-               return (x >= 0 ? 0 : +1);
-
-       if (x == 0)
-               return (y >= 0 ? 0.5 : -0.5);
-
-       if (fabs (x) == fabs (y))
-               return (y > 0 ? +1 : -1) * (x > 0 ? 0.25 : 0.75);
+       int k;
+       x = reduce_halfl (x, &k);
+       return do_sinpil (x, k + 1) / do_sinpil (x, k);
+}
 
-       /* Fallback.  */
+long double
+go_atan2pil (long double y, long double x)
+{
+       /*
+        * This works perfectly for results that are (n/4), at least with x86
+        * long double.   We currently have nothing interesting to add.
+        */
        return atan2l (y, x) / M_PIgo;
 }
 
+long double
+go_atanpil (long double x)
+{
+       return x < 0 ? go_atan2pil (-x, -1) : go_atan2pil (x, 1);
+}
+
 #endif
 
 /* ------------------------------------------------------------------------- */
diff --git a/goffice/math/go-math.h b/goffice/math/go-math.h
index 84f2c94..e7d7f22 100644
--- a/goffice/math/go-math.h
+++ b/goffice/math/go-math.h
@@ -42,7 +42,9 @@ double go_ascii_strtod (const char *s, char **end);
 double go_sinpi (double x);
 double go_cospi (double x);
 double go_tanpi (double x);
+double go_cotpi (double x);
 double go_atan2pi (double y, double x);
+double go_atanpi (double x);
 
 /*
  * We provide working versions of these functions for doubles.
@@ -88,7 +90,9 @@ long double go_ascii_strtold (const char *s, char **end);
 long double go_sinpil (long double x);
 long double go_cospil (long double x);
 long double go_tanpil (long double x);
+long double go_cotpil (long double x);
 long double go_atan2pil (long double y, long double x);
+long double go_atanpil (long double x);
 
 /*
  * We provide working versions of these functions for long doubles.
diff --git a/tests/test-math.c b/tests/test-math.c
index fe76b9a..fc737c4 100644
--- a/tests/test-math.c
+++ b/tests/test-math.c
@@ -21,23 +21,44 @@ do {                                                        \
        double fab = f_(a, b);                          \
        g_printerr ("%s(%g,%g) = %g  [%g]\n",           \
                    txt_, a, b, fab, r);                \
-       if (r == floor (r))                             \
+       if (r * 256 == floor (r * 256))                 \
                g_assert (r == fab);                    \
        else                                            \
                g_assert (fabs (r - fab) / r < 1e-14);  \
 } while (0)
 
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+#define REFTEST2l(a_,b_,f_,r_, txt_)                   \
+do {                                                   \
+       long double a = (a_);                           \
+       long double b = (b_);                           \
+       long double r = (r_);                           \
+       long double fab = f_(a, b);                     \
+       g_printerr ("%s(%Lg,%Lg) = %Lg  [%Lg]\n",       \
+                   txt_, a, b, fab, r);                \
+       if (r * 256 == floorl (r * 256))                \
+               g_assert (r == fab);                    \
+       else                                            \
+               g_assert (fabsl (r - fab) / r < 1e-14); \
+} while (0)
+#else
+#define REFTEST2l(a_,b_,f_,r_, txt_)
+#endif
+
 /* ------------------------------------------------------------------------- */
 
 static double fake_sinpi (double x) { return x == floor (x) ? 0 : sin (x * M_PI); }
 static double fake_cospi (double x) { return fake_sinpi (x + 0.5); }
+static double fake_atanpi (double x) { return atan (x) / M_PI; }
 static double fake_atan2pi (double y, double x) { return atan2 (y,x) / M_PI; }
 
 
-#define TEST1(a_) do {                                 \
-       REFTEST(a_,go_sinpi,fake_sinpi(a_),"sinpi");    \
-       REFTEST(a_,go_cospi,fake_cospi(a_),"cospi");    \
+#define TEST1(a_) do {                                                 \
+       REFTEST(a_,go_sinpi,fake_sinpi(a_),"sinpi");                    \
+       REFTEST(a_,go_cospi,fake_cospi(a_),"cospi");                    \
        REFTEST(a_,go_tanpi,(fake_sinpi(a_)/fake_cospi(a_)),"tanpi");   \
+       REFTEST(a_,go_cotpi,(fake_cospi(a_)/fake_sinpi(a_)),"cotpi");   \
+       REFTEST(a_,go_atanpi,fake_atanpi(a_),"atanpi");                 \
 } while (0)
 
 #define TEST2(a_,b_) do {                                              \
@@ -84,6 +105,26 @@ trig_tests (void)
        TEST2 (exp(1), -1);
        TEST2 (exp(1), log(2));
        TEST2 (exp(1), -log(2));
+
+       /* Since the results are n/4 these are tested exactly.  */
+       REFTEST2(0,1,go_atan2pi,0,"atan2pi");
+       REFTEST2(1,1,go_atan2pi,0.25,"atan2pi");
+       REFTEST2(1,0,go_atan2pi,0.5,"atan2pi");
+       REFTEST2(1,-1,go_atan2pi,0.75,"atan2pi");
+       REFTEST2(0,-1,go_atan2pi,1,"atan2pi");
+       REFTEST2(-1,1,go_atan2pi,-0.25,"atan2pi");
+       REFTEST2(-1,0,go_atan2pi,-0.5,"atan2pi");
+       REFTEST2(-1,-1,go_atan2pi,-0.75,"atan2pi");
+
+       /* Since the results are n/4 these are tested exactly.  */
+       REFTEST2l(0,1,go_atan2pil,0,"atan2pil");
+       REFTEST2l(1,1,go_atan2pil,0.25,"atan2pil");
+       REFTEST2l(1,0,go_atan2pil,0.5,"atan2pil");
+       REFTEST2l(1,-1,go_atan2pil,0.75,"atan2pil");
+       REFTEST2l(0,-1,go_atan2pil,1,"atan2pil");
+       REFTEST2l(-1,1,go_atan2pil,-0.25,"atan2pil");
+       REFTEST2l(-1,0,go_atan2pil,-0.5,"atan2pil");
+       REFTEST2l(-1,-1,go_atan2pil,-0.75,"atan2pil");
 }
 
 #undef TEST1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]