There is an elegant way to obtain the envelope of an oscillation function explained here https://mathematica.stackexchange.com/a/27854/15966
My question is how to modify the code below so I can fit data to the obtained envelope with a parameter. How do I introduce a parameter into the module so it can be used later for fitting when the result of the module is an interpolation function.
Lets' generate some data
a = RandomReal[{20, 30}];
b = RandomReal[{5, 10}];
data = Table[{x, Cos[a*x]^2*Exp[-b*x]}, {x, 0, 1, 0.001}];
ListPlot[data, PlotRange -> All]
The code generates something like this:
Now the module below produces envelope for the given oscillating function
FunctionEnvelope[f_, {t_, a_, b_}, n_: 40] :=
Module[{seeds, x, y, points, progress = 0, tempf, union},
seeds = Rescale[Range[0, 1, 1/n] + 1/(2 n), {0, 1}, {a, b}];
points =
Last[Last[
Reap[Monitor[
Do[Quiet@
Check[progress++; {y, x} = FindMaximum[Abs[f], {t, x0}];
x = t /. x; If[a <= x <= b, Sow[{x, y}]], Null], {x0,
seeds}],
ProgressIndicator[progress, {0, Length[seeds]}]]]]];
union[] :=
points =
Union[points,
SameTest -> (Abs[First[#1] - First[#2]]/
Replace[Max[Abs[First[#1]], Abs[First[#2]]],
u_ /; u == 0 :> 1] < 10^-6 &)];
union[];
tempf = Interpolation[points];
points = Quiet[Join[{{a, tempf[a]}}, points, {{b, tempf[b]}}]];
union[];
Interpolation[points]]
It can be used as follows:
q = 50;
f[t_] := E^(- 10*Abs[t]) * Cos[1000*t]/2 +
E^(-10*Abs[t])*Cos[(1000 + q)*t ]/2
g = FunctionEnvelope[f[x], {x, 0, 1}, 200];
Plot[{f[x], g[x]}, {x, 0, 1}, PlotRange -> All]
My question is how can I modify the module above to make it a function of the parameter q, so that the resulting interpolation function can be used to fit the data to get the optimal parameter q.
(The function f[t] is in principle can be moved to the definition of the module, I'm not going to change it.)
Thanks!
E^(-10 Abs[t]) Abs[Cos[q t/2]]
. $\endgroup$ – Rahul Jun 18 '14 at 9:30