Re: Replacements and NIntegrate
- To: mathgroup at smc.vnet.net
- Subject: [mg118588] Re: Replacements and NIntegrate
- From: Andrew Moylan <amoylan at wolfram.com>
- Date: Tue, 3 May 2011 08:22:36 -0400 (EDT)
There are different ways to do it.
As an example:
In[1]:= h[z_] := a + b + z
In[2]:= vals = {a -> 1, b -> 2, L -> 3};
The easiest way is to use Block instead of replacement rules:
In[3]:= Block[{a = 1, b = 2, L = 3},
NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]]
Out[3]= 4.79556
A good way is to make h depend on the parameters a and b:
In[4]:= h[{a_, b_}, z_] := a + b + z
Then you want NIntegrate to not be evaluated until after the replacement rules are applied by ReplaceAll. Thus:
In[5]:= Unevaluated[
NIntegrate[h[{a, b}, z] z/Sqrt[L^2 + z^2], {z, -L, L}]] /. vals
Out[5]= 4.79556
If you don't want to make either of these changes, you can construct the Block from the replacement rules:
In[6]:= Block @@
Append[Apply[Set, Hold[Evaluate[vals]], {2}],
Unevaluated[NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]]]
Out[6]= 4.79556
Take it apart piece by piece to see how it works:
In[7]:= Hold[Evaluate[vals]]
Out[7]= Hold[{a -> 1, b -> 2, L -> 3}]
In[8]:= Apply[Set, Hold[Evaluate[vals]], {2}]
Out[8]= Hold[{a = 1, b = 2, L = 3}]
In[9]:= Append[Apply[Set, Hold[Evaluate[vals]], {2}],
Unevaluated[NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]]]
Out[9]= Hold[{a = 1, b = 2, L = 3},
NIntegrate[(h[z] z)/Sqrt[L^2 + z^2], {z, -L, L}]]
You can easily make a function to do this:
In[10]:= SetAttributes[BlockRules, HoldRest];
In[11]:= BlockRules[rules_, expr_] :=
Block @@ Append[Apply[Set, Hold@rules, {2}], Unevaluated[expr]]
Use it like this:
In[12]:= BlockRules[vals,
NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]]
Out[12]= 4.79556
You can also make another useful variant, WithRules, which works the same way but with With instead of Block.
Hope this helps.
Andrew Moylan
Wolfram Research
----- Original Message -----
> From: "Giacomo Ciani" <jackspam79 at gmail.com>
> To: mathgroup at smc.vnet.net
> Sent: Tuesday, May 3, 2011 7:44:43 PM
> Subject: [mg118561] Replacements and NIntegrate
>
> Hi all,
>
> I've been reading quite a bit in the Mathematica docs and in this
> newsgroup, but didn't find (or didn't recognize...) an answer to my
> problem.
>
> I want to evaluate the following expression:
>
> NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]
>
> where h[z] has a delayed value set previously in the notebook. Also,
> I
> have previously defined a set of replacement rules in the form:
>
> vals = {a->1, b->2, ec....}
>
> to be used to specify the numerical values of the various parameters
> (including those present in the delayed value of h[z]).
>
> As for now, the only (brute force) way I found to have my expression
> correctly evaluated is to apply replacement rules separately to each
> argument of NIntegrate (including integration limits):
>
> NIntegrate[ h[z] z / Sqrt[L^2 + z^2] /.vals, {z, -L /.vals,
> L/.vals}]
>
> I think you agree with me that this does not look very elegant.
> Instead, I would like to be able to write something like this:
>
> NIntegrate[h[z] z/Sqrt[L^2 + z^2], {z, -L, L}]/.vals
>
> I know this can't work, as Mathematica tries to evaluate NIntegrate
> and then apply the replacement rules... but how can I ask Mathematica
> to apply all the replacement rules and delayed values to an
> expression
> without (or before) actually trying to evaluate it?
>
> I found a lot of commands to hold the function from evaluating the
> arguments, while I need pretty much the opposite...
>
> Maybe there is something very simple I am overlooking...
>
> Thanks
>
> Giacomo
>
>