NIntegrate :: ncvb:NIntegrateが規定の精度に収束できませんでした
統合は次のとおりです。
NIntegrate[-0.17116940940118283` + 1/(
9.736942322213501` + 7.789553857770802` Cos[q]) + (
0.02866566930866079` (0.5` + 1.` Cos[q]) Sin[
q] (-3.0095696738628313` Sqrt[1.25` + 1.` Cos[q]]
Cos[0.` + ArcTan[(0.5` Sin[q])/(-1 - 0.5` Cos[q])]] +
1.` Sin[q]))/(
0.9772727272727273` + 1.` Cos[q] - 0.045454545454545456` Cos[2 q] -
0.09090909090909091` Cos[3 q]) + ((0.35586923225834494` +
0.5931153870972414` Cos[q] + 0.11862307741944829` Cos[2 q]) Sin[
0.` + ArcTan[(0.5` Sin[q])/(-1 - 0.5` Cos[q])]])/((1.75` +
1.` Cos[q] - 0.5` Cos[2 q])^(3/2) Sqrt[
1 - (1.` Sin[q]^2)/(
1.75` + 1.` Cos[q] - 0.5000000000000001` Cos[2 q])]), {q, -Pi,
Pi}]
。エラーメッセージは
NIntegrate :: ncvb:{q} = {-3.14159254089972008785892145083358745552559732061581598827615380287}の近くのqで9回の再帰的二分法を実行した後、NIntegrateは規定の精度に収束できませんでした。NIntegrateは、積分および誤差の推定値として-1.249 10 ^ -16および4.588053980254483` ^ -13を取得しました。**
実際の統合値を取得するにはどうすればよいですか?
回答
実際にある積分の値を計算する問題を解決するには $0$、Andrew Moylanがこの前の質問で述べたようにAccuracyGoal
、デフォルト値(Infinity
)よりも低い値を設定できます。「積分の真の値がゼロの場合、デフォルトは決して満たされません。そのような場合は有限を設定する必要があります。"。PrecisionGoal
AccuracyGoal
expr
明確にするために被積分関数を定義すると、以下はエラーを返しません。
NIntegrate[expr, {q, -Pi, Pi}, AccuracyGoal -> 10]
(* Out: 1.66533*10^-16 *)
参照:
- 答えがゼロのときはいつでも数値積分に時間がかかりすぎる
- NIntegrateをFindRootに収束するためのエラー
- 統合の問題
またNDSolve
、回避策として次のように評価されます~0
expr = -0.17116940940118283` +1/(9.736942322213501` +7.789553857770802` Cos[q]) + (0.02866566930866079` (0.5` + 1.` Cos[q]) Sin[q] (-3.0095696738628313` Sqrt[1.25` + 1.` Cos[q]] Cos[0.` + ArcTan[(0.5` Sin[q])/(-1 - 0.5` Cos[q])]] +1.` Sin[q]))/(0.9772727272727273` + 1.` Cos[q] -0.045454545454545456` Cos[2 q] -0.09090909090909091` Cos[3 q]) + ((0.35586923225834494` +0.5931153870972414` Cos[q] +0.11862307741944829` Cos[2 q]) Sin[0.` + ArcTan[(0.5` Sin[q])/(-1 - 0.5` Cos[q])]])/((1.75` +1.` Cos[q] - 0.5` Cos[2 q])^(3/2) Sqrt[1 - (1.` Sin[q]^2)/(1.75` + 1.` Cos[q] -0.5000000000000001` Cos[2 q])])
// Rationalize;
NDSolveValue[{int'[q] == expr, int[-Pi] == 0}, int[Pi], {q, -Pi, Pi},AccuracyGoal -> 15]
(*-3.79922*10^-8*)
ゼロの整数値を示します!
積分の真の値がゼロの場合、NIntegrateで問題が発生する可能性があります。エラーメッセージは、これを収束問題の考えられる理由として引用しています。回避策として、被積分関数に1を加算し、最後に2Piを減算することができます。
NIntegrate[-0.17116940940118283 +
1/(9.736942322213501 + 7.789553857770802*Cos[q]) +
(0.02866566930866079*(0.5 + 1.*Cos[q])*
Sin[q]*(-3.0095696738628313*Sqrt[1.25 + 1.*Cos[q]]*
Cos[0. + ArcTan[(0.5*Sin[q])/(-1 - 0.5*Cos[q])]] +
1.*Sin[q]))/(0.9772727272727273 + 1.*Cos[q] -
0.045454545454545456*Cos[2*q] -
0.09090909090909091*Cos[3*q]) +
((0.35586923225834494 + 0.5931153870972414*Cos[q] +
0.11862307741944829*Cos[2*q])*
Sin[0. + ArcTan[(0.5*Sin[q])/(-1 - 0.5*Cos[q])]])/
((1.75 + 1.*Cos[q] - 0.5*Cos[2*q])^(3/2)*
Sqrt[1 - (1.*Sin[q]^2)/(1.75 + 1.*Cos[q] -
0.5000000000000001*Cos[2*q])]) + 1, {q, -Pi, Pi}] - 2*Pi
編集:私はすべての数値を合理化し、WorkingPrecisionをより高い値に設定できるようになりました:
NIntegrate[-(17116940940118283/100000000000000000) +
1/(9736942322213501/
1000000000000000 + (7789553857770802/1000000000000000)*Cos[q]) +
((2866566930866079/100000000000000000)*(1/2 + Cos[q])*Sin[q]*
((-(30095696738628313/10000000000000000))*Sqrt[5/4 + Cos[q]]*
Cos[ArcTan[((1/2)*Sin[q])/(-1 - (1/2)*Cos[q])]] +
Sin[q]))/
(43/44 + Cos[q] - (1/22)*Cos[2*q] - (1/11)*Cos[3*q]) +
((35586923225834494/
100000000000000000 + (5931153870972414/10000000000000000)*
Cos[q] + (11862307741944829/100000000000000000)*
Cos[2*q])*
Sin[ArcTan[((1/2)*Sin[q])/(-1 - (1/2)*Cos[q])]])/
((7/4 + Cos[q] - (1/2)*Cos[2*q])^(3/2)*
Sqrt[1 - Sin[q]^2/(7/4 + Cos[q] - (1/2)*Cos[2*q])]), {q, -Pi, Pi},
WorkingPrecision -> 30]
これで、計算の精度が高くなり(15桁?)、文句なしに完了します。したがって、OPによって与えられる積分の実際の値は次のようになります。
3.28296365*10^-16
私はおそらく私が前もって言うことを変えるべきです:
おそらく驚くべきことに、完全なエラーメッセージは、心配することは何もない、そして修正は必要ないということです。
これは、特にメッセージが「失敗」という単語で始まる場合、私のものを含むエラーメッセージに対するほとんどの人の反応の反対です。重要なのは、エラーメッセージのこの部分について考えることです。
NIntegrate
得られ-1.24910*^-16
かつ4.588053980254483*^-13
不可欠と誤差の推定値のため。
つまりNIntegrate
、積分が区間内にあるように計算されたということです
{-4.586804880254483`*^-13, 4.589303080254483`*^-13}
さて、それは十分な答えですか?
おそらく、(他の理由で、たとえば、値が表すことに基づいて)信じない限り、積分はゼロではなく、よりも小さいと考えられ10^-13
ます。おそらく、何もする必要はありません。答えを受け入れるだけです。一方、の不確実性4.6*10^-13
が許容できない場合は、以下で説明する方法のいずれもそれを修正しません。彼らはただ問題を隠します。
OPの方法はNDSolve
、この間隔のかなり外側にありAccuracyGoal
、約のそれに対応する方法よりも優れています8
。
OPの方法は、技術的な理由からNIntegrate
、積分1 + integrand
と減算によって得られる答えよりも優れてい2 Pi
ます。デフォルトの精度目標は約です6
。これは、積分値の誤差がによって制限されることを意味します。2 Pi 10*^-6
これは、よりもはるかに大きくなり4.6*10^-13
ます。さらに、この方法の積分の値(マイナス2 Pi
)は区間内にありますが、OPの積分の値よりもはるかに大きくなります。
OPの方法は下げるよりも優れていAccuracyGoal
ます。この設定AccuracyGoal -> aは、絶対誤差が、未満の場合10^-a
、NIntegrate
結果を受け入れることを大まかに意味します。を下げることによりAccuracyGoal
、実際にNIntegrate
はより悪い結果を受け入れるように指示しています。これを行う正当な理由は、@ MarcoBにリンクされた回答の1つに示されています。NIntegrate
積分が(ほぼ)ゼロの場合、設定を低くすると、精度の低い結果を計算しやすくなるため、速度が上がります。
これらの他の方法には何も悪いことはありません。小数点以下8桁を超える精度が必要な場合を除いて、ここではほぼ間違いなくそうではありませんが、問題はありませんが、OPの方法よりも優れているわけではありません。この場合のエラーメッセージは、実際、答えがどれだけ優れているかを示しています。他の場合には、それは答えがどれほど悪いかを示しているかもしれません。