Necesito evaluar numéricamente la integral a continuación:
donde ,y. Aquíes la función Bessel modificada del segundo tipo. En mi caso particular tengo,y.
Estoy usando MATLAB, y he probado las funciones integradas integral
y quadgk
, lo que me da muchos errores (ver más abajo). Naturalmente, también he intentado muchas otras cosas, como la integración por partes y la suma de integrales de a ( k + 1 ) x π .
Entonces, ¿tiene alguna sugerencia sobre qué método debería probar a continuación?
ACTUALIZACIÓN (preguntas adicionales)
Leí el documento al que se vinculó @Pedro, y no creo que fuera demasiado difícil de entender. Sin embargo, tengo algunas preguntas:
- ¿Estaría bien usar como elementos básicos ψ k , en el método univariado de Levin descrito?
- ¿Podría usar un método Filon, ya que la frecuencia de las oscilaciones es fija?
Código de ejemplo
>> integral(@(r) sin(x*r).*sqrt(E(r)),0,Inf)
Warning: Reached the limit on the maximum number of intervals in use. Approximate
bound on error is 1.6e+07. The integral may not exist, or it may be difficult to
approximate numerically to the requested accuracy.
> In funfun\private\integralCalc>iterateScalarValued at 372
In funfun\private\integralCalc>vadapt at 133
In funfun\private\integralCalc at 84
In integral at 89
ans =
3.3197e+06
fuente
Respuestas:
He escrito mi propio integrador,
quadcc
que maneja sustancialmente mejor que los integradores de Matlab con singularidades, y proporciona una estimación de error más confiable.Para usarlo para su problema, hice lo siguiente:
La función
f
ahora es tu integrando. Tenga en cuenta que acabo de asignar cualquier valor anterior ax
.Para integrar en un dominio infinito, aplico una sustitución de variables:
es decir, integrar∞
g
de 0 a 1 debería ser lo mismo que integrarf
de 0 a . Diferentes transformaciones pueden producir resultados de diferente calidad: matemáticamente todas las transformaciones deberían dar el mismo resultado, pero diferentes transformaciones pueden producir s más suaves o más fácilmente integrables .g
Luego llamo a mi propio integrador,
quadcc
que puede manejar elNaN
s en ambos extremos:Tenga en cuenta que la estimación del error es enorme, es decir
quadcc
, no tiene mucha confianza en los resultados. Sin embargo, al observar la función, esto no es sorprendente, ya que oscila en valores de tres órdenes de magnitud por encima de la integral real. Nuevamente, usar una transformación de intervalo diferente puede producir mejores resultados.También es posible que desee ver métodos más específicos como este . Es un poco más complicado, pero definitivamente es el método correcto para este tipo de problema.
fuente
integral
(1e-10, creo), pero 1.7e + 07 sigue siendo muy, muy grande. Quizás otra transformación sirva, como mencionas.Como señala Pedro, los métodos de tipo Levin son los mejores métodos establecidos para este tipo de problemas.
¿Tienes acceso a Mathematica? Para este problema, Mathematica los detectará y usará por defecto:
Aquí hay una gráfica sobre un rango de valores de x:
También puede especificar manualmente el método particular de tipo Levin para aplicar, que en este caso puede producir una ligera mejora en el rendimiento:
Consulte la documentación para obtener detalles sobre los métodos de tipo Levin en Mathematica .
fuente
Si no tiene acceso a Mathematica, podría escribir un método de tipo Levin (u otro oscilatorio especializado) en Matlab como sugiere Pedro.
¿Utiliza la biblioteca chebfun para Matlab? Me acabo de enterar que contiene una implementación de un método básico de tipo Levin aquí . La implementación está escrita por Olver (uno de los expertos en el campo de la cuadratura oscilatoria). No trata con singularidades, subdivisión adaptativa, etc., pero puede ser justo lo que necesita para comenzar.
fuente
La transformación recomendada por Pedro es una gran idea. ¿Has intentado jugar con los parámetros en la función "quadgk" de Matlab? Por ejemplo, usando la transformación de Pedro, puede hacer lo siguiente:
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
Usar esto me da una solución de:
-2184689.50220729
y solo toma 0.8 segundos (usando los valores mencionados anteriormente: x = 10)
Walter Gander y Walter Gautschi tienen un documento sobre la cuadratura adaptativa con Matlab código que puede usar también (enlace aquí )
fuente