I am only really trying to use sympy to produce full equations using Latex. I don't need it to find me any answers necessarily. I have the following expression:
expr = Eq(S(DeltaX), ((V1 + V2) / 2) * DeltaT)
When it displays in latex it distributes the 2 denominator to both V1 and V2.
(V1/2 + V2/2)
When I use UnevaluatedExpr() it converts it to a negative exponent:
(V1 + V2)*2**(-1)
And I haven't been able to use evaluate=false in any way it's happy with the syntax. Which is the only other possible solution I've found.
The default behaviour in SymPy is to distribute a Rational in a 2-arg Mul:
In [9]: (x + y) / 2
Out[9]:
x y
─ + ─
2 2
You can either control this using evaluate=False or the distribute context manager:
In [10]: Mul(Rational(1, 2), x + y, evaluate=False)
Out[10]:
x + y
─────
2
In [13]: from sympy.core.parameters import distribute
In [14]: with distribute(False):
...: e = (x + y) / 2
...:
In [15]: e
Out[15]:
x + y
─────
2
Related
So I have to write a python script for finding the root of a function using Newton's Method, and my code isn't computing a float when evaluating the derivative at a point, it's only evaluating the sin(x) part, leaving e^x and log(2) as they are.
I'm stuck, please help.
This is my code so far:
from sympy import *
x=symbols('x')
f="(e**x)+(2**(-x))+2*cos(x) - 6"
func=sympify(f)
fdiff=Derivative(func, x) #this returns an expression for the derivative
val=fdiff.doit().subs({x: 0.4})
print(val) #this should output 0.187681.... instead it returns another expression
PS: evalf doesn't work either, neither does subs(x, 0.4)
Using E instead of e:
In [19]: x=symbols('x')
...:
...: f="(E**x)+(2**(-x))+2*cos(x) - 6"
...: func=sympify(f)
In [20]: func
Out[20]:
x -x
ℯ + 2⋅cos(x) - 6 + 2
Note the different script for e.
In [21]: fdiff=Derivative(func, x)
In [22]: fdiff
Out[22]:
d ⎛ x -x⎞
──⎝ℯ + 2⋅cos(x) - 6 + 2 ⎠
dx
In [23]: fdiff.doit()
Out[23]:
x -x
ℯ - 2⋅sin(x) - 2 ⋅log(2)
In [24]: fdiff.doit().subs({x:.4})
Out[24]: 0.712988013023969 - 0.757858283255199⋅log(2)
In [25]: N(fdiff.doit().subs({x:.4}))
Out[25]: 0.187680680721628
With your expression
In [14]: func
Out[14]:
x -x
e + 2⋅cos(x) - 6 + 2
In [15]: func.free_symbols
Out[15]: {e, x}
To use this, you have to include both e and x in the subs.
In [38]: e=list(Out[15])[0]
Firstly, sorry about machine translate of "region of acceptability", I'm not sure that is exactly what I mean. "region of acceptability" must tell me where f(x) exists.
I'm using sumpy to code a script which will be give me a full f(x) analysis:
f(x)=0, d/dxf(x)=0,"region of acceptability", etc.
Which function in sympy is what I'm searching and how to use it correctly?
There is a function in sympy called singularities that tries to identify the set of singularities for an expression in a given symbol:
In [21]: from sympy import *
In [22]: x = Symbol('x', complex=True)
In [23]: expr = x**2 / ((1 - x) * (2 + x**2))
In [24]: expr
Out[24]:
2
x
────────────────
⎛ 2 ⎞
(1 - x)⋅⎝x + 2⎠
In [25]: singularities(expr, x)
Out[25]: {1, -√2⋅ⅈ, √2⋅ⅈ}
If the broader domain of the function is supposed to be the reals then you can remove those singularities from the set of real numbers using set subtraction:
In [26]: Reals - singularities(expr, x)
Out[26]: (-∞, 1) ∪ (1, ∞)
You can also convert that into relations on x with:
In [27]: (Reals - singularities(expr, x)).as_relational(x)
Out[27]: x ≠ 1
In sympy I have laurent polynomials in several variables (e.g. x,y,...) and I need the smallest exponent of the expression.
e.g.
expr = x**-3+y/x+2
The smallest power of x is -3 and the smallest power of y is 1. What I actually wish to do is normalize the laurent polynomial by multiplying by x^a y^b to obtain a non-laurent polynomial.
Maybe this is what you want:
In [14]: expr = x**-3+y/x+2
In [15]: expr
Out[15]:
y 1
2 + ─ + ──
x 3
x
In [16]: cancel(expr)
Out[16]:
3 2
2⋅x + x ⋅y + 1
───────────────
3
x
In [17]: cancel(expr).as_numer_denom()
Out[17]:
⎛ 3 2 3⎞
⎝2⋅x + x ⋅y + 1, x ⎠
This works for your example (returns -3), and believe it will work in general for any Laurent polynomial:
min((z.as_base_exp()[1] for z in expr.atoms(sympy.Pow)), default=1)
Explanation:
Extract the atoms from expr that are raised to powers other than 1. Convert each atom to a (base, exponent) pair, discard the base, and return the smallest exponent value. Default to 1 in the event that expr.atoms(sympy.Pow) is empty.
Edit:
It should be noted that atoms(*types) will return every atomic object that is matched by types. so if expr looked like this:
x**2 + y + exp(x**(-2)) - 5/y
the result set will include x**(-2) since it matches sympy.Pow, and that may not be desirable in some cases. Since this question is specifically about Laurent polynomials, it shouldn't be a problem here.
x**3-2*x-5=0
To the following forms [x = p(x)] where p(x) is continuously differentiable:
x=5/(x**2-2)
x=(2*x+5)**(1/3)
x=(x**3-5)/2
Given an expression, such as expr = x**3-2*x-5, assumed to be zero, one can form an equation x = p(x) in many ways. The simplest is to add x to both sides: Eq(x, expr + x).
This prints as one would expect: pprint(Eq(x, expr + x)):
3
x = x - x - 5
A couple of more interesting rewrites:
Iteration for Newton method: Eq(x, simplify(x - expr/diff(expr, x)))
3
2⋅x + 5
x = ────────
2
3⋅x - 2
Isolating the leading term on one side and taking a root:
p = poly(expr)
Eq(x, (LM(p) - expr)**(1/degree(p)))
3 _________
x = ╲╱ 2⋅x + 5
This is rough solution only..
from sympy import *
import numpy as np
var('x')
expr=sympify('x**3-2*x-5')
p = poly(expr);
p1=factor(p-(p).coeff_monomial(1))
for i in p1.args:
if (poly(i).is_monomial):
z=(np.prod([j for j in p1.args if j!=i]))
p2=(-(p).coeff_monomial(1)/z)**(1/degree(i));
v=i.coeff(x)
if p2:print(p2)
elif v:
p2=(-z/v)
print(p2)
for i in (p.all_terms())[:-1]:
if i[1]:
p3= ((i[1]*x**i[0][0]-expr)/i[1])**(1/Integer(i[0][0])) ;print(p3);
'''o
5/(x**2 - 2)
(2*x + 5)**(1/3)
x**3/2 - 5/2
'''
Using Sympy, say we have an expression f, which is a polynomial of the Symbol "x" (and of potentially other symbols).
I would like to know what if there is an efficient way to drop all terms in f of order greater than some integer n.
As a special case I have a very complicated function but i want to only keep terms up to 2nd order in x. What's the efficient way to do this?
The obvious, not-very-efficient way to do it would be for each m less than n, take m derivatives and set x to 0 to obtain the coefficient of x^m. We obtain each coefficient this way then reconstruct the polynomial. But taking derivatives is not the most efficient thing.
An easy way to do this is to add O(x**n) to the expression, like
In [23]: x + x**2 + x**4 + x**10 + O(x**3)
Out[23]:
2 ⎛ 3⎞
x + x + O⎝x ⎠
If you want to later remove it, use the removeO method
In [24]: (x + x**2 + x**4 + x**10 + O(x**3)).removeO()
Out[24]:
2
x + x
You can also use series to take the series expansion of the expression. The difference here is the behavior if a non-polynomial term ends up in the expression:
In [25]: x + sin(x) + O(x**3)
Out[25]:
⎛ 3⎞
sin(x) + x + O⎝x ⎠
In [26]: (x + sin(x)).series(x, 0, 3)
Out[26]:
⎛ 3⎞
2⋅x + O⎝x ⎠
If you take a look at the polynomial module docs:
http://docs.sympy.org/latest/modules/polys/reference.html
there will be plenty of ways to go about it, depending on the specifics of your situation. A couple different ways that would work:
Using .coeffs():
>>> f = 3 * x**3 + 2 * x**2 + x * y + y**3 + 1
>>> order = 2
>>> coeffs = Poly(f, x).coeffs()
>>> f_new = sum(x**n * coeffs[-(n+1)] for n in range(order+1)) # the +1 is to get 0th order
>>> f_new
2*x**2 + x*y + y**3 + 1
Alternatively, you could iterate over items in .all_terms():
>>> all_terms = Poly(f, x).all_terms()
>>> sum(x**n * term for (n,), term in all_terms() if n <= order)
There are plenty of manipulation functions in the module that you should be able to work with the expression directly rather than doing calculations/taking derivatives/etc.