Skip to main content
deleted 29 characters in body
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
(* 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[ * 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[
       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[
       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]]]
    ]];
(* 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}}
*)
(* 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]]]
    ]];
(* 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}}
*)
(* 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]]]
    ]];
(* 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}}
*)
Source Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774

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.