Utilities for Sage-mpmath interaction - C/C++ Library Interfaces

Skip to content
Back to top
View this page
Edit this page

# Utilities for Sage-mpmath interaction

sage.libs.mpmath.utils.call(func, *args, **kwargs)

  Call an mpmath function with Sage objects as inputs and convert the result back to a Sage real or complex number.

  By default, a RealNumber or ComplexNumber with the current working precision of mpmath (mpmath.mp.prec) will be returned.

  If prec=n is passed among the keyword arguments, the temporary working precision will be set to n and the result will also have this precision.

  If parent=P is passed, P.prec() will be used as working precision and the result will be coerced to P (or the corresponding complex field if necessary).

  Arguments should be Sage objects that can be coerced into RealField or ComplexField elements. Arguments may also be tuples, lists or dicts (which are converted recursively), or any type that mpmath understands natively (e.g. Python floats, strings for options).

  EXAMPLES:

  Sage

      sage: import sage.libs.mpmath.all as a
      sage: a.mp.prec = 53
      sage: a.call(a.erf, 3+4*I)
      -120.186991395079 - 27.7503372936239*I
      sage: a.call(a.polylog, 2, 1/3+4/5*I)
      0.153548951541433 + 0.875114412499637*I
      sage: a.call(a.barnesg, 3+4*I)
      -0.000676375932234244 - 0.0000442236140124728*I
      sage: a.call(a.barnesg, -4)
      0.000000000000000
      sage: a.call(a.hyper, [2,3], [4,5], 1/3)
      1.10703578162508
      sage: a.call(a.hyper, [2,3], [4,(2,3)], 1/3)
      1.95762943509305
      sage: a.call(a.quad, a.erf, [0,1])
      0.486064958112256
      sage: a.call(a.gammainc, 3+4*I, 2/3, 1-pi*I, prec=100)
      -274.18871130777160922270612331 + 101.59521032382593402947725236*I
      sage: x = (3+4*I).n(100)
      sage: y = (2/3).n(100)
      sage: z = (1-pi*I).n(100)
      sage: a.call(a.gammainc, x, y, z, prec=100)
      -274.18871130777160922270612331 + 101.59521032382593402947725236*I
      sage: a.call(a.erf, infinity)
      1.00000000000000
      sage: a.call(a.erf, -infinity)
      -1.00000000000000
      sage: a.call(a.gamma, infinity)
      +infinity
      sage: a.call(a.polylog, 2, 1/2, parent=RR)
      0.582240526465012
      sage: a.call(a.polylog, 2, 2, parent=RR)
      2.46740110027234 - 2.17758609030360*I
      sage: a.call(a.polylog, 2, 1/2, parent=RealField(100))
      0.58224052646501250590265632016
      sage: a.call(a.polylog, 2, 2, parent=RealField(100))
      2.4674011002723396547086227500 - 2.1775860903036021305006888982*I
      sage: a.call(a.polylog, 2, 1/2, parent=CC)
      0.582240526465012
      sage: type(_)
      <class 'sage.rings.complex_mpfr.ComplexNumber'>
      sage: a.call(a.polylog, 2, 1/2, parent=RDF)
      0.5822405264650125
      sage: type(_)
      <class 'sage.rings.real_double...RealDoubleElement...'>

  Python

      >>> from sage.all import *
      >>> import sage.libs.mpmath.all as a
      >>> a.mp.prec = Integer(53)
      >>> a.call(a.erf, Integer(3)+Integer(4)*I)
      -120.186991395079 - 27.7503372936239*I
      >>> a.call(a.polylog, Integer(2), Integer(1)/Integer(3)+Integer(4)/Integer(5)*I)
      0.153548951541433 + 0.875114412499637*I
      >>> a.call(a.barnesg, Integer(3)+Integer(4)*I)
      -0.000676375932234244 - 0.0000442236140124728*I
      >>> a.call(a.barnesg, -Integer(4))
      0.000000000000000
      >>> a.call(a.hyper, [Integer(2),Integer(3)], [Integer(4),Integer(5)], Integer(1)/Integer(3))
      1.10703578162508
      >>> a.call(a.hyper, [Integer(2),Integer(3)], [Integer(4),(Integer(2),Integer(3))], Integer(1)/Integer(3))
      1.95762943509305
      >>> a.call(a.quad, a.erf, [Integer(0),Integer(1)])
      0.486064958112256
      >>> a.call(a.gammainc, Integer(3)+Integer(4)*I, Integer(2)/Integer(3), Integer(1)-pi*I, prec=Integer(100))
      -274.18871130777160922270612331 + 101.59521032382593402947725236*I
      >>> x = (Integer(3)+Integer(4)*I).n(Integer(100))
      >>> y = (Integer(2)/Integer(3)).n(Integer(100))
      >>> z = (Integer(1)-pi*I).n(Integer(100))
      >>> a.call(a.gammainc, x, y, z, prec=Integer(100))
      -274.18871130777160922270612331 + 101.59521032382593402947725236*I
      >>> a.call(a.erf, infinity)
      1.00000000000000
      >>> a.call(a.erf, -infinity)
      -1.00000000000000
      >>> a.call(a.gamma, infinity)
      +infinity
      >>> a.call(a.polylog, Integer(2), Integer(1)/Integer(2), parent=RR)
      0.582240526465012
      >>> a.call(a.polylog, Integer(2), Integer(2), parent=RR)
      2.46740110027234 - 2.17758609030360*I
      >>> a.call(a.polylog, Integer(2), Integer(1)/Integer(2), parent=RealField(Integer(100)))
      0.58224052646501250590265632016
      >>> a.call(a.polylog, Integer(2), Integer(2), parent=RealField(Integer(100)))
      2.4674011002723396547086227500 - 2.1775860903036021305006888982*I
      >>> a.call(a.polylog, Integer(2), Integer(1)/Integer(2), parent=CC)
      0.582240526465012
      >>> type(_)
      <class 'sage.rings.complex_mpfr.ComplexNumber'>
      >>> a.call(a.polylog, Integer(2), Integer(1)/Integer(2), parent=RDF)
      0.5822405264650125
      >>> type(_)
      <class 'sage.rings.real_double...RealDoubleElement...'>

  Check that Issue #11885 is fixed:

  Sage

      sage: a.call(a.ei, 1.0r, parent=float)
      1.8951178163559368

  [Python]

      >>> from sage.all import *
      >>> a.call(a.ei, 1.0, parent=float)
      1.8951178163559368

  Check that Issue #14984 is fixed:

  Sage

      sage: a.call(a.log, -1.0r, parent=float)
      3.141592653589793j

  Python

      >>> from sage.all import *
      >>> a.call(a.log, -1.0, parent=float)
      3.141592653589793j

sage.libs.mpmath.utils.mpmath_to_sage(x, prec)

  Convert any mpmath number (mpf or mpc) to a Sage RealNumber or ComplexNumber of the given precision.

  EXAMPLES:

  Sage

      sage: import sage.libs.mpmath.all as a
      sage: a.mpmath_to_sage(a.mpf('2.5'), 53)
      2.50000000000000
      sage: a.mpmath_to_sage(a.mpc('2.5','-3.5'), 53)
      2.50000000000000 - 3.50000000000000*I
      sage: a.mpmath_to_sage(a.mpf('inf'), 53)
      +infinity
      sage: a.mpmath_to_sage(a.mpf('-inf'), 53)
      -infinity
      sage: a.mpmath_to_sage(a.mpf('nan'), 53)
      NaN
      sage: a.mpmath_to_sage(a.mpf('0'), 53)
      0.000000000000000

  Python

      >>> from sage.all import *
      >>> import sage.libs.mpmath.all as a
      >>> a.mpmath_to_sage(a.mpf('2.5'), Integer(53))
      2.50000000000000
      >>> a.mpmath_to_sage(a.mpc('2.5','-3.5'), Integer(53))
      2.50000000000000 - 3.50000000000000*I
      >>> a.mpmath_to_sage(a.mpf('inf'), Integer(53))
      +infinity
      >>> a.mpmath_to_sage(a.mpf('-inf'), Integer(53))
      -infinity
      >>> a.mpmath_to_sage(a.mpf('nan'), Integer(53))
      NaN
      >>> a.mpmath_to_sage(a.mpf('0'), Integer(53))
      0.000000000000000

  A real example:

  Sage

      sage: RealField(100)(pi)
      3.1415926535897932384626433833
      sage: t = RealField(100)(pi)._mpmath_(); t
      mpf('3.1415926535897932')
      sage: a.mpmath_to_sage(t, 100)
      3.1415926535897932384626433833

  [Python]

      >>> from sage.all import *
      >>> RealField(Integer(100))(pi)
      3.1415926535897932384626433833
      >>> t = RealField(Integer(100))(pi)._mpmath_(); t
      mpf('3.1415926535897932')
      >>> a.mpmath_to_sage(t, Integer(100))
      3.1415926535897932384626433833

  We can ask for more precision, but the result is undefined:

  Sage

      sage: a.mpmath_to_sage(t, 140) # random
      3.1415926535897932384626433832793333156440
      sage: ComplexField(140)(pi)
      3.1415926535897932384626433832795028841972

  Python

      >>> from sage.all import *
      >>> a.mpmath_to_sage(t, Integer(140)) # random
      3.1415926535897932384626433832793333156440
      >>> ComplexField(Integer(140))(pi)
      3.1415926535897932384626433832795028841972

  A complex example:

  Sage

      sage: ComplexField(100)([0, pi])
      3.1415926535897932384626433833*I
      sage: t = ComplexField(100)([0, pi])._mpmath_(); t
      mpc(real='0.0', imag='3.1415926535897932')
      sage: sage.libs.mpmath.all.mpmath_to_sage(t, 100)
      3.1415926535897932384626433833*I

  [Python]

      >>> from sage.all import *
      >>> ComplexField(Integer(100))([Integer(0), pi])
      3.1415926535897932384626433833*I
      >>> t = ComplexField(Integer(100))([Integer(0), pi])._mpmath_(); t
      mpc(real='0.0', imag='3.1415926535897932')
      >>> sage.libs.mpmath.all.mpmath_to_sage(t, Integer(100))
      3.1415926535897932384626433833*I

  Again, we can ask for more precision, but the result is undefined:

  Sage

      sage: sage.libs.mpmath.all.mpmath_to_sage(t, 140) # random
      3.1415926535897932384626433832793333156440*I
      sage: ComplexField(140)([0, pi])
      3.1415926535897932384626433832795028841972*I

  Python

      >>> from sage.all import *
      >>> sage.libs.mpmath.all.mpmath_to_sage(t, Integer(140)) # random
      3.1415926535897932384626433832793333156440*I
      >>> ComplexField(Integer(140))([Integer(0), pi])
      3.1415926535897932384626433832795028841972*I

sage.libs.mpmath.utils.sage_to_mpmath(x, prec)

  Convert any Sage number that can be coerced into a RealNumber or ComplexNumber of the given precision into an mpmath mpf or mpc. Integers are currently converted to int.

  Lists, tuples and dicts passed as input are converted recursively.

  EXAMPLES:

  Sage

      sage: import sage.libs.mpmath.all as a
      sage: a.mp.dps = 15
      sage: print(a.sage_to_mpmath(2/3, 53))
      0.666666666666667
      sage: print(a.sage_to_mpmath(2./3, 53))
      0.666666666666667
      sage: print(a.sage_to_mpmath(3+4*I, 53))
      (3.0 + 4.0j)
      sage: print(a.sage_to_mpmath(1+pi, 53))
      4.14159265358979
      sage: a.sage_to_mpmath(infinity, 53)
      mpf('...inf')
      sage: a.sage_to_mpmath(-infinity, 53)
      mpf('-inf')
      sage: a.sage_to_mpmath(NaN, 53)
      mpf('nan')
      sage: a.sage_to_mpmath(0, 53)
      0
      sage: a.sage_to_mpmath([0.5, 1.5], 53)
      [mpf('0.5'), mpf('1.5')]
      sage: a.sage_to_mpmath((0.5, 1.5), 53)
      (mpf('0.5'), mpf('1.5'))
      sage: a.sage_to_mpmath({'n':0.5}, 53)
      {'n': mpf('0.5')}

  Python

      >>> from sage.all import *
      >>> import sage.libs.mpmath.all as a
      >>> a.mp.dps = Integer(15)
      >>> print(a.sage_to_mpmath(Integer(2)/Integer(3), Integer(53)))
      0.666666666666667
      >>> print(a.sage_to_mpmath(RealNumber('2.')/Integer(3), Integer(53)))
      0.666666666666667
      >>> print(a.sage_to_mpmath(Integer(3)+Integer(4)*I, Integer(53)))
      (3.0 + 4.0j)
      >>> print(a.sage_to_mpmath(Integer(1)+pi, Integer(53)))
      4.14159265358979
      >>> a.sage_to_mpmath(infinity, Integer(53))
      mpf('...inf')
      >>> a.sage_to_mpmath(-infinity, Integer(53))
      mpf('-inf')
      >>> a.sage_to_mpmath(NaN, Integer(53))
      mpf('nan')
      >>> a.sage_to_mpmath(Integer(0), Integer(53))
      0
      >>> a.sage_to_mpmath([RealNumber('0.5'), RealNumber('1.5')], Integer(53))
      [mpf('0.5'), mpf('1.5')]
      >>> a.sage_to_mpmath((RealNumber('0.5'), RealNumber('1.5')), Integer(53))
      (mpf('0.5'), mpf('1.5'))
      >>> a.sage_to_mpmath({'n':RealNumber('0.5')}, Integer(53))
      {'n': mpf('0.5')}