# Compute and evaluate function of a function and keep the result a function

Let's assume I have a various functions for signal amplitudes, e.g. pulse[t_] = Sech[t]^2 and pulse2[t_]L = Exp[-2t^2].

What I'd like to have is a general function the computes different forms of autocorrelation-like responses, let's take the autocorrelation as example. The result should be a function of time. So the autocorrelation should take a function as argument and return a function: ac[pulse2] = 1/2 E^-#^2 Sqrt[\[Pi]]

An easy solution but something I don't want is:

ac1[fct_] := ac1[fct] = Convolve[fct[\[Tau]], fct[\[Tau]], \[Tau], t]


resp.

ac2[fct_] :=  ac2[fct] = Integrate[fct[\[Tau]]*fct[\[Tau] - t], {\[Tau], -Infinity, Infinity}, Assumptions -> {Element[{t}, Reals]}]


The problem is that it returns an expression dependent on t and not a function.

My approach was something like

ac3[fct_] :=  ac3[fct] = Convolve[fct[\[Tau]], fct[\[Tau]], \[Tau], t] /. {t -> #} &


(ac4 accordingly with ac2) but this won't evaluate the autocorrelation yet: ac3[pulse2]=Convolve[pulse2[\[Tau]], pulse2[\[Tau]], \[Tau], t] /. {t -> #1} &

So how can I make Mathematica evaluate the whole autocorrelation first (using t) and then replace t with # to get a function? I use version 11.1

I think what you want is to work with Function expressions for everything that represents a mathematical function. Here is how I would do what I think you intend:

First I would define pulse as a value holding a Function expression, this is not strictly necessary for the rest to work but makes more clear that you are going to pass this around:

ClearAll[pulse];
pulse = Function[t, Sech[t]^2];


The definition of ac1 becomes slightly more complicated than before:

ac1[f_] := Module[{tau},
Function[t, Evaluate[Convolve[f[tau], f[tau], tau, t]]]
]


You want to evaluate the Convolve and then turn the expression of the result into a function. As Function has the attribute HoldAll we need to explicitly evaluate its second argument, there are other ways to achieve the same thing which you can find on this site. I also localized the tau to keep the code working when the global symbol tau would have values (for t the scoping of Function does the job). Again there would be other possibilities to achieve the same thing. The result is again a Function expression which you can evaluate for a given argument or pass around as desired. It can be used just as a function defined by downvalues in almost every case, e.g.:

 response = ac1[pulse];
Plot[response[t],{t,0.1,5}]

• Thanks for the explanation about Function. Inside the module (good point!), one can also use the shorthand ac1[f_] := Evaluate[Convolve[f[tau], f[tau], tau, #]] &, but I didn't manage to get the correct behaviour when trying around. Calling Function makes the behaviour more obvious. Dec 22, 2017 at 10:24
• @riddleculous: You might want to wait a bit before accepting my answer, there are probably other interesting answers. Just in case you are not aware of it: #& is only a shortcut for Function[#] (which is again a special case for Function[x,x]). If you look at the FullForm you will see that the two are internally the same thing. Dec 22, 2017 at 10:29