Non-cartesian coordinate integration in SymPy - python

I have a function defined in elliptic coordinates. How can I symbolically integrate it in SymPy? Otherwise, do you have an example of implementation of any other non-Cartesian integration?
import sympy as sym
r = sym.Symbol('r')
Z = sym.Symbol('Z', constant = True)
#1s normalized orbital definition
def f(r):
return (1/(sym.pi)) * (Z**1.5) * sym.exp(-Z*r)
Thanks in advance!

import sympy as sym
from sympy import integrate
r = sym.Symbol('r')
Z = sym.Symbol('Z', constant = True)
integrate('(1/(pi)) * (Z**1.5) * exp(-Z*r)', r, Z)
Output:

Related

Sympy blanket initial condition (or assumption?)

I'm using Sympy 1.10.1 in Jupyter. Some cells look like:
import sympy as sp
x = sp.Symbol('x')
y = sp.Function('y')(x)
y.diff(x)
diff_eq = sp.Eq(y*y.diff(x), 4*x )
diff_eq
sol = sp.dsolve(diff_eq, y)
sol
And Sympy responds with
[Eq(y(x), -sqrt(C1 + 4*x**2)), Eq(y(x), sqrt(C1 + 4*x**2))]
Can I modify the above so that Sympy does not offer solutions
with negative range?

2nd order differential equation coupled to integro-differential equation in python

I'm trying to solve the following equations numerically in python
where f(r)=S*exp(-r^2/b^2) and µ and m_π are constants.
I have tried rewriting the 2nd order differential equation into two first order equations and solving the system of equations with root finding.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from scipy.integrate import trapz
from scipy.optimize import root
b=1
S=20
m=135
mn = 939.5
mu = m*mn/(mn+m)
g = (2*mu)
def f(r):
return S*np.exp(-r**2/b**2)
def diff(phi,r,E):
return (phi[1],g*(-E+m)*phi[0]-2/r*phi[1]+g*f(r))
phi0 = [b/m,b/m] #Initial
def phi_fun(E):
rs = np.linspace(1e-5,50,1000)
ys = odeint(lambda phi,r: diff(phi,r,E), phi0, rs)
integral = 12*np.pi*trapz(ys[:,0]*f(rs)*rs**4,rs)
return integral - E
E_true = root(phi_fun, -2).x
rs = np.linspace(1e-5,50,1000)
ys = odeint(lambda phi,r: diff(phi,r,E_true), phi0, rs)
phi_true = ys[:,0]
plt.plot(rs, phi_true,linewidth=2,label=r'$\phi(r)$')
print("Minimum found at E =",E_true)
This does not produce a result I would expect and maybe I have done something wrong. I was thinking about using IDEsolver but I'm not sure how to implement this. Any suggestions?
Thanks in advance!

Derivative and how to convert symbolic expression of it

I need to obtain a derivative to use it later in numerical calculations. And my code doesn't work at all. I tried to use lambdify but the error is "can't convert symbols int". I read other answers for similar questions but it still doesn't work.
import numpy as np
from scipy.integrate import odeint
from scipy.integrate import quad
from scipy.integrate import solve_bvp as bvp
import matplotlib.pyplot as plt
from scipy.special import genlaguerre as L
from scipy.special import gamma as G
from math import factorial
from math import sqrt
import sympy as sym
from sympy.utilities.lambdify import lambdify
mp = 938.2720813
mn = 939.5654133
mu = (mn + mp)/4
hbar = 197.3270533
h2m = hbar**2/(2*mu)
V0 = 20
Rv = 1.5
Q0 = 1.5
Rq = 4.5
EIm = 0.3
ERe = 1
V = lambda r : -V0*np.exp(-r/Rv)
Q = lambda r : -Q0*np.exp(-r/Rq)
chi = lambda r, l : sqrt(factorial(l)*beta**3/(G(3 + l))) * r * L(l,2)(beta * r) * np.exp(- beta * r / 2)
r, l, beta = sym.symbols('r, l, beta')
def chifD(r, l, beta):
return sqrt(factorial(l)*beta**3/(G(3 + l))) * r * L(l,2)(beta * r) * np.exp(- beta * r / 2)
def chiD(r, l, beta):
return sym.diff(chifD(r ,l, beta), r)
print(chiD(r, l, beta))
chiLambdified = lambdify(((r,l, beta),),chiD(r,l, beta),"numpy")
print(chiD(1, 1, 1))
I'm pretty sure you're mixing modules you shouldn't. I kept modifying your chi function until I got something that works. Nothing short of removing all math and scipy functions returned something that wasn't a TypeError.
# works with sympy sqrt.
chi = lambda r, l : sym.sqrt(l*r)
print(chi(r,l))
# doesn't work with math or numpy sqrt.
chi = lambda r, l : math.sqrt(l*r)
print(chi(r,l))
If you want to use functions, you'll have to use the ones that come with sympy, define your own using basic operators (so that sympy objects will be accepted) or find simpler ways to define your operations: sqrt() can simply be substituted by **(1/2).
Maybe you should look for a way that can make sympy accept functions from other modules because writing all of the special functions from scipy yourself looks like it will be a pain.

Comparing convolutions in Mathematica and Python

I'm comparing the results of convolution in Python (using sympy's symbolic variables) and Mathematica with its Convolve function.
In Python, my MWE is
from numpy import linspace, pi
from numpy.random import randn
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
from sympy import symbols
from sympy.utilities.lambdify import lambdify
a = 0.43
b = 0.41
c = 0.65
d = 0.71
x = symbols('x')
f = 2*b / ((x-a)**2 + b**2)
g = 2*d / ((x-c)**2 + d**2)
fog = fftconvolve(f,g,mode='same')
fog_fun = lambdify(x,fog,'numpy') # returns a numpy-ready function
x = linspace(-20,20,int(1e3))
dx = x[1]-x[0]
fogS = fog_fun(x)
fogA = 4*pi*(b+d)/((x-a-c)**2+(b+d)**2) # correct analytic solution
plt.figure()
plt.plot(x,fogA,lw=2,label='analytic')
plt.plot(x,fogS,lw=2,label='sympy')
plt.grid()
plt.legend(loc='best')
plt.show()
which calculates a convolution using symbolic variable x. The resulting function (before lambdifying) is
fog = 1.1644/(((x - 0.65)**2 + 0.5041)*((x - 0.43)**2 + 0.1681))
There is no agreement between analytic (fogA, Mathematica) and sympy (fogS, Python):
My Mathematica code is:
a = 0.43; b = 0.41; c = 0.65; d = 0.71;
fogA = FullSimplify[Convolve[2*b/((t-a)^2+b^2),2*d/((t-c)^2+d^2), t, x]];
fogS = 1.1644/(((x - 0.65)^2 + 0.5041)*((x - 0.43)^2 + 0.1681));
where
fogA = (17.683+x*(-30.4006+14.0743*x))/(3.04149+x*(-7.9428+x*(8.3428+x*(-4.32+1.*x))))
and graphs for fogS and fogA are the same as for Python.
Why is there such a large disagreement between the analytic and sympy solution? I suspect the problem lies with sympy. Another Pythonic method is to convolve two arrays which seems to agree with the analytic solution.
f = 2*b / ((x-a)**2 + b**2)
g = 2*d / ((x-c)**2 + d**2)
fogN = fftconvolve(f,g,mode='same')*dx # numeric
(Note: this is a MWE. The actual f and g I want to convolve are much more complicated than the Lorentzians defined in this post.)
I do not think this is a reasonable way of using scipy + sympy.
I am actually quite surprised that you get a result from lambdify at all.
What you should be doing, instead of using scipy.signal.fftconvolve(), is to use a symbolic definition of the convolution, e.g.:
from sympy import oo, Symbol, integrate
def convolve(f, g, t, lower=-oo, upper=oo):
tau = Symbol('__very_unlikely_name__', real=True)
return integrate(
f.subs(t, tau) * g.subs(t, t - tau), (tau, lower, upper))
adapted from here.

Finding coefficient of a specific term using sympy

I am trying to find coefficient of xy using sympy. This is the program.
import sympy as sp
fro sympy import Poly
from sympy.abc import x, y
x,y,xy=sp.symbols('x,y,xy')
K=Poly(x**2 + 5*xy + 1).coeff(xy)
print K
Kindly help. Thanks in advance.
import sympy as sp
from sympy.abc import x, y
x,y,xy=sp.symbols('x,y,xy')
expression = x**2 + 5*xy + 1
print expression.coeff(xy)
Note that this is probably not what you want. You're not looking for a symbol xy but for the coefficient with the crossterm of symbols x and y. You should therefor change the expression to:
expr = x**2 + 5*x*y+1
expr.coeff(y).coeff(x)

Categories

Resources