Arrays
Não use listas, use np.array
Um erro comum que vejo em iniciantes em Python é o uso excessivo de listas. Para resumir o que poderia ser uma longa aula de estruturas de dados, listas podem ter elementos de diferentes tipos e comprimento dinâmico. Essa flexibilidade causa perda de performance. Só use listas se você realmente precisar desses comportamentos. De forma geral, listas não devem ser usadas para representar vetores/matrizes. Nesse caso a estrutura mais eficiente em termos de memória e processamento são arrays.
Mesmo que a própria linguagem Python tenha um módulo de arrays, historicamente a implementação mais usada é a do Numpy. O uso de arrays numpy é obrigatório no LabIFSC2, usar listas simplesmente retorna erros1. Eu tomei essa decisão para que os alunos de graduação adquiram familiaridade com talvez a mais importante biblioteca científica do Python, o Numpy.
Operações elementares
Com arrays numpy temos a magia da vetorização, ou seja, podemos fazer operações matemáticas entre arrays. O resultado disso são operações elemento a elemento.
import numpy as np
x = np.array([Medida(1, 'm', 0.01), Medida(2, 'm', 0.01)])
y = np.array([Medida(200, 'cm', 1), Medida(400, 'cm', 1)])
print(x + y) # [(3,00 ± 0,01) m (6,00 ± 0,01) m]
print(x - y) # [(-1,00 ± 0,01) m (-2,00 ± 0,01) m]
print(x * y) # [(2,00 ± 0,02) m² (8,00 ± 0,04) m²]
print(x / y) # [(5,00 ± 0,06)x10⁻¹ (5,00 ± 0,03)x10⁻¹ ]
print(y ** 2) # [(4,00 ± 0,04)x10⁴ cm² (1,600 ± 0,008)x10⁵ cm²]
Perceba que isso não é possível com listas.
Operações matemáticas
Como discutido na seção de Funções matemáticas, as funções do Numpy podem atuar diretamente na classe Medida e em arrays de medidas.
import numpy as np
areas=np.array([Medida(4,'cm²',0.01),Medida(9,'m²',0.01),
Medida(16,'km²',0.01)])
lados=np.sqrt(areas)
print(lados) #[(2,000 ± 0,003) cm (3,000 ± 0,002) m (4,000 ± 0,001) km]
linspaceM
Em muitas medidas experimentais fazemos medições igualmente espaçadas. Imagine que você está medindo o campo magnético de um fio em função da sua distância . Você realiza uma medição a cada 1 cm, por exemplo. O lab.linspace recebe o valor da primeira medição, o valor da última, a quantidade de medições entre elas, a unidade e a incerteza da medição. No exemplo abaixo, fizemos 10 medições entre [1 cm, 10 cm], com precisão de 0,05 cm cada.
distancias=linspaceM(1,10,10,'cm',0.05)
print(distancias)
#[(1,00 ± 0,05) cm (2,00 ± 0,05) cm (3,00 ± 0,05) cm (4,00 ± 0,05) cm
#(5,00 ± 0,05) cm (6,00 ± 0,05) cm (7,00 ± 0,05) cm (8,00 ± 0,05) cm
#(9,00 ± 0,05) cm (1,000 ± 0,005)x10¹ cm]
A função é o análogo do np.linspace que recebe medidas.
arrayM
Agora que temos as distâncias, medimos o campo magnético para cada distância. Como registramos esses campos? Teríamos que criar 10 objetos Medida diretamente? Não, a solução é o lab.arrayM. Ele recebe uma lista/array de valores nominais, a incerteza das medidas e a unidade.
campo_magnético=arrayM([250,150,110,90,70,60,55,40,25,20],'muT',1)
#[(2,50 ± 0,01)x10² µT (1,50 ± 0,01)x10² µT (1,10 ± 0,01)x10² µT
#(9,0 ± 0,1)x10¹ µT (7,0 ± 0,1)x10¹ µT (6,0 ± 0,1)x10¹ µT
#(5,5 ± 0,1)x10¹ µT (4,0 ± 0,1)x10¹ µT (2,5 ± 0,1)x10¹ µT]
Nominais
Para obter os valores nominais de um array numpy de medidas, basta usar a função nominais(array_medida, unidade):
campo_magnético=arrayM([250,150,110,90,70,60,55,40,25,20],'muT',1)
print(nominais(campo_magnético,'muT'))
#[250. 150. 110. 90. 70. 60. 55. 40. 25. 20.]
Incertezas
De maneira análoga, podemos também pegar as incertezas com incertezas(array_medida, unidade):
campo_magnético=arrayM([250,150,110,90,70,60,55,40,25,20],'muT',1)
print(incertezas(campo_magnético,'muT'))
#[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
-
Algumas exceções a essa regra é a criação de uma Medida e o arrayM, que ambos podem receber uma lista. Mas perceba que, no caso do arrayM, a lista está sendo usada diretamente para criar um np.ndarray. Então, na prática, você sempre está lidando com arrays. ↩