You could find a general symbolic Fourier coefficient for a linear polynomial and use the formula to integrate the interpolating function piecewise. If you're content with machine precision (double precision), then you can Compile
it for really great speed.
(* Basic integral formulas *)
ClearAll[cn0];
cn0[0][{t0_, t1_}, {x0_, x1_}] = (* k == 0 is a special case *)
Integrate[(x0 + (x1 - x0)/(t1 - t0) (t - t0)) * Exp[-I*2*Pi*k*t/T]/T /. k -> 0,
{t, t0, t1}];
cn0[k_][{t0_, t1_}, {x0_, x1_}] =
Integrate[(x0 + (x1 - x0)/(t1 - t0) (t - t0)) * Exp[-I*2*Pi*k*t/T]/T,
{t, t0, t1}];
(* Coefficient function *)
Clear[cn];
cn[0] = Total@
MapThread[ (* map over interpolation segments *)
cn0[0],
{Partition[funX, 2, 1], Partition[fun, 2, 1]}];
cn[k_] = Total@
MapThread[
cn0[k],
{Partition[funX, 2, 1], Partition[fun, 2, 1]}];
(* Compiled version *)
cnC = With[ (* basic integrals *)
{i0 = Function[{t0, t1, x0, x1}, (* k == 0 is a special case *)
Evaluate@ Integrate[
(x0 + (x1 - x0)/(t1 - t0) (t - t0)) * Exp[-I*2*Pi*k*t/T]/T /. k -> 0,
{t, t0, t1}]],
i = Function[{t0, t1, x0, x1},
Evaluate@ Integrate[
(x0 + (x1 - x0)/(t1 - t0) (t - t0)) * Exp[-I*2*Pi*k*t/T]/T,
{t, t0, t1}]]},
Compile[{{k, _Integer}, {t, _Real, 1}, {x, _Real, 1}},
Total@If[k == 0,
i0[Most[t], Rest[t], Most[x], Rest[x]], (* vectorized for speed *)
i[Most[t], Rest[t], Most[x], Rest[x]]]
]];
Checks and comparison of speeds:
(* OP's method for comparison *)
cn1[k_] :=
NIntegrate[funINT[t]*Exp[-I*2*Pi*k*t/T]/T, {t, -T/2, T/2},
Method -> "Trapezoidal"];
res1 = Table[cn1[k], {k, 0, 5}] // AbsoluteTiming
res2 = Table[cn[k], {k, 0, 5}] // AbsoluteTiming
res3 = Table[cnC[k, funX, fun], {k, 0, 5}] // AbsoluteTiming
(*
{6.41549, {0.0509924, 0.0485667 + 0.000384561 I,
0.0489479 + 0.000373475 I, 0.0489737 + 0.000976852 I,
0.0459565 + 0.00132399 I, 0.0452069 + 0.000833868 I}}
{0.154046, {0.0509924, 0.0485667 + 0.000384561 I,
0.0489479 + 0.000373475 I, 0.0489737 + 0.000976852 I,
0.0459565 + 0.00132399 I, 0.0452069 + 0.000833868 I}}
{0.001207, {0.0509924 + 0. I, 0.0485667 + 0.000384561 I,
0.0489479 + 0.000373475 I, 0.0489737 + 0.000976852 I,
0.0459565 + 0.00132399 I, 0.0452069 + 0.000833868 I}}
*)
res1 - res2
res2 - res3
(*
{6.26145, {-6.245*10^-17, -1.27026*10^-10 - 3.56074*10^-10 I,
5.71595*10^-12 - 8.24057*10^-11 I, -5.08276*10^-10 - 1.50366*10^-11 I,
8.25427*10^-11 - 4.73669*10^-10 I, -3.07932*10^-10 + 1.72791*10^-10 I}}
{0.152839, {-1.38778*10^-17 + 0. I, -3.7817*10^-15 - 1.49451*10^-14 I,
1.1019*10^-14 - 3.11627*10^-15 I, -1.10328*10^-15 - 2.62073*10^-15 I,
-3.42781*10^-15 - 8.26162*10^-17 I, 1.88738*10^-15 - 1.13711*10^-15 I}}
*)
So cn
is almost 50 times faster than NIntegrate
and cnC
is over 100 times faster than cn
.
cn[k_] :=
, i.e. useSetDelayed
. As it stands, you are telling Mathematica to evaluate the RHS immediately, butNIntegrate
cannot do that for non-numericalk
. $\endgroup$rekon[t, 1000]
ifrekon[t_, st_] := Sum[cn[n]*Exp[I*2*Pi*n*t/T], {n, -st, st}]
. That is why I would like to somehow do the integration withk
as parameter. $\endgroup$