# A symbolic convolution of arbitrary functions

In this manual it is described how to get a symbolic result of "the convolution of any piecewise defined function with another". However, when I try this with functions like exponent, this does not work:

x = PolynomialRing(QQ, 'x').gen()
f = Piecewise([[(0,1),exp(x)]])
f.convolution(f)


I get an error "RuntimeError: Symbolic Ring still using old coercion framework"

If I use a 'RR' ring instead of 'QQ', Piecewise() returns another error "TypeError: cannot coerce arguments: __call__() takes exactly 1 positional argument (0 given)"

I have 2 questions:

1. Is there a way to get a function, which represent convolution of a gaussian function and a decaying exponent (and, generally, any functions)? I want to fit my data with such a function.
2. How to get a symbolical convolution of functions with parameters (they should be assumed to be constants during convolution computation)?
edit retag close merge delete

Sort by » oldest newest most voted

The possible way is to use convolution definition and to find symbolically the corresponding integral. This may be done without piecewise definition:

lg2=log(2).N()
gaussian(x,x_0,FWHM,A)=A*exp(-(x-x_0)^2/(2.0*(FWHM^2/4.0*lg2)))
expdec(x,S,x_0,tau)=S/tau*exp(-(x-x_0)/tau)
var('t, x_0, FWHM, y_0, S_1, tau_1')
assume (t>0)
subint_dec1(s,t,x_0,FWHM,a_1,tau_1)=gaussian(x=s,x_0=x_0,FWHM=FWHM,A=1)*expdec(x=t-s,x_0=x_0,S=S_1,tau=tau_1)
exp_decay=subint_dec1.integral(s,0,t)


However, the resulting function works rather slow for fitting purposes

more

I wonder how to make it faster. I tried fast_callable(), but it does not seem to help.

I can't fix this for you (yet?), but I see why this wasn't detected before - the example you reference uses

f = Piecewise([[(0,1),1*x^0]])


which becomes

sage: f
Piecewise defined function with 1 parts, [[(0, 1), 1]]


so the variables don't come into play. Also, the example (and yours) uses a polynomial variable, which of course (?) becomes non-polynomial once e^x is involved. So there are two strikes against this.

It's not clear to me that there is an easy way to get around this, because there isn't an obvious way to turn the polynomial generator x into an exponential, but the code for convolution relies pretty heavily on having those polynomial generators.

Stock disclaimer: all piecewise material dates from before Sage had any true symbolic capabilities. It has since languished. See the piecewise tag here and questions under it, such as this one.

I'm hoping someone more familiar with some of the numerical tools in Sage can help you with your underlying questions. You can certainly get some convolutions, e.g. discrete ones in Numpy, but your use case might be a little trickier.

Maxima used directly might be of help, or perhaps using its integration as at this Maxima feature request or using its piecewise capabilities.

more