Ticket #9566: mpmath_call_FIXED.patch

File mpmath_call_FIXED.patch, 4.9 KB (added by fredrik.johansson, 11 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