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$
  • 1
    $\begingroup$ I think that after defining g with Set (=, as you do), you can safely Remove[f] without affecting g. $\endgroup$ – b.gates.you.know.what Apr 18 '15 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$ – thecommexokid Apr 18 '15 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 '15 at 21:19
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, privacy policy and cookie policy

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