Ticket #9566: mpmath_call_FIXED.patch

File mpmath_call_FIXED.patch, 4.9 KB (added by fredrik.johansson, 3 years ago)

fixed patch

  • sage/libs/mpmath/utils.pyx

    # HG changeset patch
    # User Fredrik Johansson <fredrik.johansson@gmail.com>
    # Date 1279831910 -7200
    # Node ID 9ef519def1c4262f7efcc8dee1fc97be3782b6a1
    # Parent  8dec8b43ccca5f104b1e280cb33c8f4c2c1b8f85
    #9566 permit parent=something in addition to prec=n in sage.libs.mpmath.call; some code cleanup [fixed patch, incorporating suggestion by Harald Schilly]
    
    diff -r 8dec8b43ccca -r 9ef519def1c4 sage/libs/mpmath/utils.pyx
    a b  
    233233    or ComplexNumber of the given precision into an mpmath mpf or mpc. 
    234234    Integers are currently converted to int. 
    235235 
     236    Lists, tuples and dicts passed as input are converted 
     237    recursively. 
     238 
    236239    EXAMPLES:: 
    237240 
    238241        sage: import sage.libs.mpmath.all as a 
     
    241244        0.666666666666667 
    242245        sage: print a.sage_to_mpmath(2./3, 53) 
    243246        0.666666666666667 
    244         sage: print a.sage_to_mpmath(3+4*I, 53)  
     247        sage: print a.sage_to_mpmath(3+4*I, 53) 
    245248        (3.0 + 4.0j) 
    246249        sage: print a.sage_to_mpmath(1+pi, 53) 
    247250        4.14159265358979 
     
    249252        mpf('+inf') 
    250253        sage: a.sage_to_mpmath(-infinity, 53) 
    251254        mpf('-inf') 
    252         sage: a.sage_to_mpmath(NaN, 53)       
     255        sage: a.sage_to_mpmath(NaN, 53) 
    253256        mpf('nan') 
    254         sage: a.sage_to_mpmath(0, 53)   
     257        sage: a.sage_to_mpmath(0, 53) 
    255258        0 
     259        sage: a.sage_to_mpmath([0.5, 1.5], 53) 
     260        [mpf('0.5'), mpf('1.5')] 
     261        sage: a.sage_to_mpmath((0.5, 1.5), 53) 
     262        (mpf('0.5'), mpf('1.5')) 
     263        sage: a.sage_to_mpmath({'n':0.5}, 53) 
     264        {'n': mpf('0.5')} 
     265 
    256266    """ 
    257267    cdef RealNumber y 
    258268    if isinstance(x, Element): 
     
    272282                return x._mpmath_() 
    273283    if PY_TYPE_CHECK(x, tuple) or PY_TYPE_CHECK(x, list): 
    274284        return type(x)([sage_to_mpmath(v, prec) for v in x]) 
     285    if PY_TYPE_CHECK(x, dict): 
     286        return dict([(k, sage_to_mpmath(v, prec)) for (k, v) in x.items()]) 
    275287    return x 
    276288 
    277289def call(func, *args, **kwargs): 
    278290    """ 
    279291    Call an mpmath function with Sage objects as inputs and 
    280     convert the result back to a Sage real or complex number. Use the 
    281     keyword argument prec=n to set the working precision in bits 
    282     (by default mpmath's global working precision is used). 
     292    convert the result back to a Sage real or complex number. 
     293 
     294    By default, a RealNumber or ComplexNumber with the current 
     295    working precision of mpmath (mpmath.mp.prec) will be returned. 
     296 
     297    If prec=n is passed among the keyword arguments, the temporary 
     298    working precision will be set to n and the result will also 
     299    have this precision. 
     300 
     301    If parent=P is passed, P.prec() will be used as working 
     302    precision and the result will be coerced to P (or the 
     303    corresponding complex field if necessary). 
    283304 
    284305    Arguments should be Sage objects that can be coerced into RealField 
    285     or ComplexField elements. Arguments may also be tuples/lists (which 
    286     are converted recursively), or any type that mpmath understands 
    287     natively (e.g. Python floats, strings for options). 
     306    or ComplexField elements. Arguments may also be tuples, lists or 
     307    dicts (which are converted recursively), or any type that mpmath 
     308    understands natively (e.g. Python floats, strings for options). 
    288309 
    289310    EXAMPLES:: 
    290311 
     
    317338        -1.00000000000000 
    318339        sage: a.call(a.gamma, infinity) 
    319340        +infinity 
     341        sage: a.call(a.polylog, 2, 1/2, parent=RR)             
     342        0.582240526465012 
     343        sage: a.call(a.polylog, 2, 2, parent=RR) 
     344        2.46740110027234 - 2.17758609030360*I 
     345        sage: a.call(a.polylog, 2, 1/2, parent=RealField(100)) 
     346        0.58224052646501250590265632016 
     347        sage: a.call(a.polylog, 2, 2, parent=RealField(100)) 
     348        2.4674011002723396547086227500 - 2.1775860903036021305006888982*I 
     349        sage: a.call(a.polylog, 2, 1/2, parent=CC) 
     350        0.582240526465012 
     351        sage: type(_) 
     352        <type 'sage.rings.complex_number.ComplexNumber'> 
     353        sage: a.call(a.polylog, 2, 1/2, parent=RDF)  
     354        0.582240526465 
     355        sage: type(_) 
     356        <type 'sage.rings.real_double.RealDoubleElement'> 
     357 
    320358    """ 
    321359    from mpmath import mp 
    322360    orig = mp.prec 
    323361    prec = kwargs.pop('prec', orig) 
     362    parent = kwargs.pop('parent', None) 
     363    if parent is not None: 
     364        prec = parent.prec() 
    324365    prec2 = prec + 20 
    325     args = [sage_to_mpmath(x, prec2) for x in args] 
    326     if kwargs: 
    327         kwargs = dict([(key, sage_to_mpmath(value, prec2)) for (key, value) in \ 
    328             kwargs.items()]) 
     366    args = sage_to_mpmath(args, prec2) 
     367    kwargs = sage_to_mpmath(kwargs, prec2) 
    329368    try: 
    330369        mp.prec = prec 
    331370        y = func(*args, **kwargs) 
    332371    finally: 
    333372        mp.prec = orig 
    334     return mpmath_to_sage(y, prec) 
     373    y = mpmath_to_sage(y, prec) 
     374    if parent is None: 
     375        return y 
     376    try: 
     377        return parent(y) 
     378    except TypeError: 
     379        return parent.complex_field()(y) 
    335380 
    336