4

When handling derivatives of a interpolated function, I often use the following function

makeDeriv[f_InterpolatingFunction] = D[ f[x], x]

Then, I can define the derivative of f, by defining a downvalue as

interpolated = Range[5]^2 // Interpolation;
deriv[x_] = makeDeriv[interpolated]; (* To find a derivative once and then to use it later. *) 
deriv[3] (* Find a numerical value now*)

The purpose of this construct is to find the derivative once, and then use it later whenever I want to take derivatives. (As a side question: will that be a better way than computing it from f every time for each numerical argument I will be interested?)

But then, if I want to define a similar function inside the Module, it does not seem to work, i.e.,

Module[ { qq},
   qq[x_] = makeDeriv[interpolated];
   qq[2]
](*It works!!*)

However,

Module[ { qq, int = interpolated},
    qq[x_] = makeDeriv[int];
    qq[2]
 ](*It does not work!!*)

Please explain why it happens and how to circumvent this problem.

(As another side question, let me know how to define the derivative of interpolation function properly.)

Sungmin
  • 2,285
  • 15
  • 23
  • Not enough time now to test this, but have you tried: makeDeriv[f_InterpolatingFunction] := D[ f[x], x] ,deriv[x_] := makeDeriv[interpolated], and qq[x_] := makeDeriv[interpolated]? The ":" might help. – Jagra Dec 16 '15 at 13:50

2 Answers2

5

It's bad practice to have your functions depend on global symbols like x buried in their definitions, for Mathematica under certain conditions rewrites function parameters as x$_ to avoid clashing with the global symbol. Use Trace on the OP's examples to see that in the second one, x_ is rewritten as `x$_. See the tutorial Variables in Pure Functions and Rules and these questions for further discussion:

There are others, too, I'm sure.

One workaround is to use Derivative directly:

Module[{qq, int = interpolated},
 qq = Derivative[1][int];
 qq[2]]
(*  4   *)

Another way:

Module[{qq, int = interpolated, x},
 qq[x_] = D[int[x], x];
 qq[2]]

Or include all symbols as function parameters:

Clear[makeDeriv];
makeDeriv[f_InterpolatingFunction, x_] := D[f[x], x];
Module[{qq, int = interpolated, x},
 qq[x_] = makeDeriv[int, x];
 qq[2]]

And so forth, but I think the first two are simplest.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
3

If you want to stick to your code, you can redefine your derivative taking function a little bit:

makeDeriv[f_InterpolatingFunction[x_]] := D[f[x],x]

and call it accordingly in your Module environment

int = Interpolation[Range[5]^2];

Module[{modint = int, dint},
  dint[x_] = makeDeriv[modint[x]];
  dint[1.2]
] (* Out[1] = 2.4 *)

I suppose that the unspecified variable x in your definition of the makeDeriv function leads to the problem, although I am not entirely sure why this only happens in your last example. Anyway, the above definition should be safe.

Two alternatives for taking the derivatives:

D[int[x],x] /. x -> 1.2 (* Out[2] = 2.4 *)

Derivative[1][int][1.2] (* Out[3] = 2.4 *)

so there should be no need to come up with your own function in the first place