#!/usr/bin/python -tt
#=======================================================================
#                        General Documentation

"""Single public function module.

   See function docstring for description.
"""

#-----------------------------------------------------------------------
#                       Additional Documentation
#
# RCS Revision Code:
#   $Id: is_monotonic_decr.py,v 1.1 2004/04/28 00:28:15 jlin Exp $
#
# Modification History:
# - 27 Apr 2004:  Original by Johnny Lin, Computation Institute,
#   University of Chicago.  Passed reasonable tests.
#
# Notes:
# - Written for Python 2.2.2.
# - Module docstrings can be tested using the doctest module.  To
#   test, execute "python is_monotonic_decr.py".
# - See import statements throughout for packages/modules required.
#
# Copyright (c) 2004 by Johnny Lin.  For licensing, distribution 
# conditions, contact information, and additional documentation see
# the URL http://www.johnny-lin.com/py_pkgs/gemath/doc/.
#=======================================================================




#----------------------- Overall Module Imports ------------------------

#- Set module version to package version:

import gemath_version
__version__ = gemath_version.version
__author__  = gemath_version.author
__date__    = gemath_version.date
__credits__ = gemath_version.credits
del gemath_version




#--------------------------- General Function --------------------------

def is_monotonic_decr(x):
    """Check if x is monotonically decreasing.

    Returns 1 if x is monotonically decreasing and 0 if not.  If x is
    floating point, safe comparisons are used in the algorithm to
    determine whether x is monotonically decreasing; if x is integer,
    exact comparison is used.


    Positional Input Arguments:
    * x:  Rank 1 list, tuple, or Numeric array of any numerical type.  
      Must be greater than 1-element long.


    Keyword Input Arguments:  None.


    Examples:
    >>> import Numeric as N
    >>> from is_monotonic_decr import is_monotonic_decr
    >>> x = [20., -32., -1., 2., -5., 29.]
    >>> is_monotonic_decr(x)
    0
    >>> x = (32., 1., -2., -5., -29.)
    >>> is_monotonic_decr(x)
    1
    >>> x = N.array([14, -6, -7, -19])
    >>> is_monotonic_decr(x)
    1


    Note:  Because of the limits of floating point, even safe-compar-
    isons will not always return the correct answer.  Thus, in the
    first example below, the correct answer is returned, but in the
    second example, the incorrect answer is returned:

    >>> x = N.array([-1.0000001, -1.0000002, -1.0000003])
    >>> is_monotonic_decr(x)
    1
    >>> x = N.array([-1.00000001, -1.00000002, -1.00000003])
    >>> is_monotonic_decr(x)
    0
    """
    import MA
    import Numeric as N
    from where_close import where_close
    abs = N.absolute


    #- Make sure input locally is Numeric type:

    xN = N.array(x)


    #- Check rank and array size:

    if N.rank(xN) != 1:
        raise ValueError, "is_monotonic_decr:  Input not rank 1"
    if N.size(xN) < 2:
        raise ValueError, "is_monotonic_decr:  Input one element"


    #- If is monotonically decreasing, all elements of tmp should be
    #  negative, and no element of tmp should equal 0:

    tmp = xN[1:] - xN[0:-1]
    if MA.maximum( where_close(tmp, 0) ) == 1:  return 0
    if MA.minimum( where_close(tmp, -abs(tmp)) ) == 0:  return 0
    return 1




#-------------------------- Main:  Test Module -------------------------

#- Define additional examples for doctest to use:

__test__ = { 'Additional Examples':
    """
    >>> import Numeric as N
    >>> from is_monotonic_decr import is_monotonic_decr
    >>> x = [-32., -1., 2., 5., 29.]
    >>> is_monotonic_decr(x)
    0
    >>> x = N.array([[1,2,4],[53,3,2]])
    >>> is_monotonic_decr(x)
    Traceback (most recent call last):
        ...
    ValueError: is_monotonic_decr:  Input not rank 1
    >>> x = N.array([2.])
    >>> is_monotonic_decr(x)
    Traceback (most recent call last):
        ...
    ValueError: is_monotonic_decr:  Input one element
    >>> x = N.array([-1.00001, -1.00002, -1.00003])
    >>> is_monotonic_decr(x)
    1
    >>> x = N.array([1.00001, 1.00000, 1.00003])
    >>> is_monotonic_decr(x)
    0
    >>> x = N.arange(14)
    >>> is_monotonic_decr(x)
    0
    >>> x = -N.arange(14)
    >>> is_monotonic_decr(x)
    1
    >>> x = N.array([3, -4, 1, 6])
    >>> is_monotonic_decr(x)
    0
    >>> x = (3, -4, 1, 6)
    >>> is_monotonic_decr(x)
    0
    >>> x = (3, 1, 0)
    >>> is_monotonic_decr(x)
    1
    >>> x = (31, 21, 6, -8.)
    >>> is_monotonic_decr(x)
    1
    >>> x = [-3, -3, -6, -8]
    >>> is_monotonic_decr(x)
    0
    >>> x = [-3., -3., -6., -8.]
    >>> is_monotonic_decr(x)
    0
    >>> x = [12., 11., 9., 3.]
    >>> is_monotonic_decr(x)
    1
    """ }


#- Execute doctest if module is run from command line:

if __name__ == "__main__":
    """Test the module.

    Tests the examples in all the module documentation 
    strings, plus __test__.

    Note:  To help ensure that module testing of this file works, the
    parent directory to the current directory is added to sys.path.
    """
    import doctest, sys, os
    sys.path.append(os.pardir)
    doctest.testmod(sys.modules[__name__])




# ===== end file =====
