5
$\begingroup$

How can I extract a single dimension from an InterpolatingFunction? As an example:

ClearAll[x];
s = NDSolve[
 Evaluate[Derivative[1][x][t] == -x[t]] && x[0] == {10, -10, 4}, 
   x, {t, 0, 5}]
x = x /. First@s
Plot[x[t], {t, 0, 5}]

plot

I can easily extract values (and also plot) for a single dimension like this

x[1][[1]] + x[1][[3]]
(* 5.15031 *)

but if I want to create a new function representing the sum? The following generates a lot of warnings.

sum = FunctionInterpolation[x[t][[1]] + x[t][[3]], {t, 0, 5}]

(*   Part::partw: Part 3 of 
InterpolatingFunction[{{0.,5.}},{5,3,1,{57},{4},0,0,0,0,Automatic,{},{}, 
False},{{0.,0.000114457,<<48>>,<<7>>}},{{{10.,-10.,4.},{-10.,10.,-4.}},{ 
{9.99886,-9.99886,3.99954},{-9.99886,9.99886,-3.99954}},{{9.99771,-9.997 
71,3.99908},{-9.99771,9.99771,-3.99908}},{{9.9603,-9.9603,3.98412},{-9.9 
603,9.9603,-3.98412}},<<44>>,{{0.229328,-0.229328,0.0917314},{-0.229328, 
0.229328,-0.0917314}},{{0.194925,-0.194925,0.0779699},{-0.194925,0.19492 
5,-0.0779699}},<<7>>},{Automatic}][t] does not exist. >> 

....  

General::stop: Further output of Part::partw will be suppressed during 
this calculation. >>  **)

I have also noticed that

x2 = FunctionInterpolation[x[t], {t, 0, 5}]

appears to throw away all but the first dimension.

{x[2], x2[2]} // TableForm

(*    
1.35335 -1.35335    0.541341
1.35335     
*)

What is the best way to extract a single dimension from InterpolatingFunction?

$\endgroup$
3
$\begingroup$

Using some underdocumented functionality:

x = NDSolveValue[{x'[t] == -x[t], x[0] == {10, -10, 4}}, x, {t, 0, 5}];

pts = Transpose[Append[x["Coordinates"],
                       Total[Drop[x["ValuesOnGrid"], None, {2}], {2}]]];

xsum = Interpolation[pts, InterpolationOrder -> x["InterpolationOrder"][[1]],
                     Method -> x["InterpolationMethod"]];

Plot[xsum[t], {t, 0, 5}]

et voilà!


Taking a vector-valued InterpolatingFunction[] apart: A blow-by-blow account

The package DifferentialEquations`InterpolatingFunctionAnatomy`​ features a number of functions for taking an InterpolatingFunction[] apart. The secret behind this package is that there is a built-in, yet undocumented way to extract required parts of an InterpolatingFunction[] object, and the functions in this package are but an interface for this.

In the code given above, I used four of these "parts": "Coordinates", which gets the values of the independent variable ("Grid" is an alternative); "ValuesOnGrid", which gives the corresponding values of the dependent variable; "InterpolationOrder", the order of the polynomial pieces used in the interpolation; and "InterpolationMethod", which gives the method used for the interpolation.

To use the OP's simpler example of just extracting the first component, here's how it's done. x["Coordinates"] gives a list in the form {{x1, x2, …}}, while x["ValuesOnGrid"] yields a list of the vector values. To get just the first component of each vector, you can do x["ValuesOnGrid"][[All, 1]] for this extraction, before massaging it into a nice list of pairs. One such way is

x1 = Transpose[Append[x["Coordinates"], x["ValuesOnGrid"][[All, 1]]]]

tho as with tasks in general, there are a lot of other ways to proceed. You can then feed this to Interpolation[], like so:

Interpolation[x1]

but to be safe, we have the InterpolationOrder and Method options be inherited from the original interpolant; thus,

Interpolation[x1, InterpolationOrder -> x["InterpolationOrder"][[1]],
              Method -> x["InterpolationMethod"]]
$\endgroup$
  • $\begingroup$ @j-m I don't understand exactly how this works. Can you simplify the example just to extract a single dimension, like x[1]? $\endgroup$ – Åsmund Hj Mar 18 '16 at 12:31
  • $\begingroup$ If you can wait a bit, sure... $\endgroup$ – J. M. is away Mar 18 '16 at 12:33
3
$\begingroup$
x = NDSolveValue[x'[t] == -x[t] && x[0] == {10, -10, 4}, x, {t, 0, 5}]
y[t_?NumericQ] := x[t][[1]] + x[t][[3]]
sum = FunctionInterpolation[y[t], {t, 0, 5}];
Plot[{x[t], sum@t}, {t, 0, 5}]

Mathematica graphics

But I believe just using y[t] should do

$\endgroup$
  • 1
    $\begingroup$ FunctionInterpolation has some undocumented options, such as (IIRC) InterpolationPoints, that are set to an unacceptably low default. In fact, it will lose information about the source interpolation by undersampling. This is especially noticeable, if the soruce function is generally smooth but has subtle features. $\endgroup$ – LLlAMnYP Mar 18 '16 at 9:29
  • $\begingroup$ I think just using y[t] is better, actually, as the additional FunctionInterpolation causes loss of accuracy, especially when the different functions vary at different scales. Still, one ends up evaluating alle the dimensions of the InterpolatingFunction, which might not be necessary. $\endgroup$ – Åsmund Hj Mar 18 '16 at 10:26

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.