Represent placeholder for inverse of a function in SymPy - python

I am interested in solving integro-differential equations that not only contain functions of variables, but also inverse functions. In SymPy a function can be represented by Function:
from sympy import *
x = Symbol('x')
f = Function(x)
However I did not find an inverse function method. While Function has the method inverse, it is more specifically the multiplicative inverse.
Attempting to setup an equation and solve it to obtain a symbolic inverse is not implemented:
from sympy import *
x = Symbol('x')
y = Symbol('y')
f = Function(x)
solve(Eq(y, f))
NotImplementedError:
No algorithms are implemented to solve equation y - f(x)
Is there a way to setup a symbolic inverse of a function in SymPy?

Related

Solve Integro-Differential equation in Python

I am trying to solve a physics problem that involves the following equation,
As you can see, sigma could be any function and K1 is a Bessel function. The differential equation has to be solved for Y(x), but x is involved in the integral. In addition, we have another parameter m being a free parameter in the integral and outside the integral. Do you have any idea to solve this?
Sympy does not solve this since it has no analytical solution.
My idea was the following,
I write the integral as a function of x, m.
def get_integral(x,m):
integrand = lambda s: f(s,x,m)
integral = quad(integrand,4*m**2, + np.inf)[0]
return integral
Then write the derivative,
def dYdx(x,Y,m):
x1 = f(x,m))
x2 = get_integral(x,m)
x3 = Y**2-Y_0(x,m)**2
return x1*x2*x3
So I use odeint to solve it like,
solution = odeint(dYdx, y0=0, t = x_array,tfirst=True,args =(m,))
But as you can see I need to solve it for different values of x,s, and m. So that I have an array having the following structure
solution_array = [x,Y,m,integral_value]
for each time I evaluate x and m.

Sympy function evaluated at symbol

I have a problem with the symbolic Python package Sympy.
Perhaps I am missing some obvious tools in Sympy but I have read through the documentation and not come across a solution.
My question is can the derivative of g(f(y)) = g(f(x))|_(x=y) with respect to x be obtained in the form Derivative(f(x), x)(y) in Sympy? And if so how?
Here is a simple example: I have a symbolic function of one variable e.g. f(x).
I have another expression g, which calls this function with input arguments
represented by other symbols, i.e. g(f(y)) where y = Symbol('y').
I implement this with the following:
x = Symbol('x')
f = Function('f')(x)
y = Symbol('y')
g = Function('g')(f).subs('x','y')
My goal is then to evaluate the derivative of g wrt x at x=y, something like
Derivative(f(x), x)(y) * Derivative(g(f), f)(f(y))
This can be roughly achieved with
diff(g, y) = Derivative(f(y), y)*Derivative(g(f(y)), f(y)).
The problem here is that the term Derivative(f(y), y) in this case is the derivative evaluated at y.
I have expressions for the derivatives of functions wrt all input variables, i.e. Derivative(f(x), x) in this case, and not wrt y since it is not a variable of f. Hence, I would like the derivative expressed in the form Derivative(f(x), x)(y) to avoid repeating the same expression for all the possible variables used.
(For completeness, the term diff(g, x)=0 since any instances of x have been replaced by y.)
To enforce the notion that g is a function of x evaluated at y, replacing the method subs of the fourth line above with the evalf method could be the right path. But it seems that expression can only be evaluated at particular values and not other symbolic variables.
Any help and advice is most appreciated.
Wrapping the differentiation in Subs seems to work; it is a delayed substitution.
>>> from sympy import Subs, sin, cos
>>> from sympy.abc import x, y
>>> f, g = symbols('f g', cls=Function)
>>> Subs(g(f(x)).diff(x),x,y).subs(g,sin).subs(f,cos).doit(
... ) == Subs(sin(cos(x)).diff(x),x,y).doit()
True

Fastest way to integrate a function that depends on a variable

I wish to evaluate the function y(x), which consists of an integral with the integrand depending on x. The integrand thus depends on two variables z and x. Here z is the variable that I wish to integrate over the range (0,1), and x is the variable that the function y(x) depends on.
The result should thus be an array y that is the integral of this integrand over z for each x.
My approach is the following
import numpy as np
from scipy.integrate import quad
x = np.linspace(0,6,1000)
integrand = lambda z, x: z**x
y = lambda x: quad(integrand, 0, 1, args = (x))[0]
y = np.vectorize(y)(x)
This works, but it also takes some time if I want to do more complicated integrals multiple times. This makes me wonder if there is a way to improve the computation time for this procedure. Please ignore the fact that here the integral can be solved analytically. This is just an illustrative example.

Wrong result when integrating piecewise in sympy

I have been working with piecewise functions in sympy and it does not seem to be integrating them correctly with their context.
Piecewise function
Correct Integration
sympy output
from sympy import *
init_printing(use_unicode=False, wrap_line=False)
x = Symbol('x')
f = Function('f')
a1 = 4
a2 = 8
a3 = 12
G = Piecewise((x,And(x<=a1,x>=0)),(4,And(x>a1,x<=a2)),((x-a3)**2/4,And(x>a2,x<=a3)))
diffeq1= Eq(f(x).diff(x),G)
gg1 = dsolve(diffeq1,f(x))
Am I missing something in my input concerning the creation of the piecewise function or in the differential equation solver?
Edit 2/24/2021
I have included an example of what g(x) would look like with the boundary condition of g(0)=0. Sympy used this boundary condition, with its answer describing the function as 4x between 4<x<8, which is almost there, but it doesn't include the context of what occurs at x = 4. What should occur is g(3.999) ~= g(4.0001), but instead sympy is saying g(3.999) ~= 8 and g(4.0001)~= 16.
Numerically Integrated Method of f(x)

Transforming polynomial variable in Numpy

I am trying to learn how to use Numpy. Consider I have the roots of a polynomial. I use
coeff = np.polynomial.polynomial.polyfromroots(roots)
to get the coefficients of the polynomial as an array. Then I use
print np.poly1d(coeff)
To print out the polynomial. Let that polynomial be
x^2 +3x + 2
Now how do I transform the variable such that
x is now 2/x
That is the equation becomes
(2/x)^2 + 6/x + 2
In scilab I can do this using the horner function. Is it possible in numpy?
In SymPy this would be simply:
from sympy.abc import x
f = x**2 + 3*x + 2
g = f.subs({x:2/x})
Resulting in:
print(g)
#2 + 6/x + 4/x**2
The resulting expression is not a polynomial, and Sympy would probably be a better choice here.
Alternatively you can just scale the coefficients of the polynomial by the appropriate numerical factor,
coeff *= np.power(factor, np.arange(len(coefs)-1, -1, -1)) # factor=2 here
and then use the polynomial functions from numpy, with the variable 1/x instead of x.

Categories