用数值积分进行NMinimize

时间:2013-11-12 10:41:11

标签: wolfram-mathematica numerical-integration

我试图通过使用Mathematica最小化我知道为零的方程来找到函数的系数。我的代码是:

Clear[f];
Clear[g];
Clear[GetGood];
Clear[int];
Clear[xlist];
Xmax = 10;
n = 10;
dx = Xmax/n;
xlist = Table[i*dx, {i, n}];
A = 3.5;
slope = (A + 2)/3;
f[x_, a_, b_, c_, d_, e_] :=a/(1 + b*x + c*x^2 + d*x^3 + e*x^4)^(slope/4 + 2);
g[x_, a_, b_, c_, d_, e_] :=Derivative[1, 0, 0, 0, 0, 0][f][x, a, b, c, d, e];
int[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ, e_?NumericQ] :=
     Module[{ans, i},ans = 0;Do[ans =ans + Quiet[NIntegrate[
    y^-slope*(f[Sqrt[xlist[[i]]^2 + y^2 + 2*xlist[[i]]*y*m], a, b,
         c, d, e] - f[xlist[[i]], a, b, c, d, e]), {m, -1, 1}, {y,
      10^-8, \[Infinity]}, MaxRecursion -> 30]], {i, 1, 
 Length[xlist]}];
ans
];
GetGood[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ,e_?NumericQ] := 
    Module[{ans},ans = Abs[Sum[3*f[x, a, b, c, d, e] + x*g[x, a, b, c, d,e],
       {x,xlist}]+2*Pi*int[a, b, c, d, e]];
        ans
];
NMinimize[{GetGood[a, b, c, d, e], a > 0, b > 0, c > 0, d > 0, 
 e > 0}, {a, b, c, d, e}]

我在最后一行之后得到的错误是:

Part::pspec: Part specification i$3002170 is neither an integer nor a list of integers. >>
NIntegrate::inumr: "The integrand (-(1.84529/(1+<<3>>+0.595769 Part[<<2>>]^4)^2.45833)+1.84529/(1+<<18>> Sqrt[Plus[<<3>>]]+<<1>>+<<1>>+0.595769 Plus[<<3>>]^2)^2.45833)/y^1.83333 has evaluated to non-numerical values for all sampling points in the region with boundaries {{-1,1},{\[Infinity],1.*10^-8}}"

我收到错误的任何想法?

由于

1 个答案:

答案 0 :(得分:0)

将您的NMinimize更改为

NMinimize[{GetGood[a,b,c,d,e],a>0&&b>0&&c>0&&d>0&&e>0}, {a,b,c,d,e}]

让你的约束正常工作。他们的帮助页面应该真正展示使用多个约束的示例。这个旧页面确实显示了一个例子。

http://reference.wolfram.com/legacy/v5_2/functions/AdvancedDocumentationNMinimize

如果将int []更改为

int[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ, e_?NumericQ] :=
Module[{ans, i}, ans = 0; Do[
Print["First i=", i];
ans = ans + Quiet[NIntegrate[
    Print["Second i=", i]; 
    y^-slope*(f[Sqrt[xlist[[i]]^2 + y^2 + 2*xlist[[i]]*y*m], a,b,c,d,e] -
f[xlist[[i]], a,b,c,d,e]), {m,-1,1}, {y,10^-8, \[Infinity]}, MaxRecursion -> 30]],
{i, 1, Length[xlist]}];
ans];

你会看到

First i=1
Second i=1
....
First i=10
Second i=i$28850

其中第一个调试打印从不说i = i $ nnnn但是第二个调试打印经常显示我只在你的NIntegrate中取消了一个值,而不是在它之外,并且只有在我达到10之后,你的xlist的长度,在那时你不能用符号下标,你会得到你看到的错误信息。

NIntegrate中没有任何内容正在改变i的值。

我想你可能偶然发现了一个Mathematica正在写i的价值的错误。

看看你是否可以简化代码而不会将bug隐藏起来。如果你可以让它更简单并且仍然显示问题,你可能更有可能成功让Wolfram承认你发现了一个错误。