A problem that I pointed out with the proposed areclose() function is that it 
has within it a fp comparison. If such a function is to have greater utility, 
it should allow the user to specify how significant to consider the computed 
error. A natural extension of being able to tell if 2 fp numbers are close is 
to make a more general comparison. For that purpose, a proposed fpcmp function 
is appended. From that, fp boolean comparison operators (le, gt, ...) are 
easily constructed.

Python allows fp comparison. This is significantly of source of surprises and 
learning experiences. Are any of these proposals of interest for providing 
tools to more intelligently make the fp comparisons?

###
#new proposal for the areclose() function
def areclose(x,y,atol=1e-8,rtol=1e-5,prec=12):
    """Return False if the |x-y| is greater than atol or
     greater than the absolute value of the larger of x and y, 
     otherwise True. The comparison is made by computing a 
     difference that should be 0 if the two numbers satisfy 
     either condition; prec controls the precision of the
     value that is obtained, e.g. 8.3__e-17 is obtained 
     for (2.1-2)-.1. But rounding to the 12th digit (the default 
     precision) the value of 0.0 is returned indicating that for
    that precision there is no (significant) error."""
    
    diff = abs(x-y)
    return round(diff-atol,prec)<=0 or \
           round(diff-rtol*max(abs(x),abs(y)),prec)<=0

#fp cmp
def fpcmp(x,y,atol=1e-8,rtol=1e-5,prec=12):
    """Return 0 if x and y are close in the absolute or 
    relative sense. If not, then return -1 if x < y or +1 if x > y.
    Note: prec controls how many digits of the error are retained
    when checking for closeness."""
    
    if areclose(x,y,atol,rtol,prec):
        return 0
    else:
        return cmp(x,y)

# fp comparisons functions
def lt(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec)==-1
def le(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec) in (-1,0)
def eq(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec)==0
def gt(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec)==1
def ge(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec) in (0,1)
def ne(x,y,atol=1e-8,rtol=1e-5,prec=12):
    return fpcmp(x, y, atol, rtol, prec)<>0
###
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to