6

My function is

f[a_, b_] := NIntegrate[Sqrt[(Cos[t] - a)^2 + b^2], {t, 0, Pi}]

I want to calculate g[1,1] where g[a,b] is defined as...

g[a_, b_] := Derivative [1, 0][f][a, b]

I get the error

The integrand has evaluated for non-numerical values...

Now I can easily calculate the derivative first and not get an error, but I don't want to do that for a particular reason. I can also use a finite difference formula that I create myself, but I want to use procedures already defined by Mathematica.

Is it possible to avoid this error and calculate the derivative of a numerical integral?

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
potatosoup
  • 61
  • 1
  • Please, go to the help centre and read more about the markdown and how to properly format your code and format it. – Sektor Sep 09 '15 at 19:14

4 Answers4

10

This should work:

Clear[f];
f[a_?NumericQ, b_?NumericQ] := NIntegrate[Sqrt[(Cos[t] - a)^2 + b^2], {t, 0, Pi}]

and then add //N at the end of the definition of g[a,b]

g[a_, b_] := Derivative[1, 0][f][a, b]//N
g[1,1]
(*1.80525*)
Nikolay Gromov
  • 502
  • 2
  • 8
  • This is a very simple solution, thank you! What exactly does the //N change here? Does it tell Mathematica to use a different procedure to calculate the derivative? – potatosoup Sep 09 '15 at 20:14
  • 3
    Yes. In particular in the documentation it is said "N[f'[x]] will give a numerical approximation to a derivative. " at the end of the Details section. – Nikolay Gromov Sep 09 '15 at 20:17
  • Interesting. I thought that 'N[ ]' only converted a result after evaluation, and didn't effect the method of evaluation. I also tried using 'Needs["NumericalCalculus`"]' together with 'ND[f[a,b],a,{1,1}]', but this doesn't work. Do you know why the Mathematica function 'ND[ ]' doesn't do the same thing as Derivative[ ]\N? – potatosoup Sep 09 '15 at 20:26
  • As far as I understood the syntax of ND you should rather use ND[f[a, 1], a, 1] which works for me – Nikolay Gromov Sep 09 '15 at 20:52
  • Can you show me exactly what you are typing into Mathematica for ND? I am still getting an error. – potatosoup Sep 11 '15 at 19:54
7

Just ignore the error message. Use

g[a_, b_] := Quiet@Derivative[1, 0][f][a, b]
(* 1.80525 *)

This answer can be verified by

(f[1.005, 1] - f[.995, 1])/.01
(* 1.80525 *)
bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
3

If the function can be evaluated at complex arguments, one possibility is to use the complex step derivative approximation of Squire and Trapp.

For this function, it proceeds like so:

f[a_?NumericQ, b_?NumericQ] := NIntegrate[Sqrt[(a - Cos[t])^2 + b^2], {t, 0, Pi}]

(* complex step approximation *)
With[{x = 1, y = 1, h = $MachineEpsilon}, Im[f[x + I h, y]]/h]
   1.80525

(* analytic derivative *)
With[{a = 1, b = 1},
     NIntegrate[(a - Cos[t])/Sqrt[(a - Cos[t])^2 + b^2], {t, 0, Pi}]]
   1.8052526175436538
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
0

Here's a variation of bbgodfrey's answer that doesn't require quieting:

g[a_,b_]:=Activate @ Block[{NIntegrate=Inactive[NIntegrate]},Derivative[1,0][f][a,b]]

Check:

g[1, 1]

1.80525

The trick is that Mathematica knows how to take derivatives of inactive integrals, so temporarily inactivating NIntegrate avoids having NIntegrate trying to integrate a symbolic integrand.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355