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