2
$\begingroup$

Say I have a symbol with an OwnValue

a = y

And we define an integration like this

f[y_?NumericQ] := NIntegrate[a*z*y, {z, 0, 1}]

Then calling f[1] results in an error, probably because of the HoldAll attribute of NIntegrate. Using Evaluate[a] does not help.

How can an integration like this be done correctly?

$\endgroup$
4
$\begingroup$

Your example represents a practice which is best avoided. Namely, making a function implicitly depend on some variable is an invitation for trouble. Please read this answer for a partial explanation of why.

The semantics of parameter-passing in Mathematica was described e.g. here. What happens is that the value of the parameter is literally injected into the body prior to the execution of the body. Therefore, in your definition, even if you define

f[y_?NumericQ] := NIntegrate[Evaluate[a*z*y], {z, 0, 1}]

the following will happen when you pass a value (say, call f[5]):

f[5] --> NIntegrate[Evaluate[a*z*5],{z,0,1}]

meaning that the binding of y to 5 happens in any case before the body executes, so a has no chance to fire. Therefore, NIntegrate does not know about the relation between a and the actual value of y you passed, and computes a to symbolic y during evaluation.

One possible way out is to define something like this:

f[y_?NumericQ] := 
   With[{a = y}, NIntegrate[a*z*y, {z, 0, 1}]]

This will work as expected. However, better still would be to only use in the r.h.s. of a function the parameters that you pass explicitly. Here this would look something like

ClearAll[a, f];
a[y_] := y;
f[y_?NumericQ, a_] :=
  NIntegrate[Evaluate[a[y]*z*y], {z, 0, 1}]

so that

f[5, a]

(*  12.5  *)
$\endgroup$
4
  • 1
    $\begingroup$ You gotta be kidding right? 11 mins after the OP posted the question. I did not even had the chance to read it ;-) $\endgroup$
    – halirutan
    Mar 21 '13 at 13:24
  • 1
    $\begingroup$ @halirutan Yesterday, I wanted to tell the same to Szabolcs twice (for his answers on array memory management, and on Position - the latter took him just 5 mins!). $\endgroup$ Mar 21 '13 at 13:26
  • $\begingroup$ @Leonid To tell the truth, I have already read the memory management question on SO, so I had a bit of advantage :) $\endgroup$
    – Szabolcs
    Mar 21 '13 at 14:04
  • $\begingroup$ @Szabolcs But that one wasn't the biggest surprise. The one on Position was - you managed to write a full-fledged answer with links and formatting etc, citations from docs - in under 5 minutes. $\endgroup$ Mar 21 '13 at 14:06

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.