# Dealing with InterpolatingFunction in Compile

I have rather large equations that profit a lot from compiling, unfortunately they require input from external numerics and need to be interpolated.

In the end this costs a lot of performance as InterpolatingFunction triggers a MainEvaluate.

A minimal example:

testInt = Interpolation[{{0., 0.}, {2.5, 2.5}, {5., 5.}, {10., 10.}, {15.,
15.}}];

testCompile = With[{testInt = testInt},
Compile[{{x, _Real}, {a, _Real}},
testInt[a*x], CompilationTarget -> "C",
"RuntimeOptions" -> "Speed",
CompilationOptions -> {"InlineExternalDefinitions" -> True,
"InlineCompiledFunctions" -> True},
RuntimeAttributes -> {Listable}, Parallelization -> False
]];

CompilePrint[testCompile]

Out[3]= "
2 arguments
4 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking off
RuntimeAttributes -> {Listable}

R0 = A1
R1 = A2
Result = R3

1   R2 = R1 * R0
2   R3 = MainEvaluate[ Hold[InterpolatingFunction[{{0., 15.}}, <>]][ R2]]
3   Return
"


The options are set as in the case of my application.

Is there any way to access circumvent this the non compilabilty of InterpolatingFunction by accessing for example the resulting piece wise polynomial?

• Have you seen this? Of course there are other methods of interpolation that InterpolatingFunction supports. – Michael E2 Mar 20 '17 at 1:48
• Possibly you could rearrange your code such that all interpolation is done before passing that result as a packed array to the compiled function? – user21 Mar 20 '17 at 10:33
• @MichaelE2 sort of, it would boil down to writing my own compiled interpolation, which i will probably end up with. – Gebbo Mar 20 '17 at 12:26
• @user21 I don't quite understand what you mean. – Gebbo Mar 20 '17 at 12:26
• Yes, to be more specific the data/interpolation serves as an input for solving a differential equation and is only loaded once in the beginning. – Gebbo Mar 20 '17 at 14:43

Using existing code from here to extract the piece-wise polynomial from the interpolation and compile it.

data = MapIndexed[
Flatten[{#2, #1}] &, {2, 5, 9, 15, 22, 33, 50, 70, 100, 145, 200, 280, 375, 495, 635, 800, 1000, 1300, 1600, 2000, 2450, 3050, 3750, 4600, 5650, 6950}];

intF = Interpolation@data;
pwF[x_] = Piecewise[MapIndexed[{InterpolatingPolynomial[#1, x], x < 1 First[#2] + 2} &, Most[#]], InterpolatingPolynomial[Last@#1, x]] &@Partition[data, 4, 1];
compF = With[{}, Compile[{{x, _Real}}, Evaluate[N[pwf[x]]], CompilationTarget -> "C", "RuntimeOptions" -> "Speed", RuntimeAttributes -> {Listable}, CompilationOptions -> {"InlineExternalDefinitions" -> True}]];

compF[1.]//AbsoluteTiming
pwF[1.]//AbsoluteTiming
intF[1.]//AbsoluteTiming
{7.38984*10^-6,2.}
{0.0000640453,2.}
{0.0000225801,2.}


This solves the problem at hand and even speeds up the evaluation.

• Unfortunately, at least for me in 11.2, CompilePrint shows this too is bailing out to MainEvaluate – b3m2a1 Jan 8 '18 at 20:17
• @b3m2a1 wF = Which @@ Flatten[List[ MapIndexed[{x < 1 First[#2] + 2, InterpolatingPolynomial[#1, x]} &, Most[#]], {True, InterpolatingPolynomial[Last@#1, x]}] &@ Partition[data, 4, 1]]; then compF = With[{wF = wF}, Compile[{{x, _Real}}, wF, CompilationTarget -> "WVM", "RuntimeOptions" -> "Speed", RuntimeAttributes -> {Listable}, CompilationOptions -> {"InlineExternalDefinitions" -> True}]] – QuantumDot Jan 24 '18 at 21:25