diff --git a/include/logaddexp/logaddexp.h b/include/logaddexp/logaddexp.h index 45763c1..7d2f725 100644 --- a/include/logaddexp/logaddexp.h +++ b/include/logaddexp/logaddexp.h @@ -2,10 +2,10 @@ #define LOGADDEXP_H #define LOGADDEXP_VERSION_MAJOR 2 -#define LOGADDEXP_VERSION_MINOR 0 +#define LOGADDEXP_VERSION_MINOR 1 #define LOGADDEXP_VERSION_PATCH 0 -#define LOGADDEXP_VERSION "2.0.0" +#define LOGADDEXP_VERSION "2.1.0" /* For Windows. */ #define _USE_MATH_DEFINES @@ -18,7 +18,7 @@ * For example, `log(exp(1e3) + exp(-INFINITY))` will likely overflow, * while `logaddexp(1e3, -INFINITY)` will return `1e3`. */ -inline static double logaddexp(double x, double y) +inline static double logaddexpd(double x, double y) { double const tmp = x - y; @@ -53,7 +53,7 @@ inline static float logaddexpf(float x, float y) * It is a weighted version of `logaddexp`, assuming that * 𝑠ₓ⋅𝑒ˣ + 𝑠ᡧ⋅𝑒ʸ > 0. */ -inline static double logaddexps(double x, double y, double sx, double sy) +inline static double logaddexpsd(double x, double y, double sx, double sy) { double const tmp = x - y; @@ -105,9 +105,9 @@ inline static float logaddexpsf(float x, float y, float sx, float sy) /* Computes ㏒ₑ(|𝑐|) and 𝑐/|𝑐|, for 𝑐 = 𝑠ₓ⋅𝑒ˣ + 𝑠ᡧ⋅𝑒ʸ. * - * It is a generalisation of `logaddexps`. + * It is a generalisation of `logaddexpsd`. */ -inline static double logaddexpg(double x, double y, double sx, double sy, double *sign) +inline static double logaddexpgd(double x, double y, double sx, double sy, double *sign) { double const sxx = log(fabs(sx)) + x; double const syy = log(fabs(sy)) + y; @@ -139,7 +139,7 @@ inline static double logaddexpg(double x, double y, double sx, double sy, double sx *= *sign; sy *= *sign; - return logaddexps(x, y, sx, sy); + return logaddexpsd(x, y, sx, sy); } inline static float logaddexpgf(float x, float y, float sx, float sy, float *sign) @@ -178,11 +178,27 @@ inline static float logaddexpgf(float x, float y, float sx, float sy, float *sig } /** - * Deprecated since version 1.1.0. Please, use `logaddexpg` instead. + * Deprecated since version 1.1.0. Please, use `logaddexpgd` instead. */ inline static double logaddexpss(double x, double y, double sx, double sy, double *sign) { - return logaddexpg(x, y, sx, sy, sign); + return logaddexpgd(x, y, sx, sy, sign); } +#define logaddexp(a, b) \ + ((sizeof(a) == sizeof(float) && sizeof(b) == sizeof(float)) ? logaddexpf(a, b) \ + : logaddexpd(a, b)) + +#define logaddexps(x, y, sx, sy) \ + ((sizeof(x) == sizeof(float) && sizeof(y) == sizeof(float) && \ + sizeof(sx) == sizeof(float) && sizeof(sy) == sizeof(float)) \ + ? logaddexpsf(x, y, sx, sy) \ + : logaddexpsd(x, y, sx, sy)) + +#define logaddexpg(x, y, sx, sy, sign) \ + ((sizeof(x) == sizeof(float) && sizeof(y) == sizeof(float) && \ + sizeof(sx) == sizeof(float) && sizeof(sy) == sizeof(float)) \ + ? logaddexpgf(x, y, sx, sy, sign) \ + : logaddexpgd(x, y, sx, sy, sign)) + #endif diff --git a/test/logaddexpg.c b/test/logaddexpg.c index 0cd1bc4..23617ca 100644 --- a/test/logaddexpg.c +++ b/test/logaddexpg.c @@ -41,7 +41,7 @@ int test_logaddexpg_values(void) double expected_val = log(fabs(c)); double expected_sign = c / fabs(c); double sign = 0.0; - double v = logaddexpg(log(x[i]), log(y[i]), sx[i], sy[i], &sign); + double v = logaddexpgd(log(x[i]), log(y[i]), sx[i], sy[i], &sign); if (fabs(expected_val - v) > EPSILON) return 1; if (expected_sign != sign) @@ -55,7 +55,7 @@ int test_logaddexpg_dbl_max(void) { double sign = 0.0; - if (fabs(-DBL_MAX - logaddexpg(1, 1, 1, -1, &sign)) > EPSILON) + if (fabs(-DBL_MAX - logaddexpgd(1., 1., 1., -1., &sign)) > EPSILON) return 1; if (1 != sign) @@ -75,7 +75,7 @@ int test_logaddexpg_range_pos(void) double sign = 0.0; for (size_t i = 0; i < 4; ++i) { - if (fabs(z[i] - logaddexpg(x[i], y[i], 1, 1, &sign)) > EPSILON) + if (fabs(z[i] - logaddexpgd(x[i], y[i], 1., 1., &sign)) > EPSILON) return 1; if (signs[i] != sign) return 1; @@ -94,7 +94,7 @@ int test_logaddexpg_range_neg(void) double sign = 0.0; for (size_t i = 0; i < 4; ++i) { - if (fabs(z[i] - logaddexpg(x[i], y[i], 1, -1, &sign)) > EPSILON) + if (fabs(z[i] - logaddexpgd(x[i], y[i], 1., -1., &sign)) > EPSILON) return 1; if (signs[i] != sign) return 1; @@ -107,20 +107,20 @@ int test_logaddexpg_hand_made(void) double expected = 2.9946394843421738; double sign = 0.0; - if (fabs(expected - logaddexpg(-39.1, 3.1, -3.3, 0.9, &sign)) > EPSILON) + if (fabs(expected - logaddexpgd(-39.1, 3.1, -3.3, 0.9, &sign)) > EPSILON) return 1; if (sign != 1) return 1; - if (fabs(expected - logaddexpg(-39.1, 3.1, -3.3, -0.9, &sign)) > EPSILON) + if (fabs(expected - logaddexpgd(-39.1, 3.1, -3.3, -0.9, &sign)) > EPSILON) return 1; if (sign != -1) return 1; expected = -3.0440928402878482; - if (fabs(expected - logaddexpg(-4., -5., -3.3, 1.9, &sign)) > EPSILON) + if (fabs(expected - logaddexpgd(-4., -5., -3.3, 1.9, &sign)) > EPSILON) return 1; if (sign != -1) diff --git a/test/logaddexps.c b/test/logaddexps.c index 0488a26..eeea266 100644 --- a/test/logaddexps.c +++ b/test/logaddexps.c @@ -44,11 +44,11 @@ int test_logaddexps_values(void) int test_logaddexps_dbl_max(void) { - if (fabs(-DBL_MAX - logaddexps(1, 1, 1, -1)) > EPSILON) + if (fabs(-DBL_MAX - logaddexps(1., 1., 1., -1.)) > EPSILON) return 1; - double v = logaddexps(1, 1, 1, -1); - if (fabs(1 - logaddexps(v, 1, 1, 1)) > EPSILON) + double v = logaddexps(1., 1., 1., -1.); + if (fabs(1 - logaddexps(v, 1., 1., 1.)) > EPSILON) return 1; return 0; @@ -62,7 +62,7 @@ int test_logaddexps_range(void) double z[] = {1000200, -1000000, 1000200, -1000000}; for (size_t i = 0; i < 4; ++i) { - if (fabs(z[i] - logaddexps(x[i], y[i], 1, 1)) > EPSILON) + if (fabs(z[i] - logaddexps(x[i], y[i], 1., 1.)) > EPSILON) return 1; } return 0;