NIntegrate :: ncvb: NIntegrate n'a pas réussi à converger vers la précision prescrite

Dec 14 2020

L'intégration est:

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}]

. Le message d'erreur est

NIntegrate :: ncvb: NIntegrate n'a pas réussi à converger vers la précision prescrite après 9 bissections récursives dans q près de {q} = {-3.14159254089972008785892145083358745552559732061581598827615380287}. NIntegrate a obtenu -1,249 10 ^ -16 et 4,588053980254483` ^ -13 pour les estimations d'intégrale et d'erreur. **

Comment obtenir la vraie valeur d'intégration?

Réponses

6 MarcoB Dec 14 2020 at 23:17

Pour résoudre le problème du calcul de la valeur d'une intégrale qui est en fait $0$, vous pouvez définir une valeur inférieure AccuracyGoalà la valeur par défaut ( Infinity), comme Andrew Moylan l'a mentionné dans cette question précédente ici : "Lorsque la vraie valeur de l'intégrale est zéro, la valeur par défaut PrecisionGoalne peut jamais être satisfaite. Vous devez définir un fini AccuracyGoaldans de tels cas. ".

Avec votre intégrande définie exprpar souci de clarté, ce qui suit ne renvoie aucune erreur:

NIntegrate[expr, {q, -Pi, Pi}, AccuracyGoal -> 10]

(* Out: 1.66533*10^-16 *)

voir également:

  • L'intégration numérique prend trop de temps chaque fois que la réponse est zéro
  • Erreur de convergence de NIntegrate avec FindRoot
  • Problème d'intégration
4 UlrichNeumann Dec 14 2020 at 14:30

Aussi NDSolvecomme une solution de contournement évalue à~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*)

indique une valeur intégrale nulle!

3 Andreas Dec 14 2020 at 22:33

NIntegrate peut avoir des problèmes si la vraie valeur de l'intégrale est zéro. Le message d'erreur cite ceci comme raison possible du problème de convergence. Comme solution de contournement, vous pouvez ajouter 1 à l'intégrande et soustraire 2Pi à la fin comme

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

Edit: J'ai rationalisé tous les nombres et maintenant WorkingPrecision peut être défini sur une valeur plus élevée:

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]

Maintenant la précision du calcul devrait être plus élevée (15 chiffres?) Et il se termine sans se plaindre. Ainsi, la valeur réelle de l'intégrale donnée par l'OP est

3.28296365*10^-16
2 MichaelE2 Dec 15 2020 at 00:09

Je devrais probablement changer ce que je dis dès le départ:

Le message d'erreur complet, peut-être surprenant, dit qu'il n'y a rien à craindre et qu'aucune solution n'est nécessaire.

C'est le contraire de la réaction de la plupart des gens aux messages d'erreur, y compris le mien, en particulier lorsque le message mène avec le mot «échoué». Le point est de penser à cette partie du message d'erreur:

NIntegrateobtenu -1.24910*^-16et 4.588053980254483*^-13pour les estimations de l'intégrale et de l'erreur.

Cela signifie NIntegratecalculé l'intégrale pour être dans l'intervalle

{-4.586804880254483`*^-13, 4.589303080254483`*^-13} 

Maintenant, est-ce une bonne réponse?

Probablement, à moins que vous ne croyiez (pour d'autres raisons, par exemple, en fonction de ce que la valeur est censée représenter) que l'intégrale est différente de zéro et inférieure à 10^-13. Vous n'avez probablement rien à faire; acceptez simplement la réponse. D'un autre côté, si une incertitude de 4.6*10^-13est inacceptable, aucune des méthodes décrites ci-dessous ne corrige cela; ils cachent simplement le problème.

La méthode de l'OP est meilleure que la NDSolveméthode, qui se situe bien en dehors de cet intervalle et correspond à son AccuracyGoald'environ 8.

La méthode de l'OP est meilleure que la NIntegrateréponse obtenue en intégrant 1 + integrandet en soustrayant 2 Pipour des raisons quelque peu techniques: l'objectif de précision par défaut est d'environ 6, ce qui signifie que l'erreur dans la valeur par laquelle l'intégrale est bornée 2 Pi 10*^-6, qui est beaucoup plus grande que 4.6*10^-13. De plus, alors que la valeur de l'intégrale dans cette méthode (moins 2 Pi) se trouve à l'intérieur de l'intervalle, elle est beaucoup plus grande que la valeur de l'intégrale de l'OP.

La méthode de l'OP est meilleure que l'abaissement AccuracyGoal. Le paramètre AccuracyGoal -> asignifie à peu près que si l'erreur absolue est inférieure à 10^-a, NIntegrateacceptera le résultat. En abaissant AccuracyGoal, vous dites en fait NIntegrated'accepter un pire résultat. Une bonne raison de le faire est donnée dans l'une des réponses @MarcoB lié: Un réglage inférieur accélère NIntegratelorsque l'intégrale est (presque) nulle, car il est plus facile de calculer un résultat moins précis.

Il n'y a rien de très mal dans ces autres méthodes. À moins que vous n'ayez besoin de plus de 8 décimales de précision, ce qui n'est certainement pas le cas ici, elles sont bien mais pas meilleures que la méthode de l'OP. Le message d'erreur dans ce cas indique en fait la qualité de la réponse. Dans d'autres cas, cela pourrait indiquer à quel point la réponse pourrait être mauvaise.