https://www.programiz.com/python-programming/online-compiler/
html https://www.programiz.com/python-programming/online-compiler/
# Exemplo de programa Python - Linhas que começam por # são comentários
#
# O Python é interpretado. Voçê vai escrevendo e ele vai calculando.
# Ex. vamos testar. Escreva
1+2
3*2
3**2
# O programa começa normalmente por importar pacotes
# como o comando 'import'
# Vamos importar o pacote "math", com um monte de funções matemáticas:
emport math
# vamos calcular o seno de pi/4:
math.sin(math.pi/4)
# NOTE que voce teve que usar "math.sin" e "math.pi" isso é porque em Python, o
# nome do módulo sempre vem antes da função em que o módulo está.
# Se sin, ou pi são muito usados, voce pode melhorar a situação:
del math # Primeiro temos que apagar "math" da memória
from math import sin,pi
sin(pi/4)
# Agora vamos criar funções:
def quadrado(x):
y = x**2
return y
quadrado(3)
# MUITO IMPORTANTE: Python usa MARGENS para definir um bloco de programa.
# No exemplo acima, a o corpo da função 'quadrado' só tem duas linhs.
# Vamos fazer um "loop" - um pedaço de programa que se repete:
for ii in [1,2,3,4,5]:
q = quadrado(ii)
print([ii, q])
# Note a sintaxe: for "var" in "faixa de valores":
# Novamente o bloco que se repete é determinado pela MARGEM do texto.
# Condicionais: if-then-else.
# Vamos fazer um programa que intere entre os números 1,2,3,4,5 (como acima) mas se
# o número for menor que 1,2 ou 3 vamos calcular o cubo ou invés do quadrado:
for ii in [1,2,3,4,5]:
if ii<=3:
q = ii**3
print([ii, q])
print('Cubo')
else:
q = quadrado(ii)
print([ii, q])
print('Quadrado')
#
\[ e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \dots + \frac{x^n}{n!} + \dots, \]
que é uma série infinita. O computador para em algum ponto, por exemplo, no termo \(n\):
\[ e^x = \underbrace{1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \dots + \frac{x^n}{n!}}_{\text{parte que o computador calcula}} + \underbrace{\frac{x^{n+1}}{(n+1)!}+ \frac{x^{n+2}}{(n+2)!} \dots}_{\text{parte que falta!}} = \] \[ e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \dots + \frac{x^n}{n!} + O(x^{n+1}), \] o termo \(O(x^{n+1})\) diz que tudo o que está para a direita é da ordem de \(x^{n+1}\) ou maior, e é o erro de truncagem.
# Exemplo de cálculo de Erro de Truncagem
# Importa o pacote 'math'
import math
# Declara a função exata (fe) que vamos usar: aqui a exponencial (math.exp)
def fe(x):
return math.exp(x)
# Declara a função truncada (ft), ou seja, apenas os 'n' primeiros
# termos da série de Taylor da função exponencial:
# 1+x+x^2/2+...+x^n/n!
# Esta função tem 2 argumentos, o valor 'x' e o número de termos que vamos manter.
def ft(x,n):
val=0
for ii in range(0,n+1):
val = val + x**ii/math.factorial(ii);
return val
# Função principal
def main():
# Número de termos
print("Demonstração do erro de truncamento - função: exp(1)")
print("%18s%18s%18s%18s"%('Ordem','Valor Exato','Valor Aprox','Erro de Truncagem'))
for nt in range(0,5+1):
# print([nt,fe(1),ft(1,nt),(ft(1,nt)-fe(1))/fe(1)])
print("%18.6g%18.6g%18.6g%18.6e"%(nt,fe(1),ft(1,nt),(ft(1,nt)-fe(1))/fe(1)))
# main
# fim
html https://www.programiz.com/python-programming/online-compiler/
Você calculou: o valor de \(e^1=2,71828...\), o valor da aproximação dependendo da truncagem, e o erro relativo: \[\epsilon = \frac{f_t - f_e}{f_e} .\]
Você deve obter algo do gênero:
Demonstração do erro de truncamento - função: exp(1)
Ordem Valor Exato Valor Aprox Erro de Truncagem
0 2.71828 1 -6.321206e-01
1 2.71828 2 -2.642411e-01
2 2.71828 2.5 -8.030140e-02
3 2.71828 2.66667 -1.898816e-02
4 2.71828 2.70833 -3.659847e-03
5 2.71828 2.71667 -5.941848e-04
Quanto mais termos na série são acrescentados, mais próximo o valor truncado se aproxima do valor real. Note que o erro de truncágem começa com 63%, passa para 26%, 8%, 1.9%, 0.37%, 0.0059% (vai caindo).
É importante saber se o erro de truncagem existe e pode ser grande.
Normalmente este erro não é relevante para o cálculo de funções, mas será crucial quando se resolve equações diferenciais.
\[ f(x) = \arctan(x),\] para \(x=1\). Matematicamente \(\arctan(1)=\pi/4 = 0,785398...\). A Série de Taylor da função arco-tangente é:
\[ \arctan(x) = x - \frac{x^3}{3} + \frac{x^5}{5} - \dots (-1)^{\frac{n-1}{2}}\frac{x^n}{n} \dots, \] ou seja, o n-ésimo termo tem a forma: \[ \text{termo n} = (-1)^{\frac{n-1}{2}}\frac{x^n}{n}. \]
Importante:
fe(x)
, mude math.exp
para math.atan
.ft(x)
,
range
é usada assim:# Gera valores começando em valor_inicial, e indo enquanto os valores forem MENORES que o valor_superior, indo de "passo" em passo.
range(valor_inicial, valor_superior, passo)
# Por exemplo, se você quiser gerar 1,3 e 5, faça
range(1,6,2)
\[ f'(x) = \lim_{h\rightarrow 0}\frac{f(x+h)-f(x)}{h}. \]
No entanto o computador não vai calcular o limite exato, e sim uma aproximação, calculando a fração para um valor \(h\) pequeno.
Para sabermos o erro de truncagem, devemos expandir o termo \(f(x+h)\) na sua série de Taylor.
A Série de Taylor é a série infinita:
\[ f(x+h) = f(x) + f'(x)h + \frac{f''(x)}{2!}h^2 + \frac{f'''(x)}{3!}h^3 + \dots .\]
Substituindo esta expressão na definição da derivada, temos:
\[ f'(x) = \lim_{h\rightarrow 0}\frac{f(x) + f'(x)h + \frac{f''(x)}{2!}h^2 + \frac{f'''(x)}{3!}h^3 + \dots-f(x)}{h}. \]
No numerador (em cima) o primeiro termo cancela com o último, e assim
\[ f'(x) = \lim_{h\rightarrow 0}\left(f'(x) + \frac{f''(x)}{2!}h + \frac{f'''(x)}{3!}h^2 + \dots\right). \]
Como o computador não vai tomar o limite e sim usar um valor \(h\) pequeno, a “derivada numérica” \(f'_h(x)\)terá um erro:
\[ f'_h(x) = f'(x) + \underbrace{\frac{f''(x)}{2!}h + \frac{f'''(x)}{3!}h^2 + \dots}_{\text{Erro de truncagem adicionado à derivada.}},\] ou \[ f'_h(x) = f'(x) + O(h).\]
Vamos testar numericamente este erro de truncage das derivadas. Vamos usar a função \(f(x)=\cos(x)\) como função teste. Sabemos que \(f'(x) = -\sin(x)\). Vamos escolher o ponto \(x=60^o = \pi/3\), onde \(\cos(60)=0.5\) e \(\sin(60)=-\sqrt{3}/2\).
O programa abaixo calcula o valor aproximado de \(f'_h(x)\) para vários valores de \(h\). Se tudo estiver certo, o valor do ERRO deve ir diminuindo linearmente com o valor de \(h\).
# Exemplo de cálculo de Erro de Truncagem
# Importa o pacote 'math'
import math
# Declara a função exata (fe) que vamos usar: cosseno
def fe(x):
return math.cos(x)
# Declara a derivada exata da função (df): -seno
def df(x):
return -math.sin(x)
# Declara a derivada numérica:
# f'_h(x) = (f(x+h)-f(x))/h
def dfh(x,h):
return (fe(x+h) - fe(x))/h
# Função principal
def main():
# Número de termos
print("Demonstração do erro de truncamento da Derivada de Primeira Ordem")
# Declara os valores de h a serem testados
# Vamos fazer decrescentes para irmos vendo a redução do erro de truncagem.
lista_h = [1, 0.1, 0.01, 0.001, 0.0001]
# Valor de x
x = math.pi/3;
print("%18s%18s%18s%18s"%('h','df','df_h','Erro de Truncagem'))
for h in lista_h:
print("%18.6g%18.6g%18.6g%18.6e"%(h,df(x),dfh(x,h),(dfh(x,h)-df(x))))
# main
# fim
Demonstração do erro de truncamento da Derivada de Primeira Ordem
h df df_h Erro de Truncagem
1 -0.866025 -0.958584 -9.255869e-02
0.1 -0.866025 -0.889562 -2.353652e-02
0.01 -0.866025 -0.868511 -2.485545e-03
0.001 -0.866025 -0.866275 -2.498556e-04
0.0001 -0.866025 -0.86605 -2.499856e-05
Aqui fomos reduzindo o valor de \(h\) por fatores de 10. O valor da derivada numérica comessa com um erro de 9.3%, depois passa para 2.4%, uma pequena redução, mas logo em seguinda vai para 0.2%, depois 0.02%, depois 0.002%.
Ou seja quando \(h\) é menor que 0.1, o erro vai caindo de fatores de 10 tambem! Aqui dizemos que estamos no regime de convergência, neste caso linear.
A Fórmula da derivada utilizada acima é chamada de “derivada de primeira ordem” porque o Erro é linear com \(h\). Existem inúmeras outras fórmulas que diminuem o erro. A mais comum é:
\[ f'_h(x) = \frac{f(x+h) - f(x-h)}{2h}.\]
Esta fórmula garante que o erro de truncagem é do tipo \(O(h^2)\), ou seja, cai quadraticamente com \(h\).
Prove que o erro é da forma \(O(h^2)\). Utilizando o mesmo procedimento usado acima, porém trocando a série de Taylor em ambos os termos da diferença na derivada. Note que o segundo termo é \(f(x-h\)).
Modifique o programa acima para calcular o erro de truncagem desta derivada numérica. Basta modificar a função dfh(x)
apropriadamente.
A representação interna de números em computadores digitais é feita na base binária. Vamos defini-la comparando com a base decimal.
A base decimal usa os dígitos 0,1,2,3,4,5,6,7,8 e 9 para representar os números, e cada casa decimal apresenta este número multiplicado por uma potência de 10. Por exemplo, o número 3487 significa:
ou
\[ 3487 = 3\times 10^3 + 4\times 10^2 + 8\times 10^1 + 7\times 10^0.\]
Similarmente, um número binário é definido utilizando-se apenas os dígitos 0 e 1, e cada “casa binária” é multiplicada por uma potência de 2:
ou
\[ 1001 = 1\times 2^3 + 0\times 2^2 + 0\times 2^1 + 1\times 2^0 = 9_{10},\]
onde, quando necessário utilizaremos o subscrito \(x_{2}\) ou \(x_{10}\) para indicar a base numérica.
Cada dígito binário chama-se bit, e convencionou-se que 8 bits formam um byte (pronúncia “bait”).
Para se converter de uma base menor para uma maior é feito como acima, basta escrever a definição do número binário em decimal. Para a conversão oposta, é preciso fazer uma divisão por 2 em cadeia e guardar o resto das divisões, por exemplo:
\[ 15/2 = 7 \text{ - resta } 1 \text{ (1o dígito - bit 4)},\\ 7/2 = 3 \text{ - resta } 1 \text{ (2o dígito - bit 3)},\\ 3/2 = 1 \text{ - resta } 1 \text{ (3o dígito - bit 2)},\\ 1 \text{ (4o dígito - bit 1)} ,\]
e o número binário é então \(1111_{2}\).
NOTE: o bit mais a esquerda (menos significativo) recebe é o primeiro bit (bit 1), o segundo mais a esquerda é o bit 2, etc… Em um byte, o bit mais significativo é o bit 8.
Calcule todas as potências de 2 entre 0 e 10 (ou seja \(2^0\), \(2^1\), \(2^2\), até \(2^{10}\)). Voce deve memorizar essa sequência.
Expresse em binário os números 3, 7, 9, 15, 17, 30, 33, 127, 128, 255, 256. Informe quantos bits tem cada resultado.
Calcule em decimal os números binários: 101, 1001, 1010, 1100101, 10001000, 11111111.
Números inteiros (tanto \(\mathbb N\) quanto \(\mathbb Z\)) são simplesmente representados como na seção acima, mas obedecem algumas restrições.
Por exemplo, se uma máquina representa inteiros utilizando 1 byte = 8bits, ele pode representar os números de 0 (\(00000000_{b}\)) até 255 (\(11111111_{b}\)). Nada maior ou menor pode ser representado.
Para a representação de números negativos, o sinal também tem que ser armazenado, e como ele é ou \(+\) ou \(-\), então 1 bit é suficiente. Logo, utiliza-se o bit 8 para tal. Desta forma temos apenas 7 bits para representar um número. O esquema mais usado é :
\[ 00000000_2 = 0,\\ 00000001_2 = 1,\\ 00000010_2 = 2,\\ \vdots\\ 01111110_2 = 126,\\ 01111111_2 = 127,\\ 10000000_2 = -1,\\ 10000001_2 = -2,\\ 10000010_2 = -3,\\ \vdots\\ 11111110_2 = -127,\\ 11111111_2 = -128.\\ \]
Note que há um número negativo a mais.
Nas linguagens de programação usuais, os números inteiros são definidoc como:
uint64: 0 a 18446744073709551615 (=\(2^{64}-1\)) - ocupando 8 bytes (64 bits).
int64: -9223372036854775808 a 9223372036854775807 - 4 bytes
No FORTRAN todos os inteiros são do tipo INTEGER
Isto não existe no Python - não há limitação para os inteiros.
Números com ponto decimal, chamados de número de ponto flutuante, são do tipo:
\[0.MMMMMMMMMMM\times 10^{EEE},\] onde a parte \(MMMMMMMMMMM\) é chamada de mantissa, e a parte \(EEE\) é o expoente, por exemplo
\[ 123.4567 = 0.1234567\times 10^3,\] onde a mantissa é 1234567 e o expoente é 3.
Em computadores a representação é binária, fazendo o expoente ser na base 2, então:
\[0.\underbrace{bbbbbbbbb}_{m \text{bits}}\times 2^{\underbrace{eee}_{n \text{bits}}}. \]
A representação interna do número vai depender do tipo de computador, mas quase todos seguem a seguinte prescrição (IEEE):Q
Normalmente as representações mais comuns são:
x1 = 0.1
x3 = 0.3
# Vai retornal FALSE
3*x1 == x3
# Uma maneira de calcular igualdades:
# Define uma tolerância
tol = 1e-8
# Calcula se a diferença é menor que a tolerância
abs(3*x1-x3)<tol
Um programa de computador é uma sequência de comandos que são executados imediatamente um após o outro, como nos exemplos acima.
No entanto muitas vezes deseja-se que partes de um programa sejam repetidas, ou que certas partes só executem se certa condição ocorrer. Para isso há algumas formas tradicionais.
x=1
if (x==0):
print('X é igual a 0');
elif (x==1):
print('x é igual a 1');
elif (x==2):
print('x é igual a 2');
else:
print('X é diferente de 0 ou 1 ou 2');
Quando se deseja que uma certa parte de um programa se repita até que uma certa condição seja atingida, usa-se:
O programa abaixo calcula o menor número \(\epsilon\) que somado à 1 produz um número maior do que 1: \[ 1+\epsilon > 1.\] Qualquer número menor que \(\epsilon\) vai dar um resultado \(1+\epsilon=1\).
Rode o programa a baixo e explique o que está acontecendo.
NOTE:
e=1
j=0
fim=False
while not fim:
j=j+1
e=e/2
if (1+e) > 1:
continue
else:
fim=True
print('Número de bits: ' + str(j+1))
print('Valor de e= ' + str(2*e))
Calcule: