Definite integral over one variable in a function with two variables in Scipy

Question:

I am trying to calculate the definite integral of a function with multiple variables over just one variable in scipy.
This is kind of like what my code looks like-

from scipy.integrate import quad
import numpy as np
def integrand(x,y):
    return x*np.exp(x/y)

quad(integrand, 1,2, args=())

And it returns this type error:

TypeError: integrand() takes exactly 2 arguments (1 given)

However, it works if I put a number into args. But I don’t want to, because I want y to remain as y and not a number. Does anyone know how this can be done?

EDIT: Sorry, don’t think I was clear. I want the end result to be a function of y, with y still being a symbol.

Asked By: Hannah

||

Answers:

The best you can do is use functools.partial, to bind what arguments you have for the moment. But one fundamentally cannot numerically integrate a definite integral if you havnt got the entire domain specified yet; in that case the resulting expression will necessarily still contain symbolic parts, so the intermediate result isn’t numerical.

Answered By: Eelco Hoogendoorn

(Assuming that you are talking about computing the definite integral over x given a specific, fixed value of y.)

You could use a lambda:

quad(lambda x:integrand(x, 10), 1, 2, args=())

or functools.partial():

quad(functools.partial(integrand, y=10), 1, 2, args=())
Answered By: NPE

You probably just want the result to be a function of y right?:

from scipy.integrate import quad
import numpy as np
def integrand(x,y):
    return x*np.exp(x/y)

partial_int = lambda y: quad(integrand, 1,2, args=(y,))
print partial_int(5)
#(2.050684698584342, 2.2767173686148355e-14)
Answered By: CT Zhu

Thanks to mdurant, here’s what works:

from sympy import integrate, Symbol, exp
from sympy.abc import x
y=Symbol('y')
f=x*exp(x/y)
integrate(f, (x, 1, 2))

Answer:

-(-y**2 + y)*exp(1/y) + (-y**2 + 2*y)*exp(2/y)
Answered By: Hannah
from scipy.integrate import quad
import numpy as np
def integrand(x,y):
    return x*np.exp(x/y)

vec_int = np.vectorize(integrand)
y = np.linspace(0, 10, 100)
vec_int(y)
Answered By: Evilolipop