Você está na página 1de 68

Integração numérica

Cristiano de Carvalho Santos


cristcarvalhosan@gmail.com

Departamento de Estatística,
Universidade Federal de Minas Gerais (UFMG)
Introdução
Considere a integral unidimensional da forma
Z b
f (x )dx .
a

Para muitas funções f são necessárias aproximações numéricas


para a integral.

Por exemplo,
I Aproximações de integrais são frequentemente necessárias
para inferência Bayesiana, visto que a distribuição a posteriori
pode não pertencer a uma família de distribuições conhecidas.
I Aproximação de integral também é útil em alguns problemas
por inferência por máxima verossimilhança quando a
verossimilhança é uma função com uma ou mais integrais.
Para iniciar uma aproximação de ab f (x )dx , particionamos o
R

intervalo [a, b] em n subintervalos, [xi , xi+1 ], para i = 0, . . . , n − 1,


com x0 = a e xn = b. Então,
Z b n−1
X Z xi+1
f (x )dx = f (x )dx .
a i=0 xi

Dentro do intervalo [xi , xi+1 ] são inseridos m + 1 nós xij∗ para


j = 0, . . . , m.
I De forma geral, os métodos de integração numérica não
exigem mesmo espaçamento de subintervalos ou nós, nem
mesmo número de nós dentro de cada intervalo.
Uma regra simples dependerá da aproximação
Z xi+1 m
Aij f (xij∗ )
X
f (x )dx ≈
xi j=0

para constantes Aij .


Fórmulas de Newton-Côtes

I Neste caso, os nós são igualmente espaçados em [xi , xi+1 ], e o


mesmo número de nós é usado dentro de cada subintervalo.

I A aproximação Newton-Côtes substitui o verdadeiro


integrando por uma aproximação polinomial dentro de cada
intervalo.

I As constantes Aij são selecionadas tal que m ∗


P
j=0 Aij f (xij ) é
igual a integral de uma interpolação polinomial em [xi , xi+1 ]
assumindo valor igual a f nos nós dentro deste subintervalo.
Alguns casos particulares:
Regra de Riemann

É o caso em que m = 0, xi0∗ = xi e Ai0 = xi+1 − xi0∗ . A regra de


Riemann aproxima f em cada subintervalo por uma função
constante f (xi ).

Em outras palavras,
Z xi+1 Z xi+1
f (x )dx ≈ f (xi )dx = (xi+1 − xi )f (xi ).
xi xi

Obs: Podemos substituir f (xi ) por f (xi+1 ) sem ocasionar nenhuma


mudança especial.
Supondo que xi são igualmente espaçados, então cada subintervalo
tem tamanho h = (b − a)/n. Logo xi = a + ih,a regra composta é
Z b n−1
X
f (x )dx ≈ h f (a + ih) = R̂(n).
a i=0

I Esta aproximação converge para o verdadeiro valor da integral


quando n → ∞, pela definição da integral de Riemman para
uma função integrável em cálculo elementar.
I É comum calcular uma sequência de aproximações R̂(nk ), para
uma sequência crescente de número de subintervalos, nk , com
k = 1, 2, . . .. Então, a convergência de R̂(nk ) pode ser
monitorada usando um critério absoluto ou relativo de
convergência.
No R:

Riemann <- function(integrando, a, b, n = 100,...) {


# Integral numerica do integrando de a ate b com n subd
# Assumimos a < b e n eh um inteiro positivo
h <- (b-a)/n
x.vec <- seq(a, b, by = h)
f.vec <- sapply(x.vec, integrando,...)
Int <- h*sum(f.vec)
return(Int)
}
Exemplo
R1
Suponha que desejamos calcular numericamente 0 4x 3 dx . Isto é, a
área colorida abaixo.
> f1 <- function(x) return(4 * x^3)
> Riemann(f1, 0, 1, n = 20)
[1] 1.1025
> Riemann(f1, 0, 1, n = 40)
[1] 1.050625
> Riemann(f1, 0, 1, n = 60)
[1] 1.033611
Exemplo: Φ(z)

Podemos obter a função de distribuição acumulada da Normal


padrão através do seguinte código.

phi <- function(x) return(exp(-x^2/2)/sqrt(2*pi))

Phi_Riemman <- function(z) {


if (z < 0) {
return(0.5 - Riemann(phi, z, 0))
} else {
return(0.5 + Riemman(phi, 0, z))
}
}
Regra do trapézio

Consideramos a função
m
f (xij∗ )pij (x )
X
pi (x ) =
j=0

é um polinômio de grau m que interpola f em todos os nós


xi0∗ , . . . , xi0∗ em [xi , xi+1 ].

As quantidades pij , para j = 0, . . . , m, são denotados por


polinômios fundamentais e são dados por
m
Y x − xik∗
pij = .
k=0,k6=j xij∗ − xik∗
Estes polinômios são a base da aproximação
Z xi+1 Z xi+1
f (x )dx ≈ pi (x )dx
xi xi
Z xi+1 Xm
= f (xij∗ )pij (x )dx
xi j=0
m Z xi+1

X
= f (xij ) pij (x )dx
j=0 xi
m
Aij f (xij∗ ),
X
=
j=0

R xi+1
em que Aij = xi pij (x )dx .

Esta aproximação substitui a integração de uma função


arbitrária f por uma integração polinomial.
Assim, quando somamos em todos os subintervalos, temos
Z b n−1 m
Aij f (xij∗ )
XX
f (x )dx ≈
a i=0 j=0

quando existem m nós dentro de cada subintervalo.

Fazendo m = 1 com xi0∗ = xi e xi1∗ = xi+1 produz a regra do


trapézio, em que
x − xi+1 x − xi
pi0 = e pi1 = .
xi − xi+1 xi+1 − xi

Integrando estes polinômios de xi a xi+1 , temos que


Ai0 = Ai1 = (xi+1 − xi )/2.
Logo,
n−1
Z b X xi+1 − xi

f (x )dx ≈ [f (xi ) + f (xi+1 )] .
a i=0 2

Quando [a, b] está particionado em n subintervalos de tamanho


igual h = (b − a)/n, temos que
Z b n−1
h X h
f (x )dx ≈ f (a) + h f (a + ih) + f (b) = T̂ (n).
a 2 i=1 2

Quando f é uma linha em [a, b], T̂ (n) é exata.


Avaliando o erro de aproximação
Suponha que f tem duas derivadas contínuas. Pode ser mostrado
que

1
pi (x ) = f (xi ) + f 0 (xi )(x − xi ) + f 00 (xi )(xi+1 − xi ) + O(n−3 ).
2
Subtraindo a expansão de Taylor de f em xi segue que

1
pi (x ) + f (x ) = f 00 (xi )(x − xi )(x − xi+1 ) + O(n−3 )
2
e integrando sobre [xi , xi+1 ] mostra que o erro de aproximação da
regra do trapézio no i-ésimo intervalo é h3 f 00 (xi )/12 + O(n−4 ).
Disso,
m
h3 f 00 (xi )
Z b !
+ O(n−4 )
X
T̂ (n) − f (x )dx =
a i=1 12
= nh f (ε)/12 + O(n−3 )
3 00

(b − a)3 f 00 (ε)
= + O(n−3 ),
12n2
para algum ε ∈ [a, b] pelo teorema do valor médio para integrais.
Então, a ordem do erro é O(n−2 ).
No R:

trapezio <- function(integrando, a, b, n = 100,...) {


# Integral do integrando de a ate b com n subdivisoes
# Assumimos a < b e n eh um inteiro positivo
h <- (b-a)/n
x.vec <- seq(a, b, by = h)
f.vec <- sapply(x.vec, integrando,...)
Int <- h*(f.vec[1]/2 + sum(f.vec[2:n]) + f.vec[n+1]/2)
return(Int)
}
Exemplo

R1
Suponha que desejamos calcular numericamente 0 4x 3 dx .

> f1 <- function(x) return(4 * x^3)


> trapezio(f1, 0, 1, n = 20)
[1] 1.0025
> trapezio(f1, 0, 1, n = 40)
[1] 1.000625
> trapezio(f1, 0, 1, n = 60)
[1] 1.000278
Exemplo: Φ(z)

Podemos obter a função de distribuição acumulada da Normal


padrão através do seguinte código.

Phi_trapezio <- function(z, n) {


if (z < 0) {
return(0.5 - trapezio(phi, z, 0, n = n))
} else if(z > 0) {
return(0.5 + trapezio(phi, 0, z, n = n))
} else {
return(0.5)
}
}
Regra de Simpson

Fazendo m = 2 com xi0∗ = xi , xi1∗ = (xi + xi+1 )/2 e xi2∗ = xi+1


produz a regra de Simpson. Neste caso, temos que

Ai0 = Ai2 = (xi+1 − xi )/6


Ai1 = 2(Ai0 + Ai2 ) = 4(xi+1 − xi )/6.

Isto produz,
Z xi+1
xi+1 − xi xi + xi+1
   
f (x )dx ≈ f (xi ) + 4f + f (xi+1 ) .
xi 6 2
Quando [a, b] está particionado em n subintervalos de tamanho
igual h = (b − a)/n, podemos juntar intervalos adjacentes,
obtendo n/2 subintervalos de tamanho 2h, tal que
Z b n/2
hX
f (x )dx ≈ (f (x2i−2 ) + 4f (x2i−1 ) + f (x2i )) = Ŝ(n/2).
a 3 i=1

Se f é quadrática em [a, b], então também é quadrática em cada


subintervalo e o polinômio considerado é exatamente f . Disso, a
regra de Simpson é a integral exata de uma função quadrática f .

Observação: Através do uso de expansão em série de Taylor é


possível mostrar que o erro de aproximação é da ordem O(n−4 ).
No R:

simpson_n <- function(integrando, a, b, n = 100,...) {


# Integral numerica do integrando de a ate b com n subd
# Assumimos a < b e n eh um inteiro positivo
n <- max(c(2*(n %/% 2), 4))
h <- (b-a)/n
x.vec1 <- seq(a+h, b-h, by = 2*h)
x.vec2 <- seq(a+2*h, b-2*h, by = 2*h)
f.vec1 <- sapply(x.vec1, integrando,...)
f.vec2 <- sapply(x.vec2, integrando,...)
Int <- h/3*(integrando(a) + integrando(b) + 4*sum(f.vec
return(Int)
}
Exemplo

R1
Suponha que desejamos calcular numericamente 0 4x 3 dx .

> f1 <- function(x) return(4 * x^3)


> simpson_n(f1, 0, 1, n = 5)
[1] 1
> simpson_n(f1, 0, 1, n = 10)
[1] 1
> simpson_n(f1, 0, 1, n = 20)
[1] 1
Exemplo: Φ(z)

Podemos obter a função de distribuição acumulada da Normal


padrão através do seguinte código.

Phi_Simpson <- function(z, n) {


if (z < 0) {
return(0.5 - simpson_n(phi, z, 0, n=n))
} else {
return(0.5 + simpson_n(phi, 0, z, n=n))
}
}
Exemplo: Comparação dos métodos
Suponha que desejamos calcular P(X ≤ 3) com X ∼ Exp(1).
Alcançando uma tolerância definida
Ao usar a regra de Simpson na prática, precisamos de alguma regra
para escolher n que resulte em aproximação razoavelmente precisa.

Rb
I Suponha que f é contínua e desejamos estimar I = a f (x )dx .

I Seja Ŝ(n) o valor da aproximação quando usamos uma


partição de tamanho n, então Ŝ(n) → I quando n → ∞.

Assim, Ŝ(2n) − Ŝ(n) → 0 e podemos usar uma regra de parada da


forma n é suficientemente quando

|Ŝ(2n) − Ŝ(n)| ≤ ,

em que  > 0 é uma tolerância pequena.


Infelizmente, dado um δ > 0, 0 não podemos em geral encontrar
um  tal que

Ŝ(2n) − Ŝ(n) ≤  =⇒ |Ŝ(2n) − I| ≤ δ.

Estratégia:
I Podemos modificar a implementação de tal forma que em vez
de especificar o tamanho n da partição, especificamos a
tolerância . (iniciamos com um valor de n pequeno!)

I Observe que podemos aumentar n por um fator de 2 a cada


vez, para que possamos reutilizar as avaliações de função
anteriores. Na prática, avaliar f é a operação mais cara que
realizamos quando fazemos integração numérica.
No R:
simpson <- function(ftn, a, b, tol = 1e-8, verbose = FALSE) {
# ftn is a function of a single variable and a < b
# if verbose is TRUE then n is printed to the screen
n <- 4
h <- (b - a)/4
fx <- sapply(seq(a, b, by = h), ftn)
S <- sum(fx*c(1, 4, 2, 4, 1))*h/3
S.diff <- tol + 1 # ensures we loop at least once
# increase n until S changes by less than tol
while (S.diff > tol) {
S.old <- S
n <- 2*n
h <- h/2
fx[seq(1, n+1, by = 2)] <- fx # reuse old ftn values
fx[seq(2, n, by = 2)] <- sapply(seq(a+h, b-h, by = 2*h), ftn)
S <- h/3*(fx[1] + fx[n+1] + 4*sum(fx[seq(2, n, by = 2)]) +
2*sum(fx[seq(3, n-1, by = 2)]))
S.diff <- abs(S - S.old)
}
if (verbose) cat(’partition size’, n, ’\n’)
return(S)
}
Exemplo
Suponha a integração dos seguintes polinômios de ordem 4, 8, 12.

> options(digits = 16)

> f4 <- function(x) 5 * x^4


> f8 <- function(x) 9 * x^8
> f12 <- function(x) 13 * x^12

> simpson(f4, 0, 1, tol = 1e-09, verbose = TRUE)


partition size 512
[1] 1.000000000009701
> simpson(f8, 0, 1, tol = 1e-09, verbose = TRUE)
partition size 1024
[1] 1.000000000015279

> simpson(f12, 0, 1, tol = 1e-09, verbose = TRUE)


partition size 2048
[1] 1.000000000005419
Integração Romberg

I Em geral, métodos Newton-Côtes com baixo grau são lentos


para a convergência.

I Contudo existe um mecanismo muito eficiente para melhorar


com uma sequência de estimativas via regra do trapézio.

Seja T̂ (n) denotando a estimativa de ab f (x )dx via regra do


R

trapézio usando n subintervalos de igual tamanho h = (b − a)/n.


Sem perda de generalidade, suponha que a = 0 e b = 1. Então
1 1
T̂ (1) = f (0) + f (1)
2 2
1 1 1
T̂ (2) = f (0) + f (1/2) + f (1)
4 2 4
1 1 1
T̂ (4) = f (0) + [f (1/4) + f (1/2) + f (3/4)] + f (1).
8 4 8
Note que
1 1
T̂ (2) = T̂ (1) + f (1/2)
2 2
1 1
T̂ (4) = T̂ (2) + [f (1/4) + f (3/4)].
2 4
Isto sugere a seguinte forma recursiva,
n
1 hX
T̂ (2n) = T̂ (n) + f (a + (i − 1/2)h).
2 2 i=1

A fórmula de Euler-Maclaurin pode ser usada para mostrar que


Z b
T̂ (n) = f (x )dx + c1 h2 + O(n−4 )
a

para alguma constante c1 , e


Z b
c1 2
T̂ (2n) = f (x )dx + h + O(n−4 ).
a 4
Logo,
4T̂ (2n) − T̂ (n) Z b
= f (x )dx + O(n−4 ).
3 a
Seja T̂i,0 = T̂ (2i ) = T̂ para i = 0, . . . , m e defina

4j T̂i,j−1 − T̂i−1,j−1
T̂i,j = ,
4j − 1
para j = 1, . . . , i e i = 1, . . . , m.

Se f é duas vezes diferenciável em [a, b], então


Z b
T̂m,j − f (x )dx = O(2−2mj )
a

para j ≤ m.
Quadratura adaptativa

Como funciona:
I Em uma quadratura adaptativa, o tamanho h dos
subintervalos não é constante no intervalo [a, b], mas ele se
adapta a função f .

I O ponto importante é que h necessita ser pequeno apenas


onde o integrando f é íngreme.

I A quadratura adaptativa permite automaticamente que a


largura do intervalo h varie ao longo do intervalo de
integração, usando um algoritmo recursivo.
Procedimento:
I Aplicamos a regra de Simpson usando alguns valores iniciais h
e h/2. Se a diferença entre as duas estimativas é menor do
que alguma tolerância , então o algoritmo é finalizado.

I Se não, então dividimos o intervalo de integração [a, b] em


duas partes ([a, c] e [c, b] onde c = (a + b)/2) e em cada
parte aplicamos a regra de Simpson usando larguras de
intervalo h/2 e h/4 e uma tolerância de /2.

I Se o erro em cada subintervalo for menor que /2, então o


erro das estimativas combinadas será menor que .
I Ao diminuir h, melhoramos a precisão.
I Se a tolerância desejada não for atendida em um determinado
subintervalo, então a dividimos ainda mais, mas só fazemos
isso para subintervalos que não atingem a tolerância desejada.

I Assim, um pequeno h é usado somente quando necessário. O


método apenas subdivide intervalos quando ele precisa de
uma resolução maior (geralmente onde a função é
pontiaguda) e, portanto, economiza muito trabalho.
Exemplo:

R1 √
Exemplo com a integral 0 1, 5 x dx e avaliação de tempo de
execução no script3!
Outros aspectos

I Limites de integração

Integrais com limites infinitos podem se transformadas para


terem limites finitos. Algumas transformações úteis são

exp{x } x
1/x , , exp{−x } e .
1 + exp{x } 1+x

Algumas funções de distribuição acumulada também podem


ser utilizadas.
I Integrando com singularidades

Singularidades podem ser removidos com transformações, por


exemplo
Z 1
exp{x } Z 1
√ dx = 2 exp {u 2 }du
0 x 0

em que u = x .
Outro método é subtrair a singularidade, por exemplo
Z π/2 Z π/2
2
log {sin x }dx = log {(sin2 x )/x 2 }dx
−π/2 −π/2
Z π/2
+ log {x 2 }dx .
−π/2
I Integrais Múltiplas

Escrevemos, por exemplo,


Z bZ d Z b
f (x , y )dydx = g(x )dx ,
a c a

em que g(x ) = cd f (x , y )dy . Valores de g(x ) são obtidos via


R

aproximação univariada.

Observações:
I Usando n subintervalos em cada integral unidimensional,
serão necessárias np avaliações de f , em que p é o número de
dimensões da integral.
I Métodos Monte Carlo são mais eficientes para integrais sobre
regiões com alta dimensão.
Quadratura Gaussiana

O valor de uma integral é predominantemente determinado por


regiões em que a magnitude do integrando é grande, então faz
sentido colocar mais nós nestas regiões.

Com uma escolha adequada e flexível de m + 1 nós, x0 , x1 , . . . , m,


e correspondentes pesos, A0 , . . . , Am , a integral exata de um
polinômio de grau 2(m + 1) pode ser obtida usando
Z b m
X
f (x )dx = Ai f (xi ).
a i=0
Esta abordagem pode ser extremamente efetiva para integrais com
Z b
f (x )w (x )dx
a

em que w é uma função não negativa e ab x k w (x )dx < ∞ para


R

todo k ≥ 0. (Suposições atendidas por densidade com


momentos finitos).

Este método é geralmente aplicado ao definirmos


f∗ (x ) = f (x )/w (x ) e aplicar o método a
Z b
f ∗ (x )w (x )dx .
a

A melhor localização nos nós é obtida através das raízes de um


polinômio ortogonal que é determinado por w .
Polinômios ortogonais

Duas
Rb
funções f e g duplamente
Rb
integráveis em [a, b] (isto é,
2 2
a f (x ) w (x )dx < ∞ e a g(x ) w (x )dx < ∞) são ortogonais com
respeito a w se
Z b
f (x )g(x )w (x )dx = 0.
a

As funções f e g são ortonormais se


Z b Z b
2
f (x ) w (x )dx = g(x )2 w (x )dx = 1.
a a
Seja pk (x ) um polinômio genérico de grau k.

I Dado alguma w não negativa em [a, b], existe uma sequência


de polinômios {pk (x )}∞
k=0 que são ortogonais com respeito a
w em [a, b].

I Esta sequência não é única sem alguma forma de


padronização, mas uma escolha comum é o conjunto de
polinômios com coeficiente líder de pk (x ) igual a 1.

Obs: Coeficiente líder é aquele ligado ao termo de maior grau do


polinômio.
Um conjunto de polinômios ortogonais padronizados pode ser
representado pela relação de recorrência

pk (x ) = (αk + x βk )pk−1 (x ) − γk pk−2 (x )

para escolhas apropriadas de αk , βk e γk que variam com k e w , e


considerando p−1 (x ) ≡ 0 e p0 (x ) ≡ 1.

I Para o uso na quadratura Gaussiana, os limites de integração


podem ser transformados para [a∗ , b ∗ ].

I As raízes de algum polinômio em dado conjunto padronizado


estão todas em [a∗ , b ∗ ] e são usadas como nós para a
quadratura Gaussiana.
Regra da quadratura Gaussiana
Seja {pk (x )}∞
k=0 que são ortogonais com respeito a w em [a, b].
Denote as raízes pm+1 (x ) por a < x0 < x1 < . . . < xm < b. Então
existem pesos A0 , . . . , Am que:

1. Ai > 0 para i = 0, . . . , m.
0
2. Ai = −cm+2 /[cm+1 pm+2 (xi )pm+1 (xi )], em que ck é o
coeficiente líder de pk (x ).
Rb
f (x )w (x )dx = m
P
3. a i=0 Ai f (xi ) sempre que f é um polinômio
de grau menor que 2m + 1. (método é exato para a esperança
de algum polinômio com respeito a w ).
I Deve-se evitar calcular os nós e os pesos diretamente devido a
potencial imprecisão numérica. Cálculos numéricos estáveis
para estas quantidades podem ser obtidas em softwares.
Quadratura de Gauss-Hermite

I A quadratura de Gauss-Hermite é particularmente útil por


causa da integração sobre a linha real.
I A importância da distribuição Normal na prática estatística e
teoria limite implica que muitas integrais possuem como
integrando o produto de uma função suave e a densidade da
Normal.
O método de Gauss-Hermite é uma extensão do método de
Quadratura Gaussiana tal que
Z ∞ n
−x 2
X
e f (x )dx ≈ Ai f (xi ),
−∞ i=1

em que xi as raízes do polinômio de Hermite Hk (x ), i = 0, . . . , m,


e os pesos Ai associados são dados por

2n−1 n! π
Ai = 2 .
n [Hn−1 (xi )]2
O pacote statmod tem a função gauss.quad que fornece as raízes
dos polinômios e os pesos.

gauss.hermite <- function(integrando, n.pontos, ...){


pontos <- gauss.quad(n.pontos, kind="hermite")
int <- sum(pontos$weights*integrando(pontos$nodes,...)
/exp(-pontos$nodes^2))
return(int)
}
O método de Gauss-Hermite apresenta duas grandes limitações:
I A primeira está relacionada a escolha dos pontos de Gauss,
que são escolhidos baseados em exp {−x 2 }, independente da
função f (x ) no integrando. Dependendo do suporte de f (x ),
os pontos selecionados podem ou não estar dentro da área de
interesse.

I O segundo problema do método de Gauss-Hermite está


relacionado com a dimensão da integral a ser resolvida. Para
funções em duas ou mais dimensões precisamos do produto
cartesiano dos pontos de integração para espalhar na função
multidimensional, ou seja, o número de pontos cresce
exponencialmente de acordo com a dimensão da função a ser
integrada.
Quadratura Adaptativa de Gauss-Hermite

I Uma ideia natural é reescalonar os pontos de modo a


colocá-los na área de maior densidade da função f (x ) o que
gera o método chamada de Quadratura Adaptativa de
Gauss-Hermite.

I Com adaptativa Gauss-Hermite, os pontos de integração são


centrados e escalonados como se f (x ) exp {x 2 } fosse a
distribuição gaussiana.
Os novos pontos de integração adaptados serão dados por
#−1/2
δ2
"
2
xi+ = x̂ + − 2 ln{f (x )e −x }|x =x̂ xi ,
dx

em que x̂ sendo a moda de ln{f (x )e−x 2 } (moda coincide com a


média na Normal).
Os pesos correspondentes são
#−1/2 +
δ2 e xi
"
2
A+
i = − 2 ln{f (x )e −x }|x =x̂ Ai .
dx e −xi
A integral é agora aproximada por
Z ∞ n
2
e −x f (x )dx ≈ A+ +
X
i f (xi ).
−∞ i=1

O método de Laplace é o caso particular em que a quadratura


adaptativa de Gauss-Hermite é aplicada com um ponto de
integração.

Você também pode gostar