Re: how packages work
- To: mathgroup at smc.vnet.net
- Subject: [mg116686] Re: how packages work
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Thu, 24 Feb 2011 06:21:03 -0500 (EST)
Ted Sariyski wrote:
> Hi,
> I am confused how packages work. I have a simple function which I can plot
> and evaluate without any messages or warnings, e.g.
>
> # f[3000, lam1, lam2]/.{lam1-> 4.*10^-7, lam2->5.*10^-7}
> Out: -411.32
>
> When I try FindRoot I get an obscure message followed by a correct result:
>
> # FindRoot[f[x, lam1, lam2] == 0, {x, 3000}] (*lam1=4.*10^-7;
> lam2=5.*10^-7*)
>
> Out: NIntegrate::inumr: The integrand 3.74177*10^-16/((-1+E^(<<21>>/(x
> z$36620))) z$36620^5) has evaluated to non-numerical values for all sampling
> points in the region with boundaries {{4.*10^-7,5.*10^-7}}. >>
> {x -> 4969.42}
>
> Function f is defined through two modules in myUtils` package:
>
> f[x_, lam1_, lam2_] := inbInt[x, lam1, lam2] - 420.;
>
> (*myUtils`*)
>
> inbInt[t_,l1_,l2_] :=
> Module[ {z,bbint},
> bbint = NIntegrate[pFun[t, z],{z,l1,l2}];
> Return[bbint];
> ];
>
> pFun[t_, x_] :=
> Module[ {bbint},
> bbint = (3.74*10^-16/ x^5)/(Exp[0.014/(x*t)]-1);
> Return[bbint];
> ];
>
> How is that Plot doesn't complain for non-numerical values but FindRoot
> does?
>
> Thanks in advance,
> --Ted
The message is not uninformative. It indicates that there is an
integrand to an NIntegrate that has a non-numeric integrand (that is to
say, contains parameters other than the variable of integration).
Moreover it indicates that the variables it encounters are x and
something like z$36620. So we expect that a "z" variable, localized in
some way (hence the appended "$36620"), is in use. Clearly that is just
the NIntegrate "z" variable of integration. We can conclude it is "x"
that needs a value.
As has been mentioned in past on this forum, a good way to prevent this
problem is to force the function passed to FindRoot (inbInt in this
case) to be what is called a "black box", that is, undefined unless it
has numeric arguments. That way a function like FindRoot will not be
able to do any symbolic preprocessing that it might otherwise attempt
(in this case, with warning-riddled and fruitless results).
The code below, a slight simplification of yours, does this.
f[x_, lam1_, lam2_] := inbInt[x, lam1, lam2] - 420.
inbInt[t_?NumericQ, l1_?NumericQ, l2_?NumericQ] :=
NIntegrate[pFun[t, z], {z, l1, l2}]
pFun[t_, x_] := (3.74*10^(-16)/x^5)/(Exp[0.014/(x*t)] - 1)
I can now get a quiet evaluation of that FindRoot.
In[18]:= With[{lam1 = 4.*10^(-7), lam2 = 5.*10^(-7)},
FindRoot[f[x, lam1, lam2] == 0, {x, 3000}]]
Out[18]= {x -> 2000.56}
I should point out that this is in no way related to packages, their
design issues notwithstanding.
Daniel Lichtblau
Wolfram Research