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: ![](https://i.imgur.com/7NaUA4V.png) O polinômio em questão nada mais é do que uma expansão de uma expressão: ![](https://i.imgur.com/d6IOwgO.png) 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 ![](https://i.imgur.com/cCXkT96.png) para n = 17 ![](https://i.imgur.com/59nzRsx.png) Geral (em uma escala maior): ![](https://i.imgur.com/NL2Qgdj.png) ## 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() ``` ![](https://i.imgur.com/ZclouAH.png) ## 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() ``` ![](https://i.imgur.com/CrbfTWO.png) ## 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() ``` ![](https://i.imgur.com/vbR8ueC.png) **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) ![](https://i.imgur.com/ewTHYOV.png) 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: ![](https://i.imgur.com/9rhmKnH.png) **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.