NIntegrate :: ncvb: NIntegrate falhou em convergir para a precisão prescrita

Dec 14 2020

A integração é:

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

. A mensagem de erro é

NIntegrate :: ncvb: NIntegrate falhou em convergir para a precisão prescrita após 9 bissecções recursivas em q perto de {q} = {-3,14159254089972008785892145083358745552559732061581598827615380287}. NIntegrate obteve -1,249 10 ^ -16 e 4,588053980254483` ^ -13 para as estimativas de integral e erro. **

Como obter o valor real da integração?

Respostas

6 MarcoB Dec 14 2020 at 23:17

Para resolver o problema de calcular o valor de uma integral que é realmente $0$, você pode definir um valor inferior AccuracyGoalao padrão ( Infinity), como Andrew Moylan mencionou nesta questão anterior aqui : "Quando o valor verdadeiro da integral é zero, o padrão PrecisionGoalnunca pode ser satisfeito. Você precisa definir um valor finito AccuracyGoalnesses casos "

Com seu integrando definido como exprpara maior clareza, o seguinte não retorna erros:

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

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

Veja também:

  • A integração numérica está demorando muito sempre que a resposta é zero
  • Erro ao convergir NIntegrate com FindRoot
  • Problema com integração
4 UlrichNeumann Dec 14 2020 at 14:30

Também NDSolvecomo uma solução alternativa avalia para~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*)

indica um valor integral zero!

3 Andreas Dec 14 2020 at 22:33

NIntegrate pode ter problemas se o valor verdadeiro da integral for zero. A mensagem de erro cita isso como uma possível razão para o problema de convergência. Como alternativa, você pode adicionar 1 ao integrando e subtrair 2Pi no final, como

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

Editar: racionalizei todos os números e agora WorkingPrecision pode ser definido com um valor mais alto:

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]

Agora a precisão do cálculo deve ser maior (15 dígitos?) E é concluído sem reclamação. Portanto, o valor real da integral dado pelo OP é

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

Eu provavelmente deveria mudar o que digo desde o início:

A mensagem de erro completa, talvez surpreendentemente, está dizendo que não há nada com que se preocupar e nenhuma correção é necessária.

Isso é o oposto das reações da maioria das pessoas às mensagens de erro, incluindo a minha, especialmente quando a mensagem começa com a palavra "falhou". O objetivo é pensar sobre esta parte da mensagem de erro:

NIntegrateobtidos -1.24910*^-16e 4.588053980254483*^-13para as estimativas integrais e de erro.

Isso significa que NIntegratecalculou a integral para estar no intervalo

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

Agora, essa é uma resposta boa o suficiente?

Provavelmente é, a menos que você acredite (por outras razões, digamos, com base no que o valor deve representar) que a integral é diferente de zero e menor que 10^-13. Provavelmente você não precisa fazer nada; apenas aceite a resposta. Por outro lado, se uma incerteza de 4.6*10^-13é inaceitável, nenhum dos métodos discutidos a seguir corrige isso; eles apenas escondem o problema.

O método do OP é melhor do que o NDSolvemétodo, que fica bem fora deste intervalo e corresponde à sua AccuracyGoalde cerca 8.

O método do OP é melhor do que a NIntegrateresposta obtida integrando 1 + integrande subtraindo 2 Pipor razões técnicas: A meta de precisão padrão é sobre 6, o que significa que o erro no valor pelo 2 Pi 10*^-6qual a integral é limitada , que é muito maior do que 4.6*10^-13. Além disso, embora o valor da integral neste método (menos 2 Pi) esteja dentro do intervalo, é muito maior do que o valor da integral do OP.

O método do OP é melhor do que abaixar AccuracyGoal. A configuração AccuracyGoal -> asignifica aproximadamente que se o erro absoluto for menor que 10^-a, NIntegrateaceitará o resultado. Ao baixar AccuracyGoal, você está na verdade dizendo NIntegratepara aceitar um resultado pior. Uma boa razão para fazer isso é dada em uma das respostas @MarcoB linked: Uma configuração mais baixa acelera NIntegratequando a integral é (quase) zero, porque é mais fácil calcular um resultado menos preciso.

Não há nada de muito errado nesses outros métodos. A menos que você precise de mais de 8 casas decimais de precisão, o que quase certamente não é o caso aqui, elas são boas, mas não melhores do que o método OP. A mensagem de erro, neste caso, indica de fato o quão boa é a resposta. Em outros casos, pode indicar o quão ruim a resposta poderia ser.