Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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  *)
share|improve this answer
1  
You gotta be kidding right? 11 mins after the OP posted the question. I did not even had the chance to read it ;-) –  halirutan Mar 21 '13 at 13:24
1  
@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!). –  Leonid Shifrin Mar 21 '13 at 13:26
    
@Leonid To tell the truth, I have already read the memory management question on SO, so I had a bit of advantage :) –  Szabolcs Mar 21 '13 at 14:04
    
@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. –  Leonid Shifrin Mar 21 '13 at 14:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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