# Proper way to construct a function that takes too long to plot and integrate

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

NIntegrateSymbolicPiecewiseSubdivision::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.

• 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}]] Jan 22 at 1:02
• @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... Jan 22 at 1:37
• 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? Jan 22 at 3:28
• 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`. Jan 22 at 4:02
• 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. Jan 22 at 9:57