7
$\begingroup$

Consider this

s = C1 /. 
  First@NDSolve[{I C1'[t] == C2[t] E^(-I t), 
     I C2'[t] == C1[t] E^(I t), C1[0.] == 1., C2[0.] == 0.}, {C1, C2}, {t, 0., 10.}]
sol[t_] := 
 Piecewise[{{s[t], t <= 10.}, {Sin[t], t <= 20.}, {Cos[t], t <= 30}}, 0.]
On["CompilerWarnings"]
f3 = Compile[{{t, _Real}}, Evaluate@sol[t]]

I get warnings because compile doesn't know the return type of InterpolatingFunction

Compile::noinfo: No information is available for compilation of InterpolatingFunction[{{0.,10.}},{4,31,1,{107},{4},0,0,0,0,Automatic},<<1>>,{Developer`PackedArrayForm,{0,2,4,6,8,10,12,<<38>>,90,92,94,96,98,<<58>>},{1. +0. I,0. +0. I,1. +0. I,-0.000102139+0. I,1. +1.06555*10^-12 I,<<42>>,-0.5557+0.183522 I,0.767381 +0.0556081 I,-0.598783+0.22247 I,<<164>>}},{Automatic}][t] . The compiler will use an external evaluation and make assumptions about the return type. >>

and it failed to use the compiled version

f3[5.]

During evaluation of In[38]:= CompiledFunction::cfex: Could not complete external evaluation at instruction 3; proceeding with uncompiled evaluation. >>

(*-0.787326 - 0.231525 I*)

so I tried to set the return type like this

f3 = Compile[{{t, _Real}}, 
  Evaluate@sol[t], {{_InterpolatingFunction, _Complex}}]

or

f3 = Compile[{{t, _Real}}, Evaluate@sol[t], {{InterpolatingFunction[__], _Complex}}]

both don't work.

In contrary, Fourier seems also has this problem(example taken from here)

Compile[{{m, _Real, 2}}, Fourier[m]][Table[N[i - j], {i, 2}, {j, 2}]]

CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation. >>

(*{{0., 1.}, {-1., 0.}}*)

but after specify the return type, it works

Compile[{{m, _Real, 2}}, Fourier[m], {{_Fourier, _Complex, 2}}][Table[N[i - j], {i, 2}, {j, 2}]]
(*{{0. + 0. I, 1. + 0. I}, {-1. + 0. I, 0. + 0. I}}*)

So how should I specify the return type of InterpolationFunction?

$\endgroup$

1 Answer 1

11
$\begingroup$

Your pattern is wrong. I would try the following

f3 = Compile[{{t, _Real}}, 
  Evaluate@sol[t], {{InterpolatingFunction[__][t], _Complex}}]

which compiles without warning and lets you evaluate

f3[.5]
(* Out[112]= 0.880101 + 0.0200644 I *)

without a message. The problem with your pattern is that you used _InterpolatingFunction which means an expression with the Head InterpolatingFunction.

If you now check the this with the s[t] you used, then you see

Head[s[t]]
(* InterpolatingFunction[{{0.,10.}},<>] *)

Therefore, if you wanted to say it your way, you should be able to use

f3 = Function[expr, 
   Compile[{{t, _Real}}, 
    expr, {{_InterpolatingFunction[__], _Complex}}]][s[t]]

which again works on my machine.

$\endgroup$
2
  • $\begingroup$ Thanks a lot! You saved my day! Could you comment on why my pattern is wrong in the InterpolatingFunction case, but working in the Fourier case? $\endgroup$ Commented Jul 10, 2013 at 22:36
  • $\begingroup$ @xslittlegrass See my update in the post. $\endgroup$
    – halirutan
    Commented Jul 10, 2013 at 22:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.