For a (relatively large) set of triplets $(i,l,m)$, I have a table of values representing a smooth function that is only continous at $x=0$. I am attempting to construct an interpolating function, by first interpolating their values to the "left" and "right" of $x=0$, and then stitiching the two solutions together via Piecewise (or If). As this must be done for each triplet $(i,l,m)$, I am doing this inside a Do loop. A self-contained example of this is the following code:
xmin = -2; xInterface = 0; xmax = 2;
xgrid = Range[xmin, xmax, 1/100];
Monitor[Do[
(*set up the table left and right of the interface*)
interfaceValue = RandomReal[{1, 10}];
myPolyLeft[x_] =
RandomReal[{1, 3}] x^2 + RandomReal[{1, 10}] x + interfaceValue;
myPolyRight[x_] =
RandomReal[{1, 3}] x^2 + RandomReal[{1, 10}] x + interfaceValue;
leftTable =
Table[myPolyLeft[xmin + (xInterface - xmin) i/200], {i, 0, 200}];
rightTable =
Table[myPolyRight[xInterface + (xmax - xInterface) i/200], {i, 0, 200}];
(*interpolate and stitch the solutions together*)
leftInterpol[i][l, m] =
Interpolation[Transpose[{xgrid[[;; 201]], leftTable}]];
rightInterpol[i][l, m] =
Interpolation[Transpose[{xgrid[[201 ;;]], rightTable}]];
fullInterpol[i][l, m][x_] =
Piecewise[{{Evaluate[leftInterpol[i][l, m][x]], x < xInterface},
{Evaluate[rightInterpol[i][l, m][x]], x > xInterface}}, interfaceValue],
{i, 1, 10}, {l, 2, 40}, {m, -l, l}],
{i, l, m}]
What I am surprised to see is that, evaluating fullInterpol
, for some parameters $(i,l,m)$, on a grid takes about 1000x longer than its left and right interpolants:
Table[rightInterpol[10][3, 2][xInterface + i (xmax - xInterface)/100], {i, 0, 100}]; // AbsoluteTiming
Table[leftInterpol[10][3, 2][xmin + i (xInterface - xmin)/100], {i, 0,100}]; // AbsoluteTiming
Table[fullInterpol[10][3, 2][xmin + i (xmax - xmin)/100], {i, 0, 100}]; // AbsoluteTiming
(* Timing Output: 0.000499, 0.000298, 0.451422 *)
Strangely, this seems to scale(!) with the range of parameters $(i,l,m)$, for example:
myNewFunc[10][3, 2][x_] = fullInterpol[10][3, 2][x];
Table[myNewFunc[10][3, 2][xmin + i (xmax - xmin)/100], {i, 0, 100}]; // AbsoluteTiming
(* Timing Output: 0.000272 *)
Finally, using pattern matching on each indices:
fullInterpol2[i_][l_, m_][x_] =
Piecewise[{{leftInterpol[i][l, m][x], x < xInterface}, {rightInterpol[i][l, m][x], x > xInterface}}, interfaceValue]
then timing is now quick:
Table[fullInterpol2[10][3, 2][xmin + i (xmax - xmin)/100], {i, 0, 100}]; // AbsoluteTiming
(* Timing Output: 0.000346 *)
Can someone explain why this is happening?