试图让Mathematica逼近积分

时间:2011-11-09 18:58:36

标签: wolfram-mathematica

我试图让Mathematica近似一个积分,它是各种参数的函数。我不需要它非常精确 - 答案将是一小部分,5位数将是不错的,但我会满足于2。 问题是主积分中有一个符号积分,我不能使用NIntegrate,因为它是象征性的。

    F[x_, c_] := (1 - (1 - x)^c)^c;
    a[n_, c_, x_] := F[a[n - 1, c, x], c];
    a[0, c_, x_] = x;

    MyIntegral[n_,c_] := 
      NIntegrate[Integrate[(D[a[n,c,y],y]*y)/(1-a[n,c,x]),{y,x,1}],{x,0,1}]

n大于2且c大于3时,Mathematica会挂起(通常同时nc会更高一些)。< / p>

是否有重写此表达式的技巧,以便更容易评估?我在外部WorkingPrecision上使用了不同的AccuracyGoalPrecisionGoal以及NIntegrate选项,但这些选项都没有帮助内部积分,这就是问题所在。事实上,对于nc的较高值,我甚至无法使Mathematica扩展内部导数,即。

Expand[D[a[4,6,y],y]] 

挂起。

我正在为学生使用Mathematica 8。

如果有人有任何关于我如何让M.来近似这个的提示,我将不胜感激。

2 个答案:

答案 0 :(得分:7)

由于您只想要一个数字输出(或者您将获得的数字输出),您可以使用NIntegrate将符号集成转换为数字输出,如下所示:

Clear[a,myIntegral]
a[n_Integer?Positive, c_Integer?Positive, x_] := 
  a[n, c, x] = (1 - (1 - a[n - 1, c, x])^c)^c;
a[0, c_Integer, x_] = x;

myIntegral[n_, c_] := 
 NIntegrate[D[a[n, c, y], y]*y/(1 - a[n, c, x]), {x, 0, 1}, {y, x, 1},
   WorkingPrecision -> 200, PrecisionGoal -> 5]

这比以符号方式执行集成要快得多。这是一个比较:

尤达:

myIntegral[2,2]//Timing
Out[1]= {0.088441, 0.647376595...}

myIntegral[5,2]//Timing
Out[2]= {1.10486, 0.587502888...}

rcollyer:

MyIntegral[2,2]//Timing
Out[3]= {1.0029, 0.647376}

MyIntegral[5,2]//Timing 
Out[4]= {27.1697, 0.587503006...}
(* Obtained with WorkingPrecision->500, PrecisionGoal->5, MaxRecursion->20 *)

Jand的功能与rcollyer的时间相似。当然,随着您增加n,您必须将WorkingPrecision方式提高到PrecisionGoal以上,you've experienced in your previous question。由于您说您只需要大约5位数的精度,我已明确将{{1}}设置为5.您可以根据需要进行更改。

答案 1 :(得分:2)

为了编纂评论,我会尝试以下方法。首先,为了消除关于变量n的无限递归,我将你的函数重写为

F[x_, c_] := (1 - (1-x)^c)^c;
(* see note below *)
a[n_Integer?Positive, c_, x_] := F[a[n - 1, c, x], c];  
a[0, c_, x_] = x;

那样n==0实际上就是一个停止点。 ?Positive表单是PatternTest,可用于为参数应用其他条件。我怀疑问题是NIntegrate正在为Integrate的每个值重新评估内部x,因此我会将该评估结果删除,例如

MyIntegral[n_,c_] := 
  With[{ int = Integrate[(D[a[n,c,y],y]*y)/(1-a[n,c,x]),{y,x,1}] },
    NIntegrate[int,{x,0,1}]
  ]

其中With是专门用于创建局部常量的几种范围构造之一。

您的注释表明内积分需要很长时间,您是否尝试过简化积分,因为它是a乘以a函数的导数?这似乎是链规则扩展的结果。

注意:根据Yoda在评论中的建议,您可以向a添加缓存或记忆机制。将其定义更改为

d:a[n_Integer?Positive, c_, x_] := d = F[a[n - 1, c, x], c];

这里的诀窍是,在d:a[ ... ]中,d是一个命名模式,在d = F[...]中再次使用,为这些特定参数值缓存a的值。 / p>