3
$\begingroup$

I have a large array {x,y,z}

sigma = {{x1,y1,z1},{x2,y2,z2}, ......}

where z is a function of x,y: z = f(x,y); the function is known only through its numerical values. Next I do a numerical Interpolation over this array

F = Interpolation[sigma]

and obtain an InterpolatingFunction F(x,y). Now I perform a numerical integration over one of the coordinates, say y, this defines a new function g(x):

g[x_]:= NIntegrate[F[x,y],{y,0.,2.5}]

This new function g(x) is used quite frequently in the later parts of the program. I would thus like to avoid redoing the time-consuming integration over and over again. How can I store this function g(x) so that it becomes available later on without having to redo the Interpolation and the Integration?

$\endgroup$
2
  • $\begingroup$ maybe this works: g[x_]:=g[x]=NIntegrate[F[x,y],{y,0.,2.5}] $\endgroup$ Commented Jul 2, 2020 at 10:42
  • 1
    $\begingroup$ InterpolatingFunctions can be integrated symbolically, yielding a new InterpolatingFunction. Just do g[x_] = Integrate[F[x,y],{y,0.,2.5}]. $\endgroup$
    – march
    Commented Jul 2, 2020 at 15:47

1 Answer 1

11
$\begingroup$

First of all, I think you have your sigma defined incorrectly for Interpolation. Interpolation expects data like {{{x1, y1}, z1}, {{x2, y2}, z2}, ...}.

So let's make some test data:

data = Flatten[
  Table[{{x, y}, Exp[-(x^2 + y^2)]}, {x, -5, 5, 0.1}, {y, -5, 5, 0.1}],
  1
];
interp = Interpolation[data]

Interpolation functions can return their derivatives and anti-derivatives immediately. For example, the 2nd derivative w.r.t. x at {0, 0}:

Derivative[2, 0][interp][0, 0]

-1.99003

Compared to the exact result (not exactly the same due to the discretization error of the interpolation):

D[Exp[-(x^2 + y^2)], {x, 2}] /. {x -> 0, y -> 0}

-2

Similarly, you can get the anti-derivative with

primitive = Derivative[-1, -1][interp]

or

primitive = Block[{x, y}, 
  Function[{x,y}, Evaluate[Integrate[fun[x, y], x, y]]]
]

These primitive functions can be used for computing integrals in the same as always:

NIntegrate[interp[x, y], {x, -5, 0}, {y, -5, 0}]
primitive[0, 0] - primitive[-5, -5]

0.785398

0.785398

If you only want to integrate over x:

intx = Derivative[-1, 0][interp];
NIntegrate[interp[x, 0], {x, -5, 0}]
intx[0, 0] - intx[-5, 0]

0.886227

0.886227

These primitives are just just new interpolation functions, so they're very fast to use. You only need to compute the primitive once and from there you can compute basically any integral in the domain nearly instantly.

$\endgroup$
1
  • 1
    $\begingroup$ @user3584513 - to convert your data use sigma2 = {Most[#], Last[#]} & /@ sigma $\endgroup$
    – Bob Hanlon
    Commented Jul 2, 2020 at 14:02

Your Answer

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

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