| This post was kindly contributed by Ridículas - go there to comment and to read the full post. |

Trajetória obtida com os valores consecutivos nas iterações do método Newton-Raphson para estimação da raíz de uma função.
O método Newton-Raphson é empregado para encontrar o zero de funções. Em problemas de otimização, é empregado para encontrar o zero da função derivada de nossa função objetivo
. O procedimento se baseia na aproximação em série de Taylor de primeira ordem ao redor de um valor arbitrário
. Considerando que desejamos obter o zero de uma função
, temos a expansão ao redor de
como queremos saber qual o valor de para o qual
, nós isolamos
na expressão acima, assim
e como esse valor é baseado em uma aproximação linear ao redor de , agora atualizamos
com o valor encontrado e repetimos esse procedimento até alcançar convergência por algum critério. Normalmente esses critérios são sobre as diferenças entre os valores obtidos em passos consecutivos.
No CMR abaixo eu apresento a obtenção raízes de uma função composta por e
. Nos escrevemos as funções, obtemos a derivada e aplicamos o método Newton-Raphson observando graficamente o histórico de iterações. No final eu coloquei um exemplo de como obter o ponto de máximo de uma função aplicando o método Newton-Raphson. Essas funções são didáticas e o método Newton-Raphson está disponível na função
micEcon::maxNR() para maximização baseada em Newton-Raphson. No pacote animation a função newton.method() ilustra o funcionamento do método. Mais sobre métodos de otimização estão disponíveis na Task View Optimization do R. Em um post futuro vou ilustrar o uso do método Newton-Raphson em estimação por verossimilhança. Até a próxima ridícula.
#-----------------------------------------------------------------------------
# newton-raphson em uma dimensão
# http://condicaoinicial.com/2011/08/sistema-nao-lineares-newton-raphson.html
# http://www.mat.ufrgs.br/~guidi/grad/MAT01169/laminas.calculo_numerico.5.pdf
# http://www.editora.ufla.br/site/_adm/upload/revista/23-3-1999_25.pdf
# http://www.dpi.inpe.br/~miguel/cursoemilioribas/MaterialRef/Curso1Estatistica_Corina.pdf
f <- quote(sin(x)-x^2/16) # expressão da função, queremos obter a raíz
fx0 <- function(x){ eval(f) } # função
curve(fx0, -10, 10); abline(h=0) # gráfico da função
f1 <- D(f,"x") # expressão da derivada
fx1 <- function(x){ eval(f1) } # função
par(new=TRUE); curve(fx1, -10, 10, col=2, axes=FALSE) # gráfico
#-----------------------------------------------------------------------------
# método iterativo de Newton-Raphson
i <- 1 # valor inicial para o passo
dif <- 100 # valor inical para a diferença entre duas avaliações
tol <- 10^-9 # diferência mínima entre duas avaliações (tolerância)
dif <- 100 # número máximo de passos
x <- -7 # valor inicial para a raiz
while(i<100 & dif>tol){
x[i+1] <- x[i]-fx0(x[i])/fx1(x[i])
dif <- abs(x[i+1]-x[i])
i <- i+1
print(x[i])
}
#-----------------------------------------------------------------------------
# gráfico que ilustra a trajetória até a obtenção da raíz
curve(fx0, -10, 10)
for(j in 2:i){
arrows(x[j-1], fx0(x[j-1]), x[j], fx0(x[j]), length=0.1, col=3)
Sys.sleep(0.5)
}
abline(v=x[i], h=fx0(x[i]), col=2)
# experimente outros valores iniciais
# veja que essa função tem 2 raízes, cada valor inicial vai levar
# à apenas uma delas!
#-----------------------------------------------------------------------------
# fazendo animação gif
dir.create("seqpngs")
setwd("seqpngs")
png(file="p%02d.png", width=400, height=300)
for(j in 2:i){
curve(fx0, -10, 10, main=paste("passo ", j-1, ", (x = ",
round(x[j],2), ")", sep=""))
arrows(x[j-1], fx0(x[j-1]), x[j], fx0(x[j]), length=0.1, col=3, lwd=2)
abline(v=x[j], h=fx0(x[j]), col="gray50")
}
abline(v=x[i], h=fx0(x[i]), col=2, lwd=2)
text(0, -3, label="CONVERGIU!", cex=2)
dev.off()
system("convert -delay 80 *.png example_1.gif")
#-----------------------------------------------------------------------------
# encontrando o ponto de máximo de uma função com newton-raphson
f <- quote(x*(2+0.5*x)^(-4)) # expressão da função, queremos obter MÁXIMO
fx0 <- function(x){ eval(f) } # função
curve(fx0, 0, 10)
f1 <- D(f,"x") # expressão da derivada, obteremos o zero
fx1 <- function(x){ eval(f1) } # função
curve(fx1, 0, 10, col=2) # gráfico
f2 <- D(f1, "x")
fx2 <- function(x){ eval(f2) } # função
#-----------------------------------------------------------------------------
# aplicando o newton-raphson
i <- 1 # valor inicial para o passo
dif <- 100 # valor inical para a diferença entre duas avaliações
tol <- 10^-9 # diferência mínima entre duas avaliações (tolerância)
dif <- 100 # número máximo de passos
x <- 0 # valor inicial para a raiz
while(i<100 & dif>tol){
x[i+1] <- x[i]-fx1(x[i])/fx2(x[i])
dif <- abs(x[i+1]-x[i])
i <- i+1
print(x[i])
}
#-----------------------------------------------------------------------------
# trajetória
curve(fx0, 0, 10)
for(j in 2:i){
arrows(x[j-1], fx0(x[j-1]), x[j], fx0(x[j]), length=0.1, col=3)
Sys.sleep(0.5)
}
abline(v=x[i], h=fx0(x[i]), col=2)
# experimente outros valores iniciais, como por exemplo 3 e 8
# para essa última função podemos obter o ponto de máximo analiticamente
#-----------------------------------------------------------------------------