I started using SymPy recently, and I implemented convolution using it.

def convolve(f,g,x,lower_limit,upper_limit):
    h = g.subs(x,x-y)
    return integrate(f*h,(y,lower_limit,upper_limit))

It seems to work for a few tests I've done.

Would like to know what you think of it, any improvements are appreciated.


2 Answers 2


Your code shouldn't work: You are calculating: $$\int_a^b f(t) \, g(t - \tau) \; d\tau$$ but convolution is defined as: $$f(t) \, * \, g(t) \equiv \int_{-\infty}^{\infty} f(\tau) \, g(t - \tau) \; d\tau$$ so the default limits of integration should be \$-\infty\$ to \$\infty\$. More importantly you should use the proper argument for f (the integration variable). Finally, naming the integration variable y feels unusual.

from sympy import oo, Symbol, integrate
def convolve(f, g, t, lower_limit=-oo, upper_limit=oo):
    tau = Symbol('__very_unlikely_name__', real=True)
    return integrate(f.subs(t, tau) * g.subs(t, t - tau), 
                     (tau, lower_limit, upper_limit))

Problematic Assumptions

You implicitly assume that x is not Symbol('y'). If it is, then g.subs(x, x-y) will return a different, constant function (g'(x) = g(0)). You could check for this case and handle it specially, or just use a more uncommon symbol to reduce the risk.


You have inconsistent spacing in your code. PEP8 recommends a space after every comma and on either side of binary operators (like =, -, and *):

def convolve(f, g, x, lower_limit, upper_limit):
    y = Symbol('y')
    h = g.subs(x, x - y)
    return integrate(f * h, (y, lower_limit, upper_limit))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.