¿La transformación

15

He escuchado anecdóticamente que cuando uno está tratando de hacer numéricamente una integral de la forma

0f(x)J0(x)dx

con suave y de buen comportamiento (p. ej., no muy oscilatorio, no singular, etc.), entonces ayudará a la precisión reescribirlo comof(x)

1π0π0f(x)cos(xsinθ)dxdθ

y realice la integral interna numéricamente primero. No veo ninguna razón por la que debería esperar que esto funcione, pero, de nuevo, la precisión de un método numérico rara vez es obvia.

Por supuesto, sé que la mejor manera de hacerlo es usar un método optimizado para integrales oscilatorias como esta, pero por curiosidad, supongamos que me limito a usar alguna regla de cuadratura. ¿Alguien puede confirmar o refutar que hacer esta transformación tiende a mejorar la precisión de la integral? ¿Y / o señalarme una fuente que lo explique?

David Z
fuente
1
0θπ
44
NQN[][0,)QπN[][0,π]QNM[fJ0]QπM[QN[f(x)cos(xsinθ)]]
@StefanoM sí, es cierto.
David Z
FWIW, uno de los métodos más eficientes para evaluar la función de Bessel de orden cero es la regla trapezoidal, que es conocida por dar resultados muy precisos al integrar integrandos periódicos durante un período (incluso mejor que el estándar habitual, la cuadratura gaussiana). Entonces: podría ayudar, puede que no.
JM

Respuestas:

3

θJ0nxf(x)=exx2[0,xmax]xmaxabajo. Tengo:

 n      direct         rewritten
 1  0.770878284949  0.770878284949
 2  0.304480978430  0.304480978430
 3  0.356922151260  0.356922151260
 4  0.362576361509  0.362576361509
 5  0.362316789057  0.362316789057
 6  0.362314010897  0.362314010897
 7  0.362314071949  0.362314071949
 8  0.362314072182  0.362314072182
 9  0.362314072179  0.362314072179
10  0.362314072179  0.362314072179

n=9

Aquí está el código:

from scipy.integrate import fixed_quad
from scipy.special import jn
from numpy import exp, pi, sin, cos, array

def gauss(f, a, b, n):
    """Gauss quadrature"""
    return fixed_quad(f, a, b, n=n)[0]

def f(x):
    """Function f(x) to integrate"""
    return exp(-x) * x**2

xmax = 3.

print " n      direct         rewritten"
for n in range(1, 20):
    def inner(theta_array):
        return array([gauss(lambda x: f(x) * cos(x*sin(theta)), 0, xmax, n)
            for theta in theta_array])
    direct = gauss(lambda x: f(x) * jn(0, x), 0, xmax, n)
    rewritten = gauss(inner, 0, pi, 20) / pi
    print "%2d  %.12f  %.12f" % (n, direct, rewritten)

xmax[0,]f(x)rewritten = gauss(inner, 0, pi, 20) / pi

Ondřej Čertík
fuente
Sospecho que tienes razón, mis propias pruebas han mostrado resultados similares.
David Z