1
$\begingroup$

What I would like to do in Mathematica is something like

f[x_] := a x
g[a_] := NIntegrate[f[x], {x, 0, 1}]

But then of course I get

g[1]
    NIntegrate::inumr: The integrand a x has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. >>
Out= NIntegrate[f[x], {x, 0, 1}]

But I found that I can circumvent the problem with

g[a_] := Hold[NIntegrate][f[x], {x, 0, 1}] // Evaluate // ReleaseHold // Evaluate
    NIntegrate::inumr: The integrand a x has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. >>
g[1]
Out= 0.5

I don't really understand why this works nor why the definition of g throws an error. As I haven't found any other solution to my problem, I would really like to understand why my "solution" works which should also provide an answer to whether there is a simpler solution.

(I understand I can solve this simple problem with f[x_, a_] but I have in fact a more complex environment in hand where this approach becomes inconvenient.)

$\endgroup$
  • $\begingroup$ It becomes inconvenient because I have more oen parameters and later define other functions based on f which I then use in different combinations. So I would have to type expressions like g[x,a,b,c]h[g[x,a,b,c],a,b,c] instead of much clearer g[x]h[g[x]]. This wouldn't matter if I was creating static code, but I am in fact prototyping and trying different combinations all the time. $\endgroup$ – azag0 Feb 21 '14 at 0:16
  • $\begingroup$ OK, but you still didn't explain why my suggestion wouldn't work, i.e. encapsulate those parameters into the function at the beginning. $\endgroup$ – Szabolcs Feb 21 '14 at 0:18
  • $\begingroup$ Try defining g as g[aa_] := Block[{a = aa}, NIntegrate[f[x], {x, 0, 1}]]. $\endgroup$ – Alexey Popkov Feb 22 '14 at 8:13
  • $\begingroup$ @Nasser Because later I might want to do something like (f[x]^2 Sin[f[x]]+Cos[f[x]]/.a->1)+(f[x]^3 Cos[f[x]]+Sin[f[x]]/.a->2). Now I can of course do that easily with f[x,a], but it will be much more typing and during prototyping and with more parameters, it quickly becomes very time-consuming. $\endgroup$ – jhrmnn Feb 25 '14 at 12:35
  • $\begingroup$ @AlexeyPopkov This works nicely, thanks! Now the original question remains unanswered, but I don't need the answer anymore and I'm not sure whether the question is worthy in general? $\endgroup$ – jhrmnn Feb 25 '14 at 12:42
1
$\begingroup$

One workaround is to define g as:

g[aa_] := Block[{a = aa}, NIntegrate[f[x], {x, 0, 1}]]

This works because f[x] now is evaluated in local environment where variable a has a value.

The reason why the version

g[a_] :=  NIntegrate[f[x], {x, 0, 1}]

does not work is that a is absent on the right side of the definition, so nothing will be replaced: SetDelayed (:=) creates a RuleDelayed replacement rule which performs lexical scoping. So evaluating for example g[1] is equivalent to evaluation of g[a] or any other such construct.


Your "solution" is essentially equivalent to

g[a_] = NIntegrate[Evaluate@f[x], {x, 0, 1}]

In both cases the real replacement rule generated contains the variable a on the right hand side:

?g
g[a_]=NIntegrate[a x,{x,0,1}]
$\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.