Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

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.

share|improve this answer
    
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? –  xslittlegrass Jul 10 '13 at 22:36
    
@xslittlegrass See my update in the post. –  halirutan Jul 10 '13 at 22:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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