I want to differentiate the following equation
from sympy import *
init_printing()
x, t, r, phi = symbols('x, t, r, phi')
# this is how I want to do it
eq = Eq(x(t), r*phi(t))
eq.diff(t)
The result is differentiated only on the left side. I would like it to be evaluated on both sides. Is that possible in a simple way?
Currently I do the following:
Eq(eq.lhs.diff(t), eq.rhs.diff(t))
Borrowing some of the logic from Sympy: working with equalities manually, you can do something like this:
eq.func(*map(lambda x: diff(x, t), eq.args))
A bit ugly, but it works. Alternatively, you could just lift the .do() method from that and use it if you're going to want to do this a bunch of times.
Related
I have this ordinary differential equation that I need to solve using SymPy.
The equation: (m, g, C, rho, A are arbitrary constants)
I already managed to get a solution out of it using the code below, but the computation takes more than 2 minutes which is too long.
m, x, t, g, C, ρ, A = sp.symbols('m, x, t, g, C, ρ, A', real=True)
x = sp.Function("x")(t)
equation_of_motion = sp.Eq(m*x.diff(t, t), -m*g + (C*ρ*A/2)*(x.diff(t))**2)
sol = sp.dsolve(equation_of_motion, x)
print(sol)
I found that you can give a hint to the function dsolve, telling which solution method you want it to use. But to reduce the computation time, I was wondering if you have a feature that can tell you which hint you should give to the function.
If you want the function to use the 'factorable' method, the last line would look like this.
sol=sp.dsolve(equation_of_motion, x, hint='factorable')
I have this very complex symbolic function of three variables, f(x,y,z), which I need to evaluate over a point in z and integrate over all the domain in x and y.
Summarizing, I've been using:
f_substituted=f.subs(z,valueforz)
f_numeric=lambdify([x,y].f_substituted)
#and then, integrate it a la Riemann (dblquad does not converge), by doing:
N=1000
q = np.linspace(-10, 10, N)
p = np.linspace(-10, 10, N)
dS=(q[1]-q[0])*(p[1]-p[0])
q, p = np.meshgrid(q, p) #I meshgrid to have a 2D grid for integration.
#I define a dataframe here because I have seen it is quicker than vectorizing the expression
df = pd.DataFrame({'Q':np.concatenate(q),'P':np.concatenate(p)})
integral=sum((rho_dot_00_x(df['Q'],df['P'])).dropna()).real*dS
My problem is that it works really slowly and I cannot make work ufuncify, or theano.
Also, I tried to lambdify using "numpy" argument, but it ran way slowlier (I thought it should be quicker than math).
I also tried evalf after the substitution, like this:
f_substituted=f.subs(z,valueforz).evalf()
but it was even slower.
Any help to make the numeric evaluation quicker would be welcome.
Thanks in advance.
I'm currently using sympy to check my algebra on some nasty equations involving second order derivatives and complex numbers.
import sympy
from sympy.abc import a, e, i, h, t, x, m, A
# define a wavefunction
Psi = A * sympy.exp(-a * ((m*x**2 /h)+i*t))
# take the first order time derivative
Psi_dt = sympy.diff(Psi, t)
# take the second order space derivative
Psi_d2x = sympy.diff(Psi, x, 2)
# write an expression for energy potential (rearrange Schrodingers Equation)
V = 1/Psi * (i*h*Psi_dt + (((h**2)/2*m) * Psi_d2x))
# symplify potential function
sympy.simplify(V)
Which yields this nice thing:
a*(-h*i**2 + m**2*(2*a*m*x**2 - h))
It would be really nice if sympy simplified i^2 to -1.
So how do I tell it that i represents the square root of -1?
On a related note, it would also be really nice to tell sympy that e is eulers number, so if I call sympy.diff(e**x, x) I get e**x as output.
You need to use the SymPy built-ins, rather than treating those symbols as free variables. In particular:
from sympy import I, E
I is sqrt(-1); E is Euler's number.
Then use the complexes methods to manipulate the complex numbers as needed.
How to perform this kind of integral in python using scipy:
$$\int_{0}^{1} f(x) \, dx \int_{0}^{x} g(y) \, dy \int_{0}^{x} h(z) \,dz $$
Tried using tplquad, but I think the fact that the two inner integrals are independent functions of x is not something I'm able to code.
SciPy's tplquad expects a function of at least three arguments in the order (z, y, x). Nothing easier than that:
def fgh(z, y, x):
return f(x)*g(y)*h(z)
To specify bounds lambda functions are quite useful. Example code for the quadrature then reads:
tplquad(fgh, a=0, b=1, \
gfun=lambda x:0, hfun=lambda x:x, \
qfun=lambda x,y:0, rfun=lambda x,y:x)
I am quite newbie to Python and Sympy, so I googled a lot before asking this question.
I am using Sympy to derive equation of motion for a mechanical system by Lagrangian approach, which I managed to do.
from math import *
from sympy import *;
from sympy.physics.mechanics import *
from sympy.physics.vector import *
# dynamic symbols, for Lagrange equations
x, z, theta = dynamicsymbols('x z theta')
xd, zd, thetad = dynamicsymbols('x z theta',1)
xdd, zdd, thetadd = dynamicsymbols('x z theta',2)
# Lagrangian potential
L = Symbol('L')
def L(x,z,theta,xd,zd,thetad):
return 0.5*1*xd**2 + 0.5*100*thetad**2 - 0.5*300*(z)**2+0.5*250*(x+ 100*theta)**2
# build Lagrange equations
LM0 = LagrangesMethod(L(x,z,theta,xd,zd,thetad), [x, z, theta])
equations0 = LM0.form_lagranges_equations()
print(equations0)
However I obtain a 2nd order ODE system in 3 variables, which I would like to convert to a 1st order ODE system in 6 variables.
As you can see, output is given in terms of variables x, z, theta and their second derivatives. I cannot manage to get the Lagrange equations in form of variables xd, xdd, etc. so I was thinking to replace derivatives like this:
print(equations0[2].subs(Derivative(x,t,t),Derivative(xd,t)))
However substitution does not work and I get back the unmodified expression. I have seen another example where such susbstitution seem to work; the difference I see here is the use of dynamicsymbols.
Can anyone suggest how should I treat my equations to describe the system in terms of first order derivatives only?
Thanks in advance