2
$\begingroup$

Let's say I have an interpolated function f, like I might get as the solution to an NDSolve:

f[x_] = y[x] /. First[NDSolve[{y'[x] == Cos[x], y[0] == 0}, y, {x, 0, 1}]]

InterpolatingFunction[{{0., 1.}}, <>][x]

Now suppose I define some convoluted function in terms of f:

g[x_] = f[x]^2 - 2 f[x]^4 + 3 x

3 x - 2 InterpolatingFunction[{{0., 1.}}, <>][x]^4 + InterpolatingFunction[{{0., 1.}}, <>][x]^2

This new function g preserves all the structure of how I constructed it, and in order to compute a value for, say, g[0.5], it will perform the computation in terms of f.

This allows me to do algebraic things like

Simplify[g[x] / f[x]]

(3 x) / InterpolatingFunction[{{0., 1.}}, <>][x] + InterpolatingFunction[{{0., 1.}}, <>][x] - 2 InterpolatingFunction[{{0., 1.}}, <>][x]^3

which works because Mathematica is remembering the details of g's construction in terms of f.

But for my own use case, once I've defined g, I no longer care at all about f. Is there a way to tell Mathematica to forget about all the complexity that is g's definition with respect to f, and collapse g all into a single InterpolatingFunction that produces the same values?

$\endgroup$
3
  • 1
    $\begingroup$ I think that after defining g with Set (=, as you do), you can safely Remove[f] without affecting g. $\endgroup$ Apr 18, 2015 at 17:50
  • $\begingroup$ That's true, but even in that case g[x] still produces a linear combination of three terms including several InterpolatingFunctions. But I don't care, in my mind g is just a function that takes a value of x between 0 and 1 and returns a particular value; I just want a single InterpolatingFunction object that does that exact job. $\endgroup$ Apr 18, 2015 at 18:14
  • 4
    $\begingroup$ You could use FunctionInterpolation on the combined function, result will be a single interpolation function, though there's going to be some difference in result... $\endgroup$
    – ciao
    Apr 18, 2015 at 21:19

1 Answer 1

3
$\begingroup$

You can augment your NDSolve call to output your desired interpolating function. For your example we could do:

{f, g} = NDSolveValue[
    {
    y'[x] == Cos[x], y[0] == 0,
    z'[x] == 2 y[x] y'[x] - 8 y[x]^3 y'[x] + 3, z[0] == 0
    },
    {y, z},
    {x, 0, 1}
];

Here's what g looks like:

g //OutputForm

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

Let's compare the two approaches:

Plot[f[x]^2 - 2 f[x]^4 + 3 x, {x, 0, 1}]
Plot[g[x], {x, 0, 1}]

enter image description here

I think this is a better approach than using FunctionInterpolation to create a single InterpolatingFunction. NDSolve will adjust the step size so that both f and g are computed with the same precision and accuracy goals, while FunctionInterpolation can only use the accuracy/precision already present in f.

$\endgroup$

Your Answer

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

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