M ´etodos Computacionais em F´ısica I
Sandra Amato
Instituto de F´ısica
Universidade Federal do Rio de Janeiro
Containers
Ü At ´e agora vimos vari ´aveis do tipo inteiro, float, complex, bool, string. Todas elas armazenam um ´unico valor de cada vez.
Ü Em diversas aplicac¸ ˜oes, seria muito ´util poder associar diversos valores a uma ´unica vari ´avel, p. ex:
m vetor posic¸ ˜ao de uma part´ıcula: ~r = (x , y , z)
m notas dos alunos de uma turma
m medidas experimentais de uma certa quantidade
m uma matriz m × n
Ü Em vez de termos que criar uma vari ´avel para cada valor
x = . . . , y = . . . , z = . . ., poder´ıamos ter uma chamada r composta de quantos elementos quisermos, e acessar´ıamos cada um deles atrav ´es de ´ındices: r = {ri}.
Ü Essas estruturas s ˜ao chamadas decontainers
Ü Todas as linguagens oferecem essa funcionalidade
Ü Em Python, as principais s ˜aolists, arrays, tuples, dicts e sets
Lists
Ü Umalist´e um conjunto de valores (elementos), de qualquer tipo
Ü Para criar uma lista:
>>> r = [1, 1, 2, 3, 5, 8, 13] >>> print (r)
[1, 1, 2, 3, 5, 8, 13]
Ü Os elementos devem estar entre colchetes e separados por v´ırgulas
Ü Cada elemento est ´a associado `a um ´ındice, que reflete a sua posic¸ ˜ao.
Ü Atenc¸ ˜ao: o ´ındice comec¸a com zero!!!
>>> from math import sqrt >>> vel = [1, 1.5, -2.2] >>> vel[1]
1.5
>>> modulo_vel = sqrt(vel[0]**2 + vel[1]**2 + vel[2]**2 ) >>> modulo_vel
Operac¸ ˜
oes com Lists
Ü Para alterar algum valor da lista: >>> vel = [1, 1.5, -2.2] >>> vel[1] = 3.5
>>> print (vel) [1, 3.5, -2.2]
Ü para acrescentar um elemento `a lista: >>> vel.append(6.1)
>>> print (vel) [1, 3.5, -2.2, 6.1]
Ü E usual criar uma lista vazia e ir acrescentando elementos:´ >>> r = []
>>> r.append(1) >>> r.append(1.5)
>>> r.append(-2.2) >>> print (r) [1, 1.5, -2.2]
Ü >>> r[-1] # -1 ´e o ´ındice do ´ultimo elemento -2.2
Operac¸ ˜
oes com Lists
>>> r.append(3.1) # acrescenta um elemento >>> r
[1, 1.5, -2.2, 3.1]
>>> r.pop() # remove o ´ultimo elemento 3.1
>>> r
[1, 1.5, -2.2]
>>> del r[1] # remove o elemento na segunda posic¸˜ao >>> r
[1, -2.2]
>>> r.insert(1,1.5) #insere 1.5 na segunda posic¸˜ao >>> r
[1, 1.5, -2.2] >>> len(r) 3
>>> sum(r) #soma de todos os elementos 0.2999999999999998
Operac¸ ˜
oes com Lists
>>> r.index(-2.2) # obter ´ındice do elemento -2.2 2 >>> r = r + [3.1, 4.5] # concatenar listas >>> r [1, 1.5, -2.2, 3.1, 4.5] >>> x = 3.0 >>> y = 7.1
>>> pos = [x,y] #criac¸˜ao de lista usando vari´aveis >>> pos
[3.0, 7.1]
>>> x = 4 # alterar a vari´avel N˜AO altera a lista >>> pos
[3.0, 7.1]
>>> w = [x**2, 2*x*y, y**2] #criac¸˜ao de lista usando f´ormulas >>> w
[16.0, 56.8, 50.41] >>> 56.8 in w
True
Operac¸ ˜
oes com Lists
Ü Uma func¸ ˜ao de lista muito ´util ´e a map. Permite aplicar uma operac¸ ˜ao a todos os elementos de uma lista de uma vez:
>>> from math import log >>> r = [1.0, 1.5, 2.2] >>> logr = list(map(log,r)) >>> logr
[0.0, 0.4054651081081644, 0.7884573603642703]
Ü Extrac¸ ˜ao de subLists: Para extrair uma parte da lista A, usamos a sintaxe: A[i:j]. Ser ´a extra´ıda uma sublista que comec¸a com o elemento A[i] e termina com o elemento A[j-1]
>>> A = [2, 3.5, 8, 10] >>> A[1:3] [3.5, 8] >>> A[2:] [8, 10] >>> A[:3] [2, 3.5, 8]
Operac¸ ˜
oes com Lists
Construc¸ ˜ao Significado
a.remove(e) remove o elemento de valor e da lista a
a.index(e) encontra o ´ındice correspondente ao elemento de valor e e in a testa se e est ´a contido em a (True ou False)
a.count(v) conta quantos elementos possuem o valor v len(a) numero de elementos de a
min(a) menor elemento de a max(a) maior elemento de a
sum(a) soma todos os elementos de a
sorted(a) retorna uma vers ˜ao em ordem crescente (ou alfab ´etica) de a reversed(a) retorna uma vers ˜ao invertida (de tr ´as pra frente) de a ***
b[3][0][2] indexac¸ ˜ao de listas aninhadas (listas de listas). isinstance(a, list) True se a for do tipo list
type(a) is list True se a for do tipo list
*** : A func¸ ˜ao reversed(a) n ˜ao retorna uma lista diretamente. Para
visualizarmos ela diretamente como uma lista, devemos usar list(reversed(a))
For Loops
Ü
Vimos a instruc¸ ˜ao while que ´e uma forma de repetir um bloco de
comandos (loops)
Ü
Uma outra forma de fazer loop no Python ´e a instruc¸ ˜ao for
Ü
ela ´e mais conveniente para trabalhar com listas (e arrays como
veremos adiante)
For Loops
fahrenheit.py graus = [0, 5, 10, 15, 20, 25] for C in graus: F = (9/5) * C + 32 print ("%5d %7.2f" %(C,F)) print ("a lista possui \%d elementos" %len(graus)) $ python3 fahrenheit.py C F 0 32.00 5 41.00 10 50.00 15 59.00 20 68.00 25 77.00
a lista possui 6 elementos
m graus ´e uma lista de n ´umeros inteiros
m C ´e um iterator
m ao entrar no for, C recebe o valor do primeiro elemento
m os comandos identados s ˜ao executados
m ao t ´ermino dos comandos identados, C ´e atualizado com o segundo valor da lista
m e assim por diante at ´e chegar ao ´ultimo valor
m ao t ´ermino do loop, o programa segue para a pr ´oxima linha do c ´odigo
For Loops
Ü
Um loop do tipo for pode sempre ser transformado em um do
tipo while
graus = [0, 5, 10, 15, 20, 25]
indice = 0
while (indice < len(graus)):
F = (9./5) * graus[indice] + 32
print ("%5d %7.2f" %(graus[indice],F))
indice +=1
print ("a lista possui %d elementos" %len(graus))
Ü
mas nem sempre um do tipo while pode ser transformado em
um do tipo for
A func¸ ˜ao range
Ü Criamos a lista graus com 6 elementos, de 0 a 25, em passos de 5
Ü ... mas e se quisermos criar uma lista com um n ´umero muito grande de elementos?
Ü A func¸ ˜aorange ´e usada para esse fim
Ü range(n)gera iterators com valoresinteirosde 0 a n − 1 em passos de 1
for i in range(4): print (i, i**2) 0 0 1 1 2 4 3 9 Ü range(2,5) gera [2, 3, 4] range(2, 17, 3) gera [2, 5, 8, 11, 14] range(17, 2, -3) gera [17, 14, 11, 8, 5]
Somat ´
orio
Ü J ´a realizamos o c ´alculo de uma soma utilizando while
Ü Com o for ´e mais simples
100 X n=1 1 n N = 100 soma = 0 for n in range(1,N+1): soma += 1/n
#print ("soma %f" %soma) print ("soma %f" %soma)
Ü Somas matem ´aticas aparecem com muita frequencia. Lembre desta implementac¸ ˜ao
Alterando os valores dos elementos de uma lista
Ü O for tamb ´em ´e ´util para alterarmos os valores dos elementos de uma lista >>> posicao = [1, 3, -2] >>> for i in range(len(posicao)): ... posicao[i] += 5 ... >>> posicao [6, 8, 3]
Exerc´ıcios
Ü
Escreva um algoritmo, que use o loop do tipo for, para calcular a
s ´erie
sin(x ) ≈
∞X
n=0(−1)
n(2n + 1)!
x
2n+1≈ x −
x
33!
+
x
55!
−
x
77!
+ . . .
Ü
Implemente esse algoritmo em Python. Use a func¸ ˜ao factorial
do m ´odulo math
Ü
teste com x = 1.2 e n = 5. Compare com o valor de sin(1.2) do
m ´odulo math
Exerc´ıcios
ÜEm 1888 Johannes Rydberg publicou a f ´ormula que fornece os comprimentos de onda λ das linhas de emiss ˜ao do ´atomo de hidrog ˆenio:
1 λ =R 1 m2 − 1 n2
onde R ´e a constante de Rydberg R = 1.097 × 10−2nm−1e m e n s ˜ao inteiros positivos. Para um dado valor de m, teremos uma s ´erie de linhas para todos os valores de n > m. As 3 primeiras s ´eries, m = 1, 2, 3 s ˜ao conhecidas como s ´eries de Lyman, Balmer e Paschen. Os valores de λ das 5 primeiras linhas de cada s ´erie s ˜ao:
Serie para m = 1 121.54 nm 102.55 nm 97.23 nm 94.96 nm 93.76 nm Serie para m = 2 656.34 nm 486.17 nm 434.08 nm 410.21 nm 397.04 nm Serie para m = 3 1875.24 nm 1281.91 nm 1093.89 nm 1005.01 nm 954.67 nm
ÜEscreva um algoritmo para o c ´aculo de λ e implemente-o em Python(Rydberg.py)
Pacote Numpy
Numpy
E o pacote do Python mais fundamental para computac¸ ˜ao
´
cient´ıfica.
Ele cont ´em, entre outras coisas:
Ü
arrays e matrizes
Ü
func¸ ˜oes matem ´aticas sofisticadas
Ü
ferramentas de ´algebra linear
Ü
transformada de Fourier
Ü
geradores de n ´umeros aleat ´orios
Array
Ü Em computac¸ ˜ao cient´ıfica lidamos com um conjunto grande de n ´umeros
Ü Vimos que uma List ´e um recurso que pode armazenar esse conjunto
Ü Por ´em para um conjunto grande de n ´umeros a List ´e muito lenta
Ü Existe um outro tipo de container, o Array, definido no m ´odulo numpy:
m ´e muito mais r ´apido, especialmente se contiver muitos n ´umeros
m j ´a tem os m ´etodos matem ´aticos, como se fossem aplicados a vetores, p. ex. soma de dois arrays, etc. Assim n ˜ao ´e necess ´ario fazer loops sobre os elementos
m pode ser bi-dimensional, para aplicac¸ ˜oes com matrizes
m usado no m ´odulo de visualizac¸ ˜ao de gr ´aficos matplotlib
Ü Duas diferenc¸as importantes entre Array e List:
m todos os elementos devem ser do mesmo tipo (float, int ...)
m o n ´umero de elementos deve ser conhecido na criac¸ ˜ao, n ˜ao pode ser modificado posteriormente
Inicializac¸ ˜ao de um Array
Podemos inicializar um array de v ´arias formas(detalhes nosite do SciPy)
>>> import numpy as np
>>> a = np.zeros(4) # cria array com 4 el. com 0. (float) >>> print (a)
[0. 0. 0. 0.] # repare que ´e sem v´ırgula
>>> b = np.zeros(4, int) # para que os elementos sejam int >>> r = np.empty(1000) # cria com 1000 el. vazios (lixo) >>> umaLista = [1., 1.5, -2.2] # uma lista pode ser >>> umArray = np.array(umaLista) # convertida em array >>> umArray = np.array([5, 10, 15], float)
array([ 5., 10., 15.])
>>> s = np.linspace(0, 2, 3) # (in´ıcio, fim, num. elem)
array([0., 1., 2.]) # inclui o ´ultimo. sempre float
>>> s = np.arange(1, 8, 2) # (in´ıcio, fim, passo)
array([1, 3, 5, 7]) # n˜ao inclui o ´ultimo.
>>> w = np.arange(5) array([0, 1, 2, 3, 4])
Inic. de um Array c/ valores lidos de arquivo
Ü Uma outra forma de criar um array ´e atrav ´es da leitura dos valores armazenados em um arquivo
Ü Bastante ´util para ler dados obtidos em um experimento, ou gerados por outro programa
Ü Suponha que tenhamos um arquivo valores.txt com o seguinte conte ´udo:
1.0 1.5 -2.2
Para l ˆe-los em um array:
>>> from numpy import loadtxt >>> a = loadtxt ("valores.txt") >>> print (a)
[ 1. 1.5 -2.2]
ÜRepare que n ˜ao ´e preciso saber o n ´umero de linhas do arquivo
Operac¸ ˜
oes com arrays
Ü Como nas lists, podemos fazer operac¸ ˜oes com os elem. individuais: x = a[2]**2 - 2 * a[3]/y
Ü Mas, diferentemente das lists podemos fazer operac¸ ˜oes em todo o array de uma s ´o vez (vectorizing)Üc ´odigo mais simples e maior velocidade de execuc¸ ˜ao.
Ü em geral a regra ´e fazer a mesma operac¸ ˜ao em todos os elem. do array >>> from numpy import array
>>> a = array([1, 2, 3, 4], int)
>>> b = 2 * a # ´E tamb´em uma forma de criar um array >>> b
array([2, 4, 6, 8])
>>> print (a + b) # a e b tem que ter mesmo tamanho
[ 3 6 9 12]
>>> print (a * b) # Atenc¸˜ao! N˜ao ´e produto escalar
Operac¸ ˜
oes com arrays
ÜPara obter o produto escalar entre dois arrays: >>> from numpy import array, dot >>> a = array([1,2,3])
>>> b = array([2,4,6]) >>> print (dot(a,b)) 28
ÜDiferenc¸a entre func¸ ˜oes do m ´odulo math e numpy >>> from numpy import array, sin, pi
>>> angulo = array([0, pi/6, pi/4, pi/3, pi/2]) >>> sin_angulo = sin(angulo)
>>> sin_angulo
array([0. , 0.5 , 0.70710678, 0.8660254 , 1. ])
ÜA func¸ ˜ao do m ´odulo numpy pode atuar tamb ´em sobre arrays. A do math s ´o atua sobre vari ´aveis simples
C ´
opias de arrays
>>> from numpy import array >>> a = array([1, 1])
>>> b = a >>> a[0] = 2 >>> print(a, b) [2 1] [2, 1]
Üb = a n ˜aocria uma nova c ´opia do array. ´E simplesmente um novo nome associado `a mesma regi ˜ao de mem ´oria. Ao mudar algum elemento de a , b tamb ´em ser ´a alterado.
ÜPara fazer uma c ´opia:
>>> from numpy import array, copy >>> a = array([1, 1])
>>> b = copy(a) >>> a[0] = 2 >>> print(a,b) [2 1] [1 1]
Exerc´ıcio
Ü Crie um arquivo (media.txt) com algumas linhas que contenham um n ´umero real (0 - 10) por linha. Esse n ´umero pode representar, por exemplo, as notas de cada aluno de uma turma
Ü Escreva um algoritmo e implemente o programa em Python (media.py) que leia esses n ´umeros para um array e imprima:
m o n ´umero de alunos da turma
m a m ´edia da turma µ, com uma casa decimal
m o desvio padr ˜ao σ (com uma casa decimal) , dado por σ2= 1 N − 1 N X 1 (xi− µ)2= 1 N − 1 N X 1 xi2 ! − N N − 1µ 2
m o numero de alunos que passaram direto: nota ≥ 7.
m o numero de alunos reprovados: nota < 3.
Ü Nota: O m ´odulo numpy tamb ´em oferece as func¸ ˜oes min, max, sum, lenpara array