简体   繁体   中英

Is there a way to connect SymPy symbolic differentiation with SciPy's Quad Integration package?

I just recently learned how to integrate a two-variable function using SciPy's quad integration, with respect to just one variable. For instance, say we have a function f(x,y). I integrated with respect to x, in order to get f(y). I then plotted f(y) vs a NumPy array of y values. No problem here. However, I now would like to multiply my original integrand by a Jacobian Matrix (where each function in the respective entry of the Jacobian is also as a function of x and y).

The problem that I can't quite conceptualize now, is how to incorporate partial differentiation into my original code --- which very cleanly integrated my initial two-variable function. I am aware that SymPy is a great option for symbolic integration, but I could not figure out how to evaluate the Jacobian (due to the fact that this requires derivatives) in a way that would be compatible with it's result being multiplied by a separate function, and then integrating that product. Is there a form of lambdify , that instead of converting my SymPy functions to their NumPy counterparts, it converts SymPy functions to ones that are usable in SciPy's quad integration? Or is their another common practice?

from sympy import symbols, diff
import numpy as np
from scipy.integrate import quad
from scipy import integrate
import matplotlib.pyplot as plt

## define f(x,y) function *** BUT INTEGRATING dx ***
## where the bounds are as a function of y ***
## SciPy and NumPy are used in these steps

def example(y):
    return lambda x: (x * y)

def example_integral(y):
    return quad(example(y), 0, y, args=())


## F(y) = (y^3) / 2

print('F(y) --> F(4) = (4^3)/2 = ',example_integral(4)[0])
print('Integration works')


## Plotting f(y) vs. y
## This graph should follow cubic power
example_range = np.linspace(-11,10,20)
example_array = []

for i in example_range:
    example_array.append(example_integral(i)[0])

plt.figure(figsize=(6,6))    
plt.plot(example_range,example_array)
plt.title("Example Plot of original integrated function\nF(y) vs y")
plt.show()
## Here I will differentiate two separate functions for the Jacobian
## SymPy is used in these following steps
x, y = symbols('x y', real=True)
f = (2*x*(y**2)) + y**3
g = x/y

df_dx = diff(f, x)
df_dy = diff(f, y)
dg_dx = diff(g, x)
dg_dy = diff(g, y)

## I compute the Jacobian here
jacobian = (df_dy * dg_dx) - (df_dx * dg_dy)
print("The resulting Jacobian is: ", jacobian) 

Per the suggestions, I included example code that explains best what my predicament is. Should this not abide by the "minimal example" guidelines, please comment and I will fix this. As you can see, in the first block, I used SciPy and NumPy to integrate and plot my original function. In the second block, I used SymPy to differentiate two separate functions and to compute the Jacobian. Ultimately, I would like to multiply my resulting Jacobian (in the second block) by my original function (in the first block). After I have this new function (the product of the two), I would like to simply preform the same integration procedure. Attached here --> 1 is a screenshot of the error message I receive when I try to run this idea (this was expected). Please let me know if I can do anything to better explain this. Thank you!

I can only make a wild guess that SymPy's ufuncify will help you. It translates SymPy expression to vectorised NumPy ufuncs , which can be applied in a vectorised manner. Thus it can also be used by SciPy's quadrature routines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM