# 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
|
|
| 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 | sage: a.call(a.polylog, 2, 1/2, parent=RDF) |
| | 354 | 0.582240526465 |
| | 355 | sage: type(_) |
| | 356 | <type 'sage.rings.real_double.RealDoubleElement'> |
| | 357 | |
| 320 | 358 | """ |
| 321 | 359 | from mpmath import mp |
| 322 | 360 | orig = mp.prec |
| 323 | 361 | prec = kwargs.pop('prec', orig) |
| | 362 | parent = kwargs.pop('parent', None) |
| | 363 | if parent is not None: |
| | 364 | prec = parent.prec() |
| 324 | 365 | 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) |
| 329 | 368 | try: |
| 330 | 369 | mp.prec = prec |
| 331 | 370 | y = func(*args, **kwargs) |
| 332 | 371 | finally: |
| 333 | 372 | 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) |
| 335 | 380 | |
| 336 | | |