J'utilise la fonction quad
de scipy.integrate v0.19.1
d'intégrer des fonctions avec une racine carrée comme singularité à chaque extrémité de l'intervalle d'intégration comme par exempleL'intégration d'une fonction avec singularites en utilisant la routine de quad scipy
In [1]: quad(lambda x: 1/sqrt(1-x**2), -1, 1)
(I utiliser la fonction sqrt
de numpy v1.12.0
) qui donne immédiatement le pi résultat correct:
Out[1]: (3.141592653589591, 6.200897573194197e-10)
Selon la documentation du quad
fonction le mot-clé points
doit être utilisé pour indiquer l'emplacement des singularités ou discontinuités du integrand, mais si j'indiquer les points [1, -1]
où le integrand ci-dessus est singluar je reçois un avertissement et nan
comme résultat:
In [2]: quad(lambda x: 1/sqrt(1-x**2), -1, 1, points=[-1, 1])
RuntimeWarning: divide by zero encountered in double_scalars
IntegrationWarning: Extremely bad integrand behavior occurs at some
points of the integration interval.
Out[2]: (nan, nan)
Can quelqu'un clarifier, pourquoi quad
produit ces problèmes si les singularités de l'intégrande sont spécifiées et fonctionne bien si ces points ne sont pas indiqués?
EDIT: Je pense que j'ai trouvé la bonne solution pour ce problème. Pour le cas où quelqu'un rencontre les autres problèmes similaires que je veux rapidement partager mes conclusions:
Je vous souhaite intégrer une fonction de la forme f(x)*g(x)
avec une fonction lisse f(x)
et g(x) = (x-a)**alpha * (b-x)**beta
, où a
et b
sont les limites d'intégration et g(x)
a des singularités à ces limites si alpha, beta < 0
, alors vous êtes supposé simplement intégrer f(x)
en utilisant g(x)
comme fonction de pondération. Pour la routine quad
, cela est possible en utilisant les arguments weight
et wvar
. Avec ces arguments, vous êtes également capable de gérer des singularités de différents types et des comportements oscillatoires problématiques. La fonction de pondération g(x)
définie ci-dessus peut être utilisée en définissant weight='alg'
et en utilisant wvar=(alpha, beta)
pour spécifier les exposants dans g(x)
.
Depuis 1/sqrt(1-x**2) = (x+1)**(-1/2) * (1-x)**(-1/2)
je peux maintenant gérer l'intégrale comme suit:
In [1]: quad(lambda x: 1, -1, 1, weight='alg', wvar=(-1/2, -1/2))
Out[1]: (3.1415926535897927, 9.860180640534107e-14)
qui donne la bonne réponse pi
avec une très grande précision, peu importe si j'utilise l'argument points=(-1, 1)
ou non (qui, dans la mesure Je comprends maintenant, ne devrait être utilisé, si les singularités/discontinuités ne peuvent pas être traitées en choisissant une fonction de pondération appropriée).
Salut Walt, merci pour votre aimable réponse! Je pense que c'est la bonne façon de procéder. – TMueller83