[Numpy-discussion] % and fmod

Arnd Baecker arnd.baecker at web.de
Thu Apr 14 23:58:08 EDT 2005


Dear all,

I encountered the following puzzling behaviour of the modulo operator %:

In [1]: import Numeric
In [2]: print Numeric.__version__
23.8
In [3]: x=Numeric.arange(10.0)
In [4]: print x%4
[ 0.  1.  2.  3.  0.  1.  2.  3.  0.  1.]
In [5]: print 3.0%4
3.0
In [6]: print (-x)%4
[-0. -1. -2. -3. -0. -1. -2. -3. -0. -1.]     # <======
In [7]: print (-3.0)%4                        #    vs.
1.0                                           # <====== (OK)
In [8]: print Numeric.fmod(x,4)
[ 0.  1.  2.  3.  0.  1.  2.  3.  0.  1.]
In [9]: print Numeric.fmod(-x,4)
[-0. -1. -2. -3. -0. -1. -2. -3. -0. -1.]


So it seems that for arrays % behaves like fmod!
This seems in contrast to what one finds in the
python 2.3 documentation:

"5.6. Binary arithmetic operations"

   """The % (modulo) operator yields the remainder from the division
      of the first argument by the second. [...]
      The arguments may be floating point numbers, e.g.,
      3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.)
      The modulo operator always yields a result with the same sign as
      its second operand (or zero); the absolute value of the result
      is strictly smaller than the absolute value of the second
      operand."""

I am presently teaching a course on computational physics
with python and the students have huge difficulties
with % behaving differently for arrays and scalars.

I am aware that (according to Kernighan/Ritchie) the C standard
does not define the result of % when any of the operands is
negative.

So can someone help me: is the different behaviour of %
for scalars and arrays a bug, a feature,
or what should I tell my students ? ;-).

Many thanks,

Arnd


P.S.: BTW: the documentation for fmod and remainder is
pretty short on this:

In [3]:fmod?
Type:           ufunc
String Form:    <ufunc 'fmod'>
Namespace:      Interactive
Docstring:
    fmod(x,y) is remainder(x,y)

In [4]:remainder?
Type:           ufunc
String Form:    <ufunc 'remainder'>
Namespace:      Interactive
Docstring:
    returns remainder of division elementwise

Are contributions of more detailed doc-strings welcome ?


P.P.S.: for numarray one gets even less information:

In [1]: import numarray
In [2]: numarray.fmod?
Type:           _BinaryUFunc
Base Class:     <class 'numarray.ufunc._BinaryUFunc'>
String Form:    <UFunc: 'remainder'>
Namespace:      Interactive
Docstring:
    Class for ufuncs with 2 input and 1 output arguments

In [3]: numarray.remainder?
Type:           _BinaryUFunc
Base Class:     <class 'numarray.ufunc._BinaryUFunc'>
String Form:    <UFunc: 'remainder'>
Namespace:      Interactive
Docstring:
    Class for ufuncs with 2 input and 1 output arguments
In [4]: print numarray.__version__
1.1.1


P^3.S: scipy's mod seems to be an alternative:
In [1]: import scipy
In [2]: scipy.mod?
Type:           function
Base Class:     <type 'function'>
String Form:    <function mod at 0x40383994>
Namespace:      Interactive
File:
/usr/lib/python2.3/site-packages/scipy_base/function_base.py
Definition:     scipy.mod(x, y)
Docstring:
    x - y*floor(x/y)

    For numeric arrays, x % y has the same sign as x while
    mod(x,y) has the same sign as y.

In [3]: x=-scipy.arange(10)
In [4]: x%4
Out[4]: array([ 0, -1, -2, -3,  0, -1, -2, -3,  0, -1])
In [5]: scipy.mod(x,4)
Out[5]: array([ 0.,  3.,  2.,  1.,  0.,  3.,  2.,  1.,  0.,  3.])
In [6]: scipy.mod??
Type:           function
Base Class:     <type 'function'>
String Form:    <function mod at 0x40383994>
Namespace:      Interactive
File:
/usr/lib/python2.3/site-packages/scipy_base/function_base.py
Definition:     scipy.mod(x, y)
Source:
def mod(x,y):
    """ x - y*floor(x/y)

        For numeric arrays, x % y has the same sign as x while
        mod(x,y) has the same sign as y.
    """
    return x - y*Numeric.floor(x*1.0/y)





More information about the NumPy-Discussion mailing list