There is an expression:
3^(48*x)
Sympy on further calculations will convert it to:
79766443076872509863361^x
Perhaps there is some kind of flag that prohibits such horrors.
If simplify is used it will cause that expansion. One way you can keep this from happening is to replace 48 with Symbol("48") so it is a variable. An UnevaluatedExpr will not be protected from the actions of simplify so that might be your only option.
>>> simplify(UnevaluatedExpr(2**(4*x))+1)
16**x + 1
>>> simplify(2**(Symbol('4')*x)+1)
2**(4*x) + 1
Related
Is there a workaround for SymPy's apparent inability to simplify sqrt(x**2+2*x+1)?
from sympy import *
x = Symbol('x', real=True, positive=True)
simplify(sqrt(x**2)) # returns x
simplify(sqrt(x**2+2*x+1)) #fails to return x+1
SymPy does not try to simplify everything on sight, there are too many issues (starting with performance) if it did that. See the article Automatic Simplification in SymPy wiki.
If you want to factor an expression, you should tell SymPy to do that.
factor(sqrt(x**2+2*x+1)) # returns x+1
The formula sqrt(x**2) becomes x because (x**a)**b can be safely combined to x**(a*b) when the base is positive and exponents are real. (Even then, "can" does not always mean "should be". Some amount of automatic simplification is present in SymPy, maybe too much.)
The key difference between the two is that x**2 is a explicitly a power while x**2 + 2*x + 1 is a sum.
So I'm taking the determinant of a matrix, then trying to use the Solver in Sympy to solve the expression for a particular variable.
The determinant I am trying to solve while being pretty complicated only has this one variable in it. Being a long expression I don't want to paste it all in but I've shortened it to a snippit that gives the same result;
Determinant = -0.0134365566406344*Nperp**7*sqrt(Nperp**2 + 0.3249)/(3.07787011388119*Nperp**2*sqrt(3.07787011388119*Nperp**2 + 1) + sqrt(3.07787011388119*Nperp**2 + 1)) - 4.2064522609332*Nperp**6/(3.07787011388119*Nperp**2 + 1)
Solutions = solve(Determinant, Nperp**2)
The problem is that when I print Solutions, I get an expression back in terms on Nperp instead of a numerical solution which is what I want.
I'm not sure whether the problem is that Sympy cannot handle the high powers in the polynomial, or if maybe there is no numerical solution possible but I would appreciate some thoughts of people more knowledgeable than I.
Thanks!
Edit: Code not indented
You are solving for Nperp**2. The answers it gives you are correct: they do equal Nperp**2 according to your Determinant equation, but it's probably not what you want. If you give solve an expression, rather than a single symbol, it will just isolate that expression.
You are probably looking for
Solutions = solve(Determinant, Nperp)
For me, this gives two solutions, [-549.228571428573, 0.0].
I have an expression in SymPy that involves the normal cumulative function, N(x) which is directly linked to the error function through the equation N(x)=0.5*erf(x/sqrt(2)) + 0.5.
When I use the Normal(0,1).cdf(x) function of SymPy, it is written using the error function. So, when I output latex string of some (complicated) expression, the seem more complicated when using erf (instead of N(x), it outputs the equation mentionned obove). I tried to define a symbol N=0.5*erf(x/sqrt(2)) + 0.5 and tried the command 'rewrite' the rewrite my expression in terms of N, but 'rewrite' seems to work only with internally defined functions.
Does any bodu know how to rewrite erf(some_expression) in terms of N(some_expression), given that I don't know some_expression in advance (can't use subs) ?
Thanks in advance
I take it from your question that you are using Normal from sympy.statistics. You should move to sympy.stats. sympy.statistics has been deprecated for some time, and will be removed in the next version of SymPy.
To answer your question more directly, you can replace functions with functions using replace, like expr.replace(erf, lambda x: (N(x) - 0.5)/0.5).
The problem here is that there is no function N. I would expect this to be done better in sympy.stats, where the distributions are represented symbolically. However, I didn't find a way to do it. I opened https://github.com/sympy/sympy/issues/7819 for this.
I have a variety of SymPy expressions involving UndefinedFunction instances:
f = Function('f')
g = Function('g')
e = f(x) / g(x)
How can I obtain a list of the function invocations appearing in such expressions? In this example, I'd like to get [f(x), g(x)].
I'm aware of free_symbols but it kicks back set([x]) (as it should).
You are right that you want to use atoms, but be aware that all functions in SymPy subclass from Function, not just undefined functions. So you'll also get
>>> (sin(x) + f(x)).atoms(Function)
set([f(x), sin(x)])
So you'll want to further reduce your list to only those functions that are UndefinedFunctions. Note that UndefinedFunction is the metaclass of f, so do to this, you need something like
>>> [i for i in expr.atoms(Function) if isinstance(i.__class__, UndefinedFunction)]
[f(x)]
It turns out that the atoms member method can accept a type on which to filter. So
e.atoms(Function)
returns
set([f(x), g(x)])
as I'd wanted. And that fancier things like
e.diff(x).atoms(Derivative)
are possible.
I want to find all the real numbers that satisfy a particular equation. I have no trouble finding these values in Mathematica with
Solve[n*9^5 == 10^n-1, n]
which gives both 0 and 5.51257; but when I use SymPy's (0.7.3; Python 2.7.5) solve
n = sympy.symbols('n')
sympy.solve(n*9**5 - 10**n-1, n)
I seem to only get something that looks like 0, and not the second value, which is what I'm really seeking.
How can I get SymPy to produce the non-trivial solution I'm looking for? Is there a different function or package I should be using instead?
solve only gives symbolic solutions, so if it cannot find a closed form for a solution, it will not return it. If you only care about numeric solutions, you want in SymPy is nsolve, or you can use a more numerical oriented Python library. For example
sympy.nsolve(n*9**5 - 10**n-1, n, 5)
will give you the solution you are looking for.
The problem with using solve is that there are infinitely many solutions, each corresponding to a branch of the LambertW function. See WolframAlpha for the full solution set. Unfortunately, only the principal branch of LambertW is implemented in SymPy.
Until this is fixed, another way to fix the issue would be to manually evaluate the LambertW returned by solve on another branch, using mpmath.lambertw. The easiest way to do this is with lambdify:
s = sympy.solve(n*9**5 - 10**n-1, n)
import sympy.mpmath
# Replace -1 with any integer. -1 gives the other real solution, the one you want
lambdify([], s, [{'LambertW': lambda x: sympy.mpmath.lambertw(x, -1)}, "mpmath"])()
This gives [mpf('5.5125649309411875')].
The dictionary tells lambdify to evaluate the LambertW function using the -1 branch, using mpmath. The "mpmath" tells it to use mpmath for any other functions that may be in the solution.