substituting variable to second order derivative in sympy - python

I am using sympy to derive some equations and I experience some unexpected behaviour with substituting. Let's say I have a function f(x) that I differentiate by x like this:
fx = f(x).diff()
This results in the following:
Now if I substitute x with a value such as pi, like this:
fx.subs(x, pi)
I get:
However, if I substitute x with another variable, let say phi, like this:
fx.subs(x, phi)
I get something unexpected:
What is happening is that sympy is replacing x in the equation before differentiating, I would like that it does after it. I have seen some suggestions that I should use .doit(), but that does not result in a wanted solution:
fx.doit().subs(x, phi)
What am I doing wrong and how can I replace the variable after the differentiation?

Use srepr to see the structure of an expression more directly:
In [48]: f(x).diff(x).subs(x, pi)
Out[48]:
⎛d ⎞│
⎜──(f(x))⎟│
⎝dx ⎠│x=π
In [49]: srepr(f(x).diff(x).subs(x, pi))
Out[49]: "Subs(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))), Tuple(Symbol('x')), Tuple(pi))"
So you can see that Subs is what is used to represent an unevaluated substitution:
In [50]: Subs(f(x).diff(x), x, phi)
Out[50]:
⎛d ⎞│
⎜──(f(x))⎟│
⎝dx ⎠│x=φ
Then doit is used to make the Subs evaluate (by performing the substitution):
In [51]: Subs(f(x).diff(x), x, phi).doit()
Out[51]:
d
──(f(φ))
dφ
https://docs.sympy.org/latest/modules/core.html#subs

Related

Evaluating a sum in SymPy

I want to evaluate the sum
using Python and SymPy, I'm relatively new using SymPy and the first thing I tried was
from sympy import exp, oo, summation, symbols
n, x = symbols('n,x')
summation(exp(-n*x), (n, 1, oo))
But it doesn't work, it just returns the unevaluated sum.
I can make it work using
from sympy import exp, oo, summation, symbols
n, x = symbols('n,x')
f = exp(-x)
summation(x**(-n), (n, 1, oo)).subs(x,f)
But I would like to know if it is possible to make it work without need to break the expression into x^n and then substitute x by e^-x.
Thank you
Try using the following:
x , n = smp.symbols('x n')
smp.Sum(smp.exp(-n*x),(n, 1, smp.oo))

Python: Initiate integer without specifying value

Not sure why I can't find something on this but here's my question:
How do I initiate an integer without giving it a value so I can use it to solve equations.
E.g., if I specified that I had some integer x then I could write something that allows me to solve functions with respect to x.
E.g., an output might be: 2x+5
EX:
# Eisenstein Prime?
# 1J is complex number i
def eisenstein(a,b):
w = e**((2*math.pi*1J)/3)
z=a+b*w
a = a+b*(w**2)
print("Eisenstein Integer as z:")
print(z)
print("Omega as w:")
print(w)
This outputs:
Eisenstein Integer as z:
(-0.9999999999999987+5.196152422706632j)
Omega as w:
(-0.4999999999999998+0.8660254037844387j)
I'd like to have the variable similar to how j appears above.
You can't do that with plain ints. You'll need to install a package for symbolic mathematics.
python -m pip install sympy
Then to use it,
import sympy as sp
x = sp.var('x')
equation = 2*x + 5
print(sp.solve([equation], [x]))
Output:
{x: -5/2}
The solver takes lists because it can do systems of equations. You can also just
sp.solve(equation, x)
And get
[-5/2]
Another example.
import sympy as sp
x, y = sp.var('x y')
equation = 2*x + 5*y # Equations made this way are implicitly "= 0".
print(sp.solveset(equation, y, sp.S.Complexes))
Solved for y, note the output is in terms of x:
{-2*x/5}

Using sympy for symbolic math, the code runs forever

I am trying to solve simultaneous equations for x and y, I am not getting any result (code just keeps on running). I feel the error is related to using sqrt in the equations but not sure. Can someone help me figure this out?
from __future__ import division
from sympy import Symbol,sqrt,solve
x = Symbol('x')
y = Symbol('y')
z = Symbol('z')
a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
d = Symbol('d')
e = Symbol('e')
f = Symbol('f')
g = Symbol('g')
h = Symbol('h')
print (solve((sqrt((c-a)**2+(d-b)**2)+sqrt((x-c)**2+(y-d)**2)-2*sqrt((x-a)**2+(y-b)**2),(y-b)*(e-a)-(x-a)*(f-b)) ,x,y))
This is a(nother) problem were you have to rely on the A of CAS and let SymPy assist you instead of relying on SymPy (in it's current state) to do all the work. The following assumes that eqs is a list of the two equations you want to solve as you gave in the OP.
Notice that the 2nd equation is linear in both symbols. Solve for y and substitute into the first equation.
>>> yis = solve(eqs[1], y)[0]
>>> eq0 = eqs[0].subs(y,yis)
This gives an expression that has a lot of symbols in it and that slows things down. It also has two terms with sqrt that depend on x. Replace those arguments of the sqrt with Dummy symbols and then unrad the expression to get it in polynomial form, restore replacements and factor:
>>> from sympy.solvers.solvers import unrad, S
>>> reps = {i.base:Dummy() for i in eq0.atoms(Pow) if i.has(x) and i.exp==S.Half}
>>> ireps = {v:k for k,v in reps.items()}
>>> poly = unrad(eq0.xreplace(reps), *reps.values())[0].xreplace(ireps).factor()
Using factor is an expensive process to always use, but if you know the problem is going to take a long time without it, it is worth a try. In this case a quartic reduces to a product of quadratics which are easy to solve and don't require checking or simplification:
>>> xis = solve(poly, x)
There are three solutions for x and each of these can be substituted into the expression for y to get the three solutions. The solutions are large enough so they are not shown here.
>>> count_ops(xis)
386

Enforce custom ordering on Sympy print

SymPy does a wonderful work keeping track of all the operations I do to my symbolic expressions. But a the moment of printing the result for latex output I would like to enforce a certain ordering of the term. This is just for convention, and unfortunately that convention is not alphabetical on the symbol name(as reasonably sympy does)
import sympy as sp
sp.init_printing()
U,tp, z, d = sp.symbols('U t_\perp z d')
# do many operations with those symbols
# the final expression is:
z+tp**2+U+U/(z-3*tp)+d
My problem is that SymPy presents the expression ordered as
U + U/(-3*t_\perp + z) + d + t_\perp**2 + z
But this ordering is not the convention in my field. For us z has to be the leftmost expression, then tp, then U even if it is capitalized, d is the most irrelevant and is put at the right. All this variables hold a particular meaning and that is the reason we write them in such order, and the reason in the code variables are named in such way.
I don't want to rename z to a and as suggested in Prevent Sympy from rearranging the equation and then at the moment of printing transform that a into z. In Force SymPy to keep the order of terms there is a hint I can write a sorting function but I could not find documentation about it.
If you can put the terms in the order you want then setting the order flag for the Latex printer to 'none' will print them in that order.
>>> import sympy as sp
>>> sp.init_printing()
>>> U,tp, z, d = sp.symbols('U t_\perp z d')
>>> eq=z+tp**2+U+U/(z-3*tp)+d
Here we put them in order (knowing the power of tp is 2) and rebuild as an Add with evaluate=False to keep the order unchanged
>>> p = Add(*[eq.coeff(i)*i for i in (z, U, tp**2, d)],evaluate=False)
And now we print that expression with a printer instance with order='none':
>>> from sympy.printing.latex import LatexPrinter
>>> s=LatexPrinter(dict(order='none'))
>>> s._print_Add(p)
z + U \left(1 + \frac{1}{z - 3 t_\perp}\right) + t_\perp^{2} + d

Evaluating a function at a point in SymPy

I'm trying to code various optimisation methods, as a way of revising. I want to be able to use SymPy to evaluate a function with an arbitrary number of variables at a given point, where the co-ordinates of the point are stored in an array.
For example, I'd like to evaluate f(x,y) = 3*x**2 - 2*x*y + y**2 + 4*x + 3*y at the point b = [1,2]. But I'd really like a general way of doing it, that can handle a function with any number of variables and an appropriate length array as the point to be evaluated as, so sympy.evalf(f, subs = {foo}) isn't really very useful.
You are working with SymPy expression trees, not functions. On any expression you can do:
>>> vars = sorted(expression.free_symbols)
>>> evaluated = expression.subs(*zip(vars, your_values))
I would also expect this to be easier to do, but here's a good workaround:
If you know the symbol names ('x','y', e.g.), you can create a dict on the fly using zip:
fvars = sympy.symbols('x, y') #these probably already exist, use: fvars = [x,y]
b = [1,2]
sympy.evalf(f, subs = dict(zip(fvars,b)))
lambdify is a good option to generate a Python-callable function.
An example, assuming you have a function f and the symbols x and y:
from sympy import lambdify
import numpy as np
callable_fct = lambdify((x, y), f)
xn = np.arange(0, 2, 0.1)
yn = 3
print(callable_fct(xn, yn))

Categories

Resources