2016-05-25 33 views
0

こんにちは、私はmathematicaの数値積分に関して問題があります。ここに私のテスト機能mathematica:数値積分の評価順序

Table[NIntegrate[ 
Boole[Sqrt[1 - cosk^2]*Sqrt[1 - cosk2^2] > Abs[a - cosk*cosk2]]/ 
Sqrt[(1 - cosk^2)*(1 - cosk2^2) - (a - cosk*cosk2)^2], 
{cosk, -1,1}, {cosk2, -1, 1}, Method -> "GlobalAdaptive"], {a, -.9, .9, .1}] 

による積分のboolean関数にSQRTでの引数は常に正でなければなりませんので、唯一の真の値になるが、統合は、複雑な値が得られています。最初にブール関数を評価することは可能ですか?それが真である場合にのみ数値的に積分することができますか?

私はモンテカルロ統合戦略

Table[NIntegrate[ 
Boole[Sqrt[1 - cosk^2]*Sqrt[1 - cosk2^2] > Abs[a - cosk*cosk2]]/ 
Sqrt[(1 - cosk^2)*(1 - cosk2^2) - (a - cosk*cosk2)^2], {cosk, -1, 
1}, {cosk2, -1, 1}, Method -> {"MonteCarlo", "MaxPoints" -> 10^8, 
"SymbolicProcessing" -> None}], {a, -.9, .9, .1}] 

それが原因ブール関数にゼロの多くを合計する場合はどのように私は見つけることができますを使用して、同じ積分を計算する場合は?モンテカルロ・グリッドの各サンプル点のブール関数を最初に評価すると、計算時間を大幅に節約できます。私が "MonteCarlo"を "AdaptiveMonteCarlo"に置き換えると、結果は完全に間違っています。

答えて

0

真のガードに変換するとどうなりますか? (。Booleフォーム(Mathematicaが偽治療しない場合があります半分にすぎ賢いかもしれ - > 0実際のガードとして))

Table[NIntegrate[ 
If[Sqrt[1 - cosk^2]*Sqrt[1 - cosk2^2] > Abs[a - cosk*cosk2], 
1/Sqrt[(1 - cosk^2)*(1 - cosk2^2) - (a - cosk*cosk2)^2], 0], 
{cosk, -1,1}, {cosk2, -1, 1}], {a, -.9, .9, .1}] 
0

は、ここでは、サンプリング方法は何をすべきかを学ぶためにEvaluationMonitorを使用する方法である。

out = Reap[With[{a = -.9}, 
    NIntegrate[ 
    v = Boole[ 
     Sqrt[1 - cosk^2]*Sqrt[1 - cosk2^2] > Abs[a - cosk*cosk2]]/ 
     Sqrt[(1 - cosk^2)*(1 - cosk2^2) - (a - 
      cosk*cosk2)^2], {cosk, -1, 1}, {cosk2, -1, 1}, 
    Method -> "LocalAdaptive", 
    EvaluationMonitor :> Sow[{cosk, cosk2, v}]]]] 

LocalAdaptiveは非常に遅いですが、おそらく最も正確な、純粋な数値結果である:

 [email protected][out[[2, 1]][[All, {1, 2}]]] 

enter image description here

ここではグローバル適応型です。積分値に関係なく、どこでも

enter image description here

モンテカルロだけのサンプル。

おそらく、グローバルアダプティブを使用して、MinRecursionを設定することをお勧めします。想像上の部分は無視して、結果の真の部分を取ってください。 もちろん、統合の限界を分析的に解決し、Booleをすべて一緒に排除する方がはるかに優れています。