Nessa semana vamos aprender como o computador avalia funções como \(e^x\), \(\ln(x)\) e \(\mathrm{sen}(x)\). A ideia principal é que o computador faz somente as operações básicas, todo o resto é programado. Na prática o computaodr encontra valores aproximados para \(e^{-1,5}\), \(\ln(0,5)\) ou \(\mathrm{sen}(1)\), e se ele pode fazer isso usando apenas operações básicas nós também podemos.
Resultados de cálculo, que não serão discutidos nesse curso, nos mostram que \[\lim_{n \to \infty} \sum_{i=0}^n \frac{x^i}{i!} = e^x \qquad , \ \forall \ x \in \mathbb{R}.\]
Essa é a Série de Taylor em torno de \(x_0 = 0\) para a função \(f(x) = e^x\). Ou seja, para qualquer \(x \in \mathbb{R}\), se \(n \in \mathbb{N}\) for um número bem grande, \[\sum_{i=0}^n \frac{x^i}{i!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \ldots + \frac{x^n}{n!} \approx e^x.\]
Vale destacar que a convergência é mais rápida para valores de \(x\) próximos de \(x_0=0\). Isso significa que, considerando um número fixo de parcelas na equação acima, quanto mais próximo \(x\) está de zero, mais perto a soma está de \(e^x\). Mas ela acontece qualquer que seja \(x \in \mathbb{R}\), ou seja, mesmo para \(x\) distante de zero a soma converge para \(e^x\) quando o número de parcelas cresce.
Exemplo: Vejamos como podemos usar a Série de Taylor apresentada acima para encontrar uma aproximação para \(e^{-1,5}\), sem a ajuda do computador, usando apenas operações de soma e multiplicação.
Vamos começar encontrando uma aproximação usando \(n=2\): \[e^{-1,5} = e^{-\frac{3}{2}} \approx 1 + \left(-\frac{3}{2}\right) + \frac{\left(-\frac{3}{2}\right)^2}{2!} = 1 - \frac{3}{2} + \frac{9}{8} = \frac{8 - 12 + 9}{8} = \frac{5}{8} = 0,625\]
E se quisermos uma aproximação mais precisa podemos usar um valor maior de \(n\). Vamos ter que fazer um pouco mais de contas, mas teremos uma aproximação melhor. Por exemplo veja a aproximação para \(n=3\). \[e^{-1,5} = e^{-\frac{3}{2}} \approx 1 + \left(-\frac{3}{2}\right) + \frac{\left(-\frac{3}{2}\right)^2}{2!} + \frac{\left(-\frac{3}{2}\right)^3}{3!} = \frac{5}{8} - \frac{9}{16} = \frac{10 - 9}{16} = \frac{1}{16} = 0,062\]
Agora para \(n=4\). \[e^{-1,5} = e^{-\frac{3}{2}} \approx 1 + \left(-\frac{3}{2}\right) + \frac{\left(-\frac{3}{2}\right)^2}{2!} + \frac{\left(-\frac{3}{2}\right)^3}{3!} + \frac{\left(-\frac{3}{2}\right)^4}{4!} = \frac{1}{16} + \frac{27}{128} = \frac{35}{128} \approx 0,2734\]
E para \(n=5\). \[e^{-1,5} = e^{-\frac{3}{2}} \approx 1 + \left(-\frac{3}{2}\right) + \frac{\left(-\frac{3}{2}\right)^2}{2!} + \frac{\left(-\frac{3}{2}\right)^3}{3!} + \frac{\left(-\frac{3}{2}\right)^4}{4!} + \frac{\left(-\frac{3}{2}\right)^5}{5!} = \frac{35}{128} - \frac{81}{1280} = \frac{269}{1280} \approx 0,2101\]
Se usarmos uma calculadora (ou computador) vamos encontrar a seguinte aproximação para \(e^{-1,5}\):
exp(-1.5)
## [1] 0.2231302
Veja que realmente as aproximações calculadas acima melhoraram quando \(n\) cresceu.
Critério de Parada
Se tivermos um computador podemos criar um programa que faça as contas para um valor escolhido de \(n\), e assim conseguimos uma aproximação tão boa quanto a gente quiser. Mas como escolher o valor de \(n\)? Existem alternativas mais sofisticadas que conseguem controlar o erro da aproximação, mas por esse ser um curso introdutório, vamos optar por uma estratégia mais simples.
Vamos usar no mínimo \(n=10\). A partir desse valor de \(n\) calculamos atualizamos a aproximação até que o incremento entre duas aproximações consecutivas, que para esse caso é \(\dfrac{x^n}{n!}\), seja relativamente pequeno.
Veja o seguinte pseudocódigo para encontrar uma aproximação para \(e^x\).
Entrada: x
e delta
.
Saída: uma aproximação para \(e^x\).
Nome: AproxExp
1. Calcule aprox = 1 + x + (x^2)/(2!) + (x^3)/(3!) + ... + (x^10)/(10!).
2. Faça n = 11.
3. Defina incr = (x^n)/(n!).
4. Faça aprox = aprox + incr.
5. Se |incr| < delta, retorne aprox.
6. Faça n = n + 1.
7. Volte para a linha 3.
O pseudocódigo acima simplesmente calcula a série apresentada no início dessa seção até que o incremento da série, definido por incr
, seja menor que o valor atribuído à variável delta
, escolhido pelo usuário e passado como argumento de entrada. Garantimos que isso em algum momento acontece uma vez que \(\frac{x^n}{n!} \xrightarrow[n \to \infty]{} 0\) para todo \(x \in \mathbb{R}\). A escolha do valor delta
é feita pelo usuário. Geralmente se escolhe valores muito pequenos, como por exemplo delta = 0,001
, ou até menores.
Veja que a linha 3 do pseudocódigo acima poderia ser alterada para incr = incr*x/n
. Isso tornaria o código mais eficiente, pois não seria necessário calcular o fatorial em cada iteração do programa. Mas para isso seria necessário garantir que o valor de incr foi inciado em algum momento.
Resultados de cálculo, que não serão discutidos nesse curso, nos mostram que \[\lim_{n \to \infty} \sum_{i=0}^n (-1)^{i}\frac{(x-1)^{i+1}}{i+1} = \ln(x) \quad , \ \forall \ \ 0 < x < 2.\] Essa é a Série de Taylor em torno de \(x_0 = 1\) para a função \(f(x) = \ln(x)\) e só converge para \(0 < x < 2\).
Ou seja, se \(0 < x < 2\), se \(n \in \mathbb{N}\) for um número bem grande, \[\sum_{i=0}^n (-1)^{i}\frac{(x-1)^{i+1}}{i+1} = (x-1) - \frac{(x-1)^2}{2} + \frac{(x-1)^3}{3} - \ldots + (-1)^{n}\frac{(x-1)^{n+1}}{n+1} \approx \ln(x).\]
Vale destacar que a convergência é mais rápida para valores de \(x\) próximos de \(x_0=1\). Isso significa que, considerando um número fixo de parcelas na equação acima, quanto mais próximo \(x\) está de 1, mais perto a soma está de \(\ln(x)\). Mas ela acontece qualquer que seja \(0 < x < 2\), ou seja, a soma converge para \(\ln(x)\) quando o número de parcelas cresce.
Exemplo:
Vejamos como encontrar uma aproximação para \(\ln(0,5)\) sem usar calculadora ou o computador, usando apenas as operações de soma e multiplicação. Para isso vamos usar a Série de Taylor apresentada acima, atribuindo algum valor para \(n\). Quanto maior o valor de \(n\), melhor será a aproximação. Veja como fica a aproximação para \(n=3\). \[\begin{align*} \ln(0,5) = \ln\left(\frac{1}{2}\right) &\approx \left(\frac{1}{2} - 1\right) - \frac{\left(\frac{1}{2} - 1\right)^2}{2} + \frac{\left(\frac{1}{2} - 1\right)^3}{3} - \frac{\left(\frac{1}{2} - 1\right)^4}{4} \\ &= - \frac{1}{2} - \frac{1}{8} - \frac{1}{24} - \frac{1}{64} = \frac{-96 - 24 - 8 - 3}{192} = -\frac{130}{192} \approx - 0,677 \end{align*}\]
E se usarmos o computador vamos encontrar o seguinte valor para \(\ln(0,5)\):
log(0.5)
## [1] -0.6931472
Mas se quisermos o valor de \(\ln(x)\) sendo \(x \ge 2\)? Nesse caso não podemos usar a Série de Taylor substituindo \(x\), pois a convergência só acontece para \(0 < x < 2\). Mas podemos usar uma propriedade dos logaritmos para resolver esse problema. Veja que \[\ln\left(\frac{a}{b}\right) = \ln(a) - \ln(b)\] sempre que \(b \neq 0\). Então, \[\ln\left(\frac{1}{x}\right) = \ln(1) - \ln(x) = -\ln(x) \quad \Rightarrow \quad \ln(x) = - \ln\left(\frac{1}{x}\right).\] Além disso, se \(x > 2 \ \Rightarrow \ 0 < \frac{1}{x} < 2\), logo podemos usar a Série de Taylor para encontrar uma aproximação para \(\ln\left(\frac{1}{x}\right)\). Resumindo, se precisamos encontrar \(\ln(x)\) para \(x>2\), então vamos primeiro encontrar uma aproximação para \(\ln\left(\frac{1}{x}\right)\) e depois multiplicar por -1, que temos então uma aproximação para \(\ln(x)\). Veja um exemplo.
Exemplo:
Encontre uma aproximação para \(\ln(3)\) usando a Série de Taylor com \(n=3\). \[\begin{align*} \ln(3) &= - \ln\left(\frac{1}{3}\right) \approx - \left( \left(\frac{1}{3} - 1\right) - \frac{\left(\frac{1}{3} - 1\right)^2}{2} + \frac{\left(\frac{1}{3} - 1\right)^3}{3} - \frac{\left(\frac{1}{3} - 1\right)^4}{4} \right)\\ &= -\left( - \frac{2}{3} - \frac{2}{9} - \frac{8}{81} - \frac{16}{324} \right) = \frac{216 + 72 + 32 + 16}{324} = \frac{336}{324} \approx 1,037 \end{align*}\]
Usando a calculadora chegamos na seguinte aproximação para \(\ln(3)\):
log(3)
## [1] 1.098612
Veja no pseudocódigo a seguir como fica o algoritmo para encontrar uma aproximação para \(\ln(x)\). O critério de parada é o mesmo adotado na aproximação da exponencial: o algoritmo começa com \(n=10\) e depois incrementa \(n\) até encontrar duas aproximações consecutivas tais que a diferença é menor que o valor de delta
definido pelo usuário.
Entrada: x
e delta
.
Saída: uma aproximação para \(\ln(x)\).
Nome: AproxLn
1. Se x <= 0, pare e retorne uma mensagem de erro.
2. Se x >= 2, retorne -AproxLn(1/x,delta).
3. Calcule aprox = (x-1) - ((x-1)^2)/2 + ((x-1)^3)/3 - ... + ((-1)^10)*((x-1)^11)/11.
4. Faça n = 11.
5. Defina incr = ((-1)^(n))*((x-1)^(n+1))/(n+1)
6. Faça aprox = aprox + incr.
7. Se |incr| < delta, retorne aprox.
8. Faça n = n + 1.
9. Volte para a linha 5.
Veja que a linha 5 poderia ser alterada para incr = -incr*(x-1)*(n-1)/n
. Isso tornaria o código mais eficiente. Mas para isso seria necessário garantir que o valor de incr foi inciado em algum momento.
Resultados de cálculo, que não serão discutidos nesse curso, nos mostram que \[\lim_{n \to \infty} \sum_{i=0}^n (-1)^{i}\frac{x^{2i+1}}{(2i+1)!} = \mathrm{sen}(x) \quad , \ \forall \ \ x \in \mathbb{R}.\] Essa é a Série de Taylor em torno de \(x_0 = 0\) para a função \(f(x) = \mathrm{sen}(x)\).
Ou seja, para qualquer \(x \in \mathbb{R}\), se \(n \in \mathbb{N}\) for um número bem grande, \[\sum_{i=0}^n (-1)^{i}\frac{x^{2i+1}}{(2i+1)!} = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \ldots + (-1)^{n}\frac{x^{2n+1}}{(2n+1)!} \approx \mathrm{sen}(x)\]
Vale destacar que a convergência é mais rápida para valores de \(x\) próximos de \(x_0 = 0\). Isso significa que, considerando um número fixo de parcelas na equação acima, quanto mais próximo \(x\) está de 0, mais perto a soma está de \(\mathrm{sen}(x)\). Mas ela acontece qualquer que seja \(x \in \mathbb{R}\), ou seja, a soma sempre converge para \(\mathrm{sen}(x)\) quando o número de parcelas cresce.
Atenção: o argumento da função \(\mathrm{sen}\) é a medida do ângulo em radianos. Dessa forma, \(\mathrm{sen}\) é uma função periódica com período de tamanho \(2\pi\).
Exemplo:
Vejamos como encontrar uma aproximação para \(\mathrm{sen}(1)\) sem usar calculadora ou computador, usando apenas as operações de soma e multiplicação. Para isso vamos usar a Série de Taylor definifa acima com \(n=4\). \[\mathrm{sen}(1) \approx 1 - \frac{1^3}{3!} + \frac{1^5}{5!} - \frac{1^7}{7!} + \frac{1^9}{9!} = 1 - \frac{1}{6} + \frac{1}{120} - \frac{1}{5.040} + \frac{1}{362.880} = 0,8414710\]
Se usarmos o computador vamos encontrar a seguinte aproximação para \(\mathrm{sen}(1)\):
sin(1)
## [1] 0.841471
Veja que com \(n=4\) já temos uma aproximação excelente. Isso se deve ao fato de que \(1\) está razoavelmente próximo de zero. Provavelmente a aproximação não seria tão boa com \(n=4\) para encontrar \(\mathrm{sen}(10)\). Mas podemos aproveitar a periodicidade da função seno e aumentar a velocidade de convergência mesmo para valores de \(x\) longe de zero. Veja um outro exemplo.
Exemplo:
Usando o computador encontramos a seguinte aproximação para \(\mathrm{sen}(10)\):
sin(10)
## [1] -0.5440211
Vamos tentar encontrar esse valor na mão. Primeiro a partir da Série de Taylor em torno de \(x_0 = 0\) para a função \(f(x) = \mathrm{sen}(x)\) usando \(n=4\) e \(x=10\). \[\begin{align*} \mathrm{sen}(10) &\approx 10 - \frac{{10}^3}{3!} + \frac{{10}^5}{5!} - \frac{{10}^7}{7!} + \frac{{10}^9}{9!} \\ &= 10 - \frac{1.000}{6} + \frac{100.000}{120} - \frac{10.000.000}{5.040} + \frac{1.000.000.000}{362.880}\\ &\approx -1307,46. \end{align*}\]
Com \(n=4\) chegamos numa aproximação muito ruim, precisaríamos muito mais parcelas para chegar perto do valor correto de \(\mathrm{sen}(10)\).
Veja que, pela periodicidade da função seno, \(\mathrm{sen}(10) = \mathrm{sen}(10 - 2\pi) \approx \mathrm{sen}(3,716815)\). E como 3,716815 está mais perto de zero do que 10, provavelmente a aproximação será melhor usando o mesmo valor de \(n\). Vamos às contas. \[\begin{align*} \mathrm{sen}(10) & = \mathrm{sen}(10 - 2\pi) \approx \mathrm{sen}(3,716815) \\ &\approx 3,716815 - \frac{{3,716815}^3}{3!} + \frac{{3,716815}^5}{5!} - \frac{{3,716815}^7}{7!} + \frac{{3,716815}^9}{9!} \\ &\approx -0,6397173. \end{align*}\]
Veja como já melhorou! Mas ainda podemos melhorar mais, pois \(10 - 2\pi - 2\pi = -2,566371\) está ainda mais perto de zero. \[\begin{align*} \mathrm{sen}(10) & = \mathrm{sen}(10 - 2\pi - 2\pi) \approx \mathrm{sen}(-2,566371) \\ &\approx -2,566371 - \frac{{-2,566371}^3}{3!} + \frac{{-2,566371}^5}{5!} - \frac{{-2,566371}^7}{7!} + \frac{{-2,566371}^9}{9!} \\ &\approx -0,5482006. \end{align*}\]
O exemplo acima nos mostra que aproveitar a periodicidade da função seno e escolher valores próximos de zero para serem aplicados na Série de Taylor garante uma melhor convergência com menos parcelas. Esse mecanismos será aplicado no pseudocódigo a seguir. Veja no pseudocódigo a seguir como fica o algoritmo para encontrar uma aproximação para \(\mathrm{sen}(x)\).
Entrada: x
e delta
.
Saída: uma aproximação para \(\mathrm{sen}(x)\).
Nome: AproxSeno
1. Se x > pi, retorne AproxSeno(x - 2*pi,delta).
2. Se x < -pi, retorne AproxSeno(x + 2*pi,delta).
3. Calcule aprox = x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + ... + ((-1)^(10))*(x^(2*10 + 1))/((2*10 + 1)!).
4. Faça n = 11.
5. Defina incr = ((-1)^(n))*(x^(2*n + 1))/((2*n + 1)!)
6. Faça aprox = aprox + incr.
7. Se |incr| < delta, retorne aprox.
8. Faça n = n + 1.
9. Volte para a linha 5.
Veja que a linha 5 poderia ser alterada para incr = -incr*(x^2)/(n*(n+1))
. Isso tornaria o código mais eficiente, pois não seria necessário calcular o fatorial em cada iteração do programa. Mas para isso seria necessário garantir que o valor de incr foi inciado em algum momento.