Rename math.sum to math.fsum

This commit is contained in:
Mark Dickinson 2008-07-30 16:20:10 +00:00
parent f2eb2b44fc
commit fef6b13c32
5 changed files with 35 additions and 35 deletions

View File

@ -83,6 +83,16 @@ Number-theoretic and representation functions:
apart" the internal representation of a float in a portable way.
.. function:: fsum(iterable)
Return an accurate floating point sum of values in the iterable. Avoids
loss of precision by tracking multiple intermediate partial sums. The
algorithm's accuracy depends on IEEE-754 arithmetic guarantees and the
typical case where the rounding mode is half-even.
.. versionadded:: 2.6
.. function:: isinf(x)
Checks if the float *x* is positive or negative infinite.
@ -112,16 +122,6 @@ Number-theoretic and representation functions:
*x*, and both are floats.
.. function:: sum(iterable)
Return an accurate floating point sum of values in the iterable. Avoids
loss of precision by tracking multiple intermediate partial sums. The
algorithm's accuracy depends on IEEE-754 arithmetic guarantees and the
typical case where the rounding mode is half-even.
.. versionadded:: 2.6
.. function:: trunc(x)
Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually

View File

@ -1537,7 +1537,7 @@ Here are all of the changes that Python 2.6 makes to the core Python language.
* :func:`~math.factorial` computes the factorial of a number.
(Contributed by Raymond Hettinger; :issue:`2138`.)
* :func:`~math.sum` adds up the stream of numbers from an iterable,
* :func:`~math.fsum` adds up the stream of numbers from an iterable,
and is careful to avoid loss of precision by calculating partial sums.
(Contributed by Jean Brouwers, Raymond Hettinger, and Mark Dickinson;
:issue:`2819`.)

View File

@ -646,10 +646,10 @@ class MathTests(unittest.TestCase):
self.assert_(math.isnan(math.sqrt(NAN)))
def testSum(self):
# math.sum relies on exact rounding for correct operation.
# math.fsum relies on exact rounding for correct operation.
# There's a known problem with IA32 floating-point that causes
# inexact rounding in some situations, and will cause the
# math.sum tests below to fail; see issue #2937. On non IEEE
# math.fsum tests below to fail; see issue #2937. On non IEEE
# 754 platforms, and on IEEE 754 platforms that exhibit the
# problem described in issue #2937, we simply skip the whole
# test.
@ -662,7 +662,7 @@ class MathTests(unittest.TestCase):
if 1e16+2.0 != 1e16+2.9999:
return
# Python version of math.sum, for comparison. Uses a
# Python version of math.fsum, for comparison. Uses a
# different algorithm based on frexp, ldexp and integer
# arithmetic.
from sys import float_info
@ -719,13 +719,13 @@ class MathTests(unittest.TestCase):
for i, (vals, expected) in enumerate(test_values):
try:
actual = math.sum(vals)
actual = math.fsum(vals)
except OverflowError:
self.fail("test %d failed: got OverflowError, expected %r "
"for math.sum(%.100r)" % (i, expected, vals))
"for math.fsum(%.100r)" % (i, expected, vals))
except ValueError:
self.fail("test %d failed: got ValueError, expected %r "
"for math.sum(%.100r)" % (i, expected, vals))
"for math.fsum(%.100r)" % (i, expected, vals))
self.assertEqual(actual, expected)
from random import random, gauss, shuffle
@ -739,7 +739,7 @@ class MathTests(unittest.TestCase):
shuffle(vals)
s = msum(vals)
self.assertEqual(msum(vals), math.sum(vals))
self.assertEqual(msum(vals), math.fsum(vals))
def testTan(self):

View File

@ -5,7 +5,7 @@ import random
import time
import pickle
import warnings
from math import log, exp, sqrt, pi, sum as msum
from math import log, exp, sqrt, pi, fsum as msum
from test import test_support
class TestBasicOps(unittest.TestCase):

View File

@ -352,7 +352,7 @@ FUNC1(tanh, tanh, 0,
/* Extend the partials array p[] by doubling its size. */
static int /* non-zero on error */
_sum_realloc(double **p_ptr, Py_ssize_t n,
_fsum_realloc(double **p_ptr, Py_ssize_t n,
double *ps, Py_ssize_t *m_ptr)
{
void *v = NULL;
@ -370,7 +370,7 @@ _sum_realloc(double **p_ptr, Py_ssize_t n,
v = PyMem_Realloc(p, sizeof(double) * m);
}
if (v == NULL) { /* size overflow or no memory */
PyErr_SetString(PyExc_MemoryError, "math sum partials");
PyErr_SetString(PyExc_MemoryError, "math.fsum partials");
return 1;
}
*p_ptr = (double*) v;
@ -409,7 +409,7 @@ _sum_realloc(double **p_ptr, Py_ssize_t n,
*/
static PyObject*
math_sum(PyObject *self, PyObject *seq)
math_fsum(PyObject *self, PyObject *seq)
{
PyObject *item, *iter, *sum = NULL;
Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
@ -421,7 +421,7 @@ math_sum(PyObject *self, PyObject *seq)
if (iter == NULL)
return NULL;
PyFPE_START_PROTECT("sum", Py_DECREF(iter); return NULL)
PyFPE_START_PROTECT("fsum", Py_DECREF(iter); return NULL)
for(;;) { /* for x in iterable */
assert(0 <= n && n <= m);
@ -431,13 +431,13 @@ math_sum(PyObject *self, PyObject *seq)
item = PyIter_Next(iter);
if (item == NULL) {
if (PyErr_Occurred())
goto _sum_error;
goto _fsum_error;
break;
}
x = PyFloat_AsDouble(item);
Py_DECREF(item);
if (PyErr_Occurred())
goto _sum_error;
goto _fsum_error;
xsave = x;
for (i = j = 0; j < n; j++) { /* for y in partials */
@ -462,8 +462,8 @@ math_sum(PyObject *self, PyObject *seq)
summands */
if (Py_IS_FINITE(xsave)) {
PyErr_SetString(PyExc_OverflowError,
"intermediate overflow in sum");
goto _sum_error;
"intermediate overflow in fsum");
goto _fsum_error;
}
if (Py_IS_INFINITY(xsave))
inf_sum += xsave;
@ -471,8 +471,8 @@ math_sum(PyObject *self, PyObject *seq)
/* reset partials */
n = 0;
}
else if (n >= m && _sum_realloc(&p, n, ps, &m))
goto _sum_error;
else if (n >= m && _fsum_realloc(&p, n, ps, &m))
goto _fsum_error;
else
p[n++] = x;
}
@ -481,10 +481,10 @@ math_sum(PyObject *self, PyObject *seq)
if (special_sum != 0.0) {
if (Py_IS_NAN(inf_sum))
PyErr_SetString(PyExc_ValueError,
"-inf + inf in sum");
"-inf + inf in fsum");
else
sum = PyFloat_FromDouble(special_sum);
goto _sum_error;
goto _fsum_error;
}
hi = 0.0;
@ -518,7 +518,7 @@ math_sum(PyObject *self, PyObject *seq)
}
sum = PyFloat_FromDouble(hi);
_sum_error:
_fsum_error:
PyFPE_END_PROTECT(hi)
Py_DECREF(iter);
if (p != ps)
@ -528,7 +528,7 @@ _sum_error:
#undef NUM_PARTIALS
PyDoc_STRVAR(math_sum_doc,
PyDoc_STRVAR(math_fsum_doc,
"sum(iterable)\n\n\
Return an accurate floating point sum of values in the iterable.\n\
Assumes IEEE-754 floating point arithmetic.");
@ -1021,6 +1021,7 @@ static PyMethodDef math_methods[] = {
{"floor", math_floor, METH_O, math_floor_doc},
{"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
{"frexp", math_frexp, METH_O, math_frexp_doc},
{"fsum", math_fsum, METH_O, math_fsum_doc},
{"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
{"isinf", math_isinf, METH_O, math_isinf_doc},
{"isnan", math_isnan, METH_O, math_isnan_doc},
@ -1034,10 +1035,9 @@ static PyMethodDef math_methods[] = {
{"sin", math_sin, METH_O, math_sin_doc},
{"sinh", math_sinh, METH_O, math_sinh_doc},
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
{"sum", math_sum, METH_O, math_sum_doc},
{"tan", math_tan, METH_O, math_tan_doc},
{"tanh", math_tanh, METH_O, math_tanh_doc},
{"trunc", math_trunc, METH_O, math_trunc_doc},
{"trunc", math_trunc, METH_O, math_trunc_doc},
{NULL, NULL} /* sentinel */
};