<jupyter_start><jupyter_text>Table of Contents 1&nbsp;&nbsp;Numpy: Funções indices e meshgrid1.1&nbsp;&nbsp;Operador indices em pequenos exemplos numéricos1.2&nbsp;&nbsp;Operador indices em exemplo de imagens sintéticas1.3&nbsp;&nbsp;Soma1.4&nbsp;&nbsp;Subtração1.5&nbsp;&nbsp;Xadrez1.6&nbsp;&nbsp;Reta1.7&nbsp;&nbsp;Parábola1.8&nbsp;&nbsp;Círculo1.9&nbsp;&nbsp;Meshgrid1.10&nbsp;&nbsp;Gerando os vetores com linspace1.11&nbsp;&nbsp;Exemplo na geração da imagem sinc com meshgrid1.12&nbsp;&nbsp;Exemplo na geração da imagem sinc com indices1.13&nbsp;&nbsp;Documentação Oficial Numpy1.14&nbsp;&nbsp;Referências1.15&nbsp;&nbsp;Para usuários avançados1.16&nbsp;&nbsp;Exemplos com Imagem  Numpy: Funções indices e meshgridAs funções ``indices`` e ``meshgrid`` são extremamente úteis na geração de imagens sintéticas e o seu aprendizado permite tambémentender as vantagens de programação matricial, evitando-se a varredura seqüencial da imagem muito usual na programação na linguagem C. Operador indices em pequenos exemplos numéricosA função ``indices`` recebe como parâmetros uma tupla com as dimensões (H,W) das matrizes a serem criadas. No exemplo a seguir, estamosgerando matrizes de 5 linhas e 10 colunas. Esta função retorna uma tupla de duas matrizes que podem ser obtidas fazendo suas atribuiçõescomo no exemplo a seguir onde criamos as matrizes ``r`` e ``c``, ambas de tamanho (5,10), isto é, 5 linhas e 10 colunas:<jupyter_code>import numpy as np
r,c = np.indices( (5, 10) )
print('r=\n', r)
print('c=\n', c)<jupyter_output>r=
 [[0 0 0 0 0 0 0 0 0 0]
 [1 1 1 1 1 1 1 1 1 1]
 [2 2 2 2 2 2 2 2 2 2]
 [3 3 3 3 3 3 3 3 3 3]
 [4 4 4 4 4 4 4 4 4 4]]
c=
 [[0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]]<jupyter_text>Note que a matriz ``r`` é uma matriz onde cada elemento é a sua coordenada linha e a matriz ``c`` é uma matriz onde cada elemento éa sua coordenada coluna. Desta forma, qualquer operação matricial feita com ``r`` e ``c``, na realidade você está processando ascoordenadas da matriz. Assim, é possível gerar diversas imagens sintéticas a partir de uma função de suas coordenadas.Como o NumPy processa as matrizes diretamente, sem a necessidade de fazer um ``for`` explícito, a notação do programa fica bem simplese a eficiência também. O único inconveniente é o uso da memória para se calcular as matrizes de índices ``r`` e ``c``. Iremosver mais à frente que isto pode ser minimizado. Por exemplo seja a função que seja a soma de suas coordenadas $f(r,c) = r + c$:<jupyter_code>f = r + c
print('f=\n', f)<jupyter_output>f=
 [[ 0  1  2  3  4  5  6  7  8  9]
 [ 1  2  3  4  5  6  7  8  9 10]
 [ 2  3  4  5  6  7  8  9 10 11]
 [ 3  4  5  6  7  8  9 10 11 12]
 [ 4  5  6  7  8  9 10 11 12 13]]<jupyter_text>Ou ainda a função diferença entre a coordenada linha e coluna $f(r,c) = r - c$:<jupyter_code>f = r - c
print('f=\n', f)<jupyter_output>f=
 [[ 0 -1 -2 -3 -4 -5 -6 -7 -8 -9]
 [ 1  0 -1 -2 -3 -4 -5 -6 -7 -8]
 [ 2  1  0 -1 -2 -3 -4 -5 -6 -7]
 [ 3  2  1  0 -1 -2 -3 -4 -5 -6]
 [ 4  3  2  1  0 -1 -2 -3 -4 -5]]<jupyter_text>Ou ainda a função $f(r,c) = (r + c) \% 2$ onde % é operador módulo. Esta função retorna 1 se a soma das coordenadas for ímpar e 0 caso contrário.É uma imagem no estilo de um tabuleiro de xadrez de valores 0 e 1:<jupyter_code>f = (r + c) % 2
print('f=\n', f)<jupyter_output>f=
 [[0 1 0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1 0 1]]<jupyter_text>Ou ainda a função de uma reta $ f(r,c) = (r = \frac{1}{2}c)$:<jupyter_code>f = (r == c//2)
print('f=\n', f)
print('f=\n',f.astype(np.int))<jupyter_output>f=
 [[ True  True False False False False False False False False]
 [False False  True  True False False False False False False]
 [False False False False  True  True False False False False]
 [False False False False False False  True  True False False]
 [False False False False False False False False  True  True]]
f=
 [[1 1 0 0 0 0 0 0 0 0]
 [0 0 1 1 0 0 0 0 0 0]
 [0 0 0 0 1 1 0 0 0 0]
 [0 0 0 0 0 0 1 1 0 0]
 [0 0 0 0 0 0 0 0 1 1]]<jupyter_text>Ou ainda a função parabólica dada pela soma do quadrado de suas coordenadas $$ f(r,c) = r^2 + c^2 $$:<jupyter_code>f = r**2 + c**2
print('f=\n', f)<jupyter_output>f=
 [[ 0  1  4  9 16 25 36 49 64 81]
 [ 1  2  5 10 17 26 37 50 65 82]
 [ 4  5  8 13 20 29 40 53 68 85]
 [ 9 10 13 18 25 34 45 58 73 90]
 [16 17 20 25 32 41 52 65 80 97]]<jupyter_text>Ou ainda a função do círculo de raio 4, com centro em (0,0) $f(r,c) = (r^2 + c^2 < 4^2)$:<jupyter_code>f = ((r**2 + c**2) < 4**2)
print('f=\n', f * 1)<jupyter_output>f=
 [[1 1 1 1 0 0 0 0 0 0]
 [1 1 1 1 0 0 0 0 0 0]
 [1 1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]<jupyter_text>Operador indices em exemplo de imagens sintéticasVejamos os exemplos acima, porém gerados em imagens. A diferença será no tamanho da matriz, iremos utilizar matriz (200,300), ea forma de visualizá-la através do ``adshow``, ao invés de imprimir os valores como fizemos acima. Como muitas vezes o resultado das funções poderão estar forada faixa 0-255 admitida pelo ``adshow``, iremos sempre normalizar os valores finais da imagem calculada para a faixa 0-255 utilizandoa função `ia636:ianormalize ianormalize` da toolbox ia636.Gerando as coordenadas utilizando ``indices``:Observe que o parâmetro de ``indices`` é uma tupla. Verifique o número de parêntesis utilizados:<jupyter_code>import numpy as np
import sys,os
ea979path = os.path.abspath('../../')
if ea979path not in sys.path:
    sys.path.append(ea979path)
import ea979.src as ia
nb = ia.nbshow(3)
r,c = np.indices( (200, 300) )
rn = ia.normalize(r)
cn = ia.normalize(c)
nb.nbshow(rn,'rn:linhas')
nb.nbshow(cn,'cn:colunas',flush=True)<jupyter_output><empty_output><jupyter_text>SomaFunção soma: $f(r,c) = r + c$:<jupyter_code>f = r + c
ia.adshow(ia.normalize(f),'r + c')<jupyter_output><empty_output><jupyter_text>SubtraçãoFunção subtração $f(r,c) = r - c$:<jupyter_code>f = r - c
ia.adshow(ia.normalize(f),'r - c')
%matplotlib inline
import matplotlib.pyplot as plt
plt.imshow(f,cmap='gray')
plt.colorbar()<jupyter_output><empty_output><jupyter_text>XadrezFunção xadrez $f(r,c) = \frac{(r + c)}{8} \% 2$. Aqui foi feita a divisão por 8 para que o tamanho das casas do xadrez fique 8 x 8, casocontrário é muito difícil de visualizar o efeito xadrez pois a imagem possui muitos pixels.:<jupyter_code>f = (r//8 + c//8) % 2
ia.adshow(ia.normalize(f),'(r//8 + c//8) % 2')<jupyter_output><empty_output><jupyter_text>RetaOu ainda a função de uma reta $f(r,c) = (r = \frac{1}{2} c)$:<jupyter_code>f = (r == c//2)
ia.adshow(f,'r == c//2')<jupyter_output><empty_output><jupyter_text>ParábolaFunção parabólica: $f(r,c) = r^2 + c^2$:<jupyter_code>f = r**2 + c**2
ia.adshow(ia.normalize(f),'r**2 + c**2')<jupyter_output><empty_output><jupyter_text>CírculoFunção do círculo de raio 190, $f(r,c) = (r^2 + c^2 < 190^2)$:<jupyter_code>f = (r**2 + c**2 < 190**2)
ia.adshow(ia.normalize(f),'r**2 + c**2) < 190**2')<jupyter_output><empty_output><jupyter_text>Meshgrid   A função ``meshgrid`` é semelhante à  função ``indices`` vistoanteriormente, porém, enquanto ``indices`` gera as coordenadas inteiras não negativas a partir de um ``shape(H,W)``, o ``meshgrid`` gera os valores das matrizes a partir de dois vetores de valores reais quaisquer, um para as linhas e outro para as colunas.Veja a seguir um pequeno exemplo numérico. Para que o ``meshgrid`` fique compatível com a nossa convenção de (linhas,colunas), deve-seusar o parâmetro ``indexing='ij'``.<jupyter_code>import numpy as np
r, c = np.meshgrid( np.array([-1.5, -1.0, -0.5, 0.0, 0.5]), 
                    np.array([ -20,  -10,    0,  10,  20, 30]), indexing='ij')
print('r=\n',r)
print('c=\n',c)<jupyter_output>r=
 [[-1.5 -1.5 -1.5 -1.5 -1.5 -1.5]
 [-1.  -1.  -1.  -1.  -1.  -1. ]
 [-0.5 -0.5 -0.5 -0.5 -0.5 -0.5]
 [ 0.   0.   0.   0.   0.   0. ]
 [ 0.5  0.5  0.5  0.5  0.5  0.5]]
c=
 [[-20 -10   0  10  20  30]
 [-20 -10   0  10  20  30]
 [-20 -10   0  10  20  30]
 [-20 -10   0  10  20  30]
 [-20 -10   0  10  20  30]]<jupyter_text>Gerando os vetores com linspaceA função ``linspace`` gera vetor em ponto flutuante recebendo os parâmetro de valor inicial, valor final e número de pontos do vetor.Desta forma ele é bastante usado para gerar os parâmetro para o ``meshgrid``. Repetindo os mesmos valores do exemplo anterior, porém usando ``linspace``. Observe que o primeiro vetor possui 5 pontos,começando com valor -1.5 e o valor final é 0.5 (inclusive). O segundo vetor possui 6 pontos, começando de -20 até 30:<jupyter_code>rows = np.linspace(-1.5, 0.5, 5)
cols = np.linspace(-20, 30, 6)

print('rows:', rows)
print('cols:', cols)<jupyter_output>rows: [-1.5 -1.  -0.5  0.   0.5]
cols: [-20. -10.   0.  10.  20.  30.]<jupyter_text>Usando os dois vetores gerados pelo ``linspace`` no ``meshgrid``:<jupyter_code>r, c = np.meshgrid(rows, cols, indexing='ij')
print('r = \n', r)
print('c = \n', c)<jupyter_output>r = 
 [[-1.5 -1.5 -1.5 -1.5 -1.5 -1.5]
 [-1.  -1.  -1.  -1.  -1.  -1. ]
 [-0.5 -0.5 -0.5 -0.5 -0.5 -0.5]
 [ 0.   0.   0.   0.   0.   0. ]
 [ 0.5  0.5  0.5  0.5  0.5  0.5]]
c = 
 [[-20. -10.   0.  10.  20.  30.]
 [-20. -10.   0.  10.  20.  30.]
 [-20. -10.   0.  10.  20.  30.]
 [-20. -10.   0.  10.  20.  30.]
 [-20. -10.   0.  10.  20.  30.]]<jupyter_text>Podemos agora gerar uma matriz ou imagem que seja função destes valores. Por exemplo ser o produto deles:<jupyter_code>f = r * c
print('f=\n', f)<jupyter_output>f=
 [[ 30.  15.  -0. -15. -30. -45.]
 [ 20.  10.  -0. -10. -20. -30.]
 [ 10.   5.  -0.  -5. -10. -15.]
 [ -0.  -0.   0.   0.   0.   0.]
 [-10.  -5.   0.   5.  10.  15.]]<jupyter_text>Exemplo na geração da imagem sinc com meshgridNeste exemplo, geramos a imagem da função $ sinc(r,c)$ em duas dimensões, nos intervalos na vertical, de -5 a 5 e nahorizontal de -6 a 6. A função sinc é uma função trigonométrica que pode ser utilizada para filtragens.A equação é dada por:$$    sinc(r,c) = \frac{\sin(r^2 + c^2)}{r^2 + c^2}, \text{para\ } -5 \leq r \leq 5, -6 \leq c \leq 6 $$Na origem, tanto r como c são zeros, resultando uma divisão por zero. Entretanto pela teoria dos limites, $\frac{sin(x)}{x}$ éigual a 1 quando $x$ é igual a zero.Uma forma de se obter isto em ponto flutuante é somar tanto no numerador como no denominador um *epsilon*, que é amenor valor em ponto flutuante. Epsilon pode ser obtido pela função ``np.spacing``.<jupyter_code>e = np.spacing(1) # epsilon to avoid 0/0
rows = np.linspace(-5.0, 5.0, 150) # coordenadas das linhas
cols = np.linspace(-6.0, 6.0, 180) # coordenadas das colunas
r, c = np.meshgrid(rows, cols, indexing='ij') # Grid de coordenadas estilo numpy
z = np.sin(r**2 + c**2 + e) / (r**2 + c**2 + e) # epsilon is added to avoid 0/0
ia.adshow(ia.normalize(z),'Função sinc: sen(r² + c²)/(r²+c²) em duas dimensões')
plt.imshow(z)
plt.colorbar()<jupyter_output><empty_output><jupyter_text>Exemplo na geração da imagem sinc com indicesOutra forma de gerar a mesma imagem, usando a função ``indices`` é processar osindices de modo a gerar os mesmos valores relativos à grade de espaçamento regularacima, conforme ilustrado abaixo:<jupyter_code>n_rows = len(rows)
n_cols = len(cols)
r,c = np.indices((n_rows,n_cols))
r = -5. + 10.*r.astype(float)/(n_rows-1)
c = -6. + 12.*c.astype(float)/(n_cols-1)
zi = np.sin(r**2 + c**2 + e) / (r**2 + c**2 + e) # epsilon is addes to avoid 0/0
ia.adshow(ia.normalize(zi),'Função sinc: sin(r² + c²)/(r²+c²) em duas dimensões')<jupyter_output><empty_output><jupyter_text>Verificando que as duas funções são iguais:<jupyter_code>print('Máxima diferença entre z e zi?', abs(z - zi).max())
np.exp(-1/2.)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14389597057062195, 'fraction_numerical': 0.08306955257079306, 'mean_word_length': 3.449942900647126, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 25, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '17366', 'license': 'MIT', 'n_tokens_mistral': 5568, 'n_tokens_neox': 5017, 'n_words': 1732, 'path': 'master/tutorial_numpy_1_7.ipynb', 'repo_name': 'lrittner/ia979', 'size': '11689'}