Você está na página 1de 14

Cálculo Numérico

Beatriz Brum
September 24, 2019

1 Fase II: Refinamento


2 Método das Secantes

Uma das desvantagens no método de Newton é a neces-


sidade de se obter f 0 (x) e calcular seu valor numérico a
cada iteração.

f (xi )
xi+1 = xi − (1)
f 0 (xi )

Figure 1: Ilustração geométrica do método de Newton-Raphson.

A aproximação da derivada é dada por:

1
f (xi ) − f (xi−1 )
f 0 (xi ) = (2)
xi − xi−1
Substituindo (2) em (1) obtemos o método das se-
cantes (3):

f (xi )(xi − xi−1 )


xi+1 = xi − (3)
f (xi ) − f (xi−1 )
O Método das Secantes também pode ser derivado ge-
ometricamente, a partir de triângulos semelhantes.

Figure 2: Ilustração geométrica do Método de Secante.

AB DC
= (4)
AE DE
sendo escrito como

f (xi ) f (xi−1 )
= (5)
xi − xi+1 xi−1 − xi+1
2
organizando 5 temos o Método das Secantes.

f (xi )(xi − xi−1 )


xi+1 = xi − (6)
f (xi ) − f (xi−1 )

2.1 Algoritmo para o Método

1o Passo
Calcule uma estimativa da raiz a partir de duas su-
posições iniciais.

f (xi )(xi − xi−1 )


xi+1 = xi −
f (xi ) − f (xi−1 )
Encontre o erro relativo da aproximação.

xi+1 − xi
ERxi+1 = | |
xi+1
2o Passo
Descubra se o erro relativo da aproximação é maior
que a tolerância, ou o erro pé-especificado.
Nesse caso, se maior, volte ao 1o Passo, caso contrário
pare o algoritmo.
Verifique também se o número de iterações excedeu o
número máximo de iterações.

3
2.2 Exemplo 1

Encontre as raı́zes de f (x) = cos(x).


Um esboço rápido do gráfico de f (x) = cos(x) irá
ajudá-lo a obter uma escolha razoável.

4
curve( cos(x), col='blue', lwd=2, lty=2, xlim=c(-1,4))
abline(h=0)
abline(v=0)
1.0
0.5
cos(x)

0.0
−0.5
−1.0

−1 0 1 2 3 4

É possı́vel verificar que esta equação possui uma raiz


em torno de x0 = 0 e x1 = 3.
Ao plotar uma linha secante usando os valores iniciais
fornecidos acima. Resolva a equação dos pontos forneci-
dos para encontrar o valor y associado aos pontos de
partida.
f <- function(x){cos(x)}
x0 <- 0
x1 <- 3
f(x0)

[1] 1

f(x1)

[1] -0.9899925

Desenhe a linha secante usando os pontos determina-


dos.
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(-1,4))
abline(h=0)
abline(v=0)
points(x0, f(x0), cex=1.25, pch=21, bg='blue', col='blue')
points(x1,f(x1), cex=1.25, pch=21, bg='blue', col='blue')
segments(x0, f(x0), x1,f(x1), col='magenta', lwd = 2)

5
1.0
0.5
cos(x)

0.0
−0.5
−1.0

−1 0 1 2 3 4

f (x1 )(x1 − x0 )
x2 = x1 −
f (x1 ) − f (x0 )
(−0.9899925)(3 − 0)
x2 = 3− = 1.507543
(−0.9899925) − (1)

x2 <- x1 - f(x1)/((f(x1)-f(x0))/(x1-x0));x2

[1] 1.507543

A reta secante cruza o eixo x em x2 = 1.507543, onde


o erro relativo dessa estimativa em relação a anterior,
x1 = 3, é:
(1.507 − 3)
ERx2 = | | = 0.99071
1.507
ERx2 = 0.99071 > 10−2
ERx2 > 10−2

O erro relativo é superior a tolerância especificada, por-


tanto ainda não é uma boa aproximação da raiz de f (x) =
cos(x).

6
abs((1.507-3)/1.507)

[1] 0.99071

ifelse(abs((1.507-3)/1.507)>10^(-2),"Erro > 0.01, Continue iterando", "Pare")

[1] "Erro > 0.01, Continue iterando"

A linha secante cruza o eixo x próximo de onde a raiz


da função existe.
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(1.3,3.5))
abline(h=0)
abline(v=0)
points(x1, f(x1), cex=1.25, pch=21, bg='blue', col='blue')
points(x2,f(x2), cex=1.25, pch=21, bg='blue', col='blue')
segments(x1, f(x1), x2, f(x2), col='magenta', lwd = 2)
0.2
−0.2
cos(x)

−0.6
−1.0

1.5 2.0 2.5 3.0 3.5

Sabendo que x1 = 3 e x2 = 1.507543 podemos de-


terminar uma nova aproximação, então x3 . Verifique
que de fato existe pelo menos uma raiz no intervalo de
[1.507543, 3].
f(x0) # x0=0

[1] 1

f(x1) # x1=3

[1] -0.9899925

f(x2) # x2=1.507543

[1] 0.06321078

7
Desenhe a linha secante usando os pontos os pontos
do intervalo [1.507543, 3].
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(1,3.5))
abline(h=0)
abline(v=0)
points(x1, f(x1), cex=1.25, pch=21, bg='blue', col='blue')
points(x2,f(x2), cex=1.25, pch=21, bg='blue', col='blue')
segments(x1, f(x1), x2,f(x2), col='magenta', lwd = 2)
0.5
0.0
cos(x)

−0.5
−1.0

1.0 1.5 2.0 2.5 3.0 3.5

f (x2 )(x2 − x1 )
x3 = x2 −
f (x2 ) − f (x1 )
(0.06321078)(1.507543 − 3)
x3 = 1.507543 − = 1.597117
(0.06321078) − (−0.9899925)

x3 <- x2 - f(x2)/((f(x2)-f(x1))/(x2-x1));x3

[1] 1.597117

A reta secante cruza o eixo x em x3 = 1.597117, onde


o erro relativo dessa estimativa em relação a anterior,
x2 = 1.507, é:
(1.597117 − 1.507)
ERx3 = | | = 0.0564248
1.597117
ERx3 = 0.0564248 > 10−2

8
ERx3 > 10−2

O erro relativo é superior a tolerância especificada, por-


tanto ainda não é uma boa aproximação da raiz de f (x) =
cos(x).
abs((1.597117-1.507)/1.597117)

[1] 0.0564248

ifelse(abs((x3-x2)/x3)>10^(-2),"Erro > 0.01, Continue iterando", "Pare")

[1] "Erro > 0.01, Continue iterando"

A linha secante cruza o eixo x próximo de onde a raiz


da função existe.
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(1.3,3.5))
abline(h=0)
abline(v=0)
points(x2, f(x2), cex=1.25, pch=21, bg='blue', col='blue')
points(x3,f(x3), cex=1.25, pch=21, bg='blue', col='blue')
segments(x2, f(x2), x3, f(x3), col='magenta', lwd = 2)
0.2
−0.2
cos(x)

−0.6
−1.0

1.5 2.0 2.5 3.0 3.5

Sabendo que x2 = 1.507543 e x3 = 1.597117 podemos


determinar uma nova aproximação, então x4 . Verifique
que de fato existe pelo menos uma raiz no intervalo de
[1.507543, 1.597117].

9
f(x2) # x2=1.507543

[1] 0.06321078

f(x3) # x3=1.597117

[1] -0.02631774

Desenhe a linha secante usando os pontos os pontos


do intervalo [1.507543, 1.597117].
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(1,3.5))
abline(h=0)
abline(v=0)
points(x2, f(x2), cex=1.25, pch=21, bg='blue', col='blue')
points(x3,f(x3), cex=1.25, pch=21, bg='blue', col='blue')
segments(x2, f(x2), x3,f(x3), col='magenta', lwd = 2)
0.5
0.0
cos(x)

−0.5
−1.0

1.0 1.5 2.0 2.5 3.0 3.5

f (x3 )(x3 − x2 )
x4 = x3 −
f (x3 ) − f (x2 )
(−0.02631774)(1.597117 − 1.507543)
x4 = 1.597117 − = 1.570786
(−0.02631774) − (0.06321078)

x4 <- x3 - f(x3)/((f(x3)-f(x2))/(x3-x2));x4

[1] 1.570786

A reta secante cruza o eixo x em x3 = 1.597117, onde


o erro relativo dessa estimativa em relação a anterior,

10
x3 = 1.507, é:
(1.570786 − 1.597117)
ERx4 = | | = 0.01676295
1.570786
ERx4 = 0.01676295 > 10−2
ERx4 > 10−2

O erro relativo é superior a tolerância especificada, por-


tanto ainda não é uma boa aproximação da raiz de f (x) =
cos(x).
abs((1.570786-1.597117)/1.570786)

[1] 0.01676295

ifelse(abs((x4-x3)/x4)>10^(-2),"Erro > 0.01, Continue iterando", "Pare")

[1] "Erro > 0.01, Continue iterando"

A linha secante cruza o eixo x próximo de onde a raiz


da função existe.
curve(cos(x), col='blue', lwd=2, lty=2, xlim=c(1.5,1.65))
abline(h=0)
abline(v=0)
points(x3, f(x3), cex=1.25, pch=21, bg='blue', col='blue')
points(x4,f(x4), cex=1.25, pch=21, bg='blue', col='blue')
segments(x3, f(x3), x4, f(x4), col='magenta', lwd = 2)
0.05
cos(x)

0.00
−0.05

1.50 1.55 1.60 1.65

Sabendo que x3 = 1.597117 e x4 = 1.570786 podemos


determinar uma nova aproximação, então x4 . Verifique

11
que de fato existe pelo menos uma raiz no intervalo de
[1.507543, 1.597117].

Implementação do método no R
f <- function(x){cos(x)}

Fazer com que o processo se repita n vezes.


x0 <- 0
x1 <- 3
n <- 0
eps <- 0.01
for(i in 1:4){
n <- n+1
f0 <- f(x0)
f1 <- f(x1)
m <- (f1-f0)/(x1-x0)
x2 <- x1-(f1/m)# Determinando uma nova aproximaç~ao
# Se o Erro relativo for menor que a toler^ ancia
if(abs((x2-x1)/x2) < eps){
return(x2)
}
#Se a raiz n~ao foi determinada na iteraç~
ao anterior, atualize
# os valores e prossiga para a próxima iteraç~
ao.
x0 <- x1
x1 <- x2
print(paste("Iteraç~
ao", n, "Raiz", x0))
}

[1] "Iteraç~
ao 1 Raiz 3"
[1] "Iteraç~
ao 2 Raiz 1.5075433727137"
[1] "Iteraç~
ao 3 Raiz 1.59711710957145"

12
secant<- function(f, x0, x1, eps = 1e-1, n = 500) {
for (i in 1:n) {
x2 <- x1 - f(x1) / ((f(x1) - f(x0)) / (x1 - x0)) # Calculate the new x value
if (abs((x2 - x1)/x2) < eps) {
return(x2)
}
# Se a raiz n~
ao foi determinada na iteraç~
ao anterior,
#atualize os valores e prossiga para a próxima iteraç~
ao.
x0 <- x1
x1 <- x2
}
}

secant(f, 0, 3)

[1] 1.597117

Exercı́cios
1) Encontre as raı́zes de f (x) = cos(x)−x, pelo método
da secante.
2) Encontre as raı́zes do polinômio f (x) = x4 − 4x2 + 4
através do método de Newton e da secante . Realize duas
iterações na mão referente a cada método. Determine
qual é melhor.
f <- function(x){x^4 - 4*x^2 + 4}
x0 <- 0
x1 <- 3
n <- 0
eps <- 0.01
for(i in 1:4){
n <- n+1
f0 <- f(x0)
f1 <- f(x1)
m <- (f1-f0)/(x1-x0)
x2 <- x1-(f1/m)# Determinando uma nova aproximaç~ao
# Se o Erro relativo for menor que a toler^ ancia
if(abs((x2-x1)/x2) < eps){
return(x2)
}
#Se a raiz n~ao foi determinada na iteraç~
ao anterior, atualize
#os valores e prossiga para a próxima iteraç~
ao.
x0 <- x1
x1 <- x2
print(paste("Iteraç~
ao", n, "Raiz", x0))
}

[1] "Iteraç~
ao 1 Raiz 3"
[1] "Iteraç~
ao 2 Raiz -0.266666666666667"
[1] "Iteraç~
ao 3 Raiz -0.535089031871914"
[1] "Iteraç~
ao 4 Raiz -1.54065257973621"

Criando uma função.

13
secant<- function(f, x0, x1, eps = 1e-9, n = 500) {
for (i in 1:n) {
x2 <- x1 - f(x1) / ((f(x1) - f(x0)) / (x1 - x0)) # Calculate the new x value
if (abs((x2 - x1)/x2) < eps) {
return(x2)
}
# Se a raiz n~
ao foi determinada na iteraç~
ao anterior,
#atualize os valores e prossiga para a próxima iteraç~
ao.
x0 <- x1
x1 <- x2
}
}

secant(f, 0, 3)

[1] -1.414214

14

Você também pode gostar