
Aug. 11, 2023
12:43 p.m.
I'm really confused. Summing from zero should be what cumsum() does now. ```
np.__version__ '1.22.4' np.cumsum([[1, 2, 3], [4, 5, 6]]) array([ 1, 3, 6, 10, 15, 21])
which matches your example in the cumsum0() documentation. Did something
change in a recent release?
Ben Root
On Fri, Aug 11, 2023 at 8:55 AM Juan Nunez-Iglesias <jni@fastmail.com>
wrote:
> I'm very sensitive to the issues of adding to the already bloated numpy
> API, but I would definitely find use in this function. I literally made
> this error (thinking that the first element of cumsum should be 0) just a
> couple of days ago! What are the plans for the "extended" NumPy API after
> 2.0? Is there a good place for these variants?
>
> On Fri, 11 Aug 2023, at 2:07 AM, john.dawson@camlingroup.com wrote:
> > `cumsum` computes the sum of the first k summands for every k from 1.
> > Judging by my experience, it is more often useful to compute the sum of
> > the first k summands for every k from 0, as `cumsum`'s behaviour leads
> > to fencepost-like problems.
> > https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_error
> > For example, `cumsum` is not the inverse of `diff`. I propose adding a
> > function to NumPy to compute cumulative sums beginning with 0, that is,
> > an inverse of `diff`. It might be called `cumsum0`. The following code
> > is probably not the best way to implement it, but it illustrates the
> > desired behaviour.
> >
> > ```
> > def cumsum0(a, axis=None, dtype=None, out=None):
> > """
> > Return the cumulative sum of the elements along a given axis,
> > beginning with 0.
> >
> > cumsum0 does the same as cumsum except that cumsum computes the sum
> > of the first k summands for every k from 1 and cumsum, from 0.
> >
> > Parameters
> > ----------
> > a : array_like
> > Input array.
> > axis : int, optional
> > Axis along which the cumulative sum is computed. The default
> > (None) is to compute the cumulative sum over the flattened
> > array.
> > dtype : dtype, optional
> > Type of the returned array and of the accumulator in which the
> > elements are summed. If `dtype` is not specified, it defaults to
> > the dtype of `a`, unless `a` has an integer dtype with a
> > precision less than that of the default platform integer. In
> > that case, the default platform integer is used.
> > out : ndarray, optional
> > Alternative output array in which to place the result. It must
> > have the same shape and buffer length as the expected output but
> > the type will be cast if necessary. See
> > :ref:`ufuncs-output-type` for more details.
> >
> > Returns
> > -------
> > cumsum0_along_axis : ndarray.
> > A new array holding the result is returned unless `out` is
> > specified, in which case a reference to `out` is returned. If
> > `axis` is not None the result has the same shape as `a` except
> > along `axis`, where the dimension is smaller by 1.
> >
> > See Also
> > --------
> > cumsum : Cumulatively sum array elements, beginning with the first.
> > sum : Sum array elements.
> > trapz : Integration of array values using the composite trapezoidal
> rule.
> > diff : Calculate the n-th discrete difference along given axis.
> >
> > Notes
> > -----
> > Arithmetic is modular when using integer types, and no error is
> > raised on overflow.
> >
> > ``cumsum0(a)[-1]`` may not be equal to ``sum(a)`` for floating-point
> > values since ``sum`` may use a pairwise summation routine, reducing
> > the roundoff-error. See `sum` for more information.
> >
> > Examples
> > --------
> > >>> a = np.array([[1, 2, 3], [4, 5, 6]])
> > >>> a
> > array([[1, 2, 3],
> > [4, 5, 6]])
> > >>> np.cumsum0(a)
> > array([ 0, 1, 3, 6, 10, 15, 21])
> > >>> np.cumsum0(a, dtype=float) # specifies type of output value(s)
> > array([ 0., 1., 3., 6., 10., 15., 21.])
> >
> > >>> np.cumsum0(a, axis=0) # sum over rows for each of the 3 columns
> > array([[0, 0, 0],
> > [1, 2, 3],
> > [5, 7, 9]])
> > >>> np.cumsum0(a, axis=1) # sum over columns for each of the 2 rows
> > array([[ 0, 1, 3, 6],
> > [ 0, 4, 9, 15]])
> >
> > ``cumsum(b)[-1]`` may not be equal to ``sum(b)``
> >
> > >>> b = np.array([1, 2e-9, 3e-9] * 1000000)
> > >>> np.cumsum0(b)[-1]
> > 1000000.0050045159
> > >>> b.sum()
> > 1000000.0050000029
> >
> > """
> > empty = a.take([], axis=axis)
> > zero = empty.sum(axis, dtype=dtype, keepdims=True)
> > later_cumsum = a.cumsum(axis, dtype=dtype)
> > return concatenate([zero, later_cumsum], axis=axis, dtype=dtype,
> out=out)
> > ```
> > _______________________________________________
> > NumPy-Discussion mailing list -- numpy-discussion@python.org
> > To unsubscribe send an email to numpy-discussion-leave@python.org
> > https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> > Member address: jni@fastmail.com
> _______________________________________________
> NumPy-Discussion mailing list -- numpy-discussion@python.org
> To unsubscribe send an email to numpy-discussion-leave@python.org
> https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> Member address: ben.v.root@gmail.com
>