# HG changeset patch
# User Fredrik Johansson <fredrik.johansson@gmail.com>
# Date 1279734121 7200
# Node ID b0c9f1044971db2e28e430a826abaad08838822f
# Parent 8dec8b43ccca5f104b1e280cb33c8f4c2c1b8f85
permit parent=something in addition to prec=n in sage.libs.mpmath.call; some code cleanup
diff r 8dec8b43ccca r b0c9f1044971 sage/libs/mpmath/utils.pyx
a

b


159  159  bc = mpz_sizeinbase(man.value, 2) 
160  160  return (sign, man, int(exp), bc) 
161  161  
162   def mpmath_to_sage(x, prec): 
 162  def mpmath_to_sage(x, prec, parent=None): 
163  163  """ 
164  164  Convert any mpmath number (mpf or mpc) to a Sage RealNumber or 
165  165  ComplexNumber of the given precision. 
… 
… 

233  233  or ComplexNumber of the given precision into an mpmath mpf or mpc. 
234  234  Integers are currently converted to int. 
235  235  
 236  Lists, tuples and dicts passed as input are converted 
 237  recursively. 
 238  
236  239  EXAMPLES:: 
237  240  
238  241  sage: import sage.libs.mpmath.all as a 
… 
… 

241  244  0.666666666666667 
242  245  sage: print a.sage_to_mpmath(2./3, 53) 
243  246  0.666666666666667 
244   sage: print a.sage_to_mpmath(3+4*I, 53) 
 247  sage: print a.sage_to_mpmath(3+4*I, 53) 
245  248  (3.0 + 4.0j) 
246  249  sage: print a.sage_to_mpmath(1+pi, 53) 
247  250  4.14159265358979 
… 
… 

249  252  mpf('+inf') 
250  253  sage: a.sage_to_mpmath(infinity, 53) 
251  254  mpf('inf') 
252   sage: a.sage_to_mpmath(NaN, 53) 
 255  sage: a.sage_to_mpmath(NaN, 53) 
253  256  mpf('nan') 
254   sage: a.sage_to_mpmath(0, 53) 
 257  sage: a.sage_to_mpmath(0, 53) 
255  258  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  
256  266  """ 
257  267  cdef RealNumber y 
258  268  if isinstance(x, Element): 
… 
… 

272  282  return x._mpmath_() 
273  283  if PY_TYPE_CHECK(x, tuple) or PY_TYPE_CHECK(x, list): 
274  284  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()]) 
275  287  return x 
276  288  
277  289  def call(func, *args, **kwargs): 
278  290  """ 
279  291  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). 
283  304  
284  305  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). 
288  309  
289  310  EXAMPLES:: 
290  311  
… 
… 

317  338  1.00000000000000 
318  339  sage: a.call(a.gamma, infinity) 
319  340  +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  
320  354  """ 
321  355  from mpmath import mp 
322  356  orig = mp.prec 
323  357  prec = kwargs.pop('prec', orig) 
 358  parent = kwargs.pop('parent', None) 
 359  if parent is not None: 
 360  prec = parent.prec() 
324  361  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()]) 
 362  args = sage_to_mpmath(args, prec2) 
 363  kwargs = sage_to_mpmath(kwargs, prec2) 
329  364  try: 
330  365  mp.prec = prec 
331  366  y = func(*args, **kwargs) 
332  367  finally: 
333  368  mp.prec = orig 
334   return mpmath_to_sage(y, prec) 
 369  y = mpmath_to_sage(y, prec) 
 370  if parent is None: 
 371  return y 
 372  try: 
 373  return parent(y) 
 374  except TypeError: 
 375  return parent.complex_field()(y) 
335  376  
336   