Lista 1
===
Grupo
---
João Vitor Prado
Larissa Toledo
Kaleb Alves
Os enunciados dos 9 exercícios desta lista se encontram [aqui](https://drive.google.com/file/d/1dbnjlY8QjU5KZGxVuSxuQdScI-8ig6B8/view).
[toc]
## Exercício 1
Para resolver esse exercício, foi usado Python (pela facilidade).
```
print(type(s.float_info))
<class 'sys.float_info'>print(s.float_info)
```
Os resultados variam dependendo do ambiente a ser utilizado, se for direto na cpu local, ou em um ambiente online de desenvolvimento, um container...
Porém nesse caso os valores para execução em 4 cores foram:
**Valor máximo para ponto flutuante:** 1.5876231343623122e+308;
**Valor mínimo para ponto flutuante:** 2.1450572185622014e-308;
**$\epsilon$ :** 2.201444591250313e-16
Onde $\epsilon$ é a diferença entre 1 e o menor valor maior que 1 que é representável como um flutuador.
Para avaliar a expressão
$$
(1+x)-1 \over x
$$
O código utilizado foi bem simples
```
x1 = 1e-15
y_esq = ((1 + x1) - 1) / x1
x2 = 1e+15
y_dir = (((1+x2) - 1) /x2)
print ("Erro abs e rel pela esquerda:", abs(1 - y_esq)*100,"%", abs((1 - y_esq) / y_esq)*100,"%")
print ("Erro abs e rel pela direita:", abs(1 - y_dir)*100,"%", abs((1 - y_dir) / y_dir)*100,"%")
print (type(y_abs), type(y_rel))
```
Erro abs e rel pela esquerda: 9.1483214194% 8.4280524792%
Erro abs e rel pela direita: 0.0 % 0.0 %
O erro absoluto é dado pelo modulo da diferença entre o valor esperado da função, que no caso acima é um, menos o valor obtido quando calculado. O erro relativo é obtido através do quociente entre o erro absoluto e o valor esperado.
O mesmo está ligado ao tipo do tamanho máximo da variável, se utilizássemos funções hash ou algo acima de 128 bits, teríamos resultados melhores. E mesmo utilizando bibliotecas do python que extenderiam isso virtualmente, a compressão dos bits ainda não seria fidedigna em grandes escalas.
Em outras linguagens, como Rust, C, Lisp, Haskell, Erlang, Fortran, Assembly, os resultados podem ser bem melhores.
## Exercício 2
Para o segundo exercício, o código a seguir foi utilizado:
```
x = linspace(1-2.e-8, 1+2.-8,401);
y = x.^7 – 7*x.^6 + 21*x.^5 –35*x.^4 +35*x.^3-21*x.^2+7*x-1;
plot(x,y)
```
O resultado foi:

O polinômio em questão nada mais é do que uma expansão de uma expressão:

No intervalo da questão, sabe-se que existe um número infinito de pontos a serem representados. Na teoria, sabemos que esses pontos representam um valor sempre constante para y, no caso y=0. Como não estamos considerando escalas de plotagem (como log), a máquina tenta computar todas as 'combinações' possíveis. Por padrão, vários arredondamentos são feitos, e "erros" são cometidos.
## Exercício 3
```
import math
import pylab
M=[]
M.append((math.e-1)/math.e)
n=0
for i in range(0,21):
M.append(1-(n+1)*I[n])
# print "M%s = %s" %(str(n),str(M[n]))
n=n+1
#print "M%s = %s" %(str(n),str(M[n]))
x=[]
for i in range(0,22):
x.append(i)
pylab.plot(x,M)
pylab.show()
```
para n = 15

para n = 17

Geral (em uma escala maior):

## Exercício 4
```
import random as rd
import matplotlib.pyplot as plt
import math
def estima_pi(n):
m = 0
for i in range(n):
x = rd.uniform(0,1)
y = rd.uniform(0,1)
if (x*x + y*y) <= 1:
m += 1
return 4 * m / n
ns = []
erros = []
for e in range(1,7):
n = 10**e
erro_abs_medio = 0
for _ in range(50):
estimativa = estima_pi(n)
erro_abs_medio += abs(estimativa - math.pi)/50
ns.append(n)
erros.append(erro_abs_medio)
plt.loglog(ns, erros)
plt.xlabel('Número de Amostras / Pontos')
plt.ylabel('Erro Absoluto Médio')
plt.title('Estimando Pi')
plt.plot()
```

## Exercício 5
```
import random as rd
import matplotlib.pyplot as plt
import math
def estima_pi(n):
soma_parcial = 0
for m in range(n + 1):
soma_parcial += 16**(-m)*(4/(8*m + 1) - (2/(8*m + 4)) - (1/(8*m + 5)) - (1/(8*m + 6)))
return soma_parcial
ns = []
erros = []
estimativas = []
achei_n_bom = False
for n in range(10):
estimativa = estima_pi(n)
erro_abs = abs(estimativa - math.pi)
if not achei_n_bom and erro_abs < 10**(-4):
achei_n_bom = True
print("N tal que o erro absoluto foi inferior a 10⁻⁴:", n)
ns.append(n)
estimativas.append(estimativa)
erros.append(erro_abs)
plt.loglog(ns, erros)
plt.xlabel('n')
plt.ylabel('Erro Absoluto')
plt.title('Estimando Pi')
plt.show()
```

## Exercício 6
```
class Main {
public static double bissec(double tolerancia, double[] range)
{
int ite=0;
double a, b, cAnterior, c=0;
double fa, fc;
double epsilon = 1;
a = range[0];
b = range[1];
while(epsilon > tolerancia)
{
ite++;
cAnterior = c;
c = (a + b)/2;
fa = results(a);
fc = results(c);
if(fa*fc<0)
b = c;
else
a = c;
epsilon = Math.abs(c-cAnterior);
}
System.out.println("Iterações: " + ite);
return c;
}
public static double falsepos(double tolerancia, double[] range)
{
int ite=0;
double a, b, cAnterior, c=0;
double fa, fb, fc;
double epsilon = 1;
a = range[0];
b = range[1];
while(epsilon > tolerancia)
{
ite++;
cAnterior = c;
fa = results(a);
fb = results(b);
c = a - (((b-a)*fa) / (fb - fa));
fc = results(c);
if(fa*fc<0)
b = c;
else
a = c;
epsilon = Math.abs(c-cAnterior);
}
System.out.println("Iterações: " + ite);
return c;
}
public static double newton(double tolerancia, double[] range)
{
int ite=0;
double x, x_bf, fx, derx;
double epsilon=1;
x = range[1];
while(epsilon > tolerancia)
{
ite++;
x_bf = x;
fx = results(x);
derx = calcularDerivada(x);
x = x - fx/derx;
epsilon = Math.abs(x-x_bf);
}
System.out.println("Iterações: " + ite);
return x;
}
public static double[] initrange()
{
double[] range = new double[2];
double v = 0;
for(double i=0; v <=0; i+=0.01)
{
range[0] = range[1];
range[1] = i;
v = results(i);
}
return range;
}
public static double results(double a)
{
double l1 = 8;
double l2 = 10;
double y = 3*Math.PI/5;
double fx = l2 * Math.cos(Math.PI - y - a)/Math.pow(Math.sin(Math.PI - y - a), 2) - l1 * Math.cos(a)/Math.pow(Math.sin(a), 2);
return fx;
}
public static double calcularDerivada(double a)
{
double derivada = 8/Math.pow(Math.sin(a), 3) + 10/Math.pow(Math.cos(a + Math.PI/10), 3) + 8/Math.pow(Math.tan(a), 2)/Math.sin(a) + 10*Math.pow(Math.tan(a + Math.PI/10), 2)/Math.cos(a + Math.PI/10);
return derivada;
}
public static void main(String[] args)
{
double tolerancia = 1e-12;
double v;
double[] initrange;
initrange = initrange();
System.out.println("Intervalo: (" + initrange[0] + "," + initrange[1] + ")");
v = bissec(tolerancia, initrange);
System.out.println("Resultado bissecção: " + v);
v = falsepos(tolerancia, initrange);
System.out.println("Resultado falsa posição: " + v);
v = newton(tolerancia, initrange);
System.out.println("Resultado Newton: " + v);
}
}
```
Resultados da execução:
Intervalo: (0.5900000000000003,0.6000000000000003)
Iterações: 34
Resultado bissecção: 0.5962799274659486
Iterações: 5
Resultado falsa posição: 0.5962799274654735
Iterações: 4
Resultado Newton: 0.5962799274654734
## Exercício 7
```
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double x, p1, p2, p = 1;
int f3 = 0, i;
Scanner scan = new Scanner(System.in);
System.out.println("Número de vezes:");
double a = scan.nextDouble();
for (i=0;i>=0;i=i+1) {
p1 = p * (Math.pow(p, 2) + (3 * a));
p2 = (3 * Math.pow(p, 2)) + a;
x = p1 / p2;
System.out.println("Tomando " + i + "x, sqrt =" + x);
if (x - p < 0.01) {
f3 = f3 + 1;
if (f3 > 2) {break;}
}p=x;}}}
```
Resultados:
Tomando 0x, sqrt =2.3333333333333335
Tomando 1x, sqrt =2.9883040935672516
Tomando 2x, sqrt =2.9999999552965173
Tomando 3x, sqrt =3.0
Tomando 4x, sqrt =3.0
Tomando 5x, sqrt =3.0
## Exercício 8
**Bisecção**
(replit)
```
import matplotlib.pyplot as plt
def f(x):
return ((3.5*10**7) + (0.401*((1000/x)**2))) * (x - (1000*42.7*10**-6)) - ((1.3806503*10**-23)*1000*300)
def b(a,b):
c = b
n = 0
X = []
Y = []
while (f(c) > 10**-12) or (f(c) < -(10**-12)):
c = (a+b)/2
if f(c)*f(a) < 0:
b = c
elif f(c)*f(b) < 0:
a = c
n += 1
X.append(n)
Y.append(c)
return c, n, X, Y
a,n,x,y = b(-0.5,1)
print(a,n)
plt.plot(x,y, color='blue')
plt.show()
```

**falsa posição**
```
import matplotlib.pyplot as plt
def f(x):
return ((3.5*10**7) + (0.401*((1000/x)**2))) * (x - (1000*42.7*10**-6)) - ((1.3806503*10**-23)*1000*300)
def fp(a,b):
c = 1
n = 0
X = []
Y = []
while (f(c) > 10**-12) or (f(c) < -(10**-12)):
c = b - ((f(b)*(b-a))/(f(b)- f(a)))
n += 1
X.append(n)
Y.append(c)
if c==a or c==b:
return c, n, X, Y
if f(c)*f(a) < 0:
b = c
elif f(c)*f(b) < 0:
a = c
return c, n, X, Y
a,n,x,y = fp(-0.5,1)
print(a,n)
plt.figure(figsize=(10, 10))
plt.style.use('fivethirtyeight')
plt.axis([-100, x[len(x)-1]+100, min(y)-0.1, max(y)+0.1])
plt.plot(x,y, '-b', color='blue')
plt.show()
```
Valor e interações: 0.04270000000000034 3167
(google colab)

Poderemos notar pelo intervalo [a,b] e pela troca do sinal, o método mostra que sempre pode-se obter um intervalo que satisfaça a precisão requerida.
Para a falsa posição percebemos que o um ponto médio foi obtido, no qual a função do ponto médio é menor que "ℇ", sem que o intervalo seja pequeno o suficiente. O método da falsa posição é bem interessante pois com ele, conseguimos zerar o erro mais rapidamente. O termo $$1 \over V²$$ pode ser considerado um ponto a ser melhorado na questão do erro de arredondamento.
## Exercício 9
Vamos igualar a função = 0
$$(-1 / x^2) + (-1/x^3) - E = 0$$ , onde E é um número negativo.
Plotando a equação com E = 5, temos:

**Método Bisseção**
```
class Main {
public static double f(double x, double E){
return (-1/Math.pow(x, 3)+(-1/Math.pow(x,2))-E);}
public static void main(String[] args) {
double eps=Math.ulp(1.0);
double A=0.5;
double B=1;
double v=0;
if(f(A,-5)*f(B,-5)<=0){
for(int i=0;i<=51;i++){
System.out.println( v);
v= (A+B)/2;
if(Math.abs(B-A)<=eps*Math.max(1, Math.abs(v))){
System.out.println("valor da raiz:" + v);
System.out.println("iterações:" + i);
break;}
else{
if(f(v,-5)*f(A,-5)<=0){B=v;}
else{A=v;}}}}
else{System.out.println("Over");}}}
```
valor da raiz:0.6976285062787816
iterações:51
Caso queira usar um diferente valor para E, basta substituir na expressão (linha 9):
```
if(f(A,-E)*f(B,-E)<=0)
```
**Método falso positivo**
```
class Main {
public static double f(double x, double E){
return (-1/Math.pow(x, 3)+(-1/Math.pow(x,2))-E);}
public static void main(String[] args) {
double A= 0.5;
double B= 0.8;
double V;
int j= 1;
while (j<=10000) {
V = B - f(B,-5)*(B-A)/(f(B,-5)-f(A,-5));
double eps=Math.ulp(1.0);
if (f(V,-5)==0 || Math.abs(V-B)<=eps*Math.max(1, Math.abs(V))) {
System.out.println("raiz: "+V);
System.out.println("iterações: "+j);
break;}
j++;
if (f(V,-5)*f(B,-5)<0) {A=B;}B=V;}
if (j>10000) {System.out.println("n/ convergiu");}}}
```
raiz: 0.6976285062787817
iterações: 46
Testando diversos valores iniciais de E, percebemos que a raíz encontrada para a função aumenta conforme o valor de E diminui. Quando se encontra entre ]-1;0[, retornará uma raíz em x>1, enquanto se tiver valor E<-1, retornará uma raíz x<1.