Consider the functions phi[t_] and psi[t_] defined in the code below. These are used as basis functions for interpolation purposes. Consider a "time" variable T, a total number of interpolation nodes n0 and a step h0. Consider the values at nodes given by variables a and b. The required interpolation is defined by the function q[t_] defined below as the sum of a times phi plus b times psi.

phi[t_] := Boole[-1 <= t <= 1] (1 - Abs[t])^2 (1 + 2 Abs[t]);
psi[t_] := Boole[-1 <= t <= 1] t (1 - Abs[t])^2;
T = N@Pi
n0 = 500;
h0 = T/n0;
a = Table[Cos[i*h0], {i, 0, n0}];
b = Table[Sin[i*h0], {i, 0, n0}];
q[t_] = Sum[a[[k + 1]]*phi[t/h0 - k] + h0*b[[k + 1]]*psi[t/h0 - k], {k, 0, n0}];

EDIT NOTE The above example interpolates the cosine function but the targeted function is not necessarily periodic. a and b are constructed with Cos and Sin functions respectively only for example purposes. Values for a and b come from external computations and are data inputs. Function q[t] must interpolate these values using phi and psi functions defined above, which always require T, n0 and h0.

When constructing the interpolated function q[t_] in this kind of manner results in operations on q[t_] taking way too long. A simple plot for example

AbsoluteTiming[Plot[q[t], {t, 0, T}]]

takes more than 4 seconds to compute in my machine. Integrating this function with

NIntegrate[q[t], {t, 0, Pi/2}]

sends the message

NIntegrate`SymbolicPiecewiseSubdivision::maxpwc: The number of piecewise regions has exceeded the maximum value specified by the option MaxPiecewiseCases -> 100. The integration will continue with no piecewise subdivision.

I can get around the integration issue by reducing the number of interpolation nodes to no more than 200, however, this begs the question of whether or not I am doing this the right way. Is there a better way to construct the q[t_] function?

Note that I cannot define q[t_] in the "set delayed" way because my a and b coefficients are constantly changing to approach other functions, and I need to store every interpolated function separately.

  • $\begingroup$ Q[t_] = Sum[ Cos[(k + 1)*h0]*phi[t/h0 - k] + h0*Sin[(k + 1)*h0]*phi[t/h0 - k], {k, 0, n0}]; AbsoluteTiming[Plot[Q[t], {t, 0, T}]] $\endgroup$
    – cvgmt
    Jan 22 at 1:02
  • $\begingroup$ @cvgmt Your solution indeed reduces the time to Plot. However, here you are directly using Cos and Sin Mathematica functions which were used to define coefficients a and b only as an example. As I mention at the end of my query, these coefficients are variable and I often not know how they are constructed... $\endgroup$
    – Meclassic
    Jan 22 at 1:37
  • $\begingroup$ Meclassic, you can take inspiration or lesson from @cvgmt’s answer in that it shows instead how to use directly the functions for a and b in the Sum that may offer better performance, rather than listing them out & calling their corresponding parts from the Sum which costs the need to store the list before calling it. Can you, please, clarify further other functions you might use for a and b? And if you will always subdivide the function using periodic terms set like T, n0, and h0? $\endgroup$ Jan 22 at 3:28
  • 1
    $\begingroup$ Ah, my suggestion involves directly callable functions to avoid what I think may be a slowdown via the creation, storing, & subsequent calling of lists of data. However I do notice now that your phi & psi may benefit from memoization or perhaps using Set rather than SetDelayed. $\endgroup$ Jan 22 at 4:02
  • 2
    $\begingroup$ On my machine the plot takes 3.1. seconds. You can force the large sum in q[t] into a piecewise function by defining q1[t_]= q[t]//Simplify. With the new function q1 the plot time is reduced to 0.7 seconds. $\endgroup$ Jan 22 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.