evaluating a sympy function at an arbitrary-precision floating point - python

Given a sympy symbolic function, for example
x=symbols("x")
h=sin(x)
when one calls
h.subs(x, mpf('1.0000000000000000000000000000000000000000000001'))
sympy returns a floating point number. The return value is not an mpf.
Is there a convenient way to get sympy to evaluate symbolic standard functions (like exponential and trig functions), using arbitrary precision?

To evaluate an expression, use expr.evalf(), which takes a precision as the first argument (the default is 15). You can substitute expressions using expr.evalf(prec, subs=subs_dict).
>>> sin(x).evalf(50, subs={x: Float('1.0')})
0.84147098480789650665250232163029899962256306079837

Related

Specify algebra in SymPy?

Is there some way to tell SymPy that the plus operator for the type of objects you are working with is non-associative? I want to use SymPy to do symbolic computations involving gyrovector, for which the + operator is replaced with the ⊕ operator, which is non-associative.

Find the base of the power and power with given base in python

I have a number N let's say 5451 and I want to find the base for power 50. How do I do it with python?
The answer is 1.1877622648368 according this website (General Root calculator) But i need to find it with computation.
Second question. If I have the number N 5451, and I know the base 1.1877622648368, how do I find the power?
Taking the n-th root is the same as raising to the power 1/n. This is very simple to do in Python using the ** operator (exponentiation):
>>> 5451**(1/50)
1.1877622648368031
The second one requires a logarithm, which is the inverse of exponentiation. You want to take the base-1.1877622648368031 logarithm of 5451, which is done with the log function in the math module:
>>> import math
>>> math.log(5451, 1.1877622648368031)
50.00000000000001
As you can see, there's some roundoff error. This is unavoidable when working with limited-precision floating point numbers. Apply the round() function to the result if you know that it must be an integer.

What is the default accuracy for the mpmath function hyperu?

Computation of the Tricomi confluent hypergeometric function can be ill-conditioned when it uses the sum of two 1F1 functions, as they can be nearly equal in size but opposite in sign. The mpmath function "hyperu" uses arbitrary precision internally and produces a result with 35 significant figures in default mode. How many of these digits are reliable? Does it depend on the parameters passed?
import mpmath
x = mpmath.hyperu(a, b + 1, u)
I have just received an email from the main author of mpmath, Fredrik Johansson, confirming that the full 35 digits are usable. He writes "hyperu uses adaptive higher precision internally, so the result should nearly always be accurate to the full precision set by the user".

lambdify expressions with native sympy functions

I would like to lambdify sympy's exp, but I run into funny issues when trying to evaluate the function at a sympy.Symbol. This
import sympy
t = sympy.Symbol('t')
f = sympy.lambdify(t, t**2)
f(t) # no problem
works fine, but this
t = sympy.Symbol('t')
f = sympy.lambdify(t, sympy.exp(t))
f(t)
gives
AttributeError: 'Symbol' object has no attribute 'exp'
The same goes for all other native sympy functions I've tried (log, sin, etc.).
Any idea what's going on?
You should specify modules you want to use with modules argument of the lambdify function:
f = sympy.lambdify(t, sympy.exp(t), modules=["sympy"])
The main use of lambdify is to allow for a fast numerical evaluation of expressions.
This is achieved by replacing abstract and slow SymPy functions (like sympy.exp) with faster ones intended for numbers (like math.exp or numpy.exp).
These cannot handle SymPy symbols (like your t) as an argument, which is not what lambdify is intended for anyway.
If you call lambdify with dummify=False as an additional argument, you get a more meaningful error, when calling f(t), namely:
TypeError: can't convert expression to float
The expression that cannot be converted here is your argument t.
If you want to use a lambdified function with symbols as an argument for some reason, you need to pass modules=["sympy"] as an additional argument to lambdify.
This argument specifies which module lambdify uses to replace SymPy functions (like sympy.exp) – in this case, it’s sympy again, so nothing actually happens.

Simplifying exponential representation of hyperbolic functions in sympy

I am trying to rewrite some exponential functions in an expression to cosh and sinh. The rewrite() function works to get from a hyperbolic function to its exponential representation. But it does not work to get back.
>>> import sympy
>>> x=sympy.Symbol('x')
>>> sympy.cosh(x).rewrite(sympy.exp)
exp(x)/2 + exp(-x)/2
>>> sympy.cosh(x).rewrite(sympy.exp).rewrite(sympy.cosh)
exp(x)/2 + exp(-x)/2
I would expect the result of the last command to be 'cosh(x)'. Can someone explain to me why it is not?
I tried to find some documentation on the rewrite() function but the only bit I found was the short section in http://docs.sympy.org/latest/tutorial/simplification.html that is not really helpful.
Applying .rewrite(sympy.cos) returns cosh(x) as you wanted. Apparently, the hyperbolic cosine is treated by rewrite as a variant of the normal one.
Here is a reference on rewrite method.
Alternatively, simplify(expr) also transforms exp(x)/2 + exp(-x)/2 into cosh(x).

Categories