
Cette publication décrit les méthodes les plus simples pour calculer les intégrales des fonctions d'une variable sur un segment, également appelées formules de quadrature. En rÚgle générale, ces méthodes sont implémentées dans des bibliothÚques mathématiques standard telles que la bibliothÚque scientifique GNU pour C, SciPy pour Python et autres. La publication vise à démontrer comment ces méthodes fonctionnent "sous le capot" et à attirer l'attention sur certains problÚmes de précision et de performance des algorithmes. Je voudrais également noter la relation entre les formules en quadrature et les méthodes d'intégration numérique des équations différentielles ordinaires, à propos desquelles je veux écrire une autre publication.
Définition de l'intégrale
Intégrale (selon Riemann) d'une fonction f ( x ) sur le segment [ a ; b ] La limite suivante est appelée:
i n t b a f ( x ) d x = l i m D e l t a x t o 0 s u m n - 1 i = 0 f ( x i i ) ( x i + 1 - x i ) , ( 1 )
oĂč Deltax= max lbracexi+1âxi rbrace - finesse de la partition, x0=a , xn=b , xii - un nombre arbitraire sur le segment [xi;xi+1] .
Si l'intĂ©grale de la fonction existe, alors la valeur limite est la mĂȘme quelle que soit la partition, si seulement elle Ă©tait suffisamment petite.

La définition géométrique est plus claire - l'intégrale est égale à l'aire du trapÚze courbe délimitée par l'axe 0 x , le graphique de la fonction et les lignes droites x = a et x = b (région remplie sur la figure).
La dĂ©finition de l'intĂ©grale (1) peut ĂȘtre réécrite sous la forme
I= intbaf(x)dx approxIn=(bâa) sumnâ1i=0wif( xii), (2)
oĂč wi - coefficients de pondĂ©ration, dont la somme doit ĂȘtre Ă©gale Ă 1, et les coefficients eux-mĂȘmes - tendent Ă zĂ©ro avec un nombre croissant n points auxquels la fonction est calculĂ©e.
L'expression (2) est la base de toutes les formules en quadrature (c'est-à -dire les formules pour le calcul approximatif de l'intégrale). Le défi est de sélectionner des points lbrace xii rbrace et poids wi de sorte que la somme du cÎté droit se rapproche le plus précisément possible de l'intégrale requise.
TĂąche de calcul
Ensemble de fonctions f(x) pour lequel il existe un algorithme de calcul des valeurs à tout moment de l'intervalle [a;b] (Je veux dire les points représentés par un nombre à virgule flottante - il n'y a pas de fonctions Dirichlet là -bas!).
Il est nécessaire de trouver la valeur approximative de l'intégrale intbaf(x)dx .
Les solutions seront implémentées dans Python 3.6.
Pour vérifier les méthodes, utilisez l'intégrale int3/20 left[2x+ frac1 sqrtx+1/16 right]dx=17/4 .
Approximation constante par morceaux
Les formules de quadrature idéalement simples résultent de l'application de l'expression (1) "au front":
In= sumnâ1i=0f( xii)(xi+1âxi)
Parce que de la mĂ©thode de division d'un segment par des points lbracexi rbrace et sĂ©lectionnez des points lbrace xii rbrace la valeur limite ne dĂ©pend pas, alors nous les choisissons pour qu'elles puissent ĂȘtre facilement calculĂ©es - par exemple, nous prenons la partition uniformĂ©ment, et pour les points de calcul de la fonction nous considĂ©rons les options: 1) xii=xi ; 2) xii=xi+1 ; 3) xii=(xi+xi+1)/2 .
Nous obtenons respectivement les méthodes des rectangles de gauche, des rectangles de droite et des rectangles avec un milieu.
Implémentationdef _rectangle_rule(func, a, b, nseg, frac): """ .""" dx = 1.0 * (b - a) / nseg sum = 0.0 xstart = a + frac * dx
Pour analyser les performances des formules en quadrature, nous construisons un graphique de l'erreur dans les coordonnées "le nombre de points est la différence entre le résultat numérique et l'exact".

Ce que vous pouvez remarquer:
- Une formule avec un point médian est beaucoup plus précise qu'avec un point droit ou gauche
- L'erreur de la formule avec le milieu tombe plus vite que les deux autres
- Avec une trĂšs petite partition, l'erreur de la formule avec le milieu commence Ă augmenter
Les deux premiers points sont liĂ©s au fait que la formule des rectangles avec un milieu a un deuxiĂšme ordre d'approximation, c'est-Ă -dire |InâI|=O(1/n2) , et les formules des rectangles droit et gauche sont du premier ordre, c'est-Ă -dire |InâI|=O(1/n) .
Une augmentation de l'erreur lors du broyage de l'Ă©tape d'intĂ©gration est associĂ©e Ă une augmentation de l'erreur d'arrondi lors de la sommation d'un grand nombre de termes. Cette erreur se dĂ©veloppe comme |InâI|=O(1/n) cela ne permet pas l'intĂ©gration pour atteindre la prĂ©cision de la machine.
Conclusion: les mĂ©thodes des rectangles Ă points droit et gauche ont une faible prĂ©cision, qui croĂźt aussi lentement avec le raffinement de la partition. Par consĂ©quent, ils n'ont de sens qu'Ă des fins de dĂ©monstration. La mĂ©thode des rectangles avec un point mĂ©dian a un ordre d'approximation plus Ă©levĂ©, ce qui lui donne une chance d'ĂȘtre utilisĂ© dans des applications rĂ©elles (plus de dĂ©tails ci-dessous).
Approximation linéaire par morceaux
L'étape logique suivante consiste à approximer la fonction intégrable sur chacun des sous-segments par une fonction linéaire, qui donne la formule en quadrature des trapÚzes:
In= sumnâ1i=0 fracf(xi)+f(xi+1)2(xi+1âxi) (3)

Illustration de la méthode trapézoïdale pour n = 1 et n = 2.
Dans le cas d'une grille uniforme, les longueurs de tous les segments de la partition sont égales et la formule a la forme
In=h left( fracf(a)+f(b)2+ sumnâ1i=1f(a+ih) right), h= fracban (3a)
Implémentation def trapezoid_rule(func, a, b, nseg): """ nseg - , [a;b]""" dx = 1.0 * (b - a) / nseg sum = 0.5 * (func(a) + func(b)) for i in range(1, nseg): sum += func(a + i * dx) return sum * dx
AprÚs avoir tracé l'erreur en fonction du nombre de points de partage, nous voyons que la méthode trapézoïdale a également un second ordre d'approximation et donne généralement des résultats légÚrement différents de la méthode du rectangle médian (ci-aprÚs simplement la méthode du rectangle).

ContrÎle de précision de calcul
Définir le nombre de points de partage comme paramÚtre d'entrée n'est pas trÚs pratique, car il est généralement nécessaire de calculer l'intégrale non pas avec une densité de partition donnée, mais avec une erreur donnée. Si l'intégrande est connue à l'avance, alors nous pouvons estimer l'erreur à l'avance et choisir une étape d'intégration telle que la précision spécifiée est certainement atteinte. Mais c'est rarement le cas dans la pratique (et en général, n'est-il pas plus facile, avec la fonction connue à l'avance, d'intégrer l'intégrale à l'avance?), Par conséquent, une procédure d'ajustement automatique du pas à une erreur donnée est nécessaire.
Comment mettre cela en Ćuvre? Une des mĂ©thodes simples pour estimer l'erreur - la rĂšgle de Runge - la diffĂ©rence dans les valeurs des intĂ©grales calculĂ©es Ă partir de n et 2 n points, donne une estimation d'erreur: Delta2n approx|I2nâIn| . La mĂ©thode trapĂ©zoĂŻdale est plus pratique pour doubler la finesse d'une partition que la mĂ©thode des rectangles avec un point central. Lors du calcul par la mĂ©thode trapĂ©zoĂŻdale, pour doubler le nombre de points, de nouvelles valeurs de la fonction ne sont nĂ©cessaires qu'au milieu des segments de la partition prĂ©cĂ©dente, c'est-Ă -dire l'approximation prĂ©cĂ©dente de l'intĂ©grale peut ĂȘtre utilisĂ©e pour calculer la suivante.
Ă quoi sert la mĂ©thode du rectangle?La mĂ©thode du rectangle ne nĂ©cessite pas de calculer les valeurs de la fonction aux extrĂ©mitĂ©s du segment. Cela signifie qu'il peut ĂȘtre utilisĂ© pour des fonctions qui ont des caractĂ©ristiques intĂ©grables aux bords du segment (par exemple, sin x / x ou x -1/2 de 0 Ă 1). Par consĂ©quent, la mĂ©thode d'extrapolation prĂ©sentĂ©e ci-dessous fonctionnera exactement de la mĂȘme maniĂšre pour la mĂ©thode du rectangle. La diffĂ©rence avec la mĂ©thode trapĂ©zoĂŻdale est seulement que lorsque l'Ă©tape est divisĂ©e par deux, le rĂ©sultat des calculs prĂ©cĂ©dents est ignorĂ©, cependant, vous pouvez tripler le nombre de points, puis la valeur prĂ©cĂ©dente de l'intĂ©grale peut Ă©galement ĂȘtre utilisĂ©e pour calculer un nouveau. Dans ce cas, les formules d'extrapolation doivent ĂȘtre adaptĂ©es Ă un rapport diffĂ©rent d'Ă©tapes d'intĂ©gration.
De là , nous obtenons le code suivant pour la méthode trapézoïdale avec contrÎle de précision:
def trapezoid_rule(func, a, b, rtol = 1e-8, nseg0 = 1): """ rtol - nseg0 - """ nseg = nseg0 old_ans = 0.0 dx = 1.0 * (b - a) / nseg ans = 0.5 * (func(a) + func(b)) for i in range(1, nseg): ans += func(a + i * dx) ans *= dx err_est = max(1, abs(ans)) while (err_est > abs(rtol * ans)): old_ans = ans ans = 0.5 * (ans + midpoint_rectangle_rule(func, a, b, nseg))
Avec cette approche, l'intégrande ne sera pas calculée plusieurs fois à un moment donné, et toutes les valeurs calculées sont utilisées pour le résultat final.
Mais est-il possible d'obtenir une prĂ©cision plus Ă©levĂ©e avec le mĂȘme nombre de calculs de fonction? Il s'avĂšre que c'est possible, il existe des formules qui fonctionnent plus prĂ©cisĂ©ment que la mĂ©thode trapĂ©zoĂŻdale sur la mĂȘme grille.
Approximation parabolique par morceaux
L'Ă©tape suivante consiste Ă approximer la fonction avec des Ă©lĂ©ments paraboliques. Cela nĂ©cessite que le nombre de segments de la partition soit pair, puis les paraboles peuvent ĂȘtre tracĂ©es Ă travers des triplets de points avec des abscisses {( x 0 = a , x 1 , x 2 ), ( x 2 , x 3 , x 4 ), ..., ( x n -2 , x n -1 , x n = b )}.

Illustration d'une approximation parabolique par morceaux Ă 3 et 5 points ( n = 2 et n = 3).
Approcher l'intégrale de la fonction sur chacun des segments [ x k ; x k +2 ] par l'intégrale de l'approximation parabolique sur ce segment et en supposant que les points sont uniformément répartis ( x k +1 = x k + h ), on obtient la formule de Simpson :
ISimps,n= sumn/2â1i=0 frach3[f(x2i)+4f(x2i+1)+f(x2i+2)]== frach3[f(a)+4f(a+h)+2f(a+2h)+...+4f(bh)+f(b)] (4)
La formule (4) donne directement une implémentation «naïve» de la méthode Simpson:
En-tĂȘte de spoiler def simpson_rule(func, a, b, nseg): """ nseg - , [a;b]""" if nseg%2 = 1: nseg += 1 dx = 1.0 * (b - a) / nseg sum = (func(a) + 4 * func(a + dx) + func(b)) for i in range(1, nseg / 2): sum += 2 * func(a + (2 * i) * dx) + 4 * func(a + (2 * i + 1) * dx) return sum * dx / 3
Pour estimer l'erreur, vous pouvez utiliser le mĂȘme calcul de l'intĂ©grale avec les Ă©tapes h et h / 2 - mais voici le problĂšme, lors du calcul de l'intĂ©grale avec un pas plus petit, le rĂ©sultat du calcul prĂ©cĂ©dent devra ĂȘtre ignorĂ©, bien que la moitiĂ© des nouveaux calculs de fonction soient aux mĂȘmes points qu'auparavant.
Heureusement, vous pouvez Ă©viter de perdre du temps machine si vous implĂ©mentez la mĂ©thode Simpson de maniĂšre plus ingĂ©nieuse. AprĂšs avoir regardĂ© de plus prĂšs, nous notons que l'intĂ©grale par la formule de Simpson peut ĂȘtre reprĂ©sentĂ©e par deux intĂ©grales par la formule trapĂ©zoĂŻdale avec des Ă©tapes diffĂ©rentes. Cela se voit le plus clairement dans le cas de base de l'approximation de l'intĂ©grale sur trois points (a,f0), (a+h,f1), (a+2h,f2) :
ISimps,2= frach3(f0+4f1+f2)= frac43h left( fracf0+f12+ fracf1+f22 droite)â frac13 cdot2h fracf0+f22== frac4Itrap,2âItrap,13
Ainsi, si nous mettons en Ćuvre la procĂ©dure de rĂ©duction du pas de moitiĂ© et stockons les deux derniers calculs par la mĂ©thode trapĂ©zoĂŻdale, la mĂ©thode Simpson avec contrĂŽle de prĂ©cision est mise en Ćuvre plus efficacement.
Quelque chose comme ça ... class Quadrature: """ """ __sum = 0.0 __nseg = 1
Comparez l'efficacité de la méthode trapézoïdale et parabole:
>>> import math >>> Quadrature.trapezoid(lambda x: 2 * x + 1 / math.sqrt(x + 1 / 16), 0, 1.5, rtol=1e-9) Total function calls: 65537 4.250000001385811 >>> Quadrature.simpson(lambda x: 2 * x + 1 / math.sqrt(x + 1 / 16), 0, 1.5, rtol=1e-9) Total function calls: 2049 4.2500000000490985
Comme vous pouvez le voir, avec les deux mĂ©thodes, la rĂ©ponse peut ĂȘtre obtenue avec une prĂ©cision assez Ă©levĂ©e, mais le nombre d'appels Ă l'intĂ©grande est trĂšs diffĂ©rent - une mĂ©thode d'ordre supĂ©rieur est 32 fois plus efficace!
En traçant l'erreur d'intĂ©gration en fonction du nombre d'Ă©tapes, nous pouvons vĂ©rifier que l'ordre d'approximation de la formule de Simpson est quatre, c'est-Ă -dire erreur d'intĂ©gration numĂ©rique |ISimps,nâI|=O(1/n4) (et les intĂ©grales des polynĂŽmes cubiques utilisant cette formule sont calculĂ©es jusqu'aux erreurs d'arrondi pour tout n > 0!).

Par conséquent, une telle augmentation de l'efficacité se produit en comparaison avec la formule trapézoïdale simple.
Et ensuite?
La logique supplémentaire d'augmenter la précision des formules en quadrature est généralement compréhensible - si nous continuons à approximer la fonction avec des polynÎmes d'un degré toujours plus élevé, alors l'intégrale de ces polynÎmes rapprochera de plus en plus précisément l'intégrale de la fonction d'origine. Cette approche est appelée la construction de formules de Newton-Cotes quadratiques . Des formules contenant jusqu'à 8 ordres d'approximation sont connues, mais les termes alternatifs apparaissent parmi les coefficients de pondération w i dans (2), et les formules perdent de leur stabilité dans les calculs.
Essayons dans l'autre sens. L'erreur de la formule en quadrature est représentée par une série de puissances de l'étape d'intégration h . Une propriété remarquable de la méthode trapézoïdale (et des rectangles avec un point médian!) Est que pour elle cette série n'est constituée que de degrés pairs:
Itrap,n[f,a,b]= intbaf(x)dx+C2h2+C4h4+C6h6+..., h= fracban (5)
L'extrapolation de Richardson est basée sur la recherche d'approximations successives de cette expansion: au lieu d'approximer l'intégrande par un polynÎme, à partir des approximations calculées de l'intégrale I(h) une approximation polynomiale est construite, qui pour h = 0 devrait donner la meilleure approximation à la vraie valeur de l'intégrale.
L'élargissement de l'erreur d'intégration dans les puissances paires de l'étape de partition accélÚre fortement la convergence de l'extrapolation, car pour l'approximation d'ordre 2 n , seules les valeurs n de l'intégrale sont nécessaires par la méthode trapézoïdale.
Si nous supposons que chaque terme suivant est infĂ©rieur au prĂ©cĂ©dent, alors nous pouvons exclure sĂ©quentiellement les degrĂ©s de h , ayant des approximations intĂ©grales calculĂ©es avec diffĂ©rentes Ă©tapes. Ătant donnĂ© que l'implĂ©mentation ci-dessus nous permet facilement de diviser la partition en deux, il est pratique de considĂ©rer les formules des Ă©tapes h et h / 2.
Itrap,nâI approxC2h2; Itrap,2nâI approxC2 left( frach2 right)2
Il est facile de montrer que l'exception du terme supérieur de l'erreur de la formule trapézoïdale donnera exactement la formule de Simpson:
I=Itrap,2nâC2 left( frach2 right)2+O(h4) approxItrap,2nâ fracItrap,2nâIpiĂšge,n1â22=ISimps,2n
En répétant une procédure similaire pour la formule Simpson, nous obtenons:
ISimps,2nâI approxC4 left( frach2 right)4; ISimps,nâI approxC4h4
I=ISimps,2nâC4 left( frach2 right)4+O(h6) approxISimps,2nâ fracISimps,2nâISimps,n1â24
Si vous continuez, le tableau suivant se profile:
2 ordre | 4 ordre | 6 ordre | ... |
---|
I 0,0 | | |
I 1,0 | I 1,1 | |
I 2.0 | I 2.1 | I 2.2 |
... | ... | ... |
La premiÚre colonne contient les intégrales calculées par la méthode trapézoïdale. Lorsque vous vous déplacez de la ligne supérieure vers le bas, la division du segment devient deux fois plus petite et lorsque vous vous déplacez de la colonne de gauche vers la droite, l'ordre d'approximation de l'intégrale augmente (c'est-à -dire que la deuxiÚme colonne contient les intégrales par la méthode Simpson, etc.)
Les éléments du tableau, comme on peut le déduire de l'expansion (5), sont liés par la relation de récurrence:
Ii,j=Ii,jâ1â fracIi,jâ1âIiâ1,jâ11â left( frachijhi droite)2=Ii,jâ1â fracIi,jâ1âIiâ1,jâ11â22j (6)
L'erreur d'approximation de l'intĂ©grale peut ĂȘtre estimĂ©e Ă partir de la diffĂ©rence de formules de diffĂ©rents ordres sur une seule ligne, c'est-Ă -dire
Deltai,j environIi,jâIi,jâ1
L'utilisation de l'extrapolation de Richardson avec l'intégration trapézoïdale est appelée la méthode de Romberg . Si la méthode Simpson prend en compte les deux valeurs précédentes par la méthode trapézoïdale, la méthode Romberg utilise toutes les valeurs précédemment calculées par la méthode trapézoïdale pour obtenir une estimation plus précise de l'intégrale.
ImplémentationUne méthode supplémentaire est ajoutée à la classe Quadrature
class Quadrature: """ """ __sum = 0.0 __nseg = 1
Vérifions le fonctionnement de l'approximation d'ordre élevé:
>>> Quadrature.romberg(lambda x: 2 * x + 1 / math.sqrt(x + 1/16), 0, 1.5, rtol=1e-9, maxcol = 0) # Total function calls: 65537 4.250000001385811 >>> Quadrature.romberg(lambda x: 2 * x + 1 / math.sqrt(x + 1/16), 0, 1.5, rtol=1e-9, maxcol = 1) # Total function calls: 2049 4.2500000000490985 >>> Quadrature.romberg(lambda x: 2 * x + 1 / math.sqrt(x + 1/16), 0, 1.5, rtol=1e-9, maxcol = 4) Total function calls: 257 4.250000001644076
Nous sommes convaincus que, par rapport à la méthode parabole, le nombre d'appels à l'intégrande a encore diminué de 8 fois. Avec une augmentation supplémentaire de la précision requise, les avantages de la méthode Romberg deviennent encore plus prononcés:

Quelques notes
Remarque 1. Le nombre d'appels de fonction dans ces problÚmes caractérise le nombre de sommes lors du calcul de l'intégrale. La réduction du nombre de calculs de l'intégrande permet non seulement d'économiser des ressources informatiques (bien que ce soit également le cas avec une implémentation plus optimisée), mais réduit également l'effet des erreurs d'arrondi sur le résultat. Ainsi, lorsque vous essayez de calculer l'intégrale de la fonction de test, la méthode trapézoïdale se bloque lorsque vous essayez d'obtenir une précision relative de 5 à 10 -15 , la méthode parabole - avec la précision souhaitée de 2 à 10 -16 (qui est la limite des nombres à double précision), et la méthode Romberg fait face au calcul test intégral jusqu'à la précision de la machine (avec une faible erreur de bit). Autrement dit, non seulement la précision d'intégration est augmentée pour un nombre donné d'appels de fonction, mais également la précision maximale réalisable du calcul de l'intégrale.
Remarque 2. Si la mĂ©thode converge lorsqu'une certaine prĂ©cision est spĂ©cifiĂ©e, cela ne signifie pas que la valeur calculĂ©e de l'intĂ©grale a la mĂȘme prĂ©cision. Tout d'abord, cela s'applique aux cas oĂč l'erreur spĂ©cifiĂ©e est proche de la prĂ©cision de la machine.
Remarque 3. Bien que la méthode de Romberg pour un certain nombre de fonctions fonctionne de maniÚre presque magique, elle suppose que l'intégrande a borné des dérivées d'ordre élevé. Cela signifie que pour les fonctions avec des plis ou des ruptures, cela peut s'avérer pire que les méthodes simples. Par exemple, intégrez f ( x ) = | x |:
>>> Quadrature.trapezoid(abs, -1, 3, rtol=1e-5) Total function calls: 9 5.0 >>> Quadrature.simpson(abs, -1, 3, rtol=1e-5) Total function calls: 17 5.0 >>> Quadrature.romberg(abs, -1, 3, rtol=1e-5, maxcol = 2) Total function calls: 17 5.0 >>> Quadrature.romberg(abs, -1, 3, rtol=1e-5, maxcol = 3) Total function calls: 33 5.0 >>> Quadrature.romberg(abs, -1, 3, rtol=1e-5, maxcol = 4) Total function calls: 33 5.000001383269357
Remarque 4. Il peut sembler que plus l'ordre d'approximation est Ă©levĂ©, mieux c'est. En fait, il vaut mieux limiter le nombre de colonnes dans le tableau de Romberg Ă 4-6. Pour comprendre cela, regardez la formule (6). Le deuxiĂšme terme est la diffĂ©rence de deux Ă©lĂ©ments consĂ©cutifs de la j -1Ăšme colonne divisĂ©e par environ 4 j . Parce que la jiĂšme colonne contient des approximations d'une intĂ©grale d'ordre 2 j , alors la diffĂ©rence elle-mĂȘme est de l'ordre de (1 / n i ) 2 j ~ 4 - ij . En tenant compte de la division, on obtient ~ 4 - ( i +1) j ~ 4 - j 2 . C'est-Ă -dire pour j ~ 7, le deuxiĂšme terme de (6) perd sa prĂ©cision aprĂšs la rĂ©duction des ordres lors de l'ajout de nombres Ă virgule flottante, et une augmentation de l'ordre d'approximation peut conduire Ă l'accumulation d'erreurs d'arrondi.
Remarque 5. Les parties intĂ©ressĂ©es peuvent utiliser les mĂ©thodes dĂ©crites pour trouver l'intĂ©grale dans l'intĂ©rĂȘt. int10 sqrtx sinxdx et Ă©quivalent Ă lui int102t2 sint2dt . Comme on dit, ressentez la diffĂ©rence.
Conclusion
La description et la mise en Ćuvre des mĂ©thodes de base de l'intĂ©gration numĂ©rique des fonctions sur une grille uniforme sont prĂ©sentĂ©es. Il est dĂ©montrĂ© comment, Ă l'aide d'une simple modification, obtenir la classe de formules de quadrature en utilisant la mĂ©thode de Romberg sur la base de la mĂ©thode trapĂ©zoĂŻdale, ce qui accĂ©lĂšre considĂ©rablement la convergence de l'intĂ©gration numĂ©rique. La mĂ©thode fonctionne bien pour intĂ©grer des fonctions "ordinaires", c'est-Ă -dire variant faiblement sur l'intervalle d'intĂ©gration, n'ayant pas de singularitĂ©s aux bords du segment (voir remarque 5), oscillations rapides, etc.
( [3] â C++).
Littérature
- .. , .. . . .: . 1989.
- J. Stoer, R. Bulirsch. Introduction to Numerical Analysis: Second Edition. Springer-Verlag New York. 1993.
- WH Press, SA Teukolsky, WT Vetterling, BP Flannery. Numerical Recipes: Third Edition. Cambridge University Press. 2007.