我尝试整合以下功能:
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吗?
答案 0 :(得分:7)
<强>解决方案强>
使用If
,但没有任何问题:作为一般规则(预防措施),每当您将函数传递给NIntegrate
时,请确保该函数执行此操作不评估符号论证。将其定义为:
Clear[test] (* get rid of previous definition *)
test[x_?NumericQ] := ...
为什么会发生这种情况
关键在于:当您评估test
符号参数时会发生什么,例如test[x]
? Mathematica需要评估与If[x > 0, a, b]
类似的内容,即条件不是If
或True
的{{1}}。 False
未评估为x > 0
或True
,因为False
是x
,没有任何价值。结果是Symbol
将不会评估其第二个或第三个参数(If
或a
)。
答案 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