[goffice] Math: add go_sinpi, go_cospi, go_tanpi.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Math: add go_sinpi, go_cospi, go_tanpi.
- Date: Wed, 18 Dec 2013 17:22:35 +0000 (UTC)
commit 5145c7db37081488a0cacaba35c777581faa628e
Author: Morten Welinder <terra gnome org>
Date: Wed Dec 18 12:22:03 2013 -0500
Math: add go_sinpi, go_cospi, go_tanpi.
ChangeLog | 5 ++
NEWS | 1 +
goffice/math/go-math.c | 159 +++++++++++++++++++++++++++++++++++++++++------
goffice/math/go-math.h | 9 +++
tests/.gitignore | 1 +
tests/Makefile.am | 7 ++-
tests/test-math.c | 51 +++++++++++++++
tests/test-quad.c | 3 +
8 files changed, 213 insertions(+), 23 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 605a227..bb0e01e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-18 Morten Welinder <terra gnome org>
+
+ * goffice/math/go-math.c (go_sinpi, go_cospi, go_tanpi): New
+ functions.
+
2013-12-17 Morten Welinder <terra gnome org>
* goffice/math/go-math.c (go_add_epsilon, go_sub_epsilon): Base
diff --git a/NEWS b/NEWS
index eb1cd54..acaf077 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ Jean
Morten:
* Improve complex math, notably complex power.
* Add quad precision log, atan2, hypot, asin, acos functions.
+ * Add go_sinpi, go_cospi, and go_tanpi.
--------------------------------------------------------------------------
goffice 0.10.9:
diff --git a/goffice/math/go-math.c b/goffice/math/go-math.c
index c4545b2..ec9c14f 100644
--- a/goffice/math/go-math.c
+++ b/goffice/math/go-math.c
@@ -30,27 +30,6 @@
#include <signal.h>
#include <errno.h>
-#if defined (HAVE_IEEEFP_H) || defined (HAVE_IEEE754_H)
-/* Make sure we have this symbol defined, since the existance of either
- header file implies it. */
-#ifndef IEEE_754
-#define IEEE_754
-#endif
-#endif
-
-#ifdef HAVE_SUNMATH_H
-#include <sunmath.h>
-#endif
-
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-#ifdef HAVE_IEEE754_H
-#include <ieee754.h>
-#endif
-
-#define ML_UNDERFLOW (GO_EPSILON * GO_EPSILON)
-
double go_nan;
double go_pinf;
double go_ninf;
@@ -923,3 +902,141 @@ go_stern_brocot (double val, int max_denom, int *res_num, int *res_denom)
*res_denom = bd;
}
}
+
+/* ------------------------------------------------------------------------- */
+
+static double
+reduce_half (double x, int *pk)
+{
+ int k = 0;
+
+ if (x < 0) {
+ x = -reduce_half (-x, &k);
+ k = 4 - k;
+ if (x == -0.25)
+ x += 0.5, k += 3;
+ } else {
+ x = fmod (x, 2);
+ if (x >= 1)
+ x -= 1, k += 2;
+ if (x >= 0.5)
+ x -= 0.5, k++;
+ if (x > 0.25)
+ x -= 0.5, k++;
+ }
+
+ *pk = (k & 3);
+ return x;
+}
+
+static double
+do_sin (double x, int k)
+{
+ double y;
+
+ if (x == 0)
+ y = k & 1;
+ else if (x == 0.25)
+ y = 0.707106781186547524400844362104849039284835937688474036588339;
+ else
+ y = (k & 1) ? cos (M_PI * x) : sin (M_PI * x);
+
+ return (k & 2) ? 0 - y : y;
+}
+
+
+double
+go_sinpi (double x)
+{
+ int k;
+ x = reduce_half (x, &k);
+ return do_sin (x, k);
+}
+
+double
+go_cospi (double x)
+{
+ int k;
+ x = reduce_half (x, &k);
+ return do_sin (x, k + 1);
+}
+
+double
+go_tanpi (double x)
+{
+ int k;
+ x = reduce_half (x, &k);
+ return do_sin (x, k) / do_sin (x, k + 1);
+}
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+
+#define M_PIgo
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117L
+
+static long double
+reduce_halfl (long double x, int *pk)
+{
+ int k = 0;
+
+ if (x < 0) {
+ x = -reduce_halfl (-x, &k);
+ k = 4 - k;
+ if (x == -0.25)
+ x += 0.5, k += 3;
+ } else {
+ x = fmod (x, 2);
+ if (x >= 1)
+ x -= 1, k += 2;
+ if (x >= 0.5)
+ x -= 0.5, k++;
+ if (x > 0.25)
+ x -= 0.5, k++;
+ }
+
+ *pk = (k & 3);
+ return x;
+}
+
+static long double
+do_sinl (long double x, int k)
+{
+ long double y;
+
+ if (x == 0)
+ y = k & 1;
+ else if (x == 0.25)
+ y = 0.707106781186547524400844362104849039284835937688474036588339L;
+ else
+ y = (k & 1) ? cos (M_PIgo * x) : sin (M_PIgo * x);
+
+ return (k & 2) ? 0 - y : y;
+}
+
+
+long double
+go_sinpil (long double x)
+{
+ int k;
+ x = reduce_halfl (x, &k);
+ return do_sinl (x, k);
+}
+
+long double
+go_cospil (long double x)
+{
+ int k;
+ x = reduce_halfl (x, &k);
+ return do_sinl (x, k + 1);
+}
+
+long double
+go_tanpil (long double x)
+{
+ int k;
+ x = reduce_halfl (x, &k);
+ return do_sinl (x, k) / do_sinl (x, k + 1);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
diff --git a/goffice/math/go-math.h b/goffice/math/go-math.h
index 1e89dea..3d88085 100644
--- a/goffice/math/go-math.h
+++ b/goffice/math/go-math.h
@@ -38,6 +38,11 @@ double go_pow10 (int n);
double go_strtod (const char *s, char **end);
double go_ascii_strtod (const char *s, char **end);
+
+double go_sinpi (double x);
+double go_cospi (double x);
+double go_tanpi (double x);
+
/*
* We provide working versions of these functions for doubles.
*/
@@ -79,6 +84,10 @@ long double go_pow10l (int n);
long double go_strtold (const char *s, char **end);
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);
+
/*
* We provide working versions of these functions for long doubles.
*/
diff --git a/tests/.gitignore b/tests/.gitignore
index 048d6f2..cdb61bd 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -11,4 +11,5 @@ go-demo
mf-demo
pie-demo
shapes-demo
+test-math
test-quad
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cfee370..9433c51 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,12 +1,12 @@
if WITH_GTK
-check_PROGRAMS = pie-demo go-demo shapes-demo mf-demo test-quad
+check_PROGRAMS = pie-demo go-demo shapes-demo mf-demo test-quad test-math
endif
include $(top_srcdir)/goffice.mk
AM_CFLAGS = $(GOFFICE_CFLAGS)
-TESTS = test-quad
+TESTS = test-quad test-math
pie_demo_LDADD = $(GOFFICE_PLUGIN_LIBADD)
pie_demo_SOURCES = pie-demo.c
@@ -23,5 +23,8 @@ mf_demo_SOURCES = mf-demo.c
test_quad_LDADD = $(GOFFICE_PLUGIN_LIBADD)
test_quad_SOURCES = test-quad.c
+test_math_LDADD = $(GOFFICE_PLUGIN_LIBADD)
+test_math_SOURCES = test-math.c
+
EXTRA_DIST = go-demo.ui
diff --git a/tests/test-math.c b/tests/test-math.c
new file mode 100644
index 0000000..0e93829
--- /dev/null
+++ b/tests/test-math.c
@@ -0,0 +1,51 @@
+#include <goffice/goffice.h>
+
+#define REFTEST(a_,f_,r_, txt_) \
+do { \
+ double a = (a_); \
+ double r = (r_); \
+ double fa = f_(a); \
+ g_printerr ("%s(%g) = %g [%g]\n", \
+ txt_, a, fa, r); \
+ if (r == floor (r)) \
+ g_assert (r == fa); \
+ else \
+ g_assert (fabs (r - fa) / r < 1e-14); \
+} while (0)
+
+
+/* ------------------------------------------------------------------------- */
+
+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); }
+
+
+
+#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"); \
+} while (0)
+
+static void
+trig_tests (void)
+{
+ double d;
+
+ for (d = 0; d < 10; d += 0.125) {
+ TEST1(d);
+ TEST1(-d);
+ }
+}
+
+#undef TEST1
+
+/* ------------------------------------------------------------------------- */
+
+int
+main (int argc, char **argv)
+{
+ trig_tests ();
+
+ return 0;
+}
diff --git a/tests/test-quad.c b/tests/test-quad.c
index b4fe2f9..88f8514 100644
--- a/tests/test-quad.c
+++ b/tests/test-quad.c
@@ -100,6 +100,9 @@ atan2_tests (void)
TEST1 (-3, 0);
TEST1 (0, 0);
TEST1 (+1, +1);
+ TEST1 (-1, +1);
+ TEST1 (+1, -1);
+ TEST1 (-1, -1);
TEST1 (+2.3, +1.2);
TEST1 (+2.3, -1.2);
TEST1 (+2.3, +0.2);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]