4
$\begingroup$

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.)

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – Jagra Dec 16 '15 at 13:50
5
$\begingroup$

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.

$\endgroup$
  • 1
    $\begingroup$ One more reference with an answer I started which Leonid greatly extended: (20766) $\endgroup$ – Mr.Wizard Dec 16 '15 at 13:58
  • $\begingroup$ @Mr.Wizard Thanks. Added. $\endgroup$ – Michael E2 Dec 16 '15 at 14:04
2
$\begingroup$

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

$\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.