NIntegrate :: ncvb: NIntegrate nie osiągnął zbieżności z określoną dokładnością
Integracja to:
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}]
. Komunikat o błędzie to
NIntegrate :: ncvb: NIntegrate nie osiągnął zbieżności z określoną dokładnością po 9 rekurencyjnych dwusiecznych w q blisko {q} = {-3.14159254089972008785892145083358745552559732061581598827615380287}. NIntegrate uzyskał -1,249 10 ^ -16 i 4,588053980254483` ^ -13 dla oszacowań całki i błędów. **
Jak uzyskać prawdziwą wartość integracji?
Odpowiedzi
Aby rozwiązać problem obliczania wartości całki, która jest w rzeczywistości $0$, możesz ustawić wartość niższą AccuracyGoal
od domyślnej ( Infinity
), jak wspomniał Andrew Moylan w poprzednim pytaniu : „Gdy prawdziwa wartość całki wynosi zero, wartość domyślna PrecisionGoal
nigdy nie zostanie spełniona. W AccuracyGoal
takich przypadkach należy ustawić skończoną ”.
Z Twoją integrand zdefiniowaną jako expr
przejrzystość, poniższe nie zwraca żadnych błędów:
NIntegrate[expr, {q, -Pi, Pi}, AccuracyGoal -> 10]
(* Out: 1.66533*10^-16 *)
Zobacz też:
- Integracja numeryczna trwa zbyt długo, jeśli odpowiedź wynosi zero
- Błąd zbieżności NIntegrate with FindRoot
- Problem z integracją
Również NDSolve
jako obejście ocenia się~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*)
wskazuje zerową wartość całkowitą!
NIntegrate może mieć problemy, jeśli prawdziwa wartość całki wynosi zero. W komunikacie o błędzie podano tę informację jako możliwą przyczynę problemu ze zbieżnością. Aby obejść ten problem, możesz dodać 1 do całki i na końcu odjąć 2Pi, np
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
Edycja: zracjonalizowałem wszystkie liczby, a teraz WorkingPrecision można ustawić na wyższą wartość:
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]
Teraz dokładność obliczeń powinna być większa (15 cyfr?) I kończy się bez reklamacji. Zatem rzeczywista wartość całki podana w PO to
3.28296365*10^-16
Powinienem chyba zmienić to, co mówię z góry:
Pełny komunikat o błędzie, co może być zaskakujące, mówi, że nie ma się czym martwić i nie jest potrzebna naprawa.
Jest to przeciwieństwo reakcji większości ludzi na komunikaty o błędach, w tym moje, zwłaszcza gdy komunikat prowadzi ze słowem „nie powiodło się”. Chodzi o to, aby pomyśleć o tej części komunikatu o błędzie:
NIntegrate
uzyskane-1.24910*^-16
oraz4.588053980254483*^-13
dla oszacowań całki i błędów.
Oznacza to, że NIntegrate
obliczono całkę w przedziale
{-4.586804880254483`*^-13, 4.589303080254483`*^-13}
Czy to wystarczająca odpowiedź?
Prawdopodobnie tak jest, chyba że uważasz (z innych powodów, powiedzmy na podstawie tego, co ma reprezentować wartość), że całka jest różna od zera i mniejsza niż 10^-13
. Prawdopodobnie nie musisz nic robić; po prostu zaakceptuj odpowiedź. Z drugiej strony, jeśli niepewność 4.6*10^-13
jest nie do przyjęcia, żadna z metod omówionych poniżej nie naprawia tego; po prostu ukrywają problem.
Metoda OP jest lepsza niż NDSolve
metoda, która leży daleko poza tym przedziałem i odpowiada jej AccuracyGoal
około 8
.
Metoda OP jest lepsza niż NIntegrate
odpowiedź otrzymana przez całkowanie 1 + integrand
i odejmowanie 2 Pi
z powodów technicznych: Domyślny cel dokładności to około 6
, co oznacza, że błąd wartości 2 Pi 10*^-6
, którą ogranicza całka , jest znacznie większy niż 4.6*10^-13
. Co więcej, chociaż wartość całki w tej metodzie (minus 2 Pi
) leży w przedziale, jest znacznie większa niż wartość całki PO.
Metoda OP jest lepsza niż obniżanie AccuracyGoal
. Ustawienie AccuracyGoal -> aoznacza z grubsza, że jeśli bezwzględny błąd jest mniejszy niż 10^-a
, NIntegrate
zaakceptuje wynik. Obniżając AccuracyGoal
, tak naprawdę mówisz, że NIntegrate
chcesz zaakceptować gorszy wynik. Dobry powód, aby to zrobić, podano w jednej z odpowiedzi @MarcoB link: Niższe ustawienie przyspiesza, NIntegrate
gdy całka wynosi (prawie) zero, ponieważ łatwiej jest obliczyć mniej dokładny wynik.
W tych innych metodach nie ma nic złego. O ile nie potrzebujesz dokładności większej niż 8 miejsc po przecinku, co prawie na pewno nie ma tutaj miejsca, są one w porządku, ale nie lepsze niż metoda OP. Komunikat o błędzie w tym przypadku w rzeczywistości wskazuje, jak dobra jest odpowiedź. W innych przypadkach może wskazywać, jak zła może być odpowiedź.