NIntegrate对If语句的绊脚石

时间:2011-08-12 10:48:00

标签: wolfram-mathematica

我尝试整合以下功能:

test[a_] := 
 Module[{dnda, cg, atg, acg, alphag, betag, sig, b1, b2, dndavsg, a01,
 a02, bc5},
 alphag = -1.96;
 betag = -0.813;
 atg = 6.93*^-6;
 acg = 0.000348;
 cg = 2.95*^-13;
 dnda = (cg/a) (a/atg)^alphag;
 If[betag >= 0, 
       dnda = dnda (1 + betag a/atg), 
       dnda = dnda/(1 - betag a/atg)
 ];
 If[a > atg, dnda = dnda Exp[((atg - a)/acg)^3]];
 a01 = 3.5 10^-8;
 a02 = 3 10^-7;
 sig = 0.4;
 b1 = 2.0496 10^-7;
 b2 = 9.6005 10^-11;
 bc5 = 4.;
 dndavsg = (b1/a) Exp[-0.5 (Log[a/a01]/sig)^2] + 
           (b2/a) Exp[-0.5 (Log[a/a02]/sig)^2];
 If[dndavsg >= 0.0001 dnda, dnda = dnda + bc5 dndavsg];
 dnda]

奇怪的是,NIntegrate在函数定义中填充了If:

In[604]:= NIntegrate[test[x]\[Pi] x^2,{x,3.5 10^-8,6. 10^-8}]
Out[604]= 1.95204*10^-23  

In[605]:= NIntegrate[Interpolation[Table[{x,test[x]\[Pi] x^2},{x,3 10^-8,10. 10^-8,.01 10^-8}]][x],{x,3.5 10^-8,6. 10^-8}]
Out[605]= 2.18089*10^-21

我很好奇为什么会这样?我知道Integrate在If语句中存在问题,但我天真地认为NIntegrate归结为从函数定义计算数字表。这与If如何冲突?

我知道通过例如替换定义中的最后一个If语句。分段语句有助于NIntegrate获得正确的结果。

 dnda = Piecewise[{{dnda + bc5 dndavsg, dndavsg >= 0.0001 dnda}, {dnda,dndavsg < 0.0001 dnda}}]

你知道还有其他方法没有重写函数定义来强迫NIntegrate吞下If吗?

2 个答案:

答案 0 :(得分:7)

<强>解决方案

使用If没有任何问题:作为一般规则(预防措施),每当您将函数传递给NIntegrate时,请确保该函数执行此操作不评估符号论证。将其定义为:

Clear[test] (* get rid of previous definition *)
test[x_?NumericQ] := ...

为什么会发生这种情况

关键在于:当您评估test符号参数时会发生什么,例如test[x]? Mathematica需要评估与If[x > 0, a, b]类似的内容,即条件不是IfTrue的{​​{1}}。 False未评估为x > 0True,因为Falsex,没有任何价值。结果是Symbol将不会评估其第二个或第三个参数(Ifa)。

答案 1 :(得分:5)

不要太难避免使用If语句:

mytest[a_] := 
 Module[{dnda, cg, atg, acg, alphag, betag, sig, b1, b2, dndavsg, a01,
    a02, bc5}, alphag = -1.96;
  betag = -0.813;
  atg = 6.93*^-6;
  acg = 0.000348;
  cg = 2.95*^-13;
  dnda = (cg/a) (a/atg)^alphag;
  (*If[betag>=0,dnda=dnda (1+betag a/atg),dnda=dnda/(1-betag a/
  atg)]; *)
  dnda = dnda (1 + Sign[betag] betag a/atg);
  (* If[a>atg,dnda=dnda Exp[((atg-a)/acg)^3]]; *)

  dnda = dnda Exp[Min[0, ((atg - a)/acg)^3]];
  a01 = 3.5 10^-8;
  a02 = 3 10^-7;
  sig = 0.4;
  b1 = 2.0496 10^-7;
      b2 = 9.6005 10^-11;
  bc5 = 4.;
  dndavsg = (b1/a) Exp[-0.5 (Log[a/a01]/sig)^2] + (b2/
       a) Exp[-0.5 (Log[a/a02]/sig)^2];
  (*If[dndavsg>=0.0001 dnda,dnda=dnda+bc5 dndavsg];*)

  dnda = dnda + HeavisideTheta[dndavsg - 0.0001 dnda] bc5 dndavsg;
  dnda]
  

在[11]中:= NIntegrate [mytest [x] [Pi] x ^ 2,{x,3.5 10 ^ -8,6。10 ^ -8}]

     

Out [11] = 2.18111 * 10 ^ -21

     

在[12]中:= NIntegrate [Interpolation [表[{x,mytest [x] [Pi]   x ^ 2},{x,3 10 ^ -8,        10. 10 ^ -8,.01 10 ^ -8}]] [x],{x,3.5 10 ^ -8,6。10 ^ -8}]

     

输出[12] = 2.18111 * 10 ^ -21