3
$\begingroup$

Apparently it is possible to build and InterpolatingFunction that accepts a vector input and returns a vector output:

FunctionInterpolation[
 Evaluate[Table[D[{Sin[x y], Cos[x y]}, {{x, y}, k}], {k, 0, 2}]], {x,
   0., 2. Pi}, {y, 0., 2. Pi}]
%[1, 2]
{Sin[1 2], Cos[1 2]} // N

InterpolatingFunction[{{0., 6.28319}, {0., 6.28319}}, <>]

{0.909518, -0.415989}

{0.909297, -0.416147}

However trying to build an InterpolatingFunction from a scalar input with vector output I get an error and an interpolating function with scalar output:

FunctionInterpolation[{Cos[t], Sin[t]}, {t, 0., 2. Pi}]

During evaluation of In[224]:= FunctionInterpolation::ncvb: FunctionInterpolation failed to meet the prescribed accuracy and precision goals after 6 recursive bisections near t = {0.}. Continuing to refine elsewhere. >>

During evaluation of In[224]:= FunctionInterpolation::ncvb: FunctionInterpolation failed to meet the prescribed accuracy and precision goals after 6 recursive bisections near t = {0.019635}. Continuing to refine elsewhere. >>

During evaluation of In[224]:= FunctionInterpolation::ncvb: FunctionInterpolation failed to meet the prescribed accuracy and precision goals after 6 recursive bisections near t = {0.0392699}. Continuing to refine elsewhere. >>

During evaluation of In[224]:= General::stop: Further output of FunctionInterpolation::ncvb will be suppressed during this calculation. >>

Out[224]= InterpolatingFunction[{{0., 6.28319}}, <>]

0.53844

I'm unsure about the syntax so I tried also:

In[227]:= FunctionInterpolation[{{Cos[t], Sin[t]}}, {t, 0., 2. Pi}]
%[1]

During evaluation of In[227]:= Thread::tdlen: Objects of unequal length in {-0.785398,-0.261799,0.261799,0.785398}^{} cannot be combined. >>

During evaluation of In[227]:= Thread::tdlen: Objects of unequal length in {-0.241564+3.14159 I,-1.34018+3.14159 I,-1.34018,-0.241564} {} cannot be combined. >>

During evaluation of In[227]:= Thread::tdlen: Objects of unequal length in {-0.785398,-0.261799,0.261799,0.785398} {} cannot be combined. >>

During evaluation of In[227]:= General::stop: Further output of Thread::tdlen will be suppressed during this calculation. >>

During evaluation of In[227]:= FunctionInterpolation::nreal: Near t = 0.7853981633974483`, the function did not evaluate to a real number. >>

During evaluation of In[227]:= FunctionInterpolation::nreal: Near t = 0.8342673824532895`, the function did not evaluate to a real number. >>

During evaluation of In[227]:= FunctionInterpolation::nreal: Near t = 2.356194490192345`, the function did not evaluate to a real number. >>

During evaluation of In[227]:= General::stop: Further output of FunctionInterpolation::nreal will be suppressed during this calculation. >>

Out[227]= InterpolatingFunction[{{0., 6.28319}}, <>]

Out[228]= {0.539949, 0.841086}

I suppose the task can be accomplished, so What is the proper syntax?

UPDATE

I'm interested to build a single vector interpolating function of a scalar variable, given a possibly "opaque" vector function of a numerical scalar variable. Say

pf[t_?NumericQ] := With[{expensiveCalc=...}, {xof[expensiveCalc], yof[expensiveCalc]}]

pi = FunctionInterpolation[pf[t], {t,t1,t2}]

I was trying to use FunctionInterpolation in the hope to produce a "smooth" output of an expensive function describing a curve in a parametric form, evaluating the function where is more needed, and to later recognize some feature of the graph of the function(roghly speaking the point of maximal curvature, maybe directly with FindMaximum and something like pi'').

Other options comes to mind to solve this problem (for example ParametricPlot, Sow/Reap and hopefully ListInterpolation), but I'm still interested to the original question for the sake of knowledge.

$\endgroup$
  • 2
    $\begingroup$ My impression is that FunctionInterpolation is a bit of an orphan. It might be better to use another approach. $\endgroup$ – Michael E2 Jan 29 '15 at 1:52
4
$\begingroup$

I'd recommend using NDSolve instead of FunctionInterpolation, as recommended to me by some the of the Wolfram folks.

pf[t_?NumericQ] := {Cos[t], Sin[t]};
pi = NDSolveValue[{y[t] == pf[t], y[0] == pf[0], s'[t] == 1, s[0] == 0}, y, {t, 0., 2. Pi}];

pi[2]
(*  {-0.416147, 0.909297}  *)

If pf is differentiable, then perhaps this:

pi = NDSolveValue[{y'[t] == D[{Cos[t], Sin[t]}, t], y[0] == {1, 0}}, y, {t, 0., 2. Pi}]
$\endgroup$
  • $\begingroup$ This is great. But when I apply to my "real" function I get a lot of messages like "NDSolveValue::nbnum1: The function value {0,0}==0 is not True or False when the arguments are {-1.08214,{7.89896,8.72311},0.,{0.,0.},1.}. >>" and "NDSolveValue::ecboo: The value of event condition function at t = -1.08214 was not True or False. The event will be considered inactive. >>" $\endgroup$ – unlikely Jan 29 '15 at 11:54
  • $\begingroup$ @unlikely Thanks. The "{0,0}==0" would seem to be a hint (vector == scalar). There seems to be a mismatch between the two sides in your code. It's hard to speculate further without seeing code that produces the error. It's also possible that there's a lurking definition (e.g. s). $\endgroup$ – Michael E2 Jan 29 '15 at 11:58
  • $\begingroup$ I solved and now works, the problem was my function was not really "opaque". I can now try to use this approach to solve my problem. Thanks $\endgroup$ – unlikely Jan 29 '15 at 14:02
2
$\begingroup$

Kinda kludgy, but:

g[x_] = Through[(FunctionInterpolation[#, {t, 0., 2. Pi}] & /@ {Cos[t], Sin[t]})[x]]

It works:

g[2.0]
(*{-0.416147, 0.909297}*)

I'd be interested to see if there was a better way. I'm also surprised your original code doesn't work (although I may just be speaking out of ignorance here).

$\endgroup$
  • $\begingroup$ Thank but, as better explained now, I'm searching a way to build a single interpolating function at once. Sorry for confusion. $\endgroup$ – unlikely Jan 28 '15 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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